fixed casting & naming compilation errors

This commit is contained in:
17ms 2023-12-30 23:22:09 +02:00
parent da726402fe
commit ccf0d4d183
2 changed files with 58 additions and 35 deletions

View File

@ -20,14 +20,14 @@ void Load(PBYTE pImage, DWORD dwFunctionHash, PVOID pvUserData, DWORD dwUserData
return; return;
} }
FARPROC pLoadLibraryA = GetExportAddrFromHash(hKernel32, LOAD_LIBRARY_A_HASH); LOAD_LIBRARY_W pLoadLibraryW = (LOAD_LIBRARY_W)GetExportAddrFromHash(hKernel32, LOAD_LIBRARY_W_HASH);
FARPROC pGetProcAddress = GetExportAddrFromHash(hKernel32, GET_PROC_ADDRESS_HASH); GET_PROC_ADDRESS pGetProcAddress = (GET_PROC_ADDRESS)GetExportAddrFromHash(hKernel32, GET_PROC_ADDRESS_HASH);
FARPROC pVirtualAlloc = GetExportAddrFromHash(hKernel32, VIRTUAL_ALLOC_HASH); VIRTUAL_ALLOC pVirtualAlloc = (VIRTUAL_ALLOC)GetExportAddrFromHash(hKernel32, VIRTUAL_ALLOC_HASH);
FARPROC pFlushInstructionCache = GetExportAddrFromHash(hKernel32, FLUSH_INSTRUCTION_CACHE_HASH); FLUSH_INSTRUCTION_CACHE pFlushInstructionCache = (FLUSH_INSTRUCTION_CACHE)GetExportAddrFromHash(hKernel32, FLUSH_INSTRUCTION_CACHE_HASH);
FARPROC pVirtualProtect = GetExportAddrFromHash(hKernel32, VIRTUAL_PROTECT_HASH); VIRTUAL_PROTECT pVirtualProtect = (VIRTUAL_PROTECT)GetExportAddrFromHash(hKernel32, VIRTUAL_PROTECT_HASH);
FARPROC pSleep = GetExportAddrFromHash(hKernel32, SLEEP_HASH); SLEEP pSleep = (SLEEP)GetExportAddrFromHash(hKernel32, SLEEP_HASH);
if (!pLoadLibraryA || !pGetProcAddress || !pVirtualAlloc || !pFlushInstructionCache || !pVirtualProtect || !pSleep) if (!pLoadLibraryW || !pGetProcAddress || !pVirtualAlloc || !pFlushInstructionCache || !pVirtualProtect || !pSleep)
{ {
return; return;
} }
@ -58,16 +58,16 @@ void Load(PBYTE pImage, DWORD dwFunctionHash, PVOID pvUserData, DWORD dwUserData
ULONGLONG ullPreferredImageBase = pNtHeaders->OptionalHeader.ImageBase; ULONGLONG ullPreferredImageBase = pNtHeaders->OptionalHeader.ImageBase;
// Try to allocate the image to the preferred base address // Try to allocate the image to the preferred base address
PBYTE pNewImageBase = (PBYTE)pVirtualAlloc((LPVOID)ullPreferredImageBase, dwImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); ULONG_PTR pNewImageBase = (ULONG_PTR)pVirtualAlloc((LPVOID)ullPreferredImageBase, dwImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (!pNewImageBase) if (!pNewImageBase)
{ {
// Allocate to a random address if the preferred base address is already occupied // Allocate to a random address if the preferred base address is already occupied
pNewImageBase = (PBYTE)pVirtualAlloc(NULL, dwImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); pNewImageBase = (ULONG_PTR)pVirtualAlloc(NULL, dwImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
} }
CopySections(pNewImageBase, pImage, pNtHeaders); CopySections(pNewImageBase, pImage, pNtHeaders);
memcpy(pNewImageBase, pImage, pNtHeaders->OptionalHeader.SizeOfHeaders); CopyHeaders(pNewImageBase, pImage, pNtHeaders);
/* /*
3.) Process the image relocations (assumes the image couldn't be loaded to the preferred base address) 3.) Process the image relocations (assumes the image couldn't be loaded to the preferred base address)
@ -85,7 +85,7 @@ void Load(PBYTE pImage, DWORD dwFunctionHash, PVOID pvUserData, DWORD dwUserData
4.) Resolve the imports by patching the Import Address Table (IAT) 4.) Resolve the imports by patching the Import Address Table (IAT)
*/ */
if (!PatchImportAddressTable(pNewImageBase, pDataDirectory, pGetProcAddress)) if (!PatchImportAddressTable(pNewImageBase, pDataDirectory, pLoadLibraryW, pGetProcAddress))
{ {
return; return;
} }
@ -109,19 +109,19 @@ void Load(PBYTE pImage, DWORD dwFunctionHash, PVOID pvUserData, DWORD dwUserData
else else
{ {
// Execute user defined function // Execute user defined function
FARPROC pFunction = GetExportAddrFromHash((HMODULE)pNewImageBase, dwFunctionHash); USER_FUNCTION pFunction = (USER_FUNCTION)GetExportAddrFromHash((HMODULE)pNewImageBase, dwFunctionHash);
pFunction(pvUserData, dwUserDataLen); pFunction(pvUserData, dwUserDataLen);
} }
} }
void FinalizeRelocations(PBYTE pNewImageBase, PIMAGE_NT_HEADERS64 pNtHeaders, FARPROC pVirtualProtect, FARPROC pFlushInstructionCache) void FinalizeRelocations(ULONG_PTR pNewImageBase, PIMAGE_NT_HEADERS64 pNtHeaders, VIRTUAL_PROTECT pVirtualProtect, FLUSH_INSTRUCTION_CACHE pFlushInstructionCache)
{ {
PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeaders); PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeaders);
for (size_t i = 0; i < pNtHeaders->FileHeader.NumberOfSections; pSectionHeader++, i++) for (size_t i = 0; i < pNtHeaders->FileHeader.NumberOfSections; pSectionHeader++, i++)
{ {
DWORD dwOldProtect; DWORD dwOldProtect;
DWORD dwNewProtect; DWORD dwNewProtect = 0;
// Definitions for readability // Definitions for readability
DWORD dwIsExecutable = (pSectionHeader->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0; DWORD dwIsExecutable = (pSectionHeader->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0;
@ -168,13 +168,13 @@ void FinalizeRelocations(PBYTE pNewImageBase, PIMAGE_NT_HEADERS64 pNtHeaders, FA
dwNewProtect = PAGE_EXECUTE_READWRITE; dwNewProtect = PAGE_EXECUTE_READWRITE;
} }
pVirtualProtect(pNewImageBase + pSectionHeader->VirtualAddress, pSectionHeader->SizeOfRawData, dwNewProtect, &dwOldProtect); pVirtualProtect((LPVOID)(pNewImageBase + pSectionHeader->VirtualAddress), pSectionHeader->SizeOfRawData, dwNewProtect, &dwOldProtect);
} }
pFlushInstructionCache(-1, NULL, 0); pFlushInstructionCache((HANDLE)-1, NULL, 0);
} }
BOOL PatchImportAddressTable(PBYTE pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDirectory, FARPROC pGetProcAddress) BOOL PatchImportAddressTable(ULONG_PTR pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDirectory, LOAD_LIBRARY_W pLoadLibraryW, GET_PROC_ADDRESS pGetProcAddress)
{ {
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(pNewImageBase + pDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(pNewImageBase + pDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
@ -194,7 +194,7 @@ BOOL PatchImportAddressTable(PBYTE pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDir
while (pImportDescriptor->Name) while (pImportDescriptor->Name)
{ {
HMODULE hModule = pLoadLibraryA((LPCSTR)(pNewImageBase + pImportDescriptor->Name)); HMODULE hModule = pLoadLibraryW((LPCWSTR)(pNewImageBase + pImportDescriptor->Name));
if (!hModule) if (!hModule)
{ {
@ -228,7 +228,7 @@ BOOL PatchImportAddressTable(PBYTE pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDir
return TRUE; return TRUE;
} }
BOOL ProcessRelocations(PBYTE pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDirectory, ULONG_PTR ulpDelta) BOOL ProcessRelocations(ULONG_PTR pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDirectory, ULONG_PTR ulpDelta)
{ {
PIMAGE_BASE_RELOCATION pRelocation = (PIMAGE_BASE_RELOCATION)(pNewImageBase + pDataDirectory->VirtualAddress); PIMAGE_BASE_RELOCATION pRelocation = (PIMAGE_BASE_RELOCATION)(pNewImageBase + pDataDirectory->VirtualAddress);
@ -278,30 +278,40 @@ BOOL ProcessRelocations(PBYTE pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDirector
return TRUE; return TRUE;
} }
void CopySections(PBYTE pNewImageBase, PVOID pImage, PIMAGE_NT_HEADERS64 pNtHeaders) void CopySections(ULONG_PTR pNewImageBase, PVOID pImage, PIMAGE_NT_HEADERS64 pNtHeaders)
{ {
PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeaders); PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeaders);
PBYTE pSectionBase, pSectionData;
for (size_t i = 0; i < pNtHeaders->FileHeader.NumberOfSections; pSectionHeader++, i++) for (size_t i = 0; i < pNtHeaders->FileHeader.NumberOfSections; pSectionHeader++, i++)
{ {
pSectionBase = pNewImageBase + pSectionHeader->VirtualAddress; for (size_t j = 0; j < pSectionHeader->SizeOfRawData; j++)
pSectionData = pImage + pSectionHeader->PointerToRawData; {
*((PBYTE)pNewImageBase + pSectionHeader->VirtualAddress + j) = *((PBYTE)pImage + pSectionHeader->PointerToRawData + j);
}
}
}
memcpy(pSectionBase, pSectionData, pSectionHeader->SizeOfRawData); void CopyHeaders(ULONG_PTR pNewImageBase, PVOID pImage, PIMAGE_NT_HEADERS64 pNtHeaders)
{
for (size_t i = 0; i < pNtHeaders->OptionalHeader.SizeOfHeaders; i++)
{
*((PBYTE)pNewImageBase + i) = *((PBYTE)pImage + i);
} }
} }
HMODULE GetModuleAddrFromHash(DWORD dwHash) HMODULE GetModuleAddrFromHash(DWORD dwHash)
{ {
// https://en.wikipedia.org/wiki/Win32_Thread_Information_Block
#if defined(_WIN64) #if defined(_WIN64)
// PEB is located at GS:[0x60]
PPEB pPeb = (PPEB)__readgsqword(0x60); PPEB pPeb = (PPEB)__readgsqword(0x60);
#else #else
// PEB is located at FS:[0x30]
PPEB pPeb = (PPEB)__readfsdword(0x30); PPEB pPeb = (PPEB)__readfsdword(0x30);
#endif #endif
PMY_PEB_LDR_DATA pLdr = pPeb->Ldr; PMY_PEB_LDR_DATA pLdr = (PMY_PEB_LDR_DATA)pPeb->Ldr;
PMY_LDR_DATA_TABLE_ENTRY pEntry = pLdr->InLoadOrderModuleList.Flink; PMY_LDR_DATA_TABLE_ENTRY pEntry = (PMY_LDR_DATA_TABLE_ENTRY)pLdr->InLoadOrderModuleList.Flink;
DWORD dwModuleHash; DWORD dwModuleHash;
UNICODE_STRING strBaseDllName; UNICODE_STRING strBaseDllName;
@ -315,13 +325,13 @@ HMODULE GetModuleAddrFromHash(DWORD dwHash)
return pEntry->DllBase; return pEntry->DllBase;
} }
pEntry = pEntry->InLoadOrderLinks.Flink; pEntry = (PMY_LDR_DATA_TABLE_ENTRY)pEntry->InLoadOrderLinks.Flink;
} }
return NULL; return NULL;
} }
FARPROC GetExportAddrFromHash(HMODULE hModule, DWORD dwHash) HMODULE GetExportAddrFromHash(HMODULE hModule, DWORD dwHash)
{ {
PIMAGE_NT_HEADERS64 pNtHeaders = GetNtHeaders((PBYTE)hModule); PIMAGE_NT_HEADERS64 pNtHeaders = GetNtHeaders((PBYTE)hModule);
@ -347,9 +357,11 @@ FARPROC GetExportAddrFromHash(HMODULE hModule, DWORD dwHash)
wOrdinal = ((WORD *)((PBYTE)hModule + pExportDirectoryData->AddressOfNameOrdinals))[i]; wOrdinal = ((WORD *)((PBYTE)hModule + pExportDirectoryData->AddressOfNameOrdinals))[i];
dwFuncRva = ((DWORD *)((PBYTE)hModule + pExportDirectoryData->AddressOfFunctions))[wOrdinal]; dwFuncRva = ((DWORD *)((PBYTE)hModule + pExportDirectoryData->AddressOfFunctions))[wOrdinal];
return (FARPROC)((PBYTE)hModule + dwFuncRva); return (HMODULE)((PBYTE)hModule + dwFuncRva);
} }
} }
return NULL;
} }
PIMAGE_NT_HEADERS64 GetNtHeaders(PBYTE pImage) PIMAGE_NT_HEADERS64 GetNtHeaders(PBYTE pImage)

