反汇编、修改和重新组装可执行文件
Disassemble, modify, and reassemble executable
如何使用 ndisasm 在我的 mac 上反汇编可执行文件,然后使用 nasm 和 ld 重新组装和 link 它?
这是我尝试过的(顺便说一句,我是 运行 MacOS X):
*ndisasm a.out | cut -c 29- > main.asm*
这生成了干净的汇编代码,其中包含 main.asm
中的所有处理器指令
*nasm -f macho main.asm*
这生成了一个目标文件 main.o 然后我尝试 link
*ld main.o*
...这就是我卡住的地方。我不知道为什么会产生以下错误:
ld:在 __TEXT、__text 部分 reloc 0:R_ABS reloc 但在目标地址文件 'main.o' 中没有绝对符号用于推断的架构 i386。
我也尝试过指定架构 (ld -arch x86_64 main.o),但这也没有用。
我的目标是反汇编任何可执行文件,修改它,然后重新组装它。
我做错了什么?
没有可靠的方法可以用正常的assembler语法来做到这一点。参见 How to disassemble, modify and then reassemble a Linux executable?。部分信息通常不忠实地 disassembled,因此您需要一种专门用于修改和重新组装的特殊格式 + relinking.
此外,instruction-lengths 是一个问题,因为代码只有在使用更长的编码填充时才有效。 (例如,在 table 的计算跳转目标中)。请参阅 Where are GNU assembler instruction suffixes like ".s" in x86 "mov.s" documented?,但请注意 disassemblers 不支持反汇编成该格式。
ndisasm
不理解 object 文件格式,所以它 assembles headers 作为机器码!
为了让它有任何工作的希望,使用像 Agner Fog's objconv
这样的 disassembler 它将输出 asm 源(NASM、MASM 或 GAS AT&T)assemble。如果任何代码依赖于特定的 longer-than-default 编码,它可能实际上不起作用。
我不确定 objconv
在发出 section .bss
、section .rodata
和其他类似的指令以将数据放置在 [=51] 中的位置方面有多忠实=] 文件,但这就是你所需要的。
回复:绝对重定位:确保将 DEFAULT REL
放在文件的顶部。我忘记了 objconv
是否默认执行此操作。 x86-64 Mach-o 仅支持 PC-relative 重定位,因此您必须创建 position-independent 代码(例如使用 RIP-relative 寻址模式)。
ndisasm
不读取符号table,所以它的所有操作数都使用绝对寻址。 objconv
为跳转目标和未出现在符号 table.
中的静态数据组成标签名称
如何使用 ndisasm 在我的 mac 上反汇编可执行文件,然后使用 nasm 和 ld 重新组装和 link 它? 这是我尝试过的(顺便说一句,我是 运行 MacOS X):
*ndisasm a.out | cut -c 29- > main.asm*
这生成了干净的汇编代码,其中包含 main.asm
中的所有处理器指令 *nasm -f macho main.asm*
这生成了一个目标文件 main.o 然后我尝试 link
*ld main.o*
...这就是我卡住的地方。我不知道为什么会产生以下错误:
ld:在 __TEXT、__text 部分 reloc 0:R_ABS reloc 但在目标地址文件 'main.o' 中没有绝对符号用于推断的架构 i386。
我也尝试过指定架构 (ld -arch x86_64 main.o),但这也没有用。
我的目标是反汇编任何可执行文件,修改它,然后重新组装它。
我做错了什么?
没有可靠的方法可以用正常的assembler语法来做到这一点。参见 How to disassemble, modify and then reassemble a Linux executable?。部分信息通常不忠实地 disassembled,因此您需要一种专门用于修改和重新组装的特殊格式 + relinking.
此外,instruction-lengths 是一个问题,因为代码只有在使用更长的编码填充时才有效。 (例如,在 table 的计算跳转目标中)。请参阅 Where are GNU assembler instruction suffixes like ".s" in x86 "mov.s" documented?,但请注意 disassemblers 不支持反汇编成该格式。
ndisasm
不理解 object 文件格式,所以它 assembles headers 作为机器码!
为了让它有任何工作的希望,使用像 Agner Fog's objconv
这样的 disassembler 它将输出 asm 源(NASM、MASM 或 GAS AT&T)assemble。如果任何代码依赖于特定的 longer-than-default 编码,它可能实际上不起作用。
我不确定 objconv
在发出 section .bss
、section .rodata
和其他类似的指令以将数据放置在 [=51] 中的位置方面有多忠实=] 文件,但这就是你所需要的。
回复:绝对重定位:确保将 DEFAULT REL
放在文件的顶部。我忘记了 objconv
是否默认执行此操作。 x86-64 Mach-o 仅支持 PC-relative 重定位,因此您必须创建 position-independent 代码(例如使用 RIP-relative 寻址模式)。
ndisasm
不读取符号table,所以它的所有操作数都使用绝对寻址。 objconv
为跳转目标和未出现在符号 table.