首页
社区
课程
招聘
未解决 [求助]关于NtQueryVirtualMemory
发表于: 2019-3-15 09:53 4592

未解决 [求助]关于NtQueryVirtualMemory

2019-3-15 09:53
4592
你好,Xuetr上面可以查看进程线程ID,线程入口,TEB,模块名。我尝试使用NtQueryInformationThread,GetMappedFileName发现是可以获取的,代码如下:

void GetThread(DWORD dwPid)

{

DWORD dwStaAddr = NULL;

THREAD_BASIC_INFORMATION tteb = {0};

HANDLE ThreadHWND = NULL;

WCHAR path[MAX_PATH] = {0};

THREADENTRY32 te32;

te32.dwSize = sizeof(te32);

HMODULE hNtdll = LoadLibrary(L"ntdll.dll");

NTQUERYINFORMATIONTHREAD NtQueryInformationThread = NULL;

NtQueryInformationThread = (NTQUERYINFORMATIONTHREAD)

GetProcAddress(hNtdll, "NtQueryInformationThread");

HANDLE Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, NULL);

if (Thread32First(Snapshot, &te32))

{

do

{

ThreadHWND = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID);

NtQueryInformationThread(ThreadHWND, 9,

&dwStaAddr, sizeof(dwStaAddr), NULL);

NtQueryInformationThread(ThreadHWND, 0,

&tteb, sizeof(tteb), NULL);

HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);

if (dwPid == GetProcessIdOfThread(ThreadHWND))

{

GetMappedFileName(process, (PVOID)dwStaAddr, path, sizeof(path));

printf("线程ID:%d\t线程入口:%08x\t线程teb:%p\t模块:%S\n", te32.th32ThreadID, dwStaAddr, tteb.TebBaseAddress, path);

}

} while (Thread32Next(Snapshot, &te32));

}

}

发现在32位系统获取的信息跟Xuetr一致,但是编译为x86在64位的话不行,于是借用wow64ext的库,重新定义了NtQueryInformationThread,获取一致了,但是模块方面 GetMappedFileName获取的不了64位的,发现调用的是NtQueryVirtualMemory,在32位系统下改为

NtQueryVirtualMemory(process, (PVOID)dwStaAddr, MemoryMappedFilenameInformation, &tname, sizeof(tname), NULL);

32位也是可以获取模块路径的,但是用wow64ext库定义NtQueryVirtualMemory最后printf出来的是null,请问哪里出问题了?代码如下:

typedefstruct _UNICODE_STRING64 {

   USHORT Length; 

   USHORT MaximumLength;

   ULONG64 Buffer; 

} UNICODE_STRING64, *PUNICODE_STRING64; 


typedef struct _MEMORY_MAPPED_FILE_NAME_INFORMATION {

UNICODE_STRING64 Name;

} MEMORY_MAPPED_FILE_NAME_INFORMATION, *PMEMORY_MAPPED_FILE_NAME_INFORMATION;


BOOL NtQueryVirtualMemory64(HANDLE hProcess, DWORD64 BaseAddress, MEMORY_INFORMATION_CLASS MemoryInformationClass, LPVOID Buffer, DWORD64 Length, SIZE_T *ResultLength)

{

static DWORD64 nqvm = 0;

if (0 == nqvm)

{

nqvm = GetProcAddress64(getNTDLL64(), "NtQueryVirtualMemory");

if (0 == nqvm)

return 0;

}

DWORD64 numOfBytes = ResultLength ? *ResultLength : 0;

DWORD64 ret = X64Call(nqvm, 6, (DWORD64)hProcess, BaseAddress, MemoryInformationClass, Buffer, Length,(DWORD64)&numOfBytes);

if (STATUS_SUCCESS != ret)

{

SetLastErrorFromX64Call(ret);

return FALSE;

}

else

{

if (ResultLength)

*ResultLength = (SIZE_T)numOfBytes;

return TRUE;

}

}


void GetVirThread(DWORD dwPid)

{

DWORD64 dwStaAddr = NULL;

THREAD_BASIC_INFORMATION tteb = { 0 };

MEMORY_MAPPED_FILE_NAME_INFORMATION  tname = { 0 };

HANDLE ThreadHWND = NULL;

THREADENTRY32 te32;

te32.dwSize = sizeof(te32);


HANDLE Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, NULL);

if (Thread32First(Snapshot, &te32))

{

do

{

ThreadHWND = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID);

NtQueryInformationThread64(ThreadHWND, 9,

&dwStaAddr, sizeof(dwStaAddr), NULL);

NtQueryInformationThread64(ThreadHWND, 0,

&tteb, sizeof(tteb), NULL);

HANDLE process = OpenProcess(PROCESS_ALL_ACCESS,

FALSE, dwPid);

if (dwPid == GetProcessIdOfThread(ThreadHWND))

{

                            NtQueryVirtualMemory64(process, dwStaAddr, MemoryMappedFilenameInformation, &tname, sizeof(tname),NULL);

    printf("线程ID:%d\t线程入口:%llx\t模块名:%ls\n", te32.th32ThreadID, dwStaAddr, tname.Name.Buffer);

}

} while (Thread32Next(Snapshot, &te32));

}

}

谢谢~~



[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2019-3-15 09:54 被nilnull编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 12848
活跃值: (9142)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
2
MEMORY_MAPPED_FILE_NAME_INFORMATION  tname = { 0 };
这是32位的结构体吧
2019-3-15 14:18
0
雪    币: 472
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
hzqst MEMORY_MAPPED_FILE_NAME_INFORMATION tname = { 0 }; 这是32位的结构体吧
你好,找了一天没找到64位的结构体,后面有搜到
typedef enum _MEMORY_INFORMATION_CLASS
{
    MemoryBasicInformation, // MEMORY_BASIC_INFORMATION
    MemoryWorkingSetInformation, // MEMORY_WORKING_SET_INFORMATION
    MemoryMappedFilenameInformation, // UNICODE_STRING
    MemoryRegionInformation, // MEMORY_REGION_INFORMATION
    MemoryWorkingSetExInformation, // MEMORY_WORKING_SET_EX_INFORMATION
    MemorySharedCommitInformation, // MEMORY_SHARED_COMMIT_INFORMATION
    MemoryImageInformation, // MEMORY_IMAGE_INFORMATION
    MemoryRegionInformationEx,
    MemoryPrivilegedBasicInformation,
    MemoryEnclaveImageInformation, // MEMORY_ENCLAVE_IMAGE_INFORMATION // since REDSTONE3
    MemoryBasicInformationCapped
} MEMORY_INFORMATION_CLASS;

其中MemoryMappedFilenameInformation, // UNICODE_STRING  后面把UNICODE_STRING uname = {0}; 
NtQueryVirtualMemory(process, (PVOID)dwStaAddr, MemoryMappedFilenameInformation, &uname, 0x100, NULL);
这个在32位可以获得路径了,但是在x64借用wow64ext还是显示为null,其中
typedefstruct _UNICODE_STRING64 { 
   USHORT Length; 
   USHORT MaximumLength;
   ULONG64 Buffer; 
} UNICODE_STRING64, *PUNICODE_STRING64; 
2019-3-16 16:56
0
游客
登录 | 注册 方可回帖
返回
//