View File

@ -7,14 +7,23 @@
#define KERNEL32_DLL_HASH 0x6DDB9555 #define KERNEL32_DLL_HASH 0x6DDB9555
// #define NTDLL_DLL_HASH 0x1EDAB0ED // #define NTDLL_DLL_HASH 0x1EDAB0ED
#define LOAD_LIBRARY_A_HASH 0xB7072FDB // TODO: change to LoadLibraryW #define LOAD_LIBRARY_W_HASH 0xB7072FF1
#define GET_PROC_ADDRESS_HASH 0xDECFC1BF #define GET_PROC_ADDRESS_HASH 0xDECFC1BF
#define VIRTUAL_ALLOC_HASH 0x097BC257 #define VIRTUAL_ALLOC_HASH 0x097BC257
#define FLUSH_INSTRUCTION_CACHE_HASH 0xEFB7BF9D #define FLUSH_INSTRUCTION_CACHE_HASH 0xEFB7BF9D
#define VIRTUAL_PROTECT_HASH 0xE857500D #define VIRTUAL_PROTECT_HASH 0xE857500D
#define SLEEP_HASH 0x0E07CD7E #define SLEEP_HASH 0x0E07CD7E
// Signatures from MSDN
typedef HMODULE(WINAPI *LOAD_LIBRARY_W)(LPCWSTR);
typedef ULONG_PTR(WINAPI *GET_PROC_ADDRESS)(HMODULE, LPCSTR);
typedef LPVOID(WINAPI *VIRTUAL_ALLOC)(LPVOID, SIZE_T, DWORD, DWORD);
typedef BOOL(WINAPI *FLUSH_INSTRUCTION_CACHE)(HANDLE, LPCVOID, SIZE_T);
typedef BOOL(WINAPI *VIRTUAL_PROTECT)(LPVOID, SIZE_T, DWORD, PDWORD);
typedef VOID(WINAPI *SLEEP)(DWORD);
typedef BOOL(WINAPI *DLLMAIN)(HMODULE, DWORD, LPVOID); typedef BOOL(WINAPI *DLLMAIN)(HMODULE, DWORD, LPVOID);
typedef BOOL(WINAPI *USER_FUNCTION)(LPVOID, DWORD);
typedef struct _MY_PEB_LDR_DATA typedef struct _MY_PEB_LDR_DATA
{ {
@ -44,12 +53,14 @@ typedef struct
WORD type : 4; WORD type : 4;
} IMAGE_RELOC, *PIMAGE_RELOC; } IMAGE_RELOC, *PIMAGE_RELOC;
PIMAGE_NT_HEADERS64 GetNtHeaders(PBYTE pImage);
DWORD CalculateHash(UNICODE_STRING *BaseDllName); DWORD CalculateHash(UNICODE_STRING *BaseDllName);
HMODULE GetModuleAddrFromHash(DWORD dwHash); HMODULE GetModuleAddrFromHash(DWORD dwHash);
FARPROC GetExportAddrFromHash(HMODULE hModule, DWORD dwHash); HMODULE GetExportAddrFromHash(HMODULE hModule, DWORD dwHash);
void CopySections(PBYTE pNewImageBase, PVOID pImage, PIMAGE_NT_HEADERS64 pNtHeaders); void CopySections(ULONG_PTR pNewImageBase, PVOID pImage, PIMAGE_NT_HEADERS64 pNtHeaders);
BOOL ProcessRelocations(PBYTE pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDirectory, ULONG_PTR ulpDelta); void CopyHeaders(ULONG_PTR pNewImageBase, PVOID pImage, PIMAGE_NT_HEADERS64 pNtHeaders);
BOOL PatchImportAddressTable(PBYTE pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDirectory, FARPROC pGetProcAddress); BOOL ProcessRelocations(ULONG_PTR pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDirectory, ULONG_PTR ulpDelta);
void FinalizeRelocations(PBYTE pNewImageBase, PIMAGE_NT_HEADERS64 pNtHeaders, FARPROC pVirtualProtect, FARPROC pFlushInstructionCache); BOOL PatchImportAddressTable(ULONG_PTR pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDirectory, LOAD_LIBRARY_W pLoadLibraryW, GET_PROC_ADDRESS pGetProcAddress);
void FinalizeRelocations(ULONG_PTR pNewImageBase, PIMAGE_NT_HEADERS64 pNtHeaders, VIRTUAL_PROTECT pVirtualProtect, FLUSH_INSTRUCTION_CACHE pFlushInstructionCache);