Skip to content

Commit

Permalink
fix short conditional jumps to relocated code on x86_64
Browse files Browse the repository at this point in the history
the code the jump was jumping to was overwritten by our inline hook, and
also it was the wrong target address lol
  • Loading branch information
matcool committed Jun 23, 2024
1 parent b8357de commit d0c198f
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ build

balls.asm
balls2.asm

# clangd
.cache/
17 changes: 17 additions & 0 deletions src/generator/X64Generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "../target/PlatformTarget.hpp"

#include <CallingConvention.hpp>
#include <iostream>

using namespace tulip::hook;

Expand Down Expand Up @@ -758,6 +759,22 @@ Result<> X64HandlerGenerator::relocateBranchInstruction(cs_insn* insn, uint8_t*
trampolineAddress += bytes.size();
originalAddress += size;
}
else if (targetAddress - reinterpret_cast<int64_t>(m_address) < m_modifiedBytesSize) {
// conditional branch that jmps to code we relocated, so we need to keep track of where it jumps to
// relocation is later done in X86HandlerGenerator::relocatedBytes
std::memcpy(buffer, insn->bytes, size);
if (size == 2) {
auto* relativeByte = reinterpret_cast<int8_t*>(buffer + 1);
*relativeByte = -1;
m_shortBranchRelocations[targetAddress] = relativeByte;
} else {
// what
std::cerr << "Unhandled short branch relocation of " << insn->mnemonic << " with size=" << size << std::endl;
}

trampolineAddress += size;
originalAddress += size;
}
else {
X64Assembler a(trampolineAddress);
RegMem64 m;
Expand Down
14 changes: 13 additions & 1 deletion src/generator/X86Generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ Result<FunctionData> X86HandlerGenerator::generateTrampoline(uint64_t target) {
Result<X86HandlerGenerator::RelocateReturn> X86HandlerGenerator::relocatedBytes(uint64_t baseAddress, uint64_t target) {
// memcpy(m_trampoline, m_address, 32);

m_modifiedBytesSize = target;

TULIP_HOOK_UNWRAP_INTO(auto cs, Target::get().openCapstone());

cs_option(cs, CS_OPT_DETAIL, CS_OPT_ON);
Expand All @@ -215,12 +217,22 @@ Result<X86HandlerGenerator::RelocateReturn> X86HandlerGenerator::relocatedBytes(
auto trampolineAddress = baseAddress;
std::array<uint8_t, 0x80> buffer;

m_shortBranchRelocations.clear();
while (cs_disasm_iter(cs, &code, &size, &address, insn)) {
if (insn->address >= targetAddress) {
break;
}
auto bufferOffset = trampolineAddress - baseAddress;

auto it = m_shortBranchRelocations.find(originalAddress);
if (it != m_shortBranchRelocations.end()) {
auto relByte = it->second;
auto srcOffset = reinterpret_cast<uint8_t*>(relByte) - buffer.data();
// why the -1? idk
*relByte = bufferOffset - srcOffset - 1;
m_shortBranchRelocations.erase(it);
}

TULIP_HOOK_UNWRAP(this->relocateInstruction(insn, buffer.data() + bufferOffset, trampolineAddress, originalAddress));
}

Expand Down Expand Up @@ -259,7 +271,7 @@ Result<> X86HandlerGenerator::relocateInstruction(cs_insn* insn, uint8_t* buffer
// branches, jumps, calls
if (detail->x86.encoding.imm_offset != 0 && relativeGroup) {
intptr_t jmpTargetAddr = static_cast<intptr_t>(detail->x86.operands[0].imm) -
static_cast<intptr_t>(trampolineAddress) + static_cast<intptr_t>(originalAddress);
static_cast<intptr_t>(insn->address) + static_cast<intptr_t>(originalAddress);

return this->relocateBranchInstruction(insn, buffer, trampolineAddress, originalAddress, jmpTargetAddr);
}
Expand Down
4 changes: 4 additions & 0 deletions src/generator/X86Generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
namespace tulip::hook {

class X86HandlerGenerator : public HandlerGenerator {
protected:
uint64_t m_modifiedBytesSize = 0;
// this is only relevant for 64-bit relocation, pointer is to the buffer so dont keep this around
std::unordered_map<int64_t, int8_t*> m_shortBranchRelocations;
public:
using HandlerGenerator::HandlerGenerator;

Expand Down

0 comments on commit d0c198f

Please sign in to comment.