Hi, I don’t know if this is the right place to ask but I have a problem that I want to solve. I want to get the output of a reflective loaded DLL from my child’s process via anonymous pipes.
Here is the code I wrote to spawn a process and inject a reflective DLL into it.
DWORD SpawnDll(LPVOID lpDllBuffer, DWORD dwDllLength, const char* cpCommandLine , DWORD dwProcessArch) {
#ifdef DEBUG
printf("\n\n[DEBUG] SpawnDll(0x0%p, %d, %s, %d)\n",
lpDllBuffer, dwDllLength, cpCommandLine, dwProcessArch);
#endif
if (lpDllBuffer == NULL) {
free(lpDllBuffer);
return 0;
}
BOOL bSuccess = FALSE;
HANDLE hStdInPipeRead = NULL;
HANDLE hStdInPipeWrite = NULL;
HANDLE hStdOutPipeRead = NULL;
HANDLE hStdOutPipeWrite = NULL;
SECURITY_ATTRIBUTES sa = {
.nLength = sizeof(SECURITY_ATTRIBUTES),
.lpSecurityDescriptor = NULL,
.bInheritHandle = FALSE,
};
bSuccess = CreatePipe(&hStdInPipeRead, &hStdInPipeWrite, &sa, 0);
if (bSuccess == FALSE)
return ERROR_FAILED_INPUT_PIPE;
if (!SetHandleInformation(hStdInPipeWrite, HANDLE_FLAG_INHERIT, 0)) {
DEBUGF("Stdin SetHandleInformation");
goto Cleanup;
}
bSuccess = CreatePipe(&hStdOutPipeRead, &hStdOutPipeWrite, &sa, 0);
if (bSuccess == FALSE)
return ERROR_FAILED_OUTPUT_PIPE;
if (!SetHandleInformation(hStdOutPipeRead, HANDLE_FLAG_INHERIT, 0)) {
DEBUGF("Stdout SetHandleInformation");
goto Cleanup;
}
STARTUPINFOEXA sInfo = {
.StartupInfo.cb = sizeof(STARTUPINFO),
.StartupInfo.dwFlags = STARTF_USESTDHANDLES,
.StartupInfo.hStdError = hStdOutPipeWrite,
.StartupInfo.hStdOutput = hStdOutPipeWrite,
.StartupInfo.hStdInput = hStdInPipeRead,
};
PROCESS_INFORMATION pInfo = { 0 };
CreateThread(NULL, 0, ReadFromPipe, hStdOutPipeRead, 0, NULL);
if (dwProcessArch == PROCESS_ARCH_X64) {
bSuccess = CreateProcessA(NULL, (char*) "C:\\Windows\\System32\\rundll32.exe" , NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &sInfo, &pInfo);
#ifdef DEBUG
printf("[DEBUG] Started Process :: C:\\Windows\\System32\\rundll32.exe\n");
#endif
} else {
bSuccess = CreateProcessA(NULL, (char*) "C:\\Windows\\SysWOW64\\rundll32.exe", NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &sInfo, &pInfo);
#ifdef DEBUG
printf("[DEBUG] Started Process :: C:\\Windows\\SysWOW64\\rundll32.exe\n");
#endif
}
if (!bSuccess)
goto Cleanup;
InjectDLL( pInfo.dwProcessId, lpDllBuffer, dwDllLength, cpCommandLine, dwProcessArch );
#ifdef DEBUG
printf("[DEBUG] injected dll\n");
#endif
ResumeThread(pInfo.hThread);
CloseHandle(pInfo.hThread);
WaitForSingleObject(pInfo.hProcess, INFINITE);
Cleanup:
CloseHandle(hStdOutPipeRead);
CloseHandle(hStdOutPipeWrite);
CloseHandle(hStdInPipeWrite);
CloseHandle(hStdInPipeRead);
return 0;
}
The InjectDll
function is straight-up copied from pupy rat reflected dll injection.
The ReadPipe
function looks like that.
#define MAX_OUTPUT 1024
void ReadFromPipe(HANDLE hSTD_OUT_Read) {
char chBuf[MAX_OUTPUT + 1] = { 0 };
BOOL bSuccess = FALSE;
DWORD dwRead = 0;
DEBUGF("Started Reading from Pipe")
bSuccess = ReadFile(hSTD_OUT_Read, chBuf, MAX_OUTPUT, &dwRead, NULL);
DEBUGF("Starting do while loop...")
do {
chBuf[dwRead] = '\0';
#ifdef DEBUG
printf("[%s] dwRead :: %d\n", __FUNCTION__ , dwRead);
#endif
if (dwRead != 0) printf("%s\n",chBuf);
memset(chBuf, '\0', sizeof(chBuf));
bSuccess = ReadFile(hSTD_OUT_Read, chBuf, MAX_OUTPUT, &dwRead, NULL);
} while (bSuccess == TRUE);
return;
}
reflective Dll Source code based on stephenfewer’s dll:
//===============================================================================================//
// This is a stub for the actual functionality of the DLL.
//===============================================================================================//
#include "ReflectiveLoader.h"
#include <stdio.h>
// Note: REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR and REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN are
// defined in the project properties (Properties->C++->Preprocessor) so as we can specify our own
// DllMain and use the LoadRemoteLibraryR() API to inject this DLL.
// You can use this value as a pseudo hinstDLL value (defined and set via ReflectiveLoader.c)
extern HINSTANCE hAppInstance;
//===============================================================================================//
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
{
BOOL bReturnValue = TRUE;
switch( dwReason ) {
case DLL_QUERY_HMODULE:
if( lpReserved != NULL )
*(HMODULE *)lpReserved = hAppInstance;
break;
case DLL_PROCESS_ATTACH:
hAppInstance = hinstDLL;
puts("[DEBUG] Hello from DllMain");
MessageBoxA( NULL, "Hello from DllMain!", "Reflective Dll Injection", MB_OK );
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return bReturnValue;
}
The injection part works because I see Message Box popping up for a second but then closing itself.
I already searched the internet and didn’t really found anything (or i am to dump to search for it…)
Thank you guys for the help and answers : )