I want to list all libraries (.so) loaded into app address space. I use the procfs and read info from /proc/self/maps. I there existing way to detect file is executable or .so? Or I need to compare each found module name with value of /proc/self/exe?
UPD Some more questions.
When I parse /proc/self/maps procfs file, I wan to find the base addr for each found loaded .so module, but I can find the way to make it without dl* functions call.
I try to use dladdr:
Dl_info info;
int dladdrRes = dladdr((void*)(mmIt->startAddr), &info);
if (!dladdrRes) continue;
std::string modName = info.dli_fname;
void *modBase = info.dli_fbase;
but modBase is not an addr which the 'dlopen' function returns. Only the way, which calls the 'dlopen' function works:
dlopen( filename.c_str(), RTLD_NOW|RTLD_NOLOAD|RTLD_LOCAL );
My idea is that: when I parse /proc/self/maps, I know names of all loaded modules, and I don' need to call kernel to find the base of loaded module. As I find, it is my wrong.
The output of /proc/self/maps
is
address perms offset dev inode pathname
Executables have the x
permission bit set. By default there are a few maps that are executable but have no file on disk (like e.g. vdso
). So all you have to do is extracting those entries of maps
that have the x
permission bit set and have a matching file on disk.
Note that it's not really necessary for an executable map to be in a particular file format. For example wine maps Windows executables (which are PE files; any may not even have executable bit set on the file system) with the exectuable permission bit, so that the code in them can be executed. So it's generally a good idea to just look at the /proc/self/maps
and not try to infer anything from the files on storage.