|
|
|
@ -192,7 +192,7 @@ namespace drv
|
|
|
|
|
ZydisDecoder decoder;
|
|
|
|
|
ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64);
|
|
|
|
|
|
|
|
|
|
ZyanUSize offset = 0;
|
|
|
|
|
std::int32_t offset = 0;
|
|
|
|
|
ZyanUSize length = symbol.size;
|
|
|
|
|
ZydisDecodedInstruction instruction;
|
|
|
|
|
|
|
|
|
@ -203,8 +203,13 @@ namespace drv
|
|
|
|
|
length - offset, &instruction)))
|
|
|
|
|
{
|
|
|
|
|
auto symbol_name = symbol.symbol_name;
|
|
|
|
|
auto jcc_symbol = symbol.symbol_name;
|
|
|
|
|
auto next_instruction_symbol = symbol.symbol_name;
|
|
|
|
|
|
|
|
|
|
jcc_symbol.append("@")
|
|
|
|
|
.append(std::to_string(
|
|
|
|
|
offset + instruction.operands[0].imm.value.s + instruction.length));
|
|
|
|
|
|
|
|
|
|
next_instruction_symbol.append("@").append(
|
|
|
|
|
std::to_string(offset + instruction.length));
|
|
|
|
|
|
|
|
|
@ -238,12 +243,63 @@ namespace drv
|
|
|
|
|
case ZYDIS_MNEMONIC_JS:
|
|
|
|
|
case ZYDIS_MNEMONIC_JZ:
|
|
|
|
|
{
|
|
|
|
|
std::vector<std::uint8_t> final_instruction;
|
|
|
|
|
final_instruction.resize(instruction.length +
|
|
|
|
|
instruction.length + (JMP_RIP_SIZE * 2));
|
|
|
|
|
|
|
|
|
|
// copy instruction into buffer...
|
|
|
|
|
memcpy(final_instruction.data(),
|
|
|
|
|
obj.data() + symbol.file_offset + offset, instruction.length);
|
|
|
|
|
|
|
|
|
|
// TODO check to see if the compiler made a short JCC...
|
|
|
|
|
// with optimizations off it seems to not...
|
|
|
|
|
*reinterpret_cast<std::uint32_t*>(&final_instruction[
|
|
|
|
|
instruction.length - (instruction.operands[0].size / 8)]) = NULL;
|
|
|
|
|
|
|
|
|
|
// only jmping +-128 bytes to jtable...
|
|
|
|
|
final_instruction[instruction.length - (instruction.operands[0].size / 8)] = JMP_RIP_SIZE;
|
|
|
|
|
std::printf(" > fixing JCC instruction...\n");
|
|
|
|
|
std::printf(" > original rva = 0x%x, new rva = 0x%x\n", instruction.operands[0].imm.value.s, JMP_RIP_SIZE);
|
|
|
|
|
std::printf(" > conditional branch = 0x%p\n", mapped_symbols[jcc_symbol]);
|
|
|
|
|
std::printf(" > next instruction = 0x%p\n", mapped_symbols[next_instruction_symbol]);
|
|
|
|
|
|
|
|
|
|
// copy jmp [rip] after instruction...
|
|
|
|
|
memcpy(&final_instruction[instruction.length], jmp_rip, sizeof jmp_rip);
|
|
|
|
|
|
|
|
|
|
// copy jtable entry...
|
|
|
|
|
memcpy(&final_instruction[instruction.length + JMP_RIP_SIZE], jmp_rip, sizeof jmp_rip);
|
|
|
|
|
|
|
|
|
|
// this jmp [rip] goes to the conditional branch...
|
|
|
|
|
*reinterpret_cast<std::uintptr_t*>(&final_instruction[
|
|
|
|
|
instruction.length + JMP_RIP_SIZE + JMP_RIP_ADDR_IDX]) = mapped_symbols[jcc_symbol];
|
|
|
|
|
|
|
|
|
|
// this jmp [rip] goes to the next instruction...
|
|
|
|
|
*reinterpret_cast<std::uintptr_t*>(&final_instruction[
|
|
|
|
|
instruction.length + JMP_RIP_ADDR_IDX]) = mapped_symbols[next_instruction_symbol];
|
|
|
|
|
|
|
|
|
|
const auto instruc_alloc =
|
|
|
|
|
reinterpret_cast<void*>(
|
|
|
|
|
mapped_symbols[symbol_name]);
|
|
|
|
|
|
|
|
|
|
// copy the instruction into memory...
|
|
|
|
|
kmemcpy(instruc_alloc, final_instruction.data(), final_instruction.size());
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ZYDIS_MNEMONIC_JMP:
|
|
|
|
|
{
|
|
|
|
|
std::vector<std::uint8_t> final_instruction;
|
|
|
|
|
final_instruction.resize(JMP_RIP_SIZE);
|
|
|
|
|
memset(final_instruction.data(), NULL, final_instruction.size());
|
|
|
|
|
|
|
|
|
|
*reinterpret_cast<std::uintptr_t*>(
|
|
|
|
|
&final_instruction[JMP_RIP_SIZE]) = mapped_symbols[jcc_symbol];
|
|
|
|
|
|
|
|
|
|
const auto instruc_alloc =
|
|
|
|
|
reinterpret_cast<void*>(
|
|
|
|
|
mapped_symbols[symbol_name]);
|
|
|
|
|
|
|
|
|
|
// copy the instruction into memory...
|
|
|
|
|
kmemcpy(instruc_alloc, final_instruction.data(), final_instruction.size());
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ZYDIS_MNEMONIC_RET:
|
|
|
|
|