为什么gcc为使用不同形式的整数文字的程序生成不同的编译二进制文件?

时间:2017-10-18 02:22:45

标签: c gcc binary hex notation

我想知道它们之间有什么区别:

operator+(int, base&)

使用gcc编译时。

在使用看起来相同的数字编译时,我似乎得到了不同的二进制文件,只是用不同的符号。然而,当我对它运行objdump时,似乎没有任何差异。有人能告诉我发生了什么事吗?

这是我的输出:

int a = 0b00000100;
int a = 0x04;
int a = 4;

请注意,可执行文件不同,它们具有不同的哈希值,但marshall@dont.even.try.to.h4ck.me:[~]: cat testbin.c && echo && cat testbin2.c #include "stdio.h" int main () { int a = 0b00000100; int b = 0x05; int c = 6; printf("%d - %d - %d\n", a, b, c); return (0); } #include "stdio.h" int main () { int a = 4; int b = 5; int c = 6; printf("%d - %d - %d\n", a, b, c); return (0); } marshall@dont.even.try.to.h4ck.me:[~]: gcc testbin.c -o testbin marshall@dont.even.try.to.h4ck.me:[~]: gcc testbin2.c -o testbin2 marshall@dont.even.try.to.h4ck.me:[~]: md5sum testbin testbin2 fd6aaa31bdf685ea9444e1edc209565e testbin 3a3fc241bfc2917ee29999b5befecd2a testbin2 marshall@dont.even.try.to.h4ck.me:[~]: objdump -d testbin > testbin.obj && objdump -d testbin2 > testbin2.obj marshall@dont.even.try.to.h4ck.me:[~]: diff testbin.obj testbin2.obj 2c2 < testbin: file format elf64-x86-64 --- > testbin2: file format elf64-x86-64 marshall@dont.even.try.to.h4ck.me:[~]: gcc -v Using built-in specs. COLLECT_GCC=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) marshall@dont.even.try.to.h4ck.me:[~]: 没有显示任何不同的内容。

1 个答案:

答案 0 :(得分:1)

我认为这个问题与整数格式无关,也与文件名无关。

我编译了以下程序两次,首先使用文件名FIRST_PROG.c和可执行文件名COMPILED_1,第二次使用文件名SECOND_PROC.c和可执行文件COMPILED_2使用{{ 1}}没有设置其他标志:

gcc

如果你int main() { return 0; } 生成的可执行文件的内容,在某个偏移处你会看到:

hd

请注意,源文件的名称00001720 66 72 61 6d 65 5f 64 75 6d 6d 79 5f 69 6e 69 74 |frame_dummy_init| 00001730 5f 61 72 72 61 79 5f 65 6e 74 72 79 00 46 49 52 |_array_entry.FIR| 00001740 53 54 5f 50 52 4f 47 2e 63 00 5f 5f 46 52 41 4d |ST_PROG.c.__FRAM| 已嵌入到生成的可执行文件中。查看第二个文件中的相同位置显示:

FIRST_PROG.c

您也可以看到00001720 66 72 61 6d 65 5f 64 75 6d 6d 79 5f 69 6e 69 74 |frame_dummy_init| 00001730 5f 61 72 72 61 79 5f 65 6e 74 72 79 00 53 45 43 |_array_entry.SEC| 00001740 4f 4e 44 5f 50 52 4f 47 2e 63 00 5f 5f 46 52 41 |OND_PROG.c.__FRA| 也嵌入到二进制文件中。

使用SECOND_PROG.c转储这两个可执行文件并不会在任何地方显示,这与您从程序中获得的干净objdump -s相匹配。但是,使用diff列出生成的生成的可执行文件的内容会显示:

readelf -a

