5

可能重复:
反汇编、修改然后重新汇编 Linux 可执行文件

我被告知组装和拆卸不是相反的。显然,您不能反汇编程序,将输出直接放入汇编程序,并期望它正确运行,因为信息丢失了。

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

4

2 回答 2

8

反汇编程序(或其用户)通常不会保留的一件重要事情是指令编码。一些指令可以以多种不同的方式编码,例如:

mov rdx, -1 is either 48,BA,FF,FF,FF,FF,FF,FF,FF,FF (10 bytes) or 48,C7,C2,FF,FF,FF,FF (7 bytes).

If the rest of the program somehow functionally depends on the length of the above instruction being exactly 10 (or 7) bytes or on those specific byte values and the assembler chooses to assemble mov rdx, -1 differently from what it was in the original program, then after disassembly+assembly you get a different program that will work differently. For instructions with ambiguous encoding the assembler must use not the instruction mnemonic (mov rdx, -1) but its exact encoding in the disassembly of the original program (e.g. 48,BA,FF,FF,FF,FF,FF,FF,FF,FF).

There may be other things that the assembler or linker may do differently (e.g. do additional aligning of code/data, name and order things (sections/segments) differently in the output file), which usually aren't a problem, but, again, if there're some unusual dependencies on these things in the original program, then, the reassembled program will work differently.

于 2011-12-14T19:36:15.910 回答
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)。测试反汇编器的一个好方法是输出可以重新组装的代码。组装,拆卸,组装,如果两个组装输出匹配,那么您的反汇编器做得很好。

于 2011-12-14T19:11:27.397 回答