使用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

暴力枚举进程模块

旧文章搬运ZwQuerySystemInformation枚举进线程信息

SystemVerilog枚举可以为null吗?

视频| Python:枚举+选择排序

题解 非递归实现组合型枚举