可能重复:
Disassembling, modifying and then reassembling a Linux executable
我被告知装配和拆卸不是倒置的。显然,您不能对程序进行反汇编,将该输出直接放入汇编程序,并期望它能够正确运行,因为信息会丢失。
我的问题是,为什么信息会丢失?还有什么信息丢失了?
答案 0 :(得分:7)
反汇编程序(或其用户)通常不保留的一个重要事项是指令编码。某些指令可以用多种不同的方式编码,例如:
mov rdx, -1
是48,BA,FF,FF,FF,FF,FF,FF,FF,FF(10字节)或48,C7,C2,FF,FF,FF,FF(7字节) )。
如果程序的其余部分在某种程度上在功能上取决于上述指令的长度恰好是10(或7)字节或那些特定的字节值,并且汇编程序选择以不同于它的方式汇编mov rdx, -1
原始程序,然后在反汇编+汇编后,你会得到一个不同的程序。对于带有模糊编码的指令,汇编器必须使用指令助记符(mov rdx, -1
),而不是原始程序的反汇编中的精确编码(例如48,BA,FF,FF,FF,FF,FF,FF,FF) ,FF)。
汇编器或链接器可能还有其他不同的东西(例如,在输出文件中以不同的方式对代码/数据进行额外的对齐,命名和排序(部分/段)),这通常不是问题,但是,如果在原始程序中对这些事情有一些不同寻常的依赖关系,那么重新组装的程序将以不同的方式工作。
答案 1 :(得分:3)
它不是一种损失,实际上是一种收获。听起来你还没试过这个,为什么不试试呢?
.global reset
reset:
mov #0x0280,r1
call #notmain
jmp hang
.global hang
hang:
jmp hang
你可以用objdump组装的:
0000f800 <reset>:
f800: 31 40 80 02 mov #640, r1 ;#0x0280
f804: b0 12 b2 f8 call #0xf8b2
f808: 00 3c jmp $+2 ;abs 0xf80a
0000f80a <hang>:
f80a: ff 3f jmp $+0 ;abs 0xf80a
你可以看到核心代码仍然存在,如果你有一个带有列或其他矩形剪切和粘贴的文本编辑器,你可以从中间切出代码,直接或通过一些按摩重新组装它。
没有理由不能让反汇编程序生成可以重新组装的输出,我已经多次完成它并且多次看到它。事情是用反汇编程序,用例是看到额外的信息。反汇编程序的用例 可以重新组装的是像黑客一样的代码或类似的东西。
我强烈建议人们无论如何都要编写反汇编程序,如果有一个可变指令长度指令集(x86),那么这对于学习指令集及其编码方式的教育都是一个很好的理由。还有很多需要学习的东西(我建议不要先学习其中的一个,先用手臂或拇指或类似的东西,或至少不像x86那样痛苦的东西,如msp430)。测试反汇编程序的一个好方法是输出可以重新组装的代码。组装,拆卸,组装,如果两个组件输出匹配,那么你的拆卸器做得很好。