mirror of
https://github.com/racoten/BetterNetLoader
synced 2026-06-08 16:54:45 +00:00
73 lines
2.5 KiB
C++
73 lines
2.5 KiB
C++
#include <Windows.h>
|
|
#include <winternl.h>
|
|
|
|
// Replacement for GetProcAddress.
|
|
FARPROC GetProcAddressReplacement(IN HMODULE hModule, IN LPCSTR lpApiName) {
|
|
PBYTE pBase = (PBYTE)hModule;
|
|
|
|
// Get DOS header and validate signature.
|
|
PIMAGE_DOS_HEADER pImgDosHdr = (PIMAGE_DOS_HEADER)pBase;
|
|
if (pImgDosHdr->e_magic != IMAGE_DOS_SIGNATURE)
|
|
return NULL;
|
|
|
|
// Get NT headers and validate signature.
|
|
PIMAGE_NT_HEADERS pImgNtHdrs = (PIMAGE_NT_HEADERS)(pBase + pImgDosHdr->e_lfanew);
|
|
if (pImgNtHdrs->Signature != IMAGE_NT_SIGNATURE)
|
|
return NULL;
|
|
|
|
// Get the optional header.
|
|
IMAGE_OPTIONAL_HEADER ImgOptHdr = pImgNtHdrs->OptionalHeader;
|
|
|
|
// Get the export directory.
|
|
PIMAGE_EXPORT_DIRECTORY pImgExportDir = (PIMAGE_EXPORT_DIRECTORY)(pBase +
|
|
ImgOptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
|
|
|
|
// Get arrays for names, addresses, and ordinals.
|
|
PDWORD FunctionNameArray = (PDWORD)(pBase + pImgExportDir->AddressOfNames);
|
|
PDWORD FunctionAddressArray = (PDWORD)(pBase + pImgExportDir->AddressOfFunctions);
|
|
PWORD FunctionOrdinalArray = (PWORD)(pBase + pImgExportDir->AddressOfNameOrdinals);
|
|
|
|
// Loop through exported functions.
|
|
for (DWORD i = 0; i < pImgExportDir->NumberOfFunctions; i++) {
|
|
CHAR* pFunctionName = (CHAR*)(pBase + FunctionNameArray[i]);
|
|
PVOID pFunctionAddress = (PVOID)(pBase + FunctionAddressArray[FunctionOrdinalArray[i]]);
|
|
if (strcmp(lpApiName, pFunctionName) == 0) {
|
|
return (FARPROC)pFunctionAddress;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
// Simple case-insensitive wide-string comparison.
|
|
bool IsStringEqual(LPCWSTR a, LPCWSTR b) {
|
|
return (wcscmp(a, b) == 0);
|
|
}
|
|
|
|
// Replacement for GetModuleHandle.
|
|
HMODULE GetModuleHandleReplacement(IN LPCWSTR szModuleName) {
|
|
#ifdef _WIN64
|
|
PPEB pPeb = (PPEB)(__readgsqword(0x60));
|
|
#elif _WIN32
|
|
PPEB pPeb = (PPEB)(__readfsdword(0x30));
|
|
#endif
|
|
|
|
PPEB_LDR_DATA pLdr = (PPEB_LDR_DATA)(pPeb->Ldr);
|
|
PLDR_DATA_TABLE_ENTRY pDte = (PLDR_DATA_TABLE_ENTRY)(pLdr->InMemoryOrderModuleList.Flink);
|
|
|
|
while (pDte) {
|
|
if (pDte->FullDllName.Length != 0) {
|
|
if (IsStringEqual(pDte->FullDllName.Buffer, szModuleName)) {
|
|
#ifdef STRUCTS
|
|
return (HMODULE)(pDte->InInitializationOrderLinks.Flink);
|
|
#else
|
|
return (HMODULE)pDte->Reserved2[0];
|
|
#endif
|
|
}
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
pDte = *(PLDR_DATA_TABLE_ENTRY*)(pDte);
|
|
}
|
|
return NULL;
|
|
} |