Guest User

Reading LDR from PEB

a guest
Jun 12th, 2020
173
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <Windows.h>
  2. #include <stdio.h>
  3. #include <winternl.h>
  4.  
  5. typedef NTSTATUS(__stdcall* NT_QUERY_INFO) (
  6.     IN HANDLE           ProcessHandle,
  7.     IN PROCESSINFOCLASS ProcessInformationClass,
  8.     OUT PVOID           ProcessInformation,
  9.     IN ULONG            ProcessInformationLength,
  10.     OUT PULONG          ReturnLength
  11.     );
  12.  
  13. NT_QUERY_INFO NtQueryInfo;
  14.  
  15. int main() {
  16.     //Dynamically loading NtQueryInformationProcess()...
  17.     HMODULE hModule = LoadLibrary(TEXT("ntdll.dll"));
  18.     NtQueryInfo = (NT_QUERY_INFO)GetProcAddress(hModule, "NtQueryInformationProcess");
  19.     if (hModule == NULL) {
  20.         printf("Could not find ntdll. Exiting...\n");
  21.         return 1;
  22.     }
  23.  
  24.     //Creating our function call struct...
  25.     HANDLE hProc = GetCurrentProcess();
  26.     PROCESS_BASIC_INFORMATION info;
  27.     ZeroMemory(&info, sizeof(info));
  28.     DWORD retLength;
  29.  
  30.     //Actually calling the function dynamically...
  31.     NTSTATUS status = NtQueryInfo(hProc, ProcessBasicInformation, &info, sizeof(info), &retLength);
  32.     if (!NT_SUCCESS(status)) {
  33.         printf("Failed in calling NtQueryInformationProcess(). Error code: 0x%16x\n", status);
  34.         return 1;
  35.     }
  36.  
  37.     printf("Succeeded in calling NtQueryInformationProcess().\n");
  38.     printf("PEB located @ 0x%016x\n\n", info.PebBaseAddress);
  39.  
  40.     PPEB pPeb = info.PebBaseAddress;
  41.    
  42.     //Reading the LDR...
  43.     PPEB_LDR_DATA pLdr = pPeb->Ldr;
  44.  
  45.     /* The LDR is a doubly-linked list. It's circular, so the 'next' entry of the 'last' is the 'first.'
  46.     *  We first need to find how many modules are actually loaded before reading everything we want.
  47.     *  A little loop sould do the trick, so let's keep our starting point and run in a circle... */
  48.  
  49.     PLIST_ENTRY startPos = &pLdr->InMemoryOrderModuleList;
  50.     PLIST_ENTRY currPos = startPos->Flink;
  51.     int moduleCount = 0;
  52.     while (currPos != startPos) {
  53.         moduleCount++;
  54.         currPos = currPos->Flink;
  55.     }
  56.  
  57.     printf("Found %d modules loaded in memory.\nPrinting their details...\n\n", moduleCount);
  58.  
  59.     //Iterating over the data...
  60.     currPos = currPos->Flink;
  61.     PLDR_DATA_TABLE_ENTRY pLdrEntry;
  62.     for (int i = 0; i < moduleCount; ++i) {
  63.         pLdrEntry = CONTAINING_RECORD(
  64.             currPos,
  65.             LDR_DATA_TABLE_ENTRY,
  66.             InMemoryOrderLinks);
  67.         printf(
  68.             "Path: %ls, Base Address @ 0x%p, Entry Point @ 0x%p\n",
  69.             pLdrEntry->FullDllName.Buffer,
  70.             pLdrEntry->DllBase,
  71.             pLdrEntry->Reserved3[0]
  72.             );
  73.  
  74.         currPos = currPos->Flink;
  75.     }
  76.     return 0;
  77. }
RAW Paste Data