Files
racoten-BetterNetLoader/BetterNetLoader/winternal.cpp
T
2025-07-10 20:41:50 -07:00

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;
}