使用ZwQueryVirtualMemory枚举进程模块支持x64

来源:互联网 发布:php带采集小说系统 编辑:程序博客网 时间:2024/04/28 02:39
#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);typedefNTSTATUS(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;}
0 0