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

时间:2012-09-28 18:17:14

标签: linux elf

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

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

当然,我的程序中可能存在一个错误(或多个错误),但我已经费尽心思了。

除了请求帮助调试我的程序,我只是想知道,除了sh_size字段我需要更新以使其工作(减小大小时)吗?除了该字段之外,还有什么能够改变长度失败吗?

编辑:

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

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

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:3)

  

除了sh_size字段之外还有什么需要更新才能使这项工作

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

ELF代表可执行链接格式,可执行文件链接形成“双重性” ELF。在(静态)链接时间使用节来组合成段;在执行时使用(也称为运行时,也就是动态链接时间)。

当然,当你缩小二进制文件时,你没有准确地告诉我们你的修补策略是什么,结果是以什么方式破坏了。安迪罗斯的答案很可能是你破产的真正原因。