Reversing/Debugging - Identifying symlinks in applications - linux

I was wondering, is there any guidlines for identifying symlink related function in an application binary?
Let's take BusyBox for example, /bin/ping is a symlink to /bin/BusyBox.
How can I know identify the ping related functions within the BusyBox binary?
Thanks in advance :)

You can't generally do that.
In case of BusyBox, it checks upon startup which commandline was invoked to execute the binary (including the path to the binary itself). It then calls functions that provide the functionality that was selected based on the basename of the binary / symlink.
Again in case of BusyBox, most of the times the funktion names are closely related to the command name. But this is basically just coincidence: it could well be that someone created an exectable "A" that would call a function "X" when started via a symlink name "B" and function "Y" when called as "C".

Related

How to resolve system directories paths independently of system locale?

TLDR
I need to get paths to system directories like "Screenshots":
On an English system. I can just use this one:
C:/Users/User/Pictures/Screenshots
How do I get the path to "Screenshots" directory on a non-English system?
C:/Users/User/Pictures/[NAME]
Description
I have a file manager app, it displays system directories and loads them on click.
The app can run system commands via Powershell and use Node.js (preferred)
Problem
The problem is, it only works if the system has English system language.
Currently, to resolve the "Screenshots" directory path, the app simply joins the User directory with the word "Screenshots"
const pictures = electronRemote.app.getPath('pictures')
const screenshots = PATH.join(pictures, 'Screenshots')
link to the line in code
Expectedly, the C:/Users/User/Screenshots path only exists on English systems.
One way to solve this is to use short names, at least on Windows, I know that system directories have short names like SCREEN~1 and WALLPA~1 for Screenshots and Wallpapers directories, but if I use these names the paths will look like this:
C:/Users/User/SCREEN~1 instead of C:/Users/User/Screenshots throughout the app.
And even if I were to run these paths through a function to convert it to readable name, how would I know which word to replace it with? I need to get the name in the system's language.
Are these translations stored somewhere on the system? Can I just retrieve the translated directory name and use that in the code above?
Question
How do I make it to get / resolve the actual path of system directories like Screenshots and Wallpapers, independently of system locale?
If you know how to do it, could you please suggest the solution for all platforms (Win, Mac, Linux)?
Should I just use the short names like SCREEN~1 and then automatically replace all the occurrences in UI and also filter all paths through a function that replaces this short name with the actual path throughout the whole app? Seems like a lot of work, this approach

Replace a file temporarily during an sh script run

I use an sh script to start an application in the background after setting several environment variables. I use temporary variables to start binaries from different places using LD_LIBRARY_PATH and temporary variables. Problem is that the application loads one *.so file from a hardcoded path which I cannot change. Currently I solve this problem manually by replacing the hardcoded file location with a symbolic link.
Can you tell me if there is a clean solution to solve this from the sh script? Basically what I want is that a certain file location is switched with a different binary only for open calls from the application the script starts, for all other processes it should stay the same.
Regards.
Example methods to replace open("/the/original") with open("/some/other"):
One simple method is modifying a pathname within an executable.
First copy the original executable to something like "modified" and run
a utility like bvi (similar to vim).
Consider 2 cases from comparing the length of the new vs. original pathnames:
when (new-length <= original-length), overwrite the original pathname in place
when (new-length > original-length), create a short symlink that references
the new longer pathname like the example below, then overwrite the original pathname
with the short symlink pathname,
ln -s /full/path/some/new/file /shorter
For both cases, remember to include a trailing NULL byte.
After saving changes with bvi, test the newly copied+altered executable.
Once "modified" is working to plan, could also rename for convenience:
mv xyz xyz.orig
mv modified xyz
Another method can serve a transparency requirement.
Create a dynamic library (eg custom.so) with a wrapper routine for
open() which conditionally replaces the pathname and calls the real
libc open(). Run the unmodified original executable (xyz) with another
environment variable, eg:
LD_PRELOAD=/path/to/custom.so xyz
There are some tradeoffs with versatility and modest complexity;
the original xyz is left unchanged and can always be run with/without LD_PRELOAD;
some might consider added overhead from a wrapper as undesirable;
doesn't work with statically-linked or set-uid executables.
Many articles provide instructions for creating a preload library, re-using
an original symbol like open() (frequent example is malloc()), call dlsym() once to find the regular libc open(), saving the result as a function pointer, and calling libc open() indirectly.

Can an executable dynamically resolve its location on the filesystem or its actual "resting place" vs just the working directory of the user?

