└── RunPE.cpp /RunPE.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include // Standard C++ library for console I/O 3 | #include // Standard C++ Library for string manip 4 | 5 | #include // WinAPI Header 6 | #include //WinAPI Process API 7 | 8 | 9 | // use this if you want to read the executable from disk 10 | HANDLE MapFileToMemory(LPCSTR filename) 11 | { 12 | std::streampos size; 13 | std::fstream file(filename, std::ios::in | std::ios::binary | std::ios::ate); 14 | if (file.is_open()) 15 | { 16 | size = file.tellg(); 17 | 18 | char* Memblock = new char[size](); 19 | 20 | file.seekg(0, std::ios::beg); 21 | file.read(Memblock, size); 22 | file.close(); 23 | 24 | return Memblock; 25 | } 26 | return 0; 27 | } 28 | 29 | int RunPortableExecutable(void* Image) 30 | { 31 | IMAGE_DOS_HEADER* DOSHeader; // For Nt DOS Header symbols 32 | IMAGE_NT_HEADERS* NtHeader; // For Nt PE Header objects & symbols 33 | IMAGE_SECTION_HEADER* SectionHeader; 34 | 35 | PROCESS_INFORMATION PI; 36 | STARTUPINFOA SI; 37 | 38 | CONTEXT* CTX; 39 | 40 | DWORD* ImageBase; //Base address of the image 41 | void* pImageBase; // Pointer to the image base 42 | 43 | int count; 44 | char CurrentFilePath[1024]; 45 | 46 | DOSHeader = PIMAGE_DOS_HEADER(Image); // Initialize Variable 47 | NtHeader = PIMAGE_NT_HEADERS(DWORD(Image) + DOSHeader->e_lfanew); // Initialize 48 | 49 | GetModuleFileNameA(0, CurrentFilePath, 1024); // path to current executable 50 | 51 | if (NtHeader->Signature == IMAGE_NT_SIGNATURE) // Check if image is a PE File. 52 | { 53 | ZeroMemory(&PI, sizeof(PI)); // Null the memory 54 | ZeroMemory(&SI, sizeof(SI)); // Null the memory 55 | 56 | if (CreateProcessA(CurrentFilePath, NULL, NULL, NULL, FALSE, 57 | CREATE_SUSPENDED, NULL, NULL, &SI, &PI)) // Create a new instance of current 58 | //process in suspended state, for the new image. 59 | { 60 | // Allocate memory for the context. 61 | CTX = LPCONTEXT(VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE)); 62 | CTX->ContextFlags = CONTEXT_FULL; // Context is allocated 63 | 64 | if (GetThreadContext(PI.hThread, LPCONTEXT(CTX))) //if context is in thread 65 | { 66 | // Read instructions 67 | ReadProcessMemory(PI.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&ImageBase), 4, 0); 68 | 69 | pImageBase = VirtualAllocEx(PI.hProcess, LPVOID(NtHeader->OptionalHeader.ImageBase), 70 | NtHeader->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE); 71 | 72 | // Write the image to the process 73 | WriteProcessMemory(PI.hProcess, pImageBase, Image, NtHeader->OptionalHeader.SizeOfHeaders, NULL); 74 | 75 | for (count = 0; count < NtHeader->FileHeader.NumberOfSections; count++) 76 | { 77 | SectionHeader = PIMAGE_SECTION_HEADER(DWORD(Image) + DOSHeader->e_lfanew + 248 + (count * 40)); 78 | 79 | WriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + SectionHeader->VirtualAddress), 80 | LPVOID(DWORD(Image) + SectionHeader->PointerToRawData), SectionHeader->SizeOfRawData, 0); 81 | } 82 | WriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8), 83 | LPVOID(&NtHeader->OptionalHeader.ImageBase), 4, 0); 84 | 85 | // Move address of entry point to the eax register 86 | CTX->Eax = DWORD(pImageBase) + NtHeader->OptionalHeader.AddressOfEntryPoint; 87 | SetThreadContext(PI.hThread, LPCONTEXT(CTX)); // Set the context 88 | ResumeThread(PI.hThread); //´Start the process/call main() 89 | 90 | return 0; // Operation was successful. 91 | } 92 | } 93 | } 94 | } 95 | 96 | // enter valid bytes of a program here. 97 | unsigned char rawData[37376] = { 98 | 0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 99 | 0xFF, 0xFF, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 100 | }; 101 | 102 | int main() 103 | { 104 | RunPortableExecutable(rawData); // run executable from the array 105 | getchar(); 106 | } 107 | --------------------------------------------------------------------------------