Search code examples
linuxexecutableshared-librariesprocfs

How to detect executable or shared object in /proc/self/maps on Linux


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.


Solution

  • 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.