提升PE文件中导出的函数指令

逆向工程 聚乙烯 静态分析
2021-07-08 14:11:03

我正在尝试自动分析 .DLL 的导出函数中的指令,并且需要能够在不使用调试器的情况下从磁盘静态提升每个导出函数的入口点的前几条指令

我为每个导出的函数检索正确的 RVA(由 objdump 的结果验证):

     $objdump -p examples/MathLibrary.dll
     ...
     Export Table:
     DLL name: MathLibrary.dll
     Ordinal base: 1
     Ordinal      RVA  Name
          1  0x11212  fibonacci_current
          2  0x1118b  fibonacci_index
          3  0x1104b  fibonacci_init
          4  0x11307  fibonacci_next

然后使用以下方法计算似乎正确的文件偏移量:

   fo = exports.address - section.VirtualAddress + section.PointerToRawData

节是指 .text。这给了我:

    1 RVA 0x11212 'fibonacci_current' file offset:  1554
    Seeking to offset: 1554 to read 48 bytes.
    Read 14 bytes 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
    2 0x1118b 'fibonacci_index' file offset:  1419
    Seeking to offset: 1419 to read 48 bytes.
    Read 5 bytes 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
    3 0x1104b 'fibonacci_init' file offset:  1099
    Seeking to offset: 1099 to read 48 bytes.
    Read 37 bytes 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
    4 0x11307 'fibonacci_next' file offset:  1799
    Seeking to offset: 1799 to read 48 bytes.
    Read 9 bytes 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0

我得到的看起来像是位于 .text 部分中的有效偏移量,但是那里的字节都是 00。这是由 objdump 验证的。

    0001420      0000    0000    0000    0000    0000    0000    0040    4000
    0001440      722e    6c65    636f    0000    05bb    0000    f000    0001
    0001460      0600    0000    9200    0000    0000    0000    0000    0000
    0001500      0000    0000    0040    4200    0000    0000    0000    0000
    0001520      0000    0000    0000    0000    0000    0000    0000    0000
    *
    0002000      cccc    cccc    e9cc    4173    0000    71e9    002e    e900

我究竟做错了什么?这不是代码实际所在的位置吗?它们没有被转发,所以代码就在某处。谢谢你的帮助。

2个回答

RVA 是相对虚拟地址,它不是文件偏移量。

您需要解析节表以确定文件偏移如何映射到 RVA 并使用该映射来查找磁盘上的字节。

如果使用 win32 apis 是一个选项,你可以尝试沿着这条线

第一个示例命令使用 cdb 获取 rva 和字节以进行计数器检查(就像您使用 objdump 所做的那样)

第二个是一个 python 脚本,您可以将其用作参考以适应您选择的语言

第三个是实际执行和从地址获取的字节

:\>cdb -c "? ntdll!ZwYieldExecution-ntdll;db ntdll!ZwYieldExecution l10;q" cdb | awk "/Reading/,/quit/"
0:000> cdb: Reading initial command '? ntdll!ZwYieldExecution-ntdll;db ntdll!ZwYieldExecution l10;q'
Evaluate expression: 289512 = 00046ae8
77366ae8  b8 90 01 00 00 ba 00 03-fe 7f ff 12 c3 90 90 90  ................
quit:

:\>cat expbyte.py
import ctypes
import sys
if(len(sys.argv) == 3):
    ntstart = ctypes.windll.kernel32.LoadLibraryExW(sys.argv[1],0,2)
    rva = int(sys.argv[2],16)
    buff =[]
    for i in range(0,16,1):
        buff.append(ctypes.c_ubyte.from_address((ntstart+rva+i)).value)
    for i in buff:
        print("%02x " % i, end ="")
else:
    print("usage this script path rva")


:\>expbyte.py c:\Windows\System32\ntdll.dll 46ae8
b8 90 01 00 00 ba 00 03 fe 7f ff 12 c3 90 90 90
:\>