mirror of
https://github.com/monoxgas/sRDI
synced 2026-06-06 16:14:36 +00:00
Added exception handling for x64
Updated GetProcAddressR for clarity Added /EHa to the testdll with a divide by 0 for testing
This commit is contained in:
+1
-1
File diff suppressed because one or more lines are too long
@@ -14,78 +14,40 @@
|
||||
#define DEREF_16( name )*(WORD *)(name)
|
||||
#define DEREF_8( name )*(BYTE *)(name)
|
||||
|
||||
FARPROC GetProcAddressR(UINT_PTR uiLibraryAddress, LPCSTR lpProcName)
|
||||
{
|
||||
FARPROC fpResult = NULL;
|
||||
#define RVA(type, base, rva) (type)((ULONG_PTR) base + rva)
|
||||
|
||||
if (uiLibraryAddress == NULL)
|
||||
FARPROC GetProcAddressR(HMODULE hModule, LPCSTR lpProcName)
|
||||
{
|
||||
if (hModule == NULL || lpProcName == NULL)
|
||||
return NULL;
|
||||
|
||||
UINT_PTR uiAddressArray = 0;
|
||||
UINT_PTR uiNameArray = 0;
|
||||
UINT_PTR uiNameOrdinals = 0;
|
||||
PIMAGE_NT_HEADERS pNtHeaders = NULL;
|
||||
PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
|
||||
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
|
||||
PIMAGE_NT_HEADERS ntHeaders = RVA(PIMAGE_NT_HEADERS, hModule, ((PIMAGE_DOS_HEADER)hModule)->e_lfanew);
|
||||
PIMAGE_DATA_DIRECTORY dataDir = &ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
|
||||
if (!dataDir->Size)
|
||||
return NULL;
|
||||
|
||||
// get the VA of the modules NT Header
|
||||
pNtHeaders = (PIMAGE_NT_HEADERS)(uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew);
|
||||
PIMAGE_EXPORT_DIRECTORY exportDir = RVA(PIMAGE_EXPORT_DIRECTORY, hModule, dataDir->VirtualAddress);
|
||||
if (!exportDir->NumberOfNames || !exportDir->NumberOfFunctions)
|
||||
return NULL;
|
||||
|
||||
pDataDirectory = (PIMAGE_DATA_DIRECTORY)&pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
|
||||
PDWORD expName = RVA(PDWORD, hModule, exportDir->AddressOfNames);
|
||||
PWORD expOrdinal = RVA(PWORD, hModule, exportDir->AddressOfNameOrdinals);
|
||||
LPCSTR expNameStr;
|
||||
|
||||
// get the VA of the export directory
|
||||
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(uiLibraryAddress + pDataDirectory->VirtualAddress);
|
||||
for (DWORD i = 0; i < exportDir->NumberOfNames; i++, expName++, expOrdinal++) {
|
||||
|
||||
// get the VA for the array of addresses
|
||||
uiAddressArray = (uiLibraryAddress + pExportDirectory->AddressOfFunctions);
|
||||
expNameStr = RVA(LPCSTR, hModule, *expName);
|
||||
|
||||
// get the VA for the array of name pointers
|
||||
uiNameArray = (uiLibraryAddress + pExportDirectory->AddressOfNames);
|
||||
if (!expNameStr)
|
||||
break;
|
||||
|
||||
// get the VA for the array of name ordinals
|
||||
uiNameOrdinals = (uiLibraryAddress + pExportDirectory->AddressOfNameOrdinals);
|
||||
|
||||
// test if we are importing by name or by ordinal...
|
||||
if (((DWORD)lpProcName & 0xFFFF0000) == 0x00000000)
|
||||
{
|
||||
// import by ordinal...
|
||||
|
||||
// use the import ordinal (- export ordinal base) as an index into the array of addresses
|
||||
uiAddressArray += ((IMAGE_ORDINAL((DWORD)lpProcName) - pExportDirectory->Base) * sizeof(DWORD));
|
||||
|
||||
// resolve the address for this imported function
|
||||
fpResult = (FARPROC)(uiLibraryAddress + DEREF_32(uiAddressArray));
|
||||
}
|
||||
else
|
||||
{
|
||||
// import by name...
|
||||
DWORD 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(DWORD));
|
||||
|
||||
// calculate the virtual address for the function
|
||||
fpResult = (FARPROC)(uiLibraryAddress + DEREF_32(uiAddressArray));
|
||||
|
||||
// finish...
|
||||
break;
|
||||
}
|
||||
|
||||
// get the next exported function name
|
||||
uiNameArray += sizeof(DWORD);
|
||||
|
||||
// get the next exported function name ordinal
|
||||
uiNameOrdinals += sizeof(WORD);
|
||||
if (!_stricmp(lpProcName, expNameStr)) {
|
||||
DWORD funcRva = *RVA(PDWORD, hModule, exportDir->AddressOfFunctions + (*expOrdinal * 4));
|
||||
return RVA(FARPROC, hModule, funcRva);
|
||||
}
|
||||
}
|
||||
|
||||
return fpResult;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -146,9 +108,9 @@ int main()
|
||||
|
||||
LoadDLL(
|
||||
(ULONG_PTR)buffer,
|
||||
HashFunctionName("SayHello"),
|
||||
HashFunctionName("SayGoodbye"),
|
||||
NULL, 0,
|
||||
SRDI_CLEARHEADER | SRDI_CLEARMEMORY | SRDI_OBFUSCATEIMPORTS | (3 << 16)
|
||||
SRDI_CLEARHEADER | SRDI_CLEARMEMORY // | SRDI_OBFUSCATEIMPORTS | (3 << 16)
|
||||
);
|
||||
|
||||
return 0;
|
||||
|
||||
+28
-63
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -34,6 +34,7 @@
|
||||
#define LOCALFREE_HASH 0xea61fcb1
|
||||
#define VIRTUALFREE_HASH 0x300f2f0b
|
||||
#define SLEEP_HASH 0xe035f044
|
||||
#define RTLADDFUNCTIONTABLE_HASH 0x45b82eba
|
||||
|
||||
#define HASH_KEY 13
|
||||
|
||||
@@ -60,7 +61,7 @@ typedef int (WINAPI * MESSAGEBOXA)(HWND, LPSTR, LPSTR, UINT);
|
||||
typedef BOOL(WINAPI * VIRTUALFREE)(LPVOID, SIZE_T, DWORD);
|
||||
typedef BOOL(WINAPI * LOCALFREE)(LPVOID);
|
||||
typedef VOID(WINAPI* SLEEP)(DWORD);
|
||||
|
||||
typedef BOOLEAN(WINAPI* RTLADDFUNCTIONTABLE)(PVOID, DWORD, DWORD64);
|
||||
|
||||
#define RVA(type, base, rva) (type)((ULONG_PTR) base + rva)
|
||||
|
||||
@@ -93,6 +94,7 @@ ULONG_PTR LoadDLL(PBYTE dllData, DWORD dwFunctionHash, LPVOID lpUserData, DWORD
|
||||
VIRTUALFREE pVirtualFree = NULL;
|
||||
LOCALFREE pLocalFree = NULL;
|
||||
SLEEP pSleep = NULL;
|
||||
RTLADDFUNCTIONTABLE pRtlAddFunctionTable = NULL;
|
||||
/// MESSAGEBOXA pMessageBoxA = NULL;
|
||||
|
||||
// PE data
|
||||
@@ -108,6 +110,7 @@ ULONG_PTR LoadDLL(PBYTE dllData, DWORD dwFunctionHash, LPVOID lpUserData, DWORD
|
||||
PIMAGE_BASE_RELOCATION relocation;
|
||||
PIMAGE_RELOC relocList;
|
||||
PIMAGE_EXPORT_DIRECTORY exportDir;
|
||||
PIMAGE_RUNTIME_FUNCTION_ENTRY rfEntry;
|
||||
PDWORD expName;
|
||||
PWORD expOrdinal;
|
||||
LPCSTR expNameStr;
|
||||
@@ -158,10 +161,12 @@ ULONG_PTR LoadDLL(PBYTE dllData, DWORD dwFunctionHash, LPVOID lpUserData, DWORD
|
||||
pNtFlushInstructionCache = (NTFLUSHINSTRUCTIONCACHE)GetProcAddressWithHash(NTFLUSHINSTRUCTIONCACHE_HASH);
|
||||
pGetNativeSystemInfo = (GETNATIVESYSTEMINFO)GetProcAddressWithHash(GETNATIVESYSTEMINFO_HASH);
|
||||
pSleep = (SLEEP)GetProcAddressWithHash(SLEEP_HASH);
|
||||
pRtlAddFunctionTable = (RTLADDFUNCTIONTABLE)GetProcAddressWithHash(RTLADDFUNCTIONTABLE_HASH);
|
||||
|
||||
/// pMessageBoxA = (MESSAGEBOXA)GetProcAddressWithHash(MESSAGEBOXA_HASH);
|
||||
|
||||
if (!pLoadLibraryA || !pGetProcAddress || !pVirtualAlloc || !pVirtualProtect ||
|
||||
!pNtFlushInstructionCache || !pGetNativeSystemInfo || !pSleep) {
|
||||
!pNtFlushInstructionCache || !pGetNativeSystemInfo || !pSleep || !pRtlAddFunctionTable) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -416,7 +421,7 @@ ULONG_PTR LoadDLL(PBYTE dllData, DWORD dwFunctionHash, LPVOID lpUserData, DWORD
|
||||
pNtFlushInstructionCache((HANDLE)-1, NULL, 0);
|
||||
|
||||
///
|
||||
// STEP 8: execute TLS callbacks
|
||||
// STEP 8: Execute TLS callbacks
|
||||
///
|
||||
|
||||
dataDir = &ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS];
|
||||
@@ -432,14 +437,28 @@ ULONG_PTR LoadDLL(PBYTE dllData, DWORD dwFunctionHash, LPVOID lpUserData, DWORD
|
||||
}
|
||||
|
||||
///
|
||||
// STEP 9: call our images entry point
|
||||
// STEP 9: Register exception handlers (x64 only)
|
||||
///
|
||||
|
||||
#ifdef _WIN64
|
||||
dataDir = &ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
|
||||
|
||||
if (dataDir->Size)
|
||||
{
|
||||
rfEntry = RVA(PIMAGE_RUNTIME_FUNCTION_ENTRY, baseAddress, dataDir->VirtualAddress);
|
||||
pRtlAddFunctionTable(rfEntry, (dataDir->Size / sizeof(IMAGE_RUNTIME_FUNCTION_ENTRY)) - 1, baseAddress);
|
||||
}
|
||||
#endif
|
||||
|
||||
///
|
||||
// STEP 10: call our images entry point
|
||||
///
|
||||
|
||||
dllMain = RVA(DLLMAIN, baseAddress, ntHeaders->OptionalHeader.AddressOfEntryPoint);
|
||||
dllMain((HINSTANCE)baseAddress, DLL_PROCESS_ATTACH, (LPVOID)1);
|
||||
|
||||
///
|
||||
// STEP 10: call our exported function
|
||||
// STEP 11: call our exported function
|
||||
///
|
||||
|
||||
if (dwFunctionHash) {
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TESTDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -106,6 +107,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;TESTDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -125,6 +127,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;TESTDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -146,6 +149,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;TESTDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
||||
@@ -24,7 +24,16 @@ BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
//extern "C" to prevent C++ name mangling
|
||||
extern "C" __declspec(dllexport) BOOL SayGoodbye(LPVOID lpUserdata, DWORD nUserdataLen)
|
||||
{
|
||||
try {
|
||||
int i = 0, j = 1;
|
||||
j /= i; // This will throw a SE (divide by zero).
|
||||
}
|
||||
catch (...) {
|
||||
MessageBoxA(NULL, "C++ Exception Thrown!", "Caught it", 0);
|
||||
}
|
||||
|
||||
MessageBoxA(NULL, "I'm Leaving!", "Goodbye", 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user