Advertisement
Guest User

Untitled

a guest
Dec 8th, 2019
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.43 KB | None | 0 0
  1. PVOID
  2. GetProcedureAddress(
  3.     _In_ ULONG_PTR DllBase,
  4.     _In_ PCSTR RoutineName
  5.     )
  6. {
  7.     // Find and verify PE headers
  8.     const PIMAGE_DOS_HEADER DosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(DllBase);
  9.     if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
  10.         return nullptr;
  11.     const PIMAGE_NT_HEADERS NtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(DllBase + DosHeader->e_lfanew);
  12.     if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
  13.         return nullptr;
  14.  
  15.     // Get the export directory RVA and size
  16.     PIMAGE_DATA_DIRECTORY ImageDirectories;
  17.     if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
  18.         ImageDirectories = reinterpret_cast<PIMAGE_NT_HEADERS64>(NtHeaders)->OptionalHeader.DataDirectory;
  19.     else
  20.         ImageDirectories = reinterpret_cast<PIMAGE_NT_HEADERS32>(NtHeaders)->OptionalHeader.DataDirectory;
  21.  
  22.     const ULONG ExportDirRva = ImageDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
  23.     const ULONG ExportDirSize = ImageDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
  24.  
  25.     // Read the export directory
  26.     const PIMAGE_EXPORT_DIRECTORY ExportDirectory = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(DllBase + ExportDirRva);
  27.     const PULONG AddressOfFunctions = reinterpret_cast<PULONG>(DllBase + ExportDirectory->AddressOfFunctions);
  28.     const PUSHORT AddressOfNameOrdinals = reinterpret_cast<PUSHORT>(DllBase + ExportDirectory->AddressOfNameOrdinals);
  29.     const PULONG AddressOfNames = reinterpret_cast<PULONG>(DllBase + ExportDirectory->AddressOfNames);
  30.  
  31.     // Look up the import name in the name table using a binary search
  32.     LONG Low = 0;
  33.     LONG Middle = 0;
  34.     LONG High = ExportDirectory->NumberOfNames - 1;
  35.  
  36.     while (High >= Low)
  37.     {
  38.         // Compute the next probe index and compare the import name
  39.         Middle = (Low + High) >> 1;
  40.         const LONG Result = strcmp(RoutineName, reinterpret_cast<PCHAR>(DllBase + AddressOfNames[Middle]));
  41.         if (Result < 0)
  42.             High = Middle - 1;
  43.         else if (Result > 0)
  44.             Low = Middle + 1;
  45.         else
  46.             break;
  47.     }
  48.  
  49.     // If the high index is less than the low index, then a matching table entry
  50.     // was not found. Otherwise, get the ordinal number from the ordinal table
  51.     if (High < Low || Middle >= static_cast<LONG>(ExportDirectory->NumberOfFunctions))
  52.         return nullptr;
  53.     const ULONG FunctionRva = AddressOfFunctions[AddressOfNameOrdinals[Middle]];
  54.     if (FunctionRva >= ExportDirRva && FunctionRva < ExportDirRva + ExportDirSize)
  55.         return nullptr; // Ignore forwarded exports
  56.  
  57.     return reinterpret_cast<PVOID>(DllBase + FunctionRva);
  58. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement