SHARE
TWEET

NtQueryVirtualMemory hook [MemorySectionName]

ahcript Feb 7th, 2016 (edited) 115 Never
  1. #define CLOG_FILENAME "ntlog.log"
  2. #define NTDLL GetModuleHandle(TEXT("ntdll.dll"))
  3.  
  4. // NtQueryVirtualMemory
  5. typedef
  6. NTSTATUS
  7. (NTAPI *NtQueryVirtualMemory)(
  8.     _In_  HANDLE                   ProcessHandle,
  9.     _In_  PVOID                    BaseAddress,
  10.     _In_  MEMORY_INFORMATION_CLASS MemoryInformationClass,
  11.     _Out_ PVOID                    MemoryInformation,
  12.     _In_  ULONG                    MemoryInformationLength,
  13.     _Out_ PULONG                   ReturnLength OPTIONAL
  14.     );
  15.  
  16.  
  17. // NtQueryInformationProcess
  18. typedef
  19. NTSTATUS
  20. (NTAPI *NtQueryInformationProcess)(
  21.     _In_      HANDLE                    ProcessHandle,
  22.     _In_      PROCESS_INFORMATION_CLASS ProcessInformationClass,
  23.     _Out_     PVOID                     ProcessInformation,
  24.     _In_      ULONG                     ProcessInformationLength,
  25.     _Out_opt_ PULONG                    ReturnLength
  26.     );
  27.  
  28. static NtQueryVirtualMemory _NtQueryVirtualMemory = reinterpret_cast<NtQueryVirtualMemory>(GetProcAddress(NTDLL, "NtQueryVirtualMemory"));
  29. static NtQueryInformationProcess _NtQueryInformationProcess = reinterpret_cast<NtQueryInformationProcess>(GetProcAddress(NTDLL, "NtQueryInformationProcess"));
  30.  
  31.  
  32.  
  33. void LogOutputW(CONST TCHAR* lpwszFormat, ...)
  34. {
  35.     va_list list;
  36.     FILE *f;
  37.     static TCHAR lpwszBuffer[1024];
  38.  
  39.     va_start(list, lpwszFormat);
  40.  
  41.     DWORD ulLength = wvsprintf(lpwszBuffer, lpwszFormat, list);
  42.     WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), lpwszBuffer, ulLength, new DWORD, nullptr);
  43.  
  44.     if (!firstInit)
  45.         DeleteFile(TEXT(CLOG_FILENAME));
  46.  
  47.     if (fopen_s(&f, CLOG_FILENAME, "a+") == 0)
  48.     {
  49.         firstInit = true;
  50.         vfwprintf(f, lpwszFormat, list);
  51.         fflush(f);
  52.         fclose(f);
  53.     }
  54.  
  55.     va_end(list);
  56. }
  57.  
  58. DWORD HandleToProcessID(HANDLE hProcess)
  59. {
  60.     PROCESS_BASIC_INFORMATION pbi;
  61.     ZeroMemory(&pbi, sizeof(PROCESS_BASIC_INFORMATION));
  62.  
  63.     NTSTATUS ntStatus = _NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL);
  64.     if (NT_SUCCESS(ntStatus))
  65.         return pbi.UniqueProcessId;
  66.     else
  67.         return (DWORD)-1;
  68. }
  69.  
  70. void DeviceNameToPathName(_Out_ WCHAR* szPathName, _In_ const WCHAR* szDeviceName)
  71. {
  72.     memset(szPathName, 0, MAX_PATH * 2);
  73.     wstring strDeviceName = szDeviceName;
  74.     size_t pos = strDeviceName.find(L'\\', 9);
  75.     wstring strTemp1 = strDeviceName.substr(0, pos);
  76.     wstring strTemp2 = strDeviceName.substr(pos + 1);
  77.     wstring strDriverLetter = g_mapDevice2Path[strTemp1];
  78.     wstring strPathName = strDriverLetter + strTemp2;
  79.  
  80.     wcscpy_s(szPathName, MAX_PATH, strPathName.c_str());
  81. }
  82.  
  83. VOID Detour_o_o()
  84. {
  85.     static DWORD currentPID = GetCurrentProcessId();
  86.  
  87.     NtQueryVirtualMemory NtQueryVirtualMemory__Hook = [](
  88.         _In_  HANDLE                   ProcessHandle,
  89.         _In_  PVOID                    BaseAddress,
  90.         _In_  MEMORY_INFORMATION_CLASS MemoryInformationClass,
  91.         _Out_ PVOID                    MemoryInformation,
  92.         _In_  ULONG                    MemoryInformationLength,
  93.         _Out_ PULONG                   ReturnLength OPTIONAL) -> NTSTATUS
  94.     {
  95.         BYTE szBuffer[MAX_PATH * 2 + 4];
  96.         TCHAR szModuleName[MAX_PATH];
  97.         TCHAR szPathName[MAX_PATH];
  98.  
  99.         if (MemoryInformationClass == MemorySectionName)
  100.         {
  101.             NTSTATUS ntStatus1 = _NtQueryVirtualMemory(ProcessHandle, BaseAddress, MemoryInformationClass, &szBuffer, sizeof(szBuffer), ReturnLength);
  102.  
  103.             if (NT_SUCCESS(ntStatus1))
  104.             {
  105.                 PUNICODE_STRING pSectionName = (PUNICODE_STRING)szBuffer;
  106.  
  107.                 if (_wcsnicmp(szModuleName, pSectionName->Buffer, pSectionName->Length / sizeof(WCHAR)))
  108.                 {
  109.                     wcsncpy_s(szModuleName, pSectionName->Buffer, pSectionName->Length / sizeof(WCHAR));
  110.                     szModuleName[pSectionName->Length / sizeof(WCHAR)] = UNICODE_NULL;
  111.                     DeviceNameToPathName(szPathName, szModuleName);
  112.  
  113.                     if (HandleToProcessID(ProcessHandle) == currentPID)
  114.                     {
  115.                         LogOutputW(L"[0x%.8x]\t%s\n", (DWORD)BaseAddress, szPathName);
  116.                     }
  117.                     else
  118.                     {
  119.                         LogOutputW(L"[PID:%d]\t[0x%.8x]\t%s\n", HandleToProcessID(ProcessHandle), (DWORD)BaseAddress, szPathName);
  120.                     }
  121.                 }
  122.             }
  123.         }
  124.  
  125.         return _NtQueryVirtualMemory(ProcessHandle, BaseAddress, MemoryInformationClass, MemoryInformation, MemoryInformationLength, ReturnLength);
  126.     };
  127.  
  128.     DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&_NtQueryVirtualMemory), NtQueryVirtualMemory__Hook);
  129. }
RAW Paste Data
Top