Gcc 附加到组件末尾的说明
我试图按照教程创建一个二进制文件,但链接器似乎在程序集的末尾附加了额外的指令。我想这是操作系统的拆卸过程Gcc 附加到组件末尾的说明,gcc,assembly,x86,nasm,ld,Gcc,Assembly,X86,Nasm,Ld,我试图按照教程创建一个二进制文件,但链接器似乎在程序集的末尾附加了额外的指令。我想这是操作系统的拆卸过程 本教程试图在Linux上编译一个简单的32位C程序: int main() { } 使用以下命令: gcc -c test.c ld -o test -Ttext 0x0 -e main test.o objcopy -R .note -R .comment -S -O binary test test.bin ndisasm -b 32 test.bin 我正在运行64位Linux,
本教程试图在Linux上编译一个简单的32位C程序:
int main() {
}
使用以下命令:
gcc -c test.c
ld -o test -Ttext 0x0 -e main test.o
objcopy -R .note -R .comment -S -O binary test test.bin
ndisasm -b 32 test.bin
我正在运行64位Linux,因此将编译步骤修改为:
gcc -m32 -c test.c
ld -m elf_i386 -o test -Ttext 0x0 -e main test.o
objcopy -R .note -R .comment -S -O binary test test.bin
ndisasm -b 32 test.bin
;; START expected output
00000000 55 push bp
00000001 89E5 mov bp,sp
00000003 5D pop bp
00000004 C3 ret
;; END expected output
00000005 0000 add [eax],al
00000007 001400 add [eax+eax],dl
0000000A 0000 add [eax],al
0000000C 0000 add [eax],al
0000000E 0000 add [eax],al
00000010 017A52 add [edx+0x52],edi
00000013 0001 add [ecx],al
00000015 7C08 jl 0x1f
00000017 011B add [ebx],ebx
00000019 0C04 or al,0x4
0000001B 0488 add al,0x88
0000001D 0100 add [eax],eax
0000001F 001C00 add [eax+eax],bl
00000022 0000 add [eax],al
00000024 1C00 sbb al,0x0
00000026 0000 add [eax],al
00000028 D8FF fdivr st7
0000002A FF db 0xff
0000002B FF0500000000 inc dword [dword 0x0]
00000031 41 inc ecx
00000032 0E push cs
00000033 088502420D05 or [ebp+0x50d4202],al
00000039 41 inc ecx
0000003A C50C04 lds ecx,[esp+eax]
0000003D 0400 add al,0x0
0000003F 00 db 0x00
预期产出为:
00000000 55 push ebp
00000001 89E5 mov ebp,esp
00000003 C9 leave
00000004 C3 ret
我的输出如下:
gcc -m32 -c test.c
ld -m elf_i386 -o test -Ttext 0x0 -e main test.o
objcopy -R .note -R .comment -S -O binary test test.bin
ndisasm -b 32 test.bin
;; START expected output
00000000 55 push bp
00000001 89E5 mov bp,sp
00000003 5D pop bp
00000004 C3 ret
;; END expected output
00000005 0000 add [eax],al
00000007 001400 add [eax+eax],dl
0000000A 0000 add [eax],al
0000000C 0000 add [eax],al
0000000E 0000 add [eax],al
00000010 017A52 add [edx+0x52],edi
00000013 0001 add [ecx],al
00000015 7C08 jl 0x1f
00000017 011B add [ebx],ebx
00000019 0C04 or al,0x4
0000001B 0488 add al,0x88
0000001D 0100 add [eax],eax
0000001F 001C00 add [eax+eax],bl
00000022 0000 add [eax],al
00000024 1C00 sbb al,0x0
00000026 0000 add [eax],al
00000028 D8FF fdivr st7
0000002A FF db 0xff
0000002B FF0500000000 inc dword [dword 0x0]
00000031 41 inc ecx
00000032 0E push cs
00000033 088502420D05 or [ebp+0x50d4202],al
00000039 41 inc ecx
0000003A C50C04 lds ecx,[esp+eax]
0000003D 0400 add al,0x0
0000003F 00 db 0x00
附加指令的目的是什么,如何从目标文件和二进制文件中删除它们 编辑:
- 键入
args(commet->comment)。更新了反汇编输出objcopy
-x
参数查询节即可。使用此命令:
objdump -x test
在大多数现代版本的GCC中,应使用默认参数生成与此类似(不精确)的输出:
人们应该首先寻找意外的部分。在输出到文件test.bin
之前,您的命令使用-R
从ELF对象中删除节。你做到了:
objcopy -R .note -R .comment -S -O binary test test.bin
如果排除.note
和.comment
部分,则上述OBJDUMP输出中剩下的明显部分是.eh_frame
.eh_frame
被放置在文件test.bin
的.text
部分之后。这包含异常解除信息。这不是实际的指示。正在将非代码作为指令转储,因为二进制文件不区分代码和数据。NDISAM盲目地将所有数据转换为指令
有两种方法可以解决这个问题。您可以像处理其他两个部分一样排除.eh_frame
部分。您可以使用:
objcopy -R .note -R .comment -R .eh_frame -S -O binary test test.bin
您还可以告诉GCC不要在代码中生成异步异常展开表。这可以通过GCC选项完成:
这与我的评论有点不同,因为我建议禁用所有异常。您只需禁用异步展开表以抑制.eh\u frame
部分。本节讨论了本节的有用性(或不足)。gcc的手册页(mangcc
)讨论了选项-fasynchronous unwind tables
这是目前大多数GCC的默认设置。使用-fno异步展开表
可关闭此功能
您链接到的是2000年制作的。GCC及其选项(以及发行版使用的默认值)多年来发生了变化。可能在创建该教程时,异步展开表还不存在。这就解释了为什么你观察到的结果与本教程不同。@IgnacioVazquez Abrams我试图在
.comment
部分找到信息,但没有找到太多。它是什么,为什么你认为它是那个部分?如果你使用objdump-x test.o
来转储所有elf头/部分,你可能会发现你有一个.eh\u frame
部分。由于不排除,因此会占用文件中的空间。如果不打算使用异常处理,请将其添加到GCC命令行-fno exceptions-fno asynchronous unwind tables
。因此,gcc-m32-c test.c-fno异常-fno异步展开表
应该可以解决您的问题。它们实际上不是指令,而是异常帧数据,在转换为二进制平面文件时直接放在代码之后ndisam
碰巧将数据解码为指令,因为它不知道区别。@MichaelPetch谢谢,它已经工作了。您想将您的评论作为答案吗?您对本教程的看法是正确的。我不得不进行许多标志修改,以显示与示例中显示的相同的一般行为。我知道\u start
部分,但在遇到教程之前,我不知道所有注入到对象文件中的附加部分。
-fasynchronous-unwind-tables
Generate unwind table in DWARF 2 format, if supported by target machine. The table is exact at each
instruction boundary, so it can be used for stack unwinding from asynchronous events (such as debugger or
garbage collector).