系统相关
首页 > 系统相关> > 如何反汇编,修改然后重新组装Linux可执行文件?

如何反汇编,修改然后重新组装Linux可执行文件?

作者:互联网

无论如何这可以做到吗?我已经使用了objdump但是这不会产生任何我知道的汇编程序可以接受的汇编输出.我希望能够在可执行文件中更改指令,然后再对其进行测试.

解决方法:

我认为没有任何可靠的方法可以做到这一点.机器代码格式非常复杂,比汇编文件更复杂.实际上不可能采用编译的二进制文件(例如,以ELF格式)并生成源汇编程序,该汇编程序将编译为相同(或类似 – 足够)的二进制文件.为了理解这些差异,比较GCC编译直接汇编程序(gcc -S)的输出与可执行文件的objdump输出(objdump -D).

我能想到两个主要的并发症.首先,由于指针偏移之类的东西,机器代码本身与汇编代码不是一对一的对应关系.

例如,考虑Hello代码的C代码:

int main()
{
    printf("Hello, world!\n");
    return 0;
}

这将编译为x86汇编代码:

.LC0:
    .string "hello"
    .text
<snip>
    movl    $.LC0, %eax
    movl    %eax, (%esp)
    call    printf

其中.LCO是命名常量,而printf是共享库符号表中的符号.与objdump的输出相比:

80483cd:       b8 b0 84 04 08          mov    $0x80484b0,%eax
80483d2:       89 04 24                mov    %eax,(%esp)
80483d5:       e8 1a ff ff ff          call   80482f4 <printf@plt>

首先,常量.LC0现在只是内存中的一些随机偏移量 – 在正确的位置创建包含此常量的汇编源文件很困难,因为汇编器和链接器可以自由选择这些常量的位置.

其次,我对此并不完全确定(并且它取决于位置无关代码之类的东西),但我相信对printf的引用实际上并没有在那个代码中的指针地址处进行编码,但是ELF头包含一个查找表,它在运行时动态替换其地址.因此,反汇编代码与源汇编代码并不完全对应.

总之,源程序集具有符号,而编译的机器代码具有难以反转的地址.

第二个主要的复杂因素是汇编源文件不能包含原始ELF文件头中存在的所有信息,例如动态链接的库以及原始编译器放置在其中的其他元数据.重建这个很难.

就像我说的那样,一个特殊工具可能会操纵所有这些信息,但是不太可能只生成可以重新组装回可执行文件的汇编代码.

如果您只想修改可执行文件的一小部分,我建议采用比重新编译整个应用程序更精细的方法.使用objdump获取您感兴趣的函数的汇编代码.手动将其转换为“源汇编语法”(在这里,我希望有一个工具实际上使用与输入相同的语法生成反汇编) ,并根据需要进行修改.完成后,重新编译这些函数并使用objdump找出修改过的程序的机器代码.然后,使用十六进制编辑器手动将新机器代码粘贴到原始程序的相应部分的顶部,注意新代码与旧代码的字节数完全相同(或者所有偏移量都是错误的) ).如果新代码较短,您可以使用NOP指令将其填充.如果它更长,您可能遇到麻烦,可能需要创建新功能并调用它们.

标签:x86,linux,objdump,disassembly
来源: https://codeday.me/bug/20190918/1811645.html