请注意,条目37包含源文件的名称。如果您尝试Symbol table '.symtab' contains 66 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000400238 0 SECTION LOCAL DEFAULT 1 2: 0000000000400254 0 SECTION LOCAL DEFAULT 2 3: 0000000000400274 0 SECTION LOCAL DEFAULT 3 4: 0000000000400298 0 SECTION LOCAL DEFAULT 4 5: 00000000004002b8 0 SECTION LOCAL DEFAULT 5 6: 0000000000400300 0 SECTION LOCAL DEFAULT 6 7: 0000000000400338 0 SECTION LOCAL DEFAULT 7 8: 0000000000400340 0 SECTION LOCAL DEFAULT 8 9: 0000000000400360 0 SECTION LOCAL DEFAULT 9 10: 0000000000400378 0 SECTION LOCAL DEFAULT 10 11: 0000000000400390 0 SECTION LOCAL DEFAULT 11 12: 00000000004003b0 0 SECTION LOCAL DEFAULT 12 13: 00000000004003d0 0 SECTION LOCAL DEFAULT 13 14: 00000000004003e0 0 SECTION LOCAL DEFAULT 14 15: 0000000000400564 0 SECTION LOCAL DEFAULT 15 16: 0000000000400570 0 SECTION LOCAL DEFAULT 16 17: 0000000000400574 0 SECTION LOCAL DEFAULT 17 18: 00000000004005a8 0 SECTION LOCAL DEFAULT 18 19: 0000000000600e10 0 SECTION LOCAL DEFAULT 19 20: 0000000000600e18 0 SECTION LOCAL DEFAULT 20 21: 0000000000600e20 0 SECTION LOCAL DEFAULT 21 22: 0000000000600e28 0 SECTION LOCAL DEFAULT 22 23: 0000000000600ff8 0 SECTION LOCAL DEFAULT 23 24: 0000000000601000 0 SECTION LOCAL DEFAULT 24 25: 0000000000601020 0 SECTION LOCAL DEFAULT 25 26: 0000000000601030 0 SECTION LOCAL DEFAULT 26 27: 0000000000000000 0 SECTION LOCAL DEFAULT 27 28: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c 29: 0000000000600e20 0 OBJECT LOCAL DEFAULT 21 __JCR_LIST__ 30: 0000000000400410 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones 31: 0000000000400450 0 FUNC LOCAL DEFAULT 14 register_tm_clones 32: 0000000000400490 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux 33: 0000000000601030 1 OBJECT LOCAL DEFAULT 26 completed.7585 34: 0000000000600e18 0 OBJECT LOCAL DEFAULT 20 __do_global_dtors_aux_fin 35: 00000000004004b0 0 FUNC LOCAL DEFAULT 14 frame_dummy 36: 0000000000600e10 0 OBJECT LOCAL DEFAULT 19 __frame_dummy_init_array_ 37: 0000000000000000 0 FILE LOCAL DEFAULT ABS FIRST_PROG.c 38: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c 39: 0000000000400698 0 OBJECT LOCAL DEFAULT 18 __FRAME_END__ 40: 0000000000600e20 0 OBJECT LOCAL DEFAULT 21 __JCR_END__ 41: 0000000000000000 0 FILE LOCAL DEFAULT ABS 42: 0000000000600e18 0 NOTYPE LOCAL DEFAULT 19 __init_array_end 43: 0000000000600e28 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC 44: 0000000000600e10 0 NOTYPE LOCAL DEFAULT 19 __init_array_start 45: 0000000000400574 0 NOTYPE LOCAL DEFAULT 17 __GNU_EH_FRAME_HDR 46: 0000000000601000 0 OBJECT LOCAL DEFAULT 24 _GLOBAL_OFFSET_TABLE_ 47: 0000000000400560 2 FUNC GLOBAL DEFAULT 14 __libc_csu_fini 48: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab 49: 0000000000601020 0 NOTYPE WEAK DEFAULT 25 data_start 50: 0000000000601030 0 NOTYPE GLOBAL DEFAULT 25 _edata 51: 0000000000400564 0 FUNC GLOBAL DEFAULT 15 _fini 52: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_ 53: 0000000000601020 0 NOTYPE GLOBAL DEFAULT 25 __data_start 54: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 55: 0000000000601028 0 OBJECT GLOBAL HIDDEN 25 __dso_handle 56: 0000000000400570 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used 57: 00000000004004f0 101 FUNC GLOBAL DEFAULT 14 __libc_csu_init 58: 0000000000601038 0 NOTYPE GLOBAL DEFAULT 26 _end 59: 00000000004003e0 42 FUNC GLOBAL DEFAULT 14 _start 60: 0000000000601030 0 NOTYPE GLOBAL DEFAULT 26 __bss_start 61: 00000000004004d6 11 FUNC GLOBAL DEFAULT 14 main 62: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 63: 0000000000601030 0 OBJECT GLOBAL HIDDEN 25 __TMC_END__ 64: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable 65: 0000000000400390 0 FUNC GLOBAL DEFAULT 11 _init diff的输出,您会收到一些非常有用的信息:

readelf -a

似乎很多这些差异归结为源文件的名称不同。

所以我的官方答案是&#34;这与整数文字没有任何关系,纯粹是编译具有不同名称的文件的功能。&#34;