如何在反编译的 C 代码中显示 KUSER_SHARED_DATA 成员?

逆向工程 视窗 反编译 吉德拉 六线谱
2021-07-01 02:10:44

这是一个示例 C 代码,它直接从KUSER_SHARED_DATA 的地址打印 Windows 版本仅在 Windows 10 中测试。原始内存地址在 Windows 版本中有所不同,但这不是重点。

#include <stdio.h>

int main(void)
{
    wprintf(
        L"Version: %lu.%lu.%lu\n",
        *(unsigned int *)(0x7FFE0000 + 0x026C),
        *(unsigned int *)(0x7FFE0000 + 0x0270),
        *(unsigned int *)(0x7FFE0000 + 0x0260)
    );
}

下面是反编译的代码:

在 GHIDRA 中:

int main(int _Argc,char **_Argv,char **_Env)

{
    wprintf(L"Version: %lu.%lu.%lu\n",
        (ulonglong)_DAT_7ffe026c,
        (ulonglong)_DAT_7ffe0270,
        (ulonglong)_DAT_7ffe0260);
  return 0;
}

在 IDA Pro + Hex-Rays 中:

int __fastcall main()
{
    wprintf(L"Version: %lu.%lu.%lu\n",
        MEMORY[0x7FFE026C],
        MEMORY[0x7FFE0270],
        MEMORY[0x7FFE0260]);
  return 0;
}

我的问题:在反编译代码中,是否可以将内存地址显示为 KUSER_SHARED_DATA 的成员?例如,我想显示MEMORY[0x7FFE0260]SharedData.NtBuildNumber或类似的东西。

2个回答

对于 IDA/Hex 射线:

  1. 在“加载类型库”窗口 ( View->Open subviews->Type libraries) 中,加载ntddk_win10(或任何您想要的 Windows 版本,回到 Windows XP 和 Windows Server 2003)。

可用的类型库

  1. 在“结构”窗口 ( View->Open subviews->Structures) 中,导入KUSER_SHARED_DATA. 您可以简单地在对话框中写入类型的名称并按 OK,如下图所示:

创建结构/联合

  1. 在 下Edit->Segments->Create segment,创建一个具有该内存范围的新段,如下图所示。

创建一个新段

  1. 在新段的开头,使用Edit->Struct var,然后选择KUSER_SHARED_DATA

选择结构类型

而已。现在反汇编列表如下所示:

拆卸

反编译看起来像这样:

反编译

吉德拉

addr = toAddr(0x7ffe0000)
currentProgram.memory.createUninitializedBlock("KUSER_SHARED_PAGE",addr,0x1000,0)
createData(addr,getDataTypes("KUSER_SHARED_DATA")[0])

结果

undefined8 main(void)

{
  wprintf((__crt_locale_pointers *)L"Version: %lu.%lu.%lu\n",
          (ulonglong)KUSER_SHARED_DATA_7ffe0000.NtMajorVersion,
          (ulonglong)KUSER_SHARED_DATA_7ffe0000.NtMinorVersion,
          (ulonglong)KUSER_SHARED_DATA_7ffe0000.NtBuildNumber);
  return 0;
}

方法1)

使用 VirtualQuery 获得
如下所示的大小是一个 python poc 将结果与 (MEMORY_BASIC_INFO *)foo.RegionSize 进行比较

:\>cat vq.py
from ctypes import *
meminfo =(c_ulong * 0x8)()
windll.kernel32.VirtualQuery(0x7ffe0000,byref(meminfo),sizeof(meminfo))
for i in meminfo:
    print (hex(i))


:\>python vq.py
0x7ffe0000
0x7ffe0000
0x2
0x1000
0x1000
0x2
0x20000
0x0

方法2)

使用 windbg !vprot 得到相同的结果

:\>cdb -c "!vprot 7ffe0000;q" cdb | awk "/Reading/,/quit/"
0:000> cdb: Reading initial command '!vprot 7ffe0000;q'
BaseAddress:       7ffe0000
AllocationBase:    7ffe0000
AllocationProtect: 00000002  PAGE_READONLY
RegionSize:        00001000
State:             00001000  MEM_COMMIT
Protect:           00000002  PAGE_READONLY
Type:              00020000  MEM_PRIVATE
quit:

方法3)

使用 windbg !address 获取相同地址空间的更详细的详细信息

:\>cdb -c "!address 7ffe0000;q" cdb | awk "/Usage:/,/quit/"
Usage:                  Other
Base Address:           7ffe0000
End Address:            7ffe1000
Region Size:            00001000 (   4.000 kB)
State:                  00001000          MEM_COMMIT
Protect:                00000002          PAGE_READONLY
Type:                   00020000          MEM_PRIVATE
Allocation Base:        7ffe0000
Allocation Protect:     00000002          PAGE_READONLY
Additional info:        User Shared Data


Content source: 1 (target), length: 1000
quit: