Skip to content

Commit

Permalink
Land stephenfewer#10, fix Linux cross-compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
busterb committed Jul 6, 2020
2 parents 127cda3 + a7f0656 commit 6bad4c4
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 62 deletions.
44 changes: 7 additions & 37 deletions dll/src/ReflectiveLoader.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,25 @@
// Our loader will set this to a pseudo correct HINSTANCE/HMODULE value
HINSTANCE hAppInstance = NULL;
//===============================================================================================//
#ifndef __MINGW32__
#ifdef __MINGW32__
#define WIN_GET_CALLER() __builtin_extract_return_addr(__builtin_return_address(0))
#else
#pragma intrinsic(_ReturnAddress)
#define WIN_GET_CALLER() _ReturnAddress()
#endif
// This function can not be inlined by the compiler or we will not get the address we expect. Ideally
// this code will be compiled with the /O2 and /Ob1 switches. Bonus points if we could take advantage of
// RIP relative addressing in this instance but I dont believe we can do so with the compiler intrinsics
// available (and no inline asm available under x64).
__declspec(noinline) ULONG_PTR caller( VOID ) { return (ULONG_PTR)_ReturnAddress(); }
__declspec(noinline) ULONG_PTR caller( VOID ) { return (ULONG_PTR)WIN_GET_CALLER(); }
//===============================================================================================//

#ifdef ENABLE_OUTPUTDEBUGSTRING
#define OUTPUTDBG(str) pOutputDebug((LPCSTR)str)
#else /* ENABLE_OUTPUTDEBUGSTRING */
#define OUTPUTDBG(str) do{}while(0)
#endif

// Note 1: If you want to have your own DllMain, define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN,
// otherwise the DllMain at the end of this file will be used.

// Note 2: If you are injecting the DLL via LoadRemoteLibraryR, define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR,
// otherwise it is assumed you are calling the ReflectiveLoader via a stub.


#ifdef RDIDLL_NOEXPORT
#define RDIDLLEXPORT
#else
Expand All @@ -74,9 +70,6 @@ RDIDLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( VOID )
#ifdef ENABLE_STOPPAGING
VIRTUALLOCK pVirtualLock = NULL;
#endif
#ifdef ENABLE_OUTPUTDEBUGSTRING
OUTPUTDEBUG pOutputDebug = NULL;
#endif

USHORT usCounter;

Expand Down Expand Up @@ -133,7 +126,7 @@ RDIDLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( VOID )
#else
#ifdef WIN_ARM
uiBaseAddress = *(DWORD *)( (BYTE *)_MoveFromCoprocessor( 15, 0, 13, 0, 2 ) + 0x30 );
#else _WIN32
#else // _WIN32
uiBaseAddress = __readfsdword( 0x30 );
#endif
#endif
Expand Down Expand Up @@ -191,9 +184,6 @@ RDIDLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( VOID )
#ifdef ENABLE_STOPPAGING
usCounter++;
#endif
#ifdef ENABLE_OUTPUTDEBUGSTRING
usCounter++;
#endif

// loop while we still have imports to find
while( usCounter > 0 )
Expand All @@ -207,9 +197,6 @@ RDIDLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( VOID )
|| dwHashValue == VIRTUALALLOC_HASH
#ifdef ENABLE_STOPPAGING
|| dwHashValue == VIRTUALLOCK_HASH
#endif
#ifdef ENABLE_OUTPUTDEBUGSTRING
|| dwHashValue == OUTPUTDEBUG_HASH
#endif
)
{
Expand All @@ -230,10 +217,6 @@ RDIDLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( VOID )
else if( dwHashValue == VIRTUALLOCK_HASH )
pVirtualLock = (VIRTUALLOCK)( uiBaseAddress + DEREF_32( uiAddressArray ) );
#endif
#ifdef ENABLE_OUTPUTDEBUGSTRING
else if( dwHashValue == OUTPUTDEBUG_HASH )
pOutputDebug = (OUTPUTDEBUG)( uiBaseAddress + DEREF_32( uiAddressArray ) );
#endif

// decrement our counter
usCounter--;
Expand Down Expand Up @@ -307,9 +290,6 @@ RDIDLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( VOID )
&& pVirtualLock
#endif
&& pNtFlushInstructionCache
#ifdef ENABLE_OUTPUTDEBUGSTRING
&& pOutputDebug
#endif
)
break;

Expand Down Expand Up @@ -357,6 +337,7 @@ RDIDLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( VOID )
// copy the section over
uiValueD = ((PIMAGE_SECTION_HEADER)uiValueA)->SizeOfRawData;


while( uiValueD-- )
*(BYTE *)uiValueB++ = *(BYTE *)uiValueC++;

Expand All @@ -376,17 +357,11 @@ RDIDLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( VOID )
// iterate through all imports until a null RVA is found (Characteristics is mis-named)
while( ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Characteristics )
{
OUTPUTDBG("Loading library: ");
OUTPUTDBG((LPCSTR)(uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name));
OUTPUTDBG("\n");

// use LoadLibraryA to load the imported module into memory
uiLibraryAddress = (ULONG_PTR)pLoadLibraryA( (LPCSTR)( uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name ) );

if ( !uiLibraryAddress )
{
OUTPUTDBG("Loading library FAILED\n");

uiValueC += sizeof( IMAGE_IMPORT_DESCRIPTOR );
continue;
}
Expand Down Expand Up @@ -426,10 +401,6 @@ RDIDLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( VOID )
// get the VA of this functions import by name struct
uiValueB = ( uiBaseAddress + DEREF(uiValueA) );

OUTPUTDBG("Resolving function: ");
OUTPUTDBG(((PIMAGE_IMPORT_BY_NAME)uiValueB)->Name);
OUTPUTDBG("\n");

// use GetProcAddress and patch in the address for this imported function
DEREF(uiValueA) = (ULONG_PTR)pGetProcAddress( (HMODULE)uiLibraryAddress, (LPCSTR)((PIMAGE_IMPORT_BY_NAME)uiValueB)->Name );
}
Expand Down Expand Up @@ -534,7 +505,6 @@ RDIDLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( VOID )
// uiValueA = the VA of our newly loaded DLL/EXE's entry point
uiValueA = ( uiBaseAddress + ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.AddressOfEntryPoint );

OUTPUTDBG("Flushing the instruction cache");
// We must flush the instruction cache to avoid stale code being used which was updated by our relocation processing.
pNtFlushInstructionCache( (HANDLE)-1, NULL, 0 );

Expand Down
34 changes: 13 additions & 21 deletions dll/src/ReflectiveLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,37 +35,29 @@

#include "ReflectiveDLLInjection.h"

// Enable this define to turn on OutputDebugString support
//#define ENABLE_OUTPUTDEBUGSTRING 1

// Enable this define to turn on locking of memory to prevent paging
#define ENABLE_STOPPAGING 1
#define ENABLE_STOPPAGING

#define EXITFUNC_SEH 0xEA320EFE
#define EXITFUNC_THREAD 0x0A2A1DE0
#define EXITFUNC_PROCESS 0x56A2B5F0

typedef HMODULE (WINAPI * LOADLIBRARYA)( LPCSTR );
typedef FARPROC (WINAPI * GETPROCADDRESS)( HMODULE, LPCSTR );
typedef LPVOID (WINAPI * VIRTUALALLOC)( LPVOID, SIZE_T, DWORD, DWORD );
typedef DWORD (NTAPI * NTFLUSHINSTRUCTIONCACHE)( HANDLE, PVOID, ULONG );
typedef HMODULE(WINAPI*LOADLIBRARYA)(LPCSTR);
typedef FARPROC(WINAPI*GETPROCADDRESS)(HMODULE,LPCSTR);
typedef LPVOID(WINAPI*VIRTUALALLOC)(LPVOID,SIZE_T,DWORD,DWORD);
typedef DWORD(NTAPI*NTFLUSHINSTRUCTIONCACHE)(HANDLE,PVOID,ULONG);

#define KERNEL32DLL_HASH 0x6A4ABC5B
#define NTDLLDLL_HASH 0x3CFA685D
#define KERNEL32DLL_HASH 0x6A4ABC5B
#define NTDLLDLL_HASH 0x3CFA685D

#define LOADLIBRARYA_HASH 0xEC0E4E8E
#define GETPROCADDRESS_HASH 0x7C0DFCAA
#define VIRTUALALLOC_HASH 0x91AFCA54
#define NTFLUSHINSTRUCTIONCACHE_HASH 0x534C0AB8
#define LOADLIBRARYA_HASH 0xEC0E4E8E
#define GETPROCADDRESS_HASH 0x7C0DFCAA
#define VIRTUALALLOC_HASH 0x91AFCA54
#define NTFLUSHINSTRUCTIONCACHE_HASH 0x534C0AB8

#ifdef ENABLE_STOPPAGING
typedef LPVOID (WINAPI * VIRTUALLOCK)( LPVOID, SIZE_T );
#define VIRTUALLOCK_HASH 0x0EF632F2
#endif

#ifdef ENABLE_OUTPUTDEBUGSTRING
typedef LPVOID (WINAPI * OUTPUTDEBUG)( LPCSTR );
#define OUTPUTDEBUG_HASH 0x470D22BC
typedef LPVOID(WINAPI*VIRTUALLOCK)(LPVOID,SIZE_T);
#define VIRTUALLOCK_HASH 0x0EF632F2
#endif

#define IMAGE_REL_BASED_ARM_MOV32A 5
Expand Down
2 changes: 1 addition & 1 deletion inject/src/GetProcAddressR.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ FARPROC WINAPI GetProcAddressR( HANDLE hModule, LPCSTR lpProcName )
// 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) );
uiAddressArray += ( ( IMAGE_ORDINAL( (DWORD)(DWORD_PTR)lpProcName ) - pExportDirectory->Base ) * sizeof(DWORD) );

// resolve the address for this imported function
fpResult = (FARPROC)( uiLibraryAddress + DEREF_32(uiAddressArray) );
Expand Down
5 changes: 2 additions & 3 deletions inject/src/LoadLibraryR.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ DWORD GetReflectiveLoaderOffset(VOID* lpReflectiveDllBuffer, LPCSTR cpReflective
is64 = FALSE;
// uiNameArray = the address of the modules export directory entry
uiNameArray = (UINT_PTR) & ((PIMAGE_NT_HEADERS32)uiExportDir)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];

}
else if (((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x020B) // PE64
{
Expand Down Expand Up @@ -124,7 +123,7 @@ DWORD GetReflectiveLoaderOffset(VOID* lpReflectiveDllBuffer, LPCSTR cpReflective
// import by ordinal...

// use the import ordinal (- export ordinal base) as an index into the array of addresses
uiAddressArray += ((IMAGE_ORDINAL((DWORD)cpReflectiveLoaderName) - ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->Base) * sizeof(DWORD));
uiAddressArray += ((IMAGE_ORDINAL((DWORD)(DWORD_PTR)cpReflectiveLoaderName) - ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->Base) * sizeof(DWORD));

// resolve the address for this imported function
return Rva2Offset(DEREF_32(uiAddressArray), uiBaseAddress, is64);
Expand Down Expand Up @@ -253,7 +252,7 @@ HANDLE WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLeng
lpReflectiveLoader = (LPTHREAD_START_ROUTINE)( (ULONG_PTR)lpRemoteLibraryBuffer + dwReflectiveLoaderOffset );

// create a remote thread in the host process to call the ReflectiveLoader!
hThread = CreateRemoteThread( hProcess, NULL, 1024*1024, lpReflectiveLoader, lpParameter, (DWORD)NULL, &dwThreadId );
hThread = CreateRemoteThread( hProcess, NULL, 1024*1024, lpReflectiveLoader, lpParameter, (DWORD_PTR)NULL, &dwThreadId );

} while( 0 );

Expand Down

0 comments on commit 6bad4c4

Please sign in to comment.