Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ELF - entry point address changed at runtime

Tags:

c

linux

elf

I compiled a simple c program in debian virtual machine (host machine is mac osx) and entry point "_start" was like:

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x580
  Start of program headers:          64 (bytes into file)
  Start of section headers:          6808 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         9
  Size of section headers:           64 (bytes)
  Number of section headers:         31
  Section header string table index: 30

/home/bina # readelf -s a.out |grep _start |grep FUNC
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)
    56: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
    63: 0000000000000580    43 FUNC    GLOBAL DEFAULT   14 _start

but found entry point changed when I ran this program.

   (gdb) b _start
    Breakpoint 1 at 0x580
    (gdb) info b
    Num     Type           Disp Enb Address            What
    1       breakpoint     keep y   0x0000000000000580 <_start>
    (gdb) r
    Starting program: /home/bina/a.out 

    Breakpoint 1, 0x0000555555554580 in _start ()
    (gdb) info b
    Num     Type           Disp Enb Address            What
    1       breakpoint     keep y   0x0000555555554580 <_start>
        breakpoint already hit 1 time
    (gdb) shell cat /proc/7961/maps
    555555554000-555555555000 r-xp 00000000 08:01 45111                      /home/bina/a.out
    555555754000-555555755000 r--p 00000000 08:01 45111                      /home/bina/a.out
    555555755000-555555756000 rw-p 00001000 08:01 45111                      /home/bina/a.out
    7ffff7a3a000-7ffff7bcf000 r-xp 00000000 08:01 262152                     /lib/x86_64-linux-gnu/libc-2.24.so
    7ffff7bcf000-7ffff7dcf000 ---p 00195000 08:01 262152                     /lib/x86_64-linux-gnu/libc-2.24.so
    7ffff7dcf000-7ffff7dd3000 r--p 00195000 08:01 262152                     /lib/x86_64-linux-gnu/libc-2.24.so
    7ffff7dd3000-7ffff7dd5000 rw-p 00199000 08:01 262152                     /lib/x86_64-linux-gnu/libc-2.24.so
    7ffff7dd5000-7ffff7dd9000 rw-p 00000000 00:00 0 
    7ffff7dd9000-7ffff7dfc000 r-xp 00000000 08:01 262147                     /lib/x86_64-linux-gnu/ld-2.24.so
    7ffff7fd4000-7ffff7fd6000 rw-p 00000000 00:00 0 
    7ffff7ff5000-7ffff7ff8000 rw-p 00000000 00:00 0 
    7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0                          [vvar]
    7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0                          [vdso]
    7ffff7ffc000-7ffff7ffd000 r--p 00023000 08:01 262147                     /lib/x86_64-linux-gnu/ld-2.24.so
    7ffff7ffd000-7ffff7ffe000 rw-p 00024000 08:01 262147                     /lib/x86_64-linux-gnu/ld-2.24.so
    7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0 
    7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

i suspected if there is specific kernel interpreter, so i copied this program to another machine that runtime entry point is matched with which in elf header, this time entry point changed to 0x00007ffff7dfd580, i think it's a magic in elf file and tried to search related feature to meet such behaviour but failed to find it out, anyone who can tell me how is it possible?

one more question, 0x580 is a lower address which should used in kernel space, i am wired linker choose such address for entry point...

attached compilation info below and thank you for looking so long question.

/home/bina # gcc -g sample.c sample1.c --verbose
Using built-in specs.
COLLECT_GCC=/usr/bin/gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 6.3.0-18' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-6 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 6.3.0 20170516 (Debian 6.3.0-18) 
COLLECT_GCC_OPTIONS='-g' '-v' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/6/cc1 -quiet -v -imultiarch x86_64-linux-gnu sample.c -quiet -dumpbase sample.c -mtune=generic -march=x86-64 -auxbase sample -g -version -o /tmp/emacs-root/ccvlXhkr.s
GNU C11 (Debian 6.3.0-18) version 6.3.0 20170516 (x86_64-linux-gnu)
    compiled by GNU C version 6.3.0 20170516, GMP version 6.1.2, MPFR version 3.1.5, MPC version 1.0.3, isl version 0.15
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/6/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
GNU C11 (Debian 6.3.0-18) version 6.3.0 20170516 (x86_64-linux-gnu)
    compiled by GNU C version 6.3.0 20170516, GMP version 6.1.2, MPFR version 3.1.5, MPC version 1.0.3, isl version 0.15
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 0fe3e671dc62e01e15c40cc5df58cb5f
COLLECT_GCC_OPTIONS='-g' '-v' '-mtune=generic' '-march=x86-64'
 as -v --64 -o /tmp/emacs-root/cc5CWX2B.o /tmp/emacs-root/ccvlXhkr.s
GNU assembler version 2.28 (x86_64-linux-gnu) using BFD version (GNU Binutils for Debian) 2.28
COLLECT_GCC_OPTIONS='-g' '-v' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/6/cc1 -quiet -v -imultiarch x86_64-linux-gnu sample1.c -quiet -dumpbase sample1.c -mtune=generic -march=x86-64 -auxbase sample1 -g -version -o /tmp/emacs-root/ccvlXhkr.s
GNU C11 (Debian 6.3.0-18) version 6.3.0 20170516 (x86_64-linux-gnu)
    compiled by GNU C version 6.3.0 20170516, GMP version 6.1.2, MPFR version 3.1.5, MPC version 1.0.3, isl version 0.15
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/6/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
GNU C11 (Debian 6.3.0-18) version 6.3.0 20170516 (x86_64-linux-gnu)
    compiled by GNU C version 6.3.0 20170516, GMP version 6.1.2, MPFR version 3.1.5, MPC version 1.0.3, isl version 0.15
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 0fe3e671dc62e01e15c40cc5df58cb5f
COLLECT_GCC_OPTIONS='-g' '-v' '-mtune=generic' '-march=x86-64'
 as -v --64 -o /tmp/emacs-root/ccfQelQM.o /tmp/emacs-root/ccvlXhkr.s
GNU assembler version 2.28 (x86_64-linux-gnu) using BFD version (GNU Binutils for Debian) 2.28
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/6/:/usr/lib/gcc/x86_64-linux-gnu/6/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/6/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/6/:/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/6/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-g' '-v' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/6/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/6/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/6/lto-wrapper -plugin-opt=-fresolution=/tmp/emacs-root/ccDpfyEX.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/6/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/6 -L/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/6/../../.. /tmp/emacs-root/cc5CWX2B.o /tmp/emacs-root/ccfQelQM.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/6/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/crtn.o
COLLECT_GCC_OPTIONS='-g' '-v' '-mtune=generic' '-march=x86-64'
like image 980
Xuan Li Avatar asked Apr 01 '26 23:04

Xuan Li


1 Answers

Thank for poming's reply, i found my gcc is compiled with --enable-default-pie and that makes program as DYN file but EXEC file, using "-no-pie" fixed it.

like image 67
Xuan Li Avatar answered Apr 03 '26 15:04

Xuan Li