WIP Patch

This commit is contained in:
Guus Waals 2025-06-06 20:18:52 +08:00
parent 360df2dfda
commit 3537c91324
1 changed files with 53 additions and 47 deletions

View File

@ -384,6 +384,58 @@ struct Patcher {
return true; 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<int32_t>(dstVA - (entryPointVA + 5));
spdlog::info("Patching entry point with jmp instruction (offset: 0x{:x})",
static_cast<uint32_t>(jumpOffset));
// Patch the entry point with jmp instruction
char* entryData = const_cast<char*>(entrySection->get_data()) + entryFileOffset;
entryData[0] = static_cast<char>(0xE9); // jmp rel32 opcode
*reinterpret_cast<int32_t*>(&entryData[1]) = jumpOffset;
spdlog::info("Entry point patched successfully");
return true;
}
bool patchAndSave() { bool patchAndSave() {
// Check available space in both sections // Check available space in both sections
uint32_t textAvailableSpace = findAvailableSpaceAtEnd(textSection); uint32_t textAvailableSpace = findAvailableSpaceAtEnd(textSection);
@ -440,55 +492,11 @@ struct Patcher {
} }
// Patch the entry point to jump to our injected code // 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; uint64_t targetVA = textInjectionRVA + imageBase;
if (!redirectEntryPoint(targetVA)) {
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");
return false; 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<int32_t>(targetVA - (entryPointVA + 5));
spdlog::info("Patching entry point with jmp instruction (offset: 0x{:x})",
static_cast<uint32_t>(jumpOffset));
// Patch the entry point with jmp instruction
char* entryData = const_cast<char*>(entrySection->get_data()) + entryFileOffset;
entryData[0] = static_cast<char>(0xE9); // jmp rel32 opcode
*reinterpret_cast<int32_t*>(&entryData[1]) = jumpOffset;
spdlog::info("Entry point patched successfully");
// Save the modified PE file // Save the modified PE file
spdlog::info("Saving patched PE file to: {}", outputFile); spdlog::info("Saving patched PE file to: {}", outputFile);
if (!peReader.save(outputFile)) { if (!peReader.save(outputFile)) {
@ -496,8 +504,6 @@ struct Patcher {
return false; return false;
} }
spdlog::info( spdlog::info(
"Successfully patched PE file! Main function injected at VA: 0x{:x}", "Successfully patched PE file! Main function injected at VA: 0x{:x}",
textInjectionRVA + imageBase); textInjectionRVA + imageBase);