写一篇文章!WinAPI中的地址等价

写一篇文章!WinAPI中的地址等价,winapi,windbg,Winapi,Windbg,实施!Windbg的地址功能 我正在使用VirtualQueryEx查询另一个进程内存,并对从VirtualQueryEx返回的基址使用getModuleFileName给出模块名称。 剩下的是流程的其他非模块区域。如何确定文件是否映射到某个区域,或者该区域是否表示堆栈、堆或PEB/TEB等 基本上,我如何判断一个区域是表示堆、堆栈还是PEB。Windbg是如何实现的?您需要确定感兴趣的地址是否位于内存映射文件中。退房-->。获取进程的堆和堆栈地址会有点问题,因为范围是动态的,并不总是按顺序排列

实施!Windbg的地址功能

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


基本上,我如何判断一个区域是表示堆、堆栈还是PEB。Windbg是如何实现的?

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


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

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


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

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

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


尽管逆向工程的方法可能很乏味,但它比理论化的方法更具确定性!地址被实现并尝试每个理论。

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

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


尽管逆向工程的方法可能很乏味,但它比理论化的方法更具确定性!地址被实现并尝试每种理论。

添加到@Χpẘ 答案是,命令的反转应该不是很难,因为调试器扩展DLL带有符号(我已经反转了一个来解释命令)

请注意,这只是一个快速的概述,我没有在里面读太多

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

这里处理两个命令:内核模式(
kmanalyzeddress
)和用户模式(
umanalyzeddress

umanalyzeadress
内部,代码:

  • 分析命令行:
    UmParseCommandLine(CmdArgs&,UmFilterData&)
  • 检查流程PEB是否可用
    IsTypeAvailable(char const*,ulong*)
    “${$ntdllsym}!\u PEB”
  • 分配用户模式范围的std::列表:
    std::列表::列表(无效)
  • 启动循环以收集所需信息:
    • UmRangeData::GetWowState(无效)
    • UmMapBuild
    • UmMapFileMappings
    • UmMapModules
    • UmMapPebs
    • UmMapTebsAndStacks
    • ummapheps
    • UmMapPageHeaps
    • ummaplr
    • 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 *)

\u PEB
\u TEB
\u HEAP
和其他内部结构中获取大量内容,因此如果不直接通过这些结构,可能无法实现。所以,我猜,
返回的一些信息!地址
无法通过常用/通用API访问。

添加到@Χpẘ 答案是,命令的反转应该不是很难,因为调试器扩展DLL带有符号(我已经反转了一个来解释命令)

请注意,这只是一个快速的概述,我没有在里面读太多

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

这里处理两个命令,一个是内核模式(
kmanalyzeadress
),一个是用户模式(