ELF - 入口点地址在运行时更改

时间:2018-04-12 07:03:25

标签: c linux elf

我在 debian虚拟机(主机是mac osx)编译了一个简单的c程序,入口点“_start”就像:

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

但是当我运行这个程序时发现入口点发生了变化。

   (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]

我怀疑是否有特定的内核解释器,所以我将这个程序复制到另一台机器上,运行时入口点与elf头中的匹配,此时入口点变为 0x00007ffff7dfd580 ,我认为是精灵文件中的魔法并试图搜索相关功能以满足此类行为但未能找到它,任何人都可以告诉我它是如何可能的?

还有一个问题, 0x580 是一个应该在内核空间中使用的较低地址,我是有线链接器为入口点选择这样的地址...

附上下面的编译信息,感谢您查看这么长的问题。

/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'

1 个答案:

答案 0 :(得分:4)

感谢poming的回复,我发现我的gcc是使用 - enable-default-pie 编译的,并且使程序成为DYN文件而是EXEC文件,使用&#34; -no馅饼&#34;修好了。

相关问题