当前位置: 首页 > 面试题库 >

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

商麒
2023-03-14
问题内容

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


问题答案:

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

我可以想到两个主要的并发症。首先,由于指针偏移之类的原因,机器代码本身与汇编代码不是一一对应的。

例如,考虑到Hello world的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指令进行填充。如果更长,则可能会遇到麻烦,可能必须创建新函数并改为调用它们。



 类似资料:
  • 问题内容: 我需要修改现有的APK,修改源,然后重新编译。 我可以使用dex2jar或apktool对其进行反编译,效果很好 从jar文件中,我可以获取Java源代码(使用jd-gui) 然后我可以修改Java文件 但是现在我想知道如何重新编译java文件并将它们放回jar文件中!(jar部分应该很简单,主要问题似乎是如何为Android重新编译Java文件) 我知道另一种解决方案是使用apkto

  • 问题内容: 有人告诉我要使用反汇编程序。是否有任何内置的?最简单的方法是什么? 问题答案: 我认为没有标志,因为它主要是编译器,但是另一个GNU开发工具可以。带有/ 标志: 反汇编如下所示:

  • 问题内容: 为了运行MIPS汇编程序,x86 linux周围是否有任何命令行解释器或任何其他程序集? 我希望能够编写简单的MIPS汇编程序并从本地计算机上的控制台运行它们。 我知道SPIM,但是它 需要X Windows ,我很好奇是否有更好的选择。 编辑:事实证明它不需要X Windows。我仍然对SPIM有问题。我的拙见不是最好的。Qemu / Cross编译的工具链需要更多工作,但我的怪癖却

  • (gdb) set disassemble-next-line on (gdb) start The program being debugged has been started already. Start it from the beginning? (y or n) y Temporary breakpoint 3 at 0x400543: file 1.c, line 14. Star

  • 我正在开发一个webpack插件,不知道如何在构建过程中修改模块。我想做的是: null null 看起来rebuildModule应该重新解析源代码,重新建立依赖关系等,但它并没有解析我的require语句并将它们更改为webpack requires。构建的文件包括我修改过的源代码,但需要(“...”)语句未修改。 我如何使我修改的模块“更新”,以便webpack将处理我添加的源代码与最初解析

  • 问题内容: 我只是好奇地知道这一点,当我不进行“清理”就安装mvn时,maven仅编译了修改后的java文件。Maven如何识别Java文件是否被修改?我相信它没有使用文件的最后修改属性。 我相信的原因:我有一个模块,在合并了svn的更改后,我进行了mvn install,但它没有编译修改后的文件,当我查看更改时,我发现其中的’long’被修改为’Long’吸气剂和二传手。 所以我只想知道Mave