ZwQuery VirtualMemory 로 프로 세 스 모듈 매 거 진

다음으로 이동:http://www.cppblog.com/aurain/archive/2010/07/05/119361.html
 ZwQueryVirtualMemory      
              :CreateToolhelp32Snapshot,Module32First,Module32Next  "Tool Help Functions"     ,            ( Win95      ),            ntdll.dll         ZwQueryVirtualMemory,。          ,             (  IceSword)。
             :

//-------------------------------------------------------------------------------------------------

NTSTATUS
NTAPI
ZwQueryVirtualMemory(
            IN HANDLE ProcessHandle,
            IN PVOID BaseAddress,
            IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
            OUT PVOID MemoryInformation,
            IN ULONG MemoryInformationLength,
            OUT PULONG ReturnLength OPTIONAL );

typedef enum _MEMORY_INFORMATION_CLASS {
            MemoryBasicInformation,
            MemoryWorkingSetList,
            MemorySectionName,
            MemoryBasicVlmInformation
} MEMORY_INFORMATION_CLASS;

    :
           ProcessHandle -       
           BaseAddress    -           
           MemoryInformationClass -          
           MemoryInformation -         ,        
           MemoryInformationLength -      (     )
           ReturnLength -            (     )
   :
           NTSTATUS -   STATUS_SUCCESS        

//-------------------------------------------------------------------------------------------------

           ,           MemoryBasicInformation MemorySectionName,
           ,   :       ,             ,             ,
            .               MEM_IMAGE                ,              .
  ,                   \Device\HarddiskVolume1     ,                DOS   , C:\,D:\ 。         \Device\HarddiskVolume1  C \Device\HarddiskVolume2  D 。        QueryDosDevice    。
     :
// CheckDll.cpp :              。
//
 
#include "stdafx.h"
 
#include <windows.h>
#include <winternl.h>
 
#include <string>
#include <map>
using namespace std;
 
#pragma warning(disable:4312)
 
typedef enum _MEMORY_INFORMATION_CLASS
{
   MemoryBasicInformation,
   MemoryWorkingSetList,
   MemorySectionName
}MEMORY_INFORMATION_CLASS;
 
typedef
NTSTATUS
(WINAPI *ZWQUERYVIRTUALMEMORY) (
                         IN HANDLE ProcessHandle,
                         IN PVOID BaseAddress,
                         IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
                         OUT PVOID MemoryInformation,
                         IN ULONG MemoryInformationLength,
                         OUT PULONG ReturnLength OPTIONAL
                         );
 
map<wstring, wstring> g_mapDevice2Path;
 
void ConvertVolumePaths(
                   IN PWCHAR DeviceName,
                   IN PWCHAR VolumeName
                   )
{
   DWORD  CharCount = MAX_PATH + 1;
   PWCHAR Names     = NULL;
   PWCHAR NameIdx      = NULL;
   BOOL   Success      = FALSE;
 
   for (;;)
   {
      //
      //  Allocate a buffer to hold the paths.
      Names = (PWCHAR) new BYTE [CharCount * sizeof(WCHAR)];
 
      if ( !Names )
      {
         //
         //  If memory can't be allocated, return.
         return;
      }
 
      //
      //  Obtain all of the paths
      //  for this volume.
      Success = GetVolumePathNamesForVolumeNameW(
         VolumeName, Names, CharCount, &CharCount
         );
 
      if ( Success )
      {
         break;
      }
 
      if ( GetLastError() != ERROR_MORE_DATA )
      {
         break;
      }
 
      //
      //  Try again with the
      //  new suggested size.
      delete [] Names;
      Names = NULL;
   }
 
   if ( Success )
   {
      //
      //  Display the various paths.
      for ( NameIdx = Names;
         NameIdx[0] != L'\0';
         NameIdx += wcslen(NameIdx) + 1 )
      {
         g_mapDevice2Path[DeviceName] = NameIdx;
      }
   }
 
   if ( Names != NULL )
   {
      delete [] Names;
      Names = NULL;
   }
 
   return;
}
 
