我试图在minifilter回调函数中回溯一个线程的usermode堆栈。
假设我和调用线程处于相同的上下文中,从它的TEB / TIB获取线程堆栈地址并处理该堆栈上的地址应该允许我回溯它的堆栈。
由于我收到的地址不是调用系统调用的预期用户模式模块, 我一定有些不对劲。
如果你能指出我正确的方向,我会很高兴的。
提前致谢。
以下是读取堆栈内容的代码:
pTEB = (PVOID *)((char *)pThread + 0x20);
// Read TIB
pTib = (NT_TIB*)pTEB;
stackBottom = (PVOID*)pTib->StackLimit;
stackTop = (PVOID*)pTib->StackBase;
LogDbgView(("stackBottom=%p, stackTop=%p",stackBottom, stackTop));
if (!MyReadMemory(IoGetCurrentProcess(), stackBottom, buf, stackTop-stackBottom))
{
LogDbgView(("Read Memory = %x",buf));
LogDbgView(("Read Memory = %x",buf+8));
LogDbgView(("Read Memory = %x",buf+16));
LogDbgView(("Read Memory = %x",buf+24));
}
以下是获取模块名称和地址的函数:
PVOID LoadModulesInformation()
{
PVOID pSystemInfoBuffer = NULL;
__try
{
NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES;
ULONG SystemInfoBufferSize = 0;
status = ZwQuerySystemInformation(SystemModuleInformation,
&SystemInfoBufferSize,
0,
&SystemInfoBufferSize);
if (!SystemInfoBufferSize)
return NULL;
pSystemInfoBuffer = (PVOID)ExAllocatePool(NonPagedPool, SystemInfoBufferSize*2);
if (!pSystemInfoBuffer)
return NULL;
memset(pSystemInfoBuffer, 0, SystemInfoBufferSize*2);
status = ZwQuerySystemInformation(SystemModuleInformation,
pSystemInfoBuffer,
SystemInfoBufferSize*2,
&SystemInfoBufferSize);
if (NT_SUCCESS(status))
{
return pSystemInfoBuffer;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
return NULL;
}
PUNICODE_STRING findModuleName(PVOID addr, PVOID pSystemInfoBuffer, ULONG Tag FILE_AND_LINE_ARGS)
{
PVOID pModuleBase = NULL;
PCHAR pCharRet=NULL;
PUNICODE_STRING pus = NULL;
__try
{
if (pSystemInfoBuffer != NULL && MmIsAddressValid(addr))
{
PSYSTEM_MODULE_ENTRY pSysModuleEntry = ((PSYSTEM_MODULE_INFORMATION)(pSystemInfoBuffer))->Module;
ULONG i;
for (i = 0; i <((PSYSTEM_MODULE_INFORMATION)(pSystemInfoBuffer))->Count; i++)
{
if ((pSysModuleEntry[i].Base <= addr) && (pSysModuleEntry[i].Size < ((ULONG)addr - (ULONG)pSysModuleEntry[i].Base)))
{
pCharRet = pSysModuleEntry[i].ImageName+pSysModuleEntry[i].PathLength;
break;
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
pCharRet = NULL;
}
if (pCharRet)
{
pus = UtlpCharToUnicode(pCharRet, TRUE, TRUE, Tag FILE_AND_LINE_PARAMS);
}
else
{
pus = UtlpCharToUnicode("UNKNOWN", TRUE, TRUE, Tag FILE_AND_LINE_PARAMS);
}
return pus;
}
答案 0 :(得分:0)
pTEB =(PVOID *)((char *)pThread + 0x20);
即使在PoC中,也不要这样做。结构布局不时变化。您可以使用PsGetProcessPeb(请参阅此处https://code.google.com/p/arkitlib/source/browse/trunk/ARKitDrv/Ps.c)
LogDbgView((&#34;读取内存=%x&#34;,buf));
你不在buf地址读取内存,而是读取buf的值。在C中,您必须取消引用指针以从那里读取内存。喜欢这个
LogDbgView((&#34;读取内存=%x&#34;,(PVOID)* buf));
LogDbgView((&#34;读取内存=%x&#34;,buf + 8));
为了能够为x86和x64编译,你必须避免这样的事情。相反,使用sizeof(PVOID):
LogDbgView((&#34;读取内存=%x&#34;,(PVOID)*(buf + sizeof(PVOID))));