重定位如何对 SH4 ELF 中的导入函数起作用?

逆向工程 艾达 吉德拉 小精灵 sh4 搬迁
2021-06-27 04:25:47

我使用 sh4 gcc 编译器作为共享库构建了非常简单的 hello world 代码:

#include <stdio.h>
void hello()
{
    printf("Hello world!\n");
}

但是当我将 .so 文件加载到反汇编器(IDA 或 Ghidra)中时,我实际上无法找到 puts 被调用的位置。即使 hello() 函数存在: IDA 中的 hello() 函数 但是在它应该实际调用 printf/puts 的地方,有一些地址加载操作指向不存在的地址: 在此处输入图片说明 我可以在导入部分看到 puts,但是除了一些数据之外没有引用的代码来自 .LOAD 部分的参考。

尽管如此,我将代码构建为可执行文件,而不是共享库。puts thunk 在函数中变得可见: 在此处输入图片说明

好像导入 thunk 不是为共享库传播,而是为可执行文件传播。

我试图自己找到问题,所以我在两个二进制文件上都运行了 readelf。看来这取决于重定位数据。这是可执行文件转储:

'PLT' relocation section at offset 0x4002d0 contains 48 bytes:
 Offset     Info    Type            Sym.Value  Sym. Name + Addend
0041103c  000002a4 R_SH_JMP_SLOT     00400380   puts@GLIBC_2.2 + 0
00411040  000001a4 R_SH_JMP_SLOT     00000000   __gmon_start__ + 0
00411044  000005a4 R_SH_JMP_SLOT     004003b8   __libc_start_main@GLIBC_2.2 + 0
00411048  000003a4 R_SH_JMP_SLOT     004003d4   abort@GLIBC_2.2 + 0

这是它查找共享模块的方式:

'PLT' relocation section at offset 0x364 contains 36 bytes:
 Offset     Info    Type            Sym.Value  Sym. Name + Addend
00011010  000001a4 R_SH_JMP_SLOT     00000000   __cxa_finalize@GLIBC_2.2 + 0
00011014  000003a4 R_SH_JMP_SLOT     00000000   puts@GLIBC_2.2 + 0
00011018  000004a4 R_SH_JMP_SLOT     00000000   __gmon_start__ + 0

Sym.Value 为零,并且 Ghidra 和 IDA 都无法确定 thunk 指向的位置。所以问题是:

  1. 共享模块有什么特别之处,以至于 Sym.Value 为零?
  2. 当操作系统加载 so 文件时,导入 thunk 如何传播?
  3. 有没有办法将导入的函数映射到这样的 thunk 中,使它们在 IDA 或 Ghidra 中具有适当的名称?

共享库的构建方式:

sh4-linux-gnu-gcc -c -g -fPIC hello.c -o hello.o
sh4-linux-gnu-gcc hello.o -shared -o libhello.so
0个回答
没有发现任何回复~