Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- PVOID
- GetProcedureAddress(
- _In_ ULONG_PTR DllBase,
- _In_ PCSTR RoutineName
- )
- {
- // Find and verify PE headers
- const PIMAGE_DOS_HEADER DosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(DllBase);
- if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
- return nullptr;
- const PIMAGE_NT_HEADERS NtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(DllBase + DosHeader->e_lfanew);
- if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
- return nullptr;
- // Get the export directory RVA and size
- PIMAGE_DATA_DIRECTORY ImageDirectories;
- if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
- ImageDirectories = reinterpret_cast<PIMAGE_NT_HEADERS64>(NtHeaders)->OptionalHeader.DataDirectory;
- else
- ImageDirectories = reinterpret_cast<PIMAGE_NT_HEADERS32>(NtHeaders)->OptionalHeader.DataDirectory;
- const ULONG ExportDirRva = ImageDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
- const ULONG ExportDirSize = ImageDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
- // Read the export directory
- const PIMAGE_EXPORT_DIRECTORY ExportDirectory = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(DllBase + ExportDirRva);
- const PULONG AddressOfFunctions = reinterpret_cast<PULONG>(DllBase + ExportDirectory->AddressOfFunctions);
- const PUSHORT AddressOfNameOrdinals = reinterpret_cast<PUSHORT>(DllBase + ExportDirectory->AddressOfNameOrdinals);
- const PULONG AddressOfNames = reinterpret_cast<PULONG>(DllBase + ExportDirectory->AddressOfNames);
- // Look up the import name in the name table using a binary search
- LONG Low = 0;
- LONG Middle = 0;
- LONG High = ExportDirectory->NumberOfNames - 1;
- while (High >= Low)
- {
- // Compute the next probe index and compare the import name
- Middle = (Low + High) >> 1;
- const LONG Result = strcmp(RoutineName, reinterpret_cast<PCHAR>(DllBase + AddressOfNames[Middle]));
- if (Result < 0)
- High = Middle - 1;
- else if (Result > 0)
- Low = Middle + 1;
- else
- break;
- }
- // If the high index is less than the low index, then a matching table entry
- // was not found. Otherwise, get the ordinal number from the ordinal table
- if (High < Low || Middle >= static_cast<LONG>(ExportDirectory->NumberOfFunctions))
- return nullptr;
- const ULONG FunctionRva = AddressOfFunctions[AddressOfNameOrdinals[Middle]];
- if (FunctionRva >= ExportDirRva && FunctionRva < ExportDirRva + ExportDirSize)
- return nullptr; // Ignore forwarded exports
- return reinterpret_cast<PVOID>(DllBase + FunctionRva);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement