在WinAPI

时间:2016-03-11 23:35:23

标签: winapi windbg

实施Windbg的地址功能...

我正在使用VirtualQueryEx查询另一个进程内存,并在VirtualQueryEx返回的基地址上使用getModuleFileName给出了模块名称。 剩下的是Process的其他非模块区域。如何确定文件是否映射到某个区域,或者该区域是否表示堆栈或堆或PEB / TEB等。

基本上,我如何判断一个区域是代表堆,堆栈还是PEB。 Windbg是如何做到的?

3 个答案:

答案 0 :(得分:2)

一种方法是反汇编实现!地址的调试器扩展DLL中的代码。 Windbg帮助文件中有关于编写扩展的文档。您可以使用该文档来反向设计!地址的处理程序所在的位置。然后浏览反汇编,您可以看到它调用的函数。

Windbg支持调试Windbg的另一个实例,特别是调试扩展DLL。您可以使用此工具更好地深入研究!address。

的实现

虽然逆向工程方法可能很乏味,但它比确定如何实现地址以及尝试每种理论更具决定性。

答案 1 :(得分:1)

要添加到@Χpẘ应答,命令的反向应该不是很难,因为调试器扩展DLL带有符号(我已经颠倒了一个来解释internal flag of the !heap命令)。

请注意,这只是一个快速概述,我没有太多深入了解它。

根据!address文档,该命令位于exts.dll库中。命令本身位于Extension::address

有两个命令处理,一个内核模式(KmAnalyzeAddress)和一个用户模式(UmAnalyzeAddress)。

UmAnalyzeAddress内,代码:

  • 解析命令行:UmParseCommandLine(CmdArgs &,UmFilterData &)
  • 使用IsTypeAvailable(char const *,ulong *)
  • 检查流程PEB是否可用"${$ntdllsym}!_PEB"
  • 分配std ::用户模式范围列表:std::list<UmRange,std::allocator<UmRange>>::list<UmRange,std::allocator<UmRange>>(void)
  • 开始循环以收集所需信息:
    • UmRangeData::GetWowState(void)
    • UmMapBuild
    • UmMapFileMappings
    • UmMapModules
    • UmMapPebs
    • UmMapTebsAndStacks
    • UmMapHeaps
    • UmMapPageHeaps
    • UmMapCLR
    • UmMapOthers

最后,结果最终使用UmPrintResults输出到屏幕。

上述每个功能都可以简化为基本组件,例如: UmFileMappings具有以下中心代码:

.text:101119E0                 push    edi             ; hFile
.text:101119E1                 push    offset LibFileName ; "psapi.dll"
.text:101119E6                 call    ds:LoadLibraryExW(x,x,x)
.text:101119EC                 mov     [ebp+hLibModule], eax
.text:101119F2                 test    eax, eax
.text:101119F4                 jz      loc_10111BC3
.text:101119FA                 push    offset ProcName ; "GetMappedFileNameW"
.text:101119FF                 push    eax             ; hModule
.text:10111A00                 mov     byte ptr [ebp+var_4], 1
.text:10111A04                 call    ds:GetProcAddress(x,x)

另一个例子,为了找到每个堆栈,代码只是遍历所有线程,得到它们的TEB并调用:

.text:1010F44C                 push    offset aNttib_stackbas ; "NtTib.StackBase"
.text:1010F451                 lea     edx, [ebp+var_17C]
.text:1010F457                 lea     ecx, [ebp+var_CC]
.text:1010F45D                 call    ExtRemoteTyped::Field(char const *)

_PEB_TEB_HEAP和其他内部结构中获取大量内容,因此如果不直接通过这些结构,它可能无法实现。所以,我想!address返回的一些信息无法通过常规/通用API访问。

答案 2 :(得分:0)

您需要确定您感兴趣的地址是否位于内存映射文件中。退房 - &gt; GetMappedFileName。获取进程的堆和堆栈地址会有点问题,因为范围是动态的,并不总是按顺序排列。

大声笑,我不知道,我会从堆的句柄开始。如果您可以生成/继承进程,那么您很可能可以访问堆的句柄。这个功能看起来很有希望:GetProcessHeap。该调试应用程序以管理员身份运行,它可以遍历流程链并监视任何用户级进程。我不认为您将能够访问内核模式应用程序(如文件系统过滤器)的受保护内存,但是,因为它们的策略略低一些。