linux – 如何以改变文件部分数据长度的方式修改ELF文件?

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

但是,这不起作用.如果我只是用其他字节交换一些字节,它就可以工作.但是,如果我更改大小,则会失败.我知道有些sh_offsets彼此紧邻;但是,当我缩小可执行代码的大小时,这应该无关紧要.

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

我只是想知道,除了寻求帮助调试我的程序之外,还有什么比sh_size字段还需要更新才能使这项工作(减小尺寸时)?有没有什么可以改变长度失败除了那个领域?

编辑:

似乎Andy Ross完全正确.即使在这个非常简单的程序中,我在__libc_start_main中遇到了一些间接寻址,我无法轻易修改以更新它将达到的偏移量.

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

解决方法:

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

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

上一篇:linux – 确定特定进程是32位还是64位


下一篇:redis分页摘抄