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;
}
FARPROC pLoadLibraryA = GetExportAddrFromHash(hKernel32, LOAD_LIBRARY_A_HASH);
FARPROC pGetProcAddress = GetExportAddrFromHash(hKernel32, GET_PROC_ADDRESS_HASH);
FARPROC pVirtualAlloc = GetExportAddrFromHash(hKernel32, VIRTUAL_ALLOC_HASH);
FARPROC pFlushInstructionCache = GetExportAddrFromHash(hKernel32, FLUSH_INSTRUCTION_CACHE_HASH);
FARPROC pVirtualProtect = GetExportAddrFromHash(hKernel32, VIRTUAL_PROTECT_HASH);
FARPROC pSleep = GetExportAddrFromHash(hKernel32, SLEEP_HASH);
LOAD_LIBRARY_W pLoadLibraryW = (LOAD_LIBRARY_W)GetExportAddrFromHash(hKernel32, LOAD_LIBRARY_W_HASH);
GET_PROC_ADDRESS pGetProcAddress = (GET_PROC_ADDRESS)GetExportAddrFromHash(hKernel32, GET_PROC_ADDRESS_HASH);
VIRTUAL_ALLOC pVirtualAlloc = (VIRTUAL_ALLOC)GetExportAddrFromHash(hKernel32, VIRTUAL_ALLOC_HASH);
FLUSH_INSTRUCTION_CACHE pFlushInstructionCache = (FLUSH_INSTRUCTION_CACHE)GetExportAddrFromHash(hKernel32, FLUSH_INSTRUCTION_CACHE_HASH);
VIRTUAL_PROTECT pVirtualProtect = (VIRTUAL_PROTECT)GetExportAddrFromHash(hKernel32, VIRTUAL_PROTECT_HASH);
SLEEP pSleep = (SLEEP)GetExportAddrFromHash(hKernel32, SLEEP_HASH);
if (!pLoadLibraryA || !pGetProcAddress || !pVirtualAlloc || !pFlushInstructionCache || !pVirtualProtect || !pSleep)
if (!pLoadLibraryW || !pGetProcAddress || !pVirtualAlloc || !pFlushInstructionCache || !pVirtualProtect || !pSleep)
{
return;
}
@ -58,16 +58,16 @@ void Load(PBYTE pImage, DWORD dwFunctionHash, PVOID pvUserData, DWORD dwUserData
ULONGLONG ullPreferredImageBase = pNtHeaders->OptionalHeader.ImageBase;
// 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)
{
// 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);
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)
@ -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)
*/
if (!PatchImportAddressTable(pNewImageBase, pDataDirectory, pGetProcAddress))
if (!PatchImportAddressTable(pNewImageBase, pDataDirectory, pLoadLibraryW, pGetProcAddress))
{
return;
}
@ -109,19 +109,19 @@ void Load(PBYTE pImage, DWORD dwFunctionHash, PVOID pvUserData, DWORD dwUserData
else
{
// Execute user defined function
FARPROC pFunction = GetExportAddrFromHash((HMODULE)pNewImageBase, dwFunctionHash);
USER_FUNCTION pFunction = (USER_FUNCTION)GetExportAddrFromHash((HMODULE)pNewImageBase, dwFunctionHash);
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);
for (size_t i = 0; i < pNtHeaders->FileHeader.NumberOfSections; pSectionHeader++, i++)
{
DWORD dwOldProtect;
DWORD dwNewProtect;
DWORD dwNewProtect = 0;
// Definitions for readability
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;
}
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);
@ -194,7 +194,7 @@ BOOL PatchImportAddressTable(PBYTE pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDir
while (pImportDescriptor->Name)
{
HMODULE hModule = pLoadLibraryA((LPCSTR)(pNewImageBase + pImportDescriptor->Name));
HMODULE hModule = pLoadLibraryW((LPCWSTR)(pNewImageBase + pImportDescriptor->Name));
if (!hModule)
{
@ -228,7 +228,7 @@ BOOL PatchImportAddressTable(PBYTE pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDir
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);
@ -278,30 +278,40 @@ BOOL ProcessRelocations(PBYTE pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDirector
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);
PBYTE pSectionBase, pSectionData;
for (size_t i = 0; i < pNtHeaders->FileHeader.NumberOfSections; pSectionHeader++, i++)
{
pSectionBase = pNewImageBase + pSectionHeader->VirtualAddress;
pSectionData = pImage + pSectionHeader->PointerToRawData;
for (size_t j = 0; j < pSectionHeader->SizeOfRawData; j++)
{
*((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)
{
// https://en.wikipedia.org/wiki/Win32_Thread_Information_Block
#if defined(_WIN64)
// PEB is located at GS:[0x60]
PPEB pPeb = (PPEB)__readgsqword(0x60);
#else
// PEB is located at FS:[0x30]
PPEB pPeb = (PPEB)__readfsdword(0x30);
#endif
PMY_PEB_LDR_DATA pLdr = pPeb->Ldr;
PMY_LDR_DATA_TABLE_ENTRY pEntry = pLdr->InLoadOrderModuleList.Flink;
PMY_PEB_LDR_DATA pLdr = (PMY_PEB_LDR_DATA)pPeb->Ldr;
PMY_LDR_DATA_TABLE_ENTRY pEntry = (PMY_LDR_DATA_TABLE_ENTRY)pLdr->InLoadOrderModuleList.Flink;
DWORD dwModuleHash;
UNICODE_STRING strBaseDllName;
@ -315,13 +325,13 @@ HMODULE GetModuleAddrFromHash(DWORD dwHash)
return pEntry->DllBase;
}
pEntry = pEntry->InLoadOrderLinks.Flink;
pEntry = (PMY_LDR_DATA_TABLE_ENTRY)pEntry->InLoadOrderLinks.Flink;
}
return NULL;
}
FARPROC GetExportAddrFromHash(HMODULE hModule, DWORD dwHash)
HMODULE GetExportAddrFromHash(HMODULE hModule, DWORD dwHash)
{
PIMAGE_NT_HEADERS64 pNtHeaders = GetNtHeaders((PBYTE)hModule);
@ -347,9 +357,11 @@ FARPROC GetExportAddrFromHash(HMODULE hModule, DWORD dwHash)
wOrdinal = ((WORD *)((PBYTE)hModule + pExportDirectoryData->AddressOfNameOrdinals))[i];
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)

View File

@ -7,14 +7,23 @@
#define KERNEL32_DLL_HASH 0x6DDB9555
// #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 VIRTUAL_ALLOC_HASH 0x097BC257
#define FLUSH_INSTRUCTION_CACHE_HASH 0xEFB7BF9D
#define VIRTUAL_PROTECT_HASH 0xE857500D
#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 *USER_FUNCTION)(LPVOID, DWORD);
typedef struct _MY_PEB_LDR_DATA
{
@ -44,12 +53,14 @@ typedef struct
WORD type : 4;
} IMAGE_RELOC, *PIMAGE_RELOC;
PIMAGE_NT_HEADERS64 GetNtHeaders(PBYTE pImage);
DWORD CalculateHash(UNICODE_STRING *BaseDllName);
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);
BOOL ProcessRelocations(PBYTE pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDirectory, ULONG_PTR ulpDelta);
BOOL PatchImportAddressTable(PBYTE pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDirectory, FARPROC pGetProcAddress);
void FinalizeRelocations(PBYTE pNewImageBase, PIMAGE_NT_HEADERS64 pNtHeaders, FARPROC pVirtualProtect, FARPROC pFlushInstructionCache);
void CopySections(ULONG_PTR pNewImageBase, PVOID pImage, PIMAGE_NT_HEADERS64 pNtHeaders);
void CopyHeaders(ULONG_PTR pNewImageBase, PVOID pImage, PIMAGE_NT_HEADERS64 pNtHeaders);
BOOL ProcessRelocations(ULONG_PTR pNewImageBase, PIMAGE_DATA_DIRECTORY pDataDirectory, ULONG_PTR ulpDelta);
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);