mehcode / guerrilla

☢ Guerrilla (or Monkey) Patching in Rust for (unsafe) fun and profit.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

collateral damage

kazcw opened this issue · comments

Patching functions smaller than JMP_SIZE overwrites whatever happens to follow them. On x86_64, this affects the the_ultimate_question function in mod tests; patching it causes the next function defined, default, to crash.

What triple is your machine?

Darn rust and allowing functions to be so small. 🗡

nightly-x86_64-unknown-linux-gnu
rustc 1.32.0-nightly (25a42b2ce 2018-11-07)

I was getting a SIGSEGV, but now the outcome is test_patch spuriously failing.
Edit: I think the behavior switched when I rebased

The smallest possible function is RET (1 byte), so fixing this in general will be fun. INT 3 (0xCC) would work. The interrupt handler could consult a static hashmap from IP to destination.

With INT 3 wouldn't we interfere with debuggers?


We could reduce the assembled size to 2-3 bytes easily with relative jumps.

pub fn other_question() -> u8 {
    10
}

Is 4 bytes on 32-bit and 64-bit systems.

pub fn nothing() { }

Is 1 byte, true but I feel that we could test for a ret and if we find one at the beginning we just panic! early with "target function too small to patch".

Yeah, relative jumps are simpler to implement and don't mess with debuggers, and panicking if the jump can't be made smaller than the target function is probably a reasonable limitation for mocking-type use cases

Self-debugging code would be so cool tho :)

Reduced assembled instruction size. I get spurious failures unless run with --test-threads=1 as patch is definitely not thread-safe.