BOOL InitDevice2Path()
{
   BOOL   bRet               = FALSE; 
   DWORD  CharCount           = 0;
   WCHAR  DeviceName[MAX_PATH] = L"";
   DWORD  Error              = ERROR_SUCCESS;
   HANDLE FindHandle          = INVALID_HANDLE_VALUE;
   BOOL   Found              = FALSE;
   size_t Index              = 0;
   BOOL   Success                = FALSE;
   WCHAR  VolumeName[MAX_PATH] = L"";
 
   //
   //  Enumerate all volumes in the system.
   FindHandle = FindFirstVolumeW(VolumeName, ARRAYSIZE(VolumeName));
 
   if (FindHandle == INVALID_HANDLE_VALUE)
   {
      Error = GetLastError();
      wprintf(L"FindFirstVolumeW failed with error code %d
", Error); return bRet; } for (;;) { // // Skip the \\?\ prefix and remove the trailing backslash. Index = wcslen(VolumeName) - 1; if (VolumeName[0] != L'\\' || VolumeName[1] != L'\\' || VolumeName[2] != L'?' || VolumeName[3] != L'\\' || VolumeName[Index] != L'\\') { Error = ERROR_BAD_PATHNAME; wprintf(L"FindFirstVolumeW/FindNextVolumeW returned a bad path: %s
", VolumeName); break; } // // QueryDosDeviceW doesn't allow a trailing backslash, // so temporarily remove it. VolumeName[Index] = L'\0'; CharCount = QueryDosDeviceW(&VolumeName[4], DeviceName, ARRAYSIZE(DeviceName)); VolumeName[Index] = L'\\'; if ( CharCount == 0 ) { Error = GetLastError(); wprintf(L"QueryDosDeviceW failed with error code %d
", Error); break; } ConvertVolumePaths(DeviceName, VolumeName); // // Move on to the next volume. Success = FindNextVolumeW(FindHandle, VolumeName, ARRAYSIZE(VolumeName)); if ( !Success ) { Error = GetLastError(); if (Error != ERROR_NO_MORE_FILES) { wprintf(L"FindNextVolumeW failed with error code %d
", Error); break; } // // Finished iterating // through all the volumes. Error = ERROR_SUCCESS; break; } } FindVolumeClose(FindHandle); FindHandle = INVALID_HANDLE_VALUE; return bRet; } void DeviceName2PathName(OUT WCHAR* szPathName, IN const WCHAR* szDeviceName) { memset(szPathName, 0, MAX_PATH * 2); wstring strDeviceName = szDeviceName; size_t pos = strDeviceName.find(L'\\', 9); wstring strTemp1 = strDeviceName.substr(0, pos); wstring strTemp2 = strDeviceName.substr(pos + 1); wstring strDriverLetter = g_mapDevice2Path[strTemp1]; wstring strPathName = strDriverLetter + strTemp2; wcscpy_s(szPathName, MAX_PATH, strPathName.c_str()); } /** * * @param dwProcessId Id * @return void */ void EnumProcessModules(IN DWORD dwProcessId) { DWORD dwStartAddr = 0x00000000; 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; HANDLE hProcess =NULL; hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwProcessId); if (hProcess == NULL) { wprintf(L"Open Process %d Error
", dwProcessId); return; } dwStartAddr = 0x00000000; fnZwQueryVirtualMemory = (ZWQUERYVIRTUALMEMORY) ::GetProcAddress(GetModuleHandleA("ntdll.dll"), "ZwQueryVirtualMemory" ); if(fnZwQueryVirtualMemory) { do { if (fnZwQueryVirtualMemory( hProcess, (PVOID)dwStartAddr, MemoryBasicInformation, &mbi, sizeof(mbi), 0) >= 0 ) { if(mbi.Type == MEM_IMAGE) { if (fnZwQueryVirtualMemory( hProcess, (PVOID)dwStartAddr, MemorySectionName, szBuffer, sizeof(szBuffer), 0) >= 0 ) { usSectionName = (PUNICODE_STRING)szBuffer; if( _wcsnicmp(szModuleName, usSectionName->Buffer, usSectionName->Length / sizeof(WCHAR)) ) { wcsncpy_s(szModuleName, usSectionName->Buffer, usSectionName->Length / sizeof(WCHAR) ); szModuleName[usSectionName->Length / sizeof(WCHAR)] = UNICODE_NULL; DeviceName2PathName(szPathName, szModuleName); wprintf(L"[0x%.8x]\t%s
", dwStartAddr, szPathName); } } } } // , ! dwStartAddr += 0x1000; }while( dwStartAddr < 0x80000000 ); } CloseHandle(hProcess); } /** * ("SeDebugPrivilege" 、 ) * @param void * @return TRUE- ;FALSE- */ BOOL EnableDebugPriv() { HANDLE hToken; TOKEN_PRIVILEGES tkp; LUID Luid; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { return FALSE; } if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Luid )) { CloseHandle(hToken); return FALSE; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Luid = Luid; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) { CloseHandle(hToken); return FALSE; } return TRUE; } int _tmain(int argc, _TCHAR* argv[]) { DWORD dwProcessId = 4; if (argc != 2) { wprintf(L"usage:CheckDll ProcessId"); return 1; } dwProcessId = _ttoi(argv[1]); InitDevice2Path(); // if (EnableDebugPriv()) { EnumProcessModules(dwProcessId); } g_mapDevice2Path.clear(); return 0; }

좋은 웹페이지 즐겨찾기