塞翁364 发表于 2024-3-4 09:21:46

使用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]
查看完整版本: 使用ZwQueryVirtualMemory枚举进程模块支持x64