使用ZwQueryVirtualMemory枚举进程模块支持x64
使用ZwQueryVirtualMemory枚举进程模块支持x64#include "stdio.h"#include "windows.h"
typedef struct _LSA_UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTRBuffer;
} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;
//typedef struct _MEMORY_BASIC_INFORMATION {
//PVOIDBaseAddress;
//PVOIDAllocationBase;
//DWORDAllocationProtect;
//SIZE_T RegionSize;
//DWORDState;
//DWORDProtect;
//DWORDType;
//} 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= {0}; //dos设备名最大长度为4
WCHAR NtPath= {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=i;
DosDevice=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 = {0};
WCHAR szModuleName = {0};
WCHAR szPathName = {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 = UNICODE_NULL;
// DeviceName2PathName(szPathName, szModuleName);
NtPathToDosPathW(szModuleName,szPathName);
wprintf(L"\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);
}
voidmain()
{
int pid = 0;
printf("Input Pid:");
scanf("%d",&pid);
EnumProcessModules(pid);
printf("ok!");
getchar();
getchar();
getchar();
return;
}
页:
[1]