如何重用 .bss 部分中定义的符号/数据?

逆向工程 拆卸 部件 小精灵 重新组装
2021-07-06 12:57:38

所以基本上我试图objdump在 Linux 上重新使用一些从 32 位 ELF 二进制文件转储的汇编代码/数据

所以基本上,在反汇编的二进制文件中,我发现了一些引用.bss像这样的部分的符号

 80486b7:   mov    0x804b264,%eax   <- 0x804b264 is an addr in .bss
 80486bc:   movl   $0x0,0x4(%esp)
 80486c3:
 80486c4:   mov    %eax,(%esp)
 80486c7:   call   804876c <sum>

通过深入研究原始源代码,我发现它0x804b264用于stdinin.bss部分。

恕我直言,.bss节的数据基本上有两种情况

  1. 未初始化的数据,将在源代码中未初始化

  2. 一些全局/系统相关的数据(如上述情况下的stdin

因此,在尝试重新使用.bss部分数据时,我尝试过这种方式:

.section .bss
S_0x804B260 : .byte 0x00
           .byte 0x00
           .byte 0x00
          .byte 0x00
S_0x804B264 : .byte 0x00          <- I lift addr into symbol!
          .byte 0x00
         .byte 0x00
         .byte 0x00
         .byte 0x00

在本.text节中,我也会将相应的地址提升为符号。

同样的情况适用于.rodata.data部分

但问题是,有一些全局变量(例如stdin stdout),定位在.bsssection 中,而没有被用户定义的代码初始化,这意味着在我重用的 asm 代码中,这个符号变量将始终为零

我尝试手动替换与stdin对应的符号,看起来它工作正常。

但问题是:

  1. 如何识别该.bss部分中的哪个符号是系统初始化的某些变量?例如stdinstdout*等?

  2. 如果这是不可能的,那么无论如何我可以强制系统.bss在我希望它使用部分中使用内存

我清楚吗?谁能给我一些帮助?

1个回答

当您谈论“重用”程序的某些部分时,恐怕您不太清楚。你到底想做什么?将原始程序加载到调试器中,然后只调用它的一个函数?提取一系列地址并将其转换为新程序?或者从原始程序中提取一个函数,可能连同该函数所依赖的所有内容,然后将该函数嵌入到一个更大的程序中?

有一件事你错了: .bss 部分在程序开始时根本没有初始化(至少除了\0字节负载之外没有初始化)。诸如此类的初始化stdout是在 main() 开始之前在运行时完成的。用常量数据初始化的东西进入 .data 段。

(旁注:stdout FILE 结构未放入 .data 并初始化为常量的原因之一是类 Unix 系统上的大多数运行时将检查它们的文件描述符是否进入终端或其他东西,然后打开开/关缓冲取决于该检查)。

当您提取代码的一部分时,您必须检查对 .data 和 .bss 的每个引用(以及对 .text - 代码 - 以及提取的部分是否依赖于任何库等)。对于这些引用中的每一个,您必须决定如何处理它们 - 与新程序共享它们,为您提取的函数保留它们,等等。

如果你很幸运,并且有一个未剥离的可执行文件,你可以使用它nm来找出哪个符号在哪里;如果你不是那么幸运,你将不得不反汇编/反编译所有东西,理解它,将它重写成新的源代码,然后将它与你想要嵌入的任何东西一起编译。