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

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

你可能感兴趣的:(枚举模块)