WIP Patch
This commit is contained in:
parent
360df2dfda
commit
3537c91324
|
@ -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<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() {
|
||||
// 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<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
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue