From 3537c91324ca08cc27d35467625cffb1024ad701 Mon Sep 17 00:00:00 2001 From: Guus Waals <_@guusw.nl> Date: Fri, 6 Jun 2025 20:18:52 +0800 Subject: [PATCH] WIP Patch --- patcher/patcher.cpp | 100 +++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 47 deletions(-) diff --git a/patcher/patcher.cpp b/patcher/patcher.cpp index 1e1dc269..bcc4e0e8 100644 --- a/patcher/patcher.cpp +++ b/patcher/patcher.cpp @@ -384,6 +384,58 @@ struct Patcher { return true; } + bool redirectEntryPoint(uint64_t dstVA) { + // Patch the entry point to jump to our injected code + auto optionalHeader = peReader.get_optional_header(); + if (!optionalHeader) { + spdlog::error("Could not get optional header for entry point patching"); + return false; + } + + uint32_t entryPointRVA = optionalHeader->get_entry_point_address(); + uint64_t entryPointVA = imageBase + entryPointRVA; + + spdlog::info("Entry point at RVA: 0x{:x} (VA: 0x{:x})", entryPointRVA, entryPointVA); + spdlog::info("Target injection at VA: 0x{:x}", dstVA); + + // Find which section contains the entry point + COFFI::section* entrySection = nullptr; + uint32_t entryFileOffset = 0; + + auto& sections = peReader.get_sections(); + for (auto& section : sections) { + uint32_t sectionRVA = section->get_virtual_address(); + uint32_t sectionSize = section->get_virtual_size(); + + if (entryPointRVA >= sectionRVA && entryPointRVA < sectionRVA + sectionSize) { + entrySection = section; + entryFileOffset = entryPointRVA - sectionRVA; + break; + } + } + + if (!entrySection) { + spdlog::error("Could not find section containing entry point"); + return false; + } + + // Calculate relative jump offset + // jmp rel32 instruction: E9 xx xx xx xx (5 bytes) + // offset = target_address - (current_address + 5) + int32_t jumpOffset = static_cast(dstVA - (entryPointVA + 5)); + + spdlog::info("Patching entry point with jmp instruction (offset: 0x{:x})", + static_cast(jumpOffset)); + + // Patch the entry point with jmp instruction + char* entryData = const_cast(entrySection->get_data()) + entryFileOffset; + entryData[0] = static_cast(0xE9); // jmp rel32 opcode + *reinterpret_cast(&entryData[1]) = jumpOffset; + + spdlog::info("Entry point patched successfully"); + return true; + } + bool patchAndSave() { // Check available space in both sections uint32_t textAvailableSpace = findAvailableSpaceAtEnd(textSection); @@ -440,54 +492,10 @@ struct Patcher { } // Patch the entry point to jump to our injected code - auto optionalHeader = peReader.get_optional_header(); - if (!optionalHeader) { - spdlog::error("Could not get optional header for entry point patching"); - return false; - } - - uint32_t entryPointRVA = optionalHeader->get_entry_point_address(); - uint64_t entryPointVA = imageBase + entryPointRVA; uint64_t targetVA = textInjectionRVA + imageBase; - - spdlog::info("Entry point at RVA: 0x{:x} (VA: 0x{:x})", entryPointRVA, entryPointVA); - spdlog::info("Target injection at VA: 0x{:x}", targetVA); - - // Find which section contains the entry point - COFFI::section* entrySection = nullptr; - uint32_t entryFileOffset = 0; - - auto& sections = peReader.get_sections(); - for (auto& section : sections) { - uint32_t sectionRVA = section->get_virtual_address(); - uint32_t sectionSize = section->get_virtual_size(); - - if (entryPointRVA >= sectionRVA && entryPointRVA < sectionRVA + sectionSize) { - entrySection = section; - entryFileOffset = entryPointRVA - sectionRVA; - break; - } - } - - if (!entrySection) { - spdlog::error("Could not find section containing entry point"); + if (!redirectEntryPoint(targetVA)) { return false; } - - // Calculate relative jump offset - // jmp rel32 instruction: E9 xx xx xx xx (5 bytes) - // offset = target_address - (current_address + 5) - int32_t jumpOffset = static_cast(targetVA - (entryPointVA + 5)); - - spdlog::info("Patching entry point with jmp instruction (offset: 0x{:x})", - static_cast(jumpOffset)); - - // Patch the entry point with jmp instruction - char* entryData = const_cast(entrySection->get_data()) + entryFileOffset; - entryData[0] = static_cast(0xE9); // jmp rel32 opcode - *reinterpret_cast(&entryData[1]) = jumpOffset; - - spdlog::info("Entry point patched successfully"); // Save the modified PE file spdlog::info("Saving patched PE file to: {}", outputFile); @@ -496,8 +504,6 @@ struct Patcher { return false; } - - spdlog::info( "Successfully patched PE file! Main function injected at VA: 0x{:x}", textInjectionRVA + imageBase);