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));
}
}