Friday 16 September 2011

howoto get load address of a kernel module or libraries

In case of kernel modules, cat /proc/modules will give you a rough guide to where things are loaded. I f you are debugging some kernel crash in a module, you might get more of a clue about exactly where the  crash is by looking at /proc/kallsyms.

The shared library loader ld.so may change the virtual addresses at which a shared library is loaded depending on the needs of a binary. Its reason is the size of code, data and other sections may vary from one binary to the next. The process of rearranging the address space is called relocation. Relocation is also the reason why you have to compile shared libraries as position-independent code with gcc -fPIC.Additionally, each shared library can contain different segments (for static zeroed data, static initialized data, program text, TLS, etc.). Each of those segments will occupy different regions of the address space and will likely have different permissions.

So if you want to know the load address of a shared library used by your process, u should check it for your process itself. cat /proc/<pid>/maps will give you the mapping information of the process with process id <pid>. One line of information will look something like this:

003fb000-00410000 r-xp 00000000 08:01 504990 /lib/ld-2.3.2.so
  
003fb000-00410000: Virtual memory range.

 r-x:
Permissions for the mapping. The chars denote read, write, and
execute. What is shown in maps is the permissions requested by
the application. The actual permissions may differ because of
hardware limitations.

p: Is the mapping shared or private.

00000000: Offset in backing file.

08:01: Device number for the backing file.

504990: Inode number for the backing file.

/lib/ld-2.3.2.so:
Name of the backing file. This name does not have proper
escaping of special chars, so with a carefully crafted file
name, this entire maps file may be fubar.

The ldd utility prints the shared library dependencies of an executable. If the ldd is native, it will provide the load addresses for all shared libraries. For example, following output is the shared library dependecies of ls command in my system.
ldd /bin/ls
    librt.so.1 => /lib64/librt.so.1 (0x0000003af7c00000)
    libacl.so.1 => /lib64/libacl.so.1 (0x0000003b00600000)
    libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003965200000)
    libc.so.6 => /lib64/libc.so.6 (0x0000003af4000000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003af4c00000)
    /lib64/ld-linux-x86-64.so.2 (0x0000003af3000000)
    libattr.so.1 => /lib64/libattr.so.1 (0x0000003b00a00000)
    libdl.so.2 => /lib64/libdl.so.2 (0x0000003af4800000)
    libsepol.so.1 => /lib64/libsepol.so.1 (0x0000003964e00000)