ASM: Write a jump command to a x86-64 binary file

2019-02-27 18:54发布

问题:

I'm debugging a Mac OSX 64bit app with GDB. I see that jumping over a chunk of code solves all my problems.

But:

How can I patch the executable file to implement the jump? I want the app to automatically jump to a defined point in the code without the debugger.

This is what I want to do:

at address 0x1000027a9 (given by the debugger) jump to address 0x100003b6e. I'm trying very hard to do it via HexEdit, but with no success. I read anywhere about jmp to absolute addresses opcodes (FF seems the right opcode, but it's a call, not a jump...) but nothing works. bad access, sigfault.

How can I do that?

Thank you.

回答1:

What you want is not a call, but a jmp, and you want a direct jmp. Direct jumps usually use an addressing relative to the next instruction's rip (see my answer to SO question: How encode a relative short jmp in x86).

So, you are at 0x1000027a9 and want to jump to 0x100003b6e.

0x100003b6e - 0x1000027a9 = 0x000013C5 = 5061d, so that definitively doesn't fit in a short jump (rel8 in Intel documentation), but you need jmp rel32. It would fit in rel16 too, but that's not supported in x86-64 (in 64-bit mode).

So, you want a jmp rel32. This is encoded relative to the next instruction after jmp, and as the length of the instruction is 5 bytes (E9 xx xx xx xx), rel32 will be 0x000013C0. As x86 is a little-endian architecture, it is encoded as E9 C0 13 00 00.

To confirm this, I assembled a small test executable with NASM and disassembled it with ndisasm (note I left first 0x10000000 bytes out, but as the jump is relative, it doesn't change anything in the encoding):

000027A8  90                nop
000027A9  E9C0130000        jmp dword 0x3b6e ; this is the instruction you need.
000027AE  90                nop