使用ZwQueryVirtualMemory枚举进程模块支持x64
Posted zhuhuibeishadiao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用ZwQueryVirtualMemory枚举进程模块支持x64相关的知识,希望对你有一定的参考价值。
最新代码(内核) 应用层简单改下即可
typedef struct _MEMORY_SECTION_NAME
UNICODE_STRING Name;
WCHAR Buffer[260];
MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME;
ULONG_PTR dqCurrentBase = 0;
PEPROCESS Process = nullptr;
MEMORY_BASIC_INFORMATION baseinfo;
MEMORY_SECTION_NAME sec;
do
auto status = PsLookupProcessByProcessId(pid, &Process);
if (!NT_SUCCESS(status))
break;
RtlZeroMemory(&baseinfo, sizeof(baseinfo));
SIZE_T ret = 0;
KeAttachProcess(Process);
for (dqCurrentBase = 0;
NT_SUCCESS(ZwQueryVirtualMemory(NtCurrentProcess(), (PVOID)dqCurrentBase, MemoryBasicInformation, &baseinfo, sizeof(MEMORY_BASIC_INFORMATION), &ret));
dqCurrentBase = (ULONG_PTR)baseinfo.BaseAddress + baseinfo.RegionSize)
if (baseinfo.Type == MEM_IMAGE && (ULONG_PTR)baseinfo.AllocationBase == dqCurrentBase)
// MemorySectionName
if (NT_SUCCESS(ZwQueryVirtualMemory(NtCurrentProcess(), (PVOID)dqCurrentBase, (MEMORY_INFORMATION_CLASS)2, &sec, sizeof(MEMORY_SECTION_NAME), &ret)))
base = (PVOID)dqCurrentBase;
DPRINT("0x%llx, %wZ\\n", dqCurrentBase, &sec.Name);
KeDetachProcess();
ObDereferenceObject(Process);
while (false);
#include "stdio.h"
#include "windows.h"
typedef struct _LSA_UNICODE_STRING
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;
//typedef struct _MEMORY_BASIC_INFORMATION
// PVOID BaseAddress;
// PVOID AllocationBase;
// DWORD AllocationProtect;
// SIZE_T RegionSize;
// DWORD State;
// DWORD Protect;
// DWORD Type;
// MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
typedef long (*RTLADJUSTPRIVILEGE)(ULONG,ULONG,ULONG,PVOID);
RTLADJUSTPRIVILEGE RtlAdjustPrivilege;
typedef enum _MEMORY_INFORMATION_CLASS
MemoryBasicInformation,
MemoryWorkingSetList,
MemorySectionName
MEMORY_INFORMATION_CLASS;
NTSTATUS ZwQueryVirtualMemory(
_In_ HANDLE ProcessHandle,
_In_opt_ PVOID BaseAddress,
_In_ MEMORY_INFORMATION_CLASS MemoryInformationClass,
_Out_ PVOID MemoryInformation,
_In_ SIZE_T MemoryInformationLength,
_Out_opt_ PSIZE_T ReturnLength
);
typedef
NTSTATUS
(WINAPI *ZWQUERYVIRTUALMEMORY) (
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
OUT PVOID MemoryInformation,
IN SIZE_T MemoryInformationLength,
OUT PSIZE_T ReturnLength OPTIONAL
);
BOOLEAN NtPathToDosPathW(WCHAR *FullNtPath, WCHAR *FullDosPath)
WCHAR DosDevice[4]= 0; //dos设备名最大长度为4
WCHAR NtPath[64]= 0; //nt设备名最大长度为64
WCHAR *RetStr=NULL;
size_t NtPathLen=0;
short i = 0;
if (!FullNtPath || !FullDosPath)
return FALSE;
for(i=65; i<26+65; i++)
DosDevice[0]=i;
DosDevice[1]=L':';
if(QueryDosDeviceW(DosDevice,NtPath,64))
if (NtPath)
NtPathLen=wcslen(NtPath);
if (!wcsnicmp(NtPath,FullNtPath,NtPathLen))
wcscpy(FullDosPath,DosDevice);
wcscat(FullDosPath,FullNtPath+NtPathLen);
return TRUE;
return FALSE;
void EnumProcessModules(IN DWORD dwProcessId)
DWORD64 dwStartAddr = 0x00000000;
ULONG num = 0;
BYTE szBuffer[MAX_PATH * 2 + 4] = 0;
WCHAR szModuleName[MAX_PATH] = 0;
WCHAR szPathName[MAX_PATH] = 0;
MEMORY_BASIC_INFORMATION mbi;
PUNICODE_STRING usSectionName;
ZWQUERYVIRTUALMEMORY fnZwQueryVirtualMemory;
BOOL modulex64 = FALSE;
HANDLE hProcess =NULL;
ULONG dwRetVal=0;
RtlAdjustPrivilege=(RTLADJUSTPRIVILEGE)GetProcAddress(LoadLibraryW(L"ntdll.dll"),"RtlAdjustPrivilege");
RtlAdjustPrivilege(20,1,0,&dwRetVal);//debug
RtlAdjustPrivilege(19,1,0,&dwRetVal);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwProcessId);
if (hProcess == NULL)
wprintf(L"Open Process %d Error\\n", dwProcessId);
return;
//dwStartAddr = 0x000007fef4530000;
dwStartAddr = 0x0000000000000000;
fnZwQueryVirtualMemory = (ZWQUERYVIRTUALMEMORY)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQueryVirtualMemory" );
if(fnZwQueryVirtualMemory)
do
if (fnZwQueryVirtualMemory(
hProcess,
(PVOID64)dwStartAddr,
MemoryBasicInformation,
&mbi,
sizeof(mbi),
0) >= 0 )
if(mbi.Type == MEM_IMAGE)
if (fnZwQueryVirtualMemory(
hProcess,
(PVOID64)dwStartAddr,
MemorySectionName,
szBuffer,
sizeof(szBuffer),
0) >= 0 )
usSectionName = (PUNICODE_STRING)szBuffer;
if( _wcsnicmp(szModuleName, usSectionName->Buffer, usSectionName->Length / sizeof(WCHAR)) )
wcsncpy(szModuleName,usSectionName->Buffer,usSectionName->Length/sizeof(WCHAR));
szModuleName[usSectionName->Length / sizeof(WCHAR)] = UNICODE_NULL;
// DeviceName2PathName(szPathName, szModuleName);
NtPathToDosPathW(szModuleName,szPathName);
wprintf(L"[0x%.8llx]\\t%s\\n", dwStartAddr, szPathName);
num++;
// 递增基址,开始下一轮查询!
dwStartAddr += (ULONGLONG)0x1000;
if(!modulex64)
if(dwStartAddr>0x0000000200000000)
modulex64 = TRUE;
dwStartAddr = 0x000007fe00000000;
while( dwStartAddr < 0x000007ff00000000 );
CloseHandle(hProcess);
printf("module num :%d\\n",num);
void main()
int pid = 0;
printf("Input Pid:");
scanf("%d",&pid);
EnumProcessModules(pid);
printf("ok!");
getchar();
getchar();
getchar();
return;
以上是关于使用ZwQueryVirtualMemory枚举进程模块支持x64的主要内容,如果未能解决你的问题,请参考以下文章
使用ZwQueryVirtualMemory枚举进程模块支持x64