2011-12-14 32 views
3

可能重复:
Disassembling, modifying and then reassembling a Linux executable试图组装的反汇编器的输出(如objdump的)

我已经告诉组件和dissassembly不是逆。显然,你不能分解一个程序,把这个输出直接放到一个汇编程序中,并且期望它能够正确运行,因为信息丢失了。

我的问题是,为什么信息丢失?另外,什么信息丢失?

+2

http://stackoverflow.com/questions/4309771/disassembling-modifying-and-then-reassembling-a-linux-executable – n0p 2011-12-14 19:14:11

+0

谢谢,我试着问这个问题之前问,但我一定错过了那一个 – matzahboy 2011-12-14 19:19:33

回答

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)中使用其确切编码。

可能还有其他一些东西,汇编程序或链接程序可能会做不同的处理(例如,在输出文件中以不同方式执行代码/数据,名称和顺序事件(节/段)的附加对齐),这通常不是问题,但是,如果在原始程序中对这些东西有一些不寻常的依赖关系,那么重新组合的程序将以不同的方式工作。

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)。测试反汇编程序的好方法是输出可重新组装的代码。组装,拆卸,组装,如果两个组件输出匹配,那么你的反汇编程序做得很好。