mirror of
https://github.com/monoxgas/sRDI
synced 2026-06-06 16:14:36 +00:00
Add new obfuscate_imports (0x4) flag
Finish refactor + fixes for x86 code. Small code cleanup.
This commit is contained in:
+2
-2
File diff suppressed because one or more lines are too long
@@ -5,6 +5,10 @@
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
|
||||
#define SRDI_CLEARHEADER 0x1
|
||||
#define SRDI_CLEARMEMORY 0x2
|
||||
#define SRDI_OBFUSCATEIMPORTS 0x4
|
||||
|
||||
DWORD GetFileContents(LPCSTR filename, LPSTR *data, DWORD &size)
|
||||
{
|
||||
std::FILE *fp = std::fopen(filename, "rb");
|
||||
@@ -50,7 +54,7 @@ int main()
|
||||
#ifdef _WIN64
|
||||
LPCSTR fileName = "../bin/TestDLL_x64.dll";
|
||||
#else
|
||||
LPCSTR fileName = "../../bin/TestDLL_x86.dll";
|
||||
LPCSTR fileName = "../bin/TestDLL_x86.dll";
|
||||
#endif
|
||||
|
||||
DWORD result = GetFileContents(fileName, &buffer, bufferSize);
|
||||
@@ -60,7 +64,12 @@ int main()
|
||||
return 1;
|
||||
}
|
||||
|
||||
LoadDLL((ULONG_PTR)buffer, HashFunctionName("SayHello"), NULL, 0, 0x1);
|
||||
LoadDLL(
|
||||
(ULONG_PTR)buffer,
|
||||
HashFunctionName("SayHello"),
|
||||
NULL, 0,
|
||||
SRDI_CLEARHEADER | SRDI_CLEARMEMORY | SRDI_OBFUSCATEIMPORTS | (3 << 16)
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+3
-3
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
@@ -28,7 +28,7 @@ typedef struct _MY_LDR_DATA_TABLE_ENTRY
|
||||
UNICODE_STRING BaseDllName;
|
||||
} MY_LDR_DATA_TABLE_ENTRY, *PMY_LDR_DATA_TABLE_ENTRY;
|
||||
|
||||
HMODULE GetProcAddressWithHash( _In_ DWORD dwModuleFunctionHash )
|
||||
HMODULE GetProcAddressWithHash( DWORD dwModuleFunctionHash )
|
||||
{
|
||||
PPEB PebAddress;
|
||||
PMY_PEB_LDR_DATA pLdr;
|
||||
@@ -50,11 +50,6 @@ HMODULE GetProcAddressWithHash( _In_ DWORD dwModuleFunctionHash )
|
||||
|
||||
#if defined(_WIN64)
|
||||
PebAddress = (PPEB) __readgsqword( 0x60 );
|
||||
#elif defined(_M_ARM)
|
||||
// I can assure you that this is not a mistake. The C compiler improperly emits the proper opcodes
|
||||
// necessary to get the PEB.Ldr address
|
||||
PebAddress = (PPEB) ( (ULONG_PTR) _MoveFromCoprocessor(15, 0, 13, 0, 2) + 0);
|
||||
__emit( 0x00006B1B );
|
||||
#else
|
||||
PebAddress = (PPEB) __readfsdword( 0x30 );
|
||||
#endif
|
||||
|
||||
+53
-22
@@ -8,9 +8,9 @@
|
||||
#include <winternl.h>
|
||||
#include <intrin.h>
|
||||
|
||||
// we declare some common stuff in here...
|
||||
|
||||
#define DLL_QUERY_HMODULE 6
|
||||
#define SRDI_CLEARHEADER 0x1
|
||||
#define SRDI_CLEARMEMORY 0x2
|
||||
#define SRDI_OBFUSCATEIMPORTS 0x4
|
||||
|
||||
#define DEREF( name )*(UINT_PTR *)(name)
|
||||
#define DEREF_64( name )*(DWORD64 *)(name)
|
||||
@@ -33,19 +33,18 @@
|
||||
#define MESSAGEBOXA_HASH 0x7568345
|
||||
#define LOCALFREE_HASH 0xea61fcb1
|
||||
#define VIRTUALFREE_HASH 0x300f2f0b
|
||||
#define SLEEP_HASH 0xe035f044
|
||||
|
||||
#define HASH_KEY 13
|
||||
|
||||
#define SRDI_CLEARHEADER 0x1
|
||||
#define SRDI_CLEARMEMORY 0x2
|
||||
#define SRDI_OBFUSCATEIMPORTS 0x4
|
||||
|
||||
#ifdef _WIN64
|
||||
#define HOST_MACHINE IMAGE_FILE_MACHINE_AMD64
|
||||
#else
|
||||
#define HOST_MACHINE IMAGE_FILE_MACHINE_I386
|
||||
#endif
|
||||
|
||||
// 100-ns period
|
||||
#define OBFUSCATE_IMPORT_DELAY 5 * 1000 * 10000
|
||||
|
||||
typedef BOOL(WINAPI * DLLMAIN)(HINSTANCE, DWORD, LPVOID);
|
||||
typedef BOOL(*EXPORTFUNC)(LPVOID, DWORD);
|
||||
@@ -60,6 +59,8 @@ typedef BOOL(WINAPI * VIRTUALPROTECT)(LPVOID, SIZE_T, DWORD, PDWORD);
|
||||
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);
|
||||
|
||||
|
||||
#define RVA(type, base, rva) (type)((ULONG_PTR) base + rva)
|
||||
|
||||
@@ -91,6 +92,7 @@ ULONG_PTR LoadDLL(PBYTE dllData, DWORD dwFunctionHash, LPVOID lpUserData, DWORD
|
||||
VIRTUALPROTECT pVirtualProtect = NULL;
|
||||
VIRTUALFREE pVirtualFree = NULL;
|
||||
LOCALFREE pLocalFree = NULL;
|
||||
SLEEP pSleep = NULL;
|
||||
/// MESSAGEBOXA pMessageBoxA = NULL;
|
||||
|
||||
// PE data
|
||||
@@ -125,13 +127,21 @@ ULONG_PTR LoadDLL(PBYTE dllData, DWORD dwFunctionHash, LPVOID lpUserData, DWORD
|
||||
DWORD lastSectionEnd;
|
||||
DWORD endOfSection;
|
||||
DWORD alignedImageSize;
|
||||
ULONGLONG baseOffset;
|
||||
ULONG_PTR baseOffset;
|
||||
SYSTEM_INFO sysInfo;
|
||||
|
||||
// General
|
||||
PBYTE libraryAddress;
|
||||
DWORD funcHash;
|
||||
|
||||
DWORD importCount;
|
||||
|
||||
// Import obfuscation
|
||||
DWORD randSeed;
|
||||
DWORD rand;
|
||||
DWORD sleep;
|
||||
DWORD selection;
|
||||
IMAGE_IMPORT_DESCRIPTOR tempDesc;
|
||||
|
||||
// Relocated base
|
||||
ULONG_PTR baseAddress;
|
||||
|
||||
@@ -147,14 +157,14 @@ ULONG_PTR LoadDLL(PBYTE dllData, DWORD dwFunctionHash, LPVOID lpUserData, DWORD
|
||||
pVirtualProtect = (VIRTUALPROTECT)GetProcAddressWithHash(VIRTUALPROTECT_HASH);
|
||||
pNtFlushInstructionCache = (NTFLUSHINSTRUCTIONCACHE)GetProcAddressWithHash(NTFLUSHINSTRUCTIONCACHE_HASH);
|
||||
pGetNativeSystemInfo = (GETNATIVESYSTEMINFO)GetProcAddressWithHash(GETNATIVESYSTEMINFO_HASH);
|
||||
pSleep = (SLEEP)GetProcAddressWithHash(SLEEP_HASH);
|
||||
/// pMessageBoxA = (MESSAGEBOXA)GetProcAddressWithHash(MESSAGEBOXA_HASH);
|
||||
|
||||
if (!pLoadLibraryA || !pGetProcAddress || !pVirtualAlloc || !pVirtualProtect ||
|
||||
!pNtFlushInstructionCache || !pGetNativeSystemInfo) {
|
||||
!pNtFlushInstructionCache || !pGetNativeSystemInfo || !pSleep) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
// STEP 2: load our image into a new permanent location in memory
|
||||
///
|
||||
@@ -196,7 +206,6 @@ ULONG_PTR LoadDLL(PBYTE dllData, DWORD dwFunctionHash, LPVOID lpUserData, DWORD
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Allocate all the memory for the DLL to be loaded into. Attempt to use the preferred base address.
|
||||
|
||||
baseAddress = (ULONG_PTR)pVirtualAlloc(
|
||||
@@ -228,8 +237,6 @@ ULONG_PTR LoadDLL(PBYTE dllData, DWORD dwFunctionHash, LPVOID lpUserData, DWORD
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ntHeaders = RVA(PIMAGE_NT_HEADERS, baseAddress, ((PIMAGE_DOS_HEADER)baseAddress)->e_lfanew);
|
||||
|
||||
///
|
||||
@@ -249,12 +256,34 @@ ULONG_PTR LoadDLL(PBYTE dllData, DWORD dwFunctionHash, LPVOID lpUserData, DWORD
|
||||
///
|
||||
|
||||
dataDir = &ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
|
||||
randSeed = (DWORD)dllData;
|
||||
|
||||
if (dataDir->Size) {
|
||||
|
||||
importDesc = RVA(PIMAGE_IMPORT_DESCRIPTOR, baseAddress, dataDir->VirtualAddress);
|
||||
|
||||
importCount = 0;
|
||||
for (; importDesc->Name; importDesc++) {
|
||||
importCount++;
|
||||
}
|
||||
|
||||
importDesc = RVA(PIMAGE_IMPORT_DESCRIPTOR, baseAddress, dataDir->VirtualAddress);
|
||||
if (flags & SRDI_OBFUSCATEIMPORTS && importCount > 1) {
|
||||
sleep = (flags & 0xFFFF0000);
|
||||
sleep = sleep >> 16;
|
||||
|
||||
for (i = 0; i < importCount - 1; i++) {
|
||||
randSeed = (214013 * randSeed + 2531011);
|
||||
rand = (randSeed >> 16) & 0x7FFF;
|
||||
selection = i + rand / (32767 / (importCount - i) + 1);
|
||||
|
||||
tempDesc = importDesc[selection];
|
||||
importDesc[selection] = importDesc[i];
|
||||
importDesc[i] = tempDesc;
|
||||
}
|
||||
}
|
||||
|
||||
importDesc = RVA(PIMAGE_IMPORT_DESCRIPTOR, baseAddress, dataDir->VirtualAddress);
|
||||
for (; importDesc->Name; importDesc++) {
|
||||
libraryAddress = (PBYTE)pLoadLibraryA((LPCSTR)(baseAddress + importDesc->Name));
|
||||
firstThunk = RVA(PIMAGE_THUNK_DATA, baseAddress, importDesc->FirstThunk);
|
||||
origFirstThunk = RVA(PIMAGE_THUNK_DATA, baseAddress, importDesc->OriginalFirstThunk);
|
||||
@@ -263,13 +292,17 @@ ULONG_PTR LoadDLL(PBYTE dllData, DWORD dwFunctionHash, LPVOID lpUserData, DWORD
|
||||
for (; origFirstThunk->u1.Function; firstThunk++, origFirstThunk++) {
|
||||
|
||||
if (IMAGE_SNAP_BY_ORDINAL(origFirstThunk->u1.Ordinal)) {
|
||||
firstThunk->u1.Function = (ULONGLONG)pGetProcAddress((HMODULE)libraryAddress, (LPCSTR)IMAGE_ORDINAL(origFirstThunk->u1.Ordinal));
|
||||
firstThunk->u1.Function = (ULONG_PTR)pGetProcAddress((HMODULE)libraryAddress, (LPCSTR)IMAGE_ORDINAL(origFirstThunk->u1.Ordinal));
|
||||
}
|
||||
else {
|
||||
importByName = RVA(PIMAGE_IMPORT_BY_NAME, baseAddress, origFirstThunk->u1.AddressOfData);
|
||||
firstThunk->u1.Function = (ULONGLONG)pGetProcAddress((HMODULE)libraryAddress, importByName->Name);
|
||||
firstThunk->u1.Function = (ULONG_PTR)pGetProcAddress((HMODULE)libraryAddress, importByName->Name);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & SRDI_OBFUSCATEIMPORTS && importCount > 1) {
|
||||
pSleep(sleep * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,11 +324,11 @@ ULONG_PTR LoadDLL(PBYTE dllData, DWORD dwFunctionHash, LPVOID lpUserData, DWORD
|
||||
// iterate through all imported functions, importing by ordinal if no name present
|
||||
for (; firstThunk->u1.Function; firstThunk++, origFirstThunk++) {
|
||||
if (IMAGE_SNAP_BY_ORDINAL(origFirstThunk->u1.Ordinal)) {
|
||||
firstThunk->u1.Function = (ULONGLONG)pGetProcAddress((HMODULE)libraryAddress, (LPCSTR)IMAGE_ORDINAL(origFirstThunk->u1.Ordinal));
|
||||
firstThunk->u1.Function = (ULONG_PTR)pGetProcAddress((HMODULE)libraryAddress, (LPCSTR)IMAGE_ORDINAL(origFirstThunk->u1.Ordinal));
|
||||
}
|
||||
else {
|
||||
importByName = RVA(PIMAGE_IMPORT_BY_NAME, baseAddress, origFirstThunk->u1.AddressOfData);
|
||||
firstThunk->u1.Function = (ULONGLONG)pGetProcAddress((HMODULE)libraryAddress, importByName->Name);
|
||||
firstThunk->u1.Function = (ULONG_PTR)pGetProcAddress((HMODULE)libraryAddress, importByName->Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -378,7 +411,6 @@ ULONG_PTR LoadDLL(PBYTE dllData, DWORD dwFunctionHash, LPVOID lpUserData, DWORD
|
||||
|
||||
}
|
||||
|
||||
|
||||
// We must flush the instruction cache to avoid stale code being used
|
||||
pNtFlushInstructionCache((HANDLE)-1, NULL, 0);
|
||||
|
||||
@@ -386,8 +418,7 @@ ULONG_PTR LoadDLL(PBYTE dllData, DWORD dwFunctionHash, LPVOID lpUserData, DWORD
|
||||
// STEP 8: execute TLS callbacks
|
||||
///
|
||||
|
||||
|
||||
baseOffset = (ULONGLONG)(baseAddress - ntHeaders->OptionalHeader.ImageBase);
|
||||
baseOffset = (ULONG_PTR)(baseAddress - ntHeaders->OptionalHeader.ImageBase);
|
||||
dataDir = &ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS];
|
||||
|
||||
if (dataDir->Size)
|
||||
|
||||
Reference in New Issue
Block a user