3

我正在尝试修改我自己的 ELF 文件的可执行内容,看看这是否可行。我编写了一个程序,它读取和解析 ELF 文件,搜索它应该更新的代码,对其进行更改,然后在更新节标题中的 sh_size 字段后将其写回。

但是,这不起作用。如果我只是用其他字节交换一些字节,它就可以工作。但是,如果我更改大小,它会失败。我知道一些 sh_offsets 是直接相邻的;但是,当我减小可执行代码的大小时,这无关紧要。

当然,我的程序中可能存在一个错误(或多个),但我已经煞费苦心地完成了它。

除了寻求帮助来调试我的程序,我只是想知道,除了我需要更新的 sh_size 字段之外,还有什么其他的东西需要更新才能使这项工作(减小大小时)?除了该字段之外,还有什么会导致更改长度失败的吗?

编辑:

看来安迪·罗斯是完全正确的。即使在这个非常简单的程序中,我也遇到了 __libc_start_main 中的一些间接寻址,我无法轻易修改它来更新它将达到的偏移量。

不过我很好奇,仍然试图尽可能解决这个问题的最佳方法是什么?我知道我不能在每种情况下都解决这个问题,但是对于一些简单的程序,应该可以更新使其运行所需的内容?我应该尝试编写自己的虚拟机还是尝试开发一个“调试器”,用 INT 3 替换每个可疑的问题指令?有任何想法吗?

4

2 回答 2

5

文本段可能在内部与相对偏移量相关联。所以一个函数可能试图跳转到,比如说,“当前地址加上 194 个字节”。如果你移动东西使得跳转目标现在是 190 字节,你显然会破坏东西。某些架构上的常量数据也是如此(例如 x86-64 但不是 i686)。要知道内部引用在哪里,没有简单的方法可以完全反汇编,事实上,要找到它们在计算上是无法确定的(即,试图找出运行时计算分支的所有可能的跳转目标是停止问题)。

基本上,这在一般情况下是无法解决的,所以如果你有一个来自其他人的 ELF 二进制文件,你正在尝试修补,你需要尝试其他技术。但是(非常!)小心,可以生成一个库,其中所有内部引用都通过 GOT/PLT,可以像这样分割和重新链接。你想达到什么目的?

于 2012-09-28T18:58:40.993 回答
3

除了我需要更新的 sh_size 字段之外,是否还有其他内容才能完成这项工作

听起来您正在修补完全链接的二进制文件(ET_EXECET_DYN)。请注意,在静态链接完成后,.sh_size不会用于任何事情。您可以剥离整个节表,二进制文件将继续正常工作。运行时重要的是ELF中的段,而不是section

ELF 代表可执行链接格式,可执行链接形成 ELF 的“双重性质”。在(静态)链接时使用部分来组合成段;在执行时(又名运行时,又名动态链接时)使用。

当然,您还没有确切地告诉我们,当您缩小二进制文件时,您的修补策略是什么,以及结果以何种方式被破坏。安迪·罗斯的回答很可能是你断线的真正原因。

于 2012-10-01T05:22:56.977 回答