Dlsym - get overridden character

I have an application that dynamically loads libraries that dynamically load libraries that ...

On Windows, I can iterate over all loaded modules that are looking for the character that interests me. I do not know how to do this in a Unix / Linux environment. I know that I can use dlsym(dlopen(0, flag)) or dlsym(RTLD_DEFAULT / RTLD_NEXT) for the first two characters and know the order of the modules to search for - how can I go deeper and get all the definitions of this character?

+4
source share
2 answers

To find a symbol in a shard object, open it with dlopen .

  void* foobar = dlopen ("/usr/local/lib/foobar.so", RTLD_NOW); void* mysymbol = dlsym (foobar, "mysymbol"); 

Refresh Here is a program that iterates over all characters named "foo". These are not POSIX, but GNU libs. I am pretty sure that POSIX does not provide such capabilities.

 #define _GNU_SOURCE #include <link.h> #include <dlfcn.h> #include <stdio.h> void doit (const char* s) { void* obj = dlopen (s, RTLD_LAZY); void* fcn = dlsym (obj, "foo"); if (fcn) printf ("Object %s has 'foo' at addr %p\n", *s ? s : "(exe)", fcn); } int cb (struct dl_phdr_info *info, size_t size, void *data) { doit (info->dlpi_name); return 0; } int main () { dl_iterate_phdr (cb, 0); return 0; } 

Here's the conclusion:

 Object (exe) has 'foo' at addr 0xb76f8418 Object (exe) has 'foo' at addr 0xb76f8418 Object /tmp/libfoo.so has 'foo' at addr 0xb76f8418 Object /tmp/libfoo1.so has 'foo' at addr 0xb76f5418 Object /tmp/libfoo2.so has 'foo' at addr 0xb76f2418 

There are some duplicates, but this is a small problem.

+6
source

Answering your own question to make life easier for people looking for a solution. There is no single way requiring iteration on loadable modules to search for the following commands / data types (experts invite comments on this):

Windows:
MODULEENTRY32, CreateToolhelp32Snapshot, Module32First, Module32Next

Linux:
as described in nm, answer, return a nonzero value from the callback when you find the corresponding module (terminates the loop).

AIX:
loadquery (L_GETINFO, buffer, size), struct ld_info.

HP-UX:
dlget, dlgetname (if you need a path to the module).

Solaris:
ldinfo, Link_map.

In addition, I would recommend decrypting the modules and getting the character from the new descriptor to increase the library reference count, which prevents it from unloading. At least on AIX, it may have the side effect of a library loaded and initialized again, but in most cases is better than trying to call a function from an unloaded library.

+2
source

Source: https://habr.com/ru/post/1383899/


All Articles