Can I get module handle from function address on linux? - linux

Same as Win32:
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)(void*)(myFunc), &h);
http://www.kernel.org/doc/man-pages/online/pages/man3/dlsym.3.html is not helpful.

Use dladdr. Documentation here.

Not per se, no; if the symbol was compiled in instead of accessed via dlopen()/dlsym(), then there is no handle to be returned. (The handle abstraction only exists to enable dlsym() fine control over where it loads symbols from; there is no such control over the original link, except via linker scripts.) In the normal course of events, an object is simply open()ed and mmap()ed, other details being hidden within ld.so and only accessible indirectly via RTLD_DEFAULT and RTLD_NEXT parameters to dlsym(). If you are using dlopen(), you are expected to keep track of your handles.

The only method I am aware of is to parse the contents of /proc/self/maps (and/or perhaps smaps) and then use the symbol address to calculate from the boundaries of the mapped .so (start and its size) within which mapped module the function lies.
Note: /proc/self is a symlink (on Linux) to the current process's (with ID <pid>) meta-information, i.e. /proc/<pid>.
It's possible there is some programming interface to this very information that you could use.
Edit: Ah, so dladdr() would be that interface.

Related

Linux ELF shared library issue

Currently I am working with ELF files and trying to deal with loading SO files. I am trying to "forcibly" link a new (a fake one, without actual calls to the code) SO dependency into executable file. To do that, I modified the .dynstr section contents (created a new section, filled it with the new contents, and resolved all sh_link fileds of Elf64_Shdr entries). Also I modified the .dynamic section (it has more than one null entry, so I modified one) to have DT_NEEDED type with linkage to the needed third-party SO name.
My small test app, being analyzed, appears to be fine (as readelf with -d option, or objdump -p, show). Nevertheless, when trying to run the application, it tells:
error while loading shared libraries: ��oU: cannot open shared object file: No such file or directory
Every time running, the name is different. This makes me think some addresses in the ELF loaded are invalid.
I understand that this way of patching is highly error-prone, but I am interested anyway. So, my question is: are there any ELF tools (like gdb or strace), which can debug image loading process (i.e. which can tell one what is wrong before entry point is hit)? Or are there any switches or options, which can help with this situation?
I have tried things like strace -d, but it would not tell anything interesting.
You do not mention patching DT_STRTAB and DT_STRSZ. These tags control how the dynamic loader locates the dynamic string table. The section headers are only used by the link editor, not at run time.
First of all, I did not manage to find any possibility to deal with sane debugging. My solution came in just because of hard-way raw ELF file hex bytes manual analysis.
My conception in general was right (forgot to mention the DT_STRTAB and DT_STRSZ modification though, thanks to Florian Weimer for reminding of it). The patchelf util (see in the postscriptum below) made me sure I am generally right.
The thing is: when you add a new section to the end, make sure you put data to the PLT right way. To add a new ".dynstr" section, I had to overwrite an auxiliary note segment (Elf**_Phdr::p_type == PT_NOTE) with a new segment, right for the new ".dynstr" section data. Not yet sure if such overwriting might cause some error.
It turned out that I put a raw ELF file ('offline') offset, but had to put this data RVA in the running image (after loading ELF into memory by the system loader, 'online'). Once I fixed it, the ELF started to work properly.
P.S. found a somewhat similar question: How can I change the filename of a shared library after building a program that depends on it? (a useful util for the same purpose I need, patchelf, is mentioned there; patchelf is available under Debian via APT, it is a nice tool for the stated purpose)

When a shared library is loaded, is it possible that it references something in the current binary?

Say I have a binary server, and when it's compiled, it's linked from server.c, static_lib.a, and dynamically with dynamic_lib.so.
When server is executed and it loads dynamic_lib.so dynamically, but on the code path, dynamic_lib.so actually expects some symbols from static_lib.a. What I'm seeing is that, dynamic_lib.so pulls in static_lib.so so essentially I have two static_lib in memory.
Let's assume there's no way we can change dynamic_lib.so, because it's a 3rd-party library.
My question is, is it possible to make dynamic_lib.so or ld itself search the current binary first, or even not search for it in ld's path, just use the binary's symbol, or abort.
I tried to find some related docs about it, but it's not easy for noobs about linkers like me :-)
You can not change library to not load static_lib.so but you can trick it to use static_lib.a instead.
By default ld does not export any symbols from executables but you can change this via -rdynamic. This option is quite crude as it exports all static symbols so for finer-grained control you can use -Wl,--dynamic-list (see example use in Clang sources).

Why you need to use C++'s "data_seg"

When I trace one open source, I saw someone has the following code
#prama data_seg(".XXXX")
static char *test=NULL;
FILE *f1;
#prama data_seg()
However, even after checking http://msdn.microsoft.com/en-us/library/thfhx4st(VS.80).aspx, I still not sure why we need to do so, can someone help me to understand this part?
thank you
This is usually done to share the data that's designated to be in that segment. The code you have above will normally go in a DLL. You also use a .def file that specifies that the ".XXXX" segment is going to have the "SHARED" attribute.
When you do all that, the data in that segment gets shared between all the processes that load the DLL, so those variables are shared between all those processes.

How to check Shared Library exposed functions in program

I am using a third party shared library and I need to check whether a function is exported by shared library programatically.
How to do this. I need this because if function does not exist I need to run some other function locally.
You could probably use dlsym for this.
If you load the library with dlopen, you will use the handle that it returns.
If you're linked against this library you may use special pseudo-handles (10x to caf for pointing it out):
From dlsym man:
There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT. The former will find the first occurrence of the desired symbol using the default library search order. The latter will find the next occurrence of a function in the search order after the current library. This allows one to provide a wrapper around a function in another shared library.
Check the header file of the intended library to get the function signature.
Using dlopen you can load the library dynamically and fetch the symbol if it is exposed in the library with subsequent calls to dlsym and dlclose.
may be you can use objdump command to check all symbol exposed like this
objdump -T libtest.so

Nlist equivalent for Linux?

I am just wondering if there is an Linux equivalent to Novels nlist(). nlist()
does the following:
Privileged processes calling nlist() should beware of the possibility of an unexpected file being substituted as the operand.
The nlist() function returns symbol table information for the specified symbol names, for the executable file whose name is supplied as an argument.
Thanks,
Rob
The function that comes closest that I know about is dlinfo. It is completely undocumented in glibc (no man page, nothing in the info files), but is apparently a clone of a Solaris interface, which is documented:
http://docs.oracle.com/cd/E23824_01/html/821-1465/dlinfo-3c.html#scrolltoc
You can find it declared on Linux in dlfcn.h

Resources