#include "head.h" /* from google */ ULONG_PTR GetProcAddressR(ULONG_PTR hModule, const char* lpProcName, BOOL x64Module) { UINT_PTR uiLibraryAddress = 0; ULONG_PTR fpResult = NULL; if (hModule == NULL) return NULL; // a module handle is really its base address uiLibraryAddress = (UINT_PTR)hModule; __try { UINT_PTR uiAddressArray = 0; UINT_PTR uiNameArray = 0; UINT_PTR uiNameOrdinals = 0; PIMAGE_NT_HEADERS32 pNtHeaders32 = NULL; PIMAGE_NT_HEADERS64 pNtHeaders64 = NULL; PIMAGE_DATA_DIRECTORY pDataDirectory = NULL; PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL; // get the VA of the modules NT Header pNtHeaders32 = (PIMAGE_NT_HEADERS32)(uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew); pNtHeaders64 = (PIMAGE_NT_HEADERS64)(uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew); if (x64Module) { pDataDirectory = (PIMAGE_DATA_DIRECTORY)&pNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; } else { pDataDirectory = (PIMAGE_DATA_DIRECTORY)&pNtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; } // get the VA of the export directory pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(uiLibraryAddress + pDataDirectory->VirtualAddress); // get the VA for the array of addresses uiAddressArray = (uiLibraryAddress + pExportDirectory->AddressOfFunctions); // get the VA for the array of name pointers uiNameArray = (uiLibraryAddress + pExportDirectory->AddressOfNames); // get the VA for the array of name ordinals uiNameOrdinals = (uiLibraryAddress + pExportDirectory->AddressOfNameOrdinals); // test if we are importing by name or by ordinal... if ((PtrToUlong(lpProcName) & 0xFFFF0000) == 0x00000000) { // import by ordinal... // use the import ordinal (- export ordinal base) as an index into the array of addresses uiAddressArray += ((IMAGE_ORDINAL(PtrToUlong(lpProcName)) - pExportDirectory->Base) * sizeof(unsigned long)); // resolve the address for this imported function fpResult = (ULONG_PTR)(uiLibraryAddress + DEREF_32(uiAddressArray)); } else { // import by name... unsigned long dwCounter = pExportDirectory->NumberOfNames; while (dwCounter--) { char* cpExportedFunctionName = (char*)(uiLibraryAddress + DEREF_32(uiNameArray)); // test if we have a match... if (strcmp(cpExportedFunctionName, lpProcName) == 0) { // use the functions name ordinal as an index into the array of name pointers uiAddressArray += (DEREF_16(uiNameOrdinals) * sizeof(unsigned long)); // calculate the virtual address for the function fpResult = (ULONG_PTR)(uiLibraryAddress + DEREF_32(uiAddressArray)); // finish... break; } // get the next exported function name uiNameArray += sizeof(unsigned long); // get the next exported function name ordinal uiNameOrdinals += sizeof(unsigned short); } } } __except (EXCEPTION_EXECUTE_HANDLER) { fpResult = NULL; } return fpResult; } /* from blackbone */ LONG BlackBoneSafeSearchString(IN PUNICODE_STRING source, IN PUNICODE_STRING target, IN BOOLEAN CaseInSensitive) { ASSERT(source != NULL && target != NULL); if (source == NULL || target == NULL || source->Buffer == NULL || target->Buffer == NULL) return STATUS_INVALID_PARAMETER; // Size mismatch if (source->Length < target->Length) return -1; USHORT diff = source->Length - target->Length; for (USHORT i = 0; i <= (diff / sizeof(WCHAR)); i++) { if (RtlCompareUnicodeStrings( source->Buffer + i, target->Length / sizeof(WCHAR), target->Buffer, target->Length / sizeof(WCHAR), CaseInSensitive ) == 0) { return i; } } return -1; } /* from windows explorer */ bool _memcpy(PVOID address, PVOID target_address, ULONG length) { bool result = false; PHYSICAL_ADDRESS physicial_address; physicial_address = MmGetPhysicalAddress(address); if (physicial_address.QuadPart) { PVOID maped_mem = MmMapIoSpace(physicial_address, length, MmNonCached); if (maped_mem) { memcpy(maped_mem, target_address, length); MmUnmapIoSpace(maped_mem, length); result = true; } } return result; }