If I have an executable in /usr/bin and call it while I'm located at ~/dev/wikis/ (that is user#HAL:~/dev/wikis$ the_executable), the ioutil.ReadFile("file.txt") function in the executable will look in /home/user/dev/wikis/file.txt, but is it possible to make it look in /usr/bin/file.txt instead without the user or developer knowing beforehand that the executable will be located in /usr/bin (it could just as well be located in /home/user/dev/my_program/the_executable)?
And then to add a layer of complexity, another situation, say I call the executable from a symbolic link in /usr/bin with the "source" of the executable actually being in /home/user/dev/my_program/the_executable, and I want the program to know about /home/user/dev/my_program/ in this case, dynamically, rather then /usr/bin.
In short: How can an executable dynamically resolve its location on the filesystem or its actual "resting place" vs the working directory of the user (which can easily be gotten through os.Getwd() and which other commands like ioutil.ReadFile use, or use something comparible, for resolving paths).
My best bet is that I have to get the PID of the running program (os.Getpid) and then somehow use that integer to access information about the instance of the program running under that PID, and hopefully that information contains a string of its directory which I can then use.
In Linux (and perhaps in other Unixy systems) you'll find a symbolic link to the actual executable running as pid under /proc/pid/exe, checking that one will give what you want if it is a binary. If it is a script of some sort, that will probably just give the interpreter.
But note that it is perfectly possible to start a process and delete the executable while it is running, leaving either a dangling link or just nothing.
This will depend on the language but as far as I know most programming languages have a way to get either the 'basename' of the program, e.g. helloworld, or the full path, e.g. /usr/bin/helloworld. Often this is provided as the first argument to the program, inserted by the OS/runtime library/interpreter, etc. For example, in C, argv[0] (as we start counting from 0 in C) gives the name of the current program, but the calling process initialises this special argument so the exact format can vary, and in bash, $0 will expand into the path of the script as given when executed (I think). From here: https://gobyexample.com/command-line-arguments, "os.Args provides access to raw command-line arguments. Note that the first value in this slice is the path to the program, and os.Args[1:] holds the arguments to the program." So it appears you don't need to worry about /proc but if you're interested, How do I find the location of the executable in C?
The exported variable os.Args (which is a slice: []string) holds the program arguments, its first element being the executable name with full path.
If the executable is not a symlink, you can use the path or filepath packages to get the folder of the executable like this:
folder := filepath.Dir(os.Args[0])
And you can use os.Readlink() to resolve a symbolic link.
And to test if your executable is a symlink, you can use os.Lstat() which makes no attempt to follow a link (as opposed to os.Stat()).
So your final version should look like this:
s := os.Args[0]
fi, err := os.Lstat(s)
if err != nil {
panic(err) // Failed to get stats
}
// Check if it's a symlink and if so, try to resolve it
if fi.Mode()&os.ModeSymlink != 0 {
if s, err = os.Readlink(s); err != nil {
panic(err) // Failed to resolve symlink
}
}
s = filepath.Dir(s) // We only want the folder part

build variable in Linux kernel Makefile

I am currently trying to understand the build process for the Linux kernel. While looking through the Makefiles, I found several rules in the form
scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic
$(Q)rm -f .tmp_quiet_recordmcount
which all recursively call other make processes and also pass the directory to process. Simultaneously, there seems to be a variable, which is passed, indicating what to do with the subdirectory (the $(build) part.
Looking at the make process, as far as I can see, this always seems to be obj, I cannot find any other value for this variable so far during the make process. Also, I cannot seem to find any place where this variable is set.
So what exactely is this variable for and how is it used (e.g., where is set and processed).
Not exactly. The relevant bit is in scripts/Kbuild.include, where it says
build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
What this means is that if $(KBUILD_SRC) is not empty, the path to scripts/Makefile.build is given as an absolute path (or at least with a path that can be found from the working directory) by prepending the path to the top of the kernel source tree. As far as I can tell, this is to make the sub-makes all use the same Makefile and avoid having the same make code several dozen times.

how to find a library that's being included in a lua application

I'm kinda new to linux so you'll have to pardon my question if it's really basic. I have a code snippet that includes the following line:
require("axf.sf")
I am trying to find the file that contains this code.
I've tried the following commands on my server:
find / -name axf.sf
find / -name axf.sf*
But I can't locate it. I know the code exists because the program works.
any suggestions would be appreciated.
Lua, like many languages, has the concept of a "path" to search for required modules.
It can be configured by several means, but it's usually something like
./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua;/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua
(you can verify if your's is different by checking typing =package.path at a Lua prompt)
The default package searcher first takes the package name ("axf.sf" in your example) and replaces each dot with the OS's directory separator. ("axf/sf" in your example, since you're on Linux). Then it replaces the ? on each pattern with the transformed package name, and uses the first one that exists on your system.
so, it would search for
./axf/sf.lua
/usr/local/share/lua/5.1/axf/sf.lua
/usr/local/share/lua/5.1/axf/sf/init.lua
/usr/local/lib/lua/5.1/axf/sf.lua
/usr/local/lib/lua/5.1/axf/sf/init.lua
/usr/share/lua/5.1/axf/sf.lua
/usr/share/lua/5.1/axf/sf/init.lua

Resources