subhook
subhook copied to clipboard
8 bit relative jump tripping up my use case (instruction 0x79 0x07)
2 byte instruction "jns 0x9" (bytes "0x79 0x07") (jump forward 7 bytes from updated IP) - using 8 bit offset), trips me up.
The function I am trying to subhook_make_trampoline for is as follows:
int fact(int n) {
if (n < 0) return 0;
if (n <= 1) return 1;
int i, ans = 1;
for (i = 2; i <= n; i++) {
ans *= i;
}
return ans;
}
compiled w/ gcc 9.3 with -ggdb -mmanual-endbr I get:
(gdb) di fact
Dump of assembler code for function fact:
0x00005555555551e9 <+0>: push %rbp
0x00005555555551ea <+1>: mov %rsp,%rbp
0x00005555555551ed <+4>: mov %edi,-0x14(%rbp)
0x00005555555551f0 <+7>: cmpl $0x0,-0x14(%rbp)
0x00005555555551f4 <+11>: jns 0x5555555551fd <fact+20> # <<< ISSUE IS HERE
0x00005555555551f6 <+13>: mov $0x0,%eax
0x00005555555551fb <+18>: jmp 0x555555555233 <fact+74>
0x00005555555551fd <+20>: cmpl $0x1,-0x14(%rbp)
0x0000555555555201 <+24>: jg 0x55555555520a <fact+33>
0x0000555555555203 <+26>: mov $0x1,%eax
0x0000555555555208 <+31>: jmp 0x555555555233 <fact+74>
0x000055555555520a <+33>: movl $0x1,-0x4(%rbp)
0x0000555555555211 <+40>: movl $0x2,-0x8(%rbp)
0x0000555555555218 <+47>: jmp 0x555555555228 <fact+63>
0x000055555555521a <+49>: mov -0x4(%rbp),%eax
0x000055555555521d <+52>: imul -0x8(%rbp),%eax
0x0000555555555221 <+56>: mov %eax,-0x4(%rbp)
0x0000555555555224 <+59>: addl $0x1,-0x8(%rbp)
0x0000555555555228 <+63>: mov -0x8(%rbp),%eax
0x000055555555522b <+66>: cmp -0x14(%rbp),%eax
0x000055555555522e <+69>: jle 0x55555555521a <fact+49>
0x0000555555555230 <+71>: mov -0x4(%rbp),%eax
0x0000555555555233 <+74>: pop %rbp
0x0000555555555234 <+75>: retq
Instruction at fact+11 is "jns 0x09" or in raw bytes "0x79 0x07"
In subhook_x86.c it says:
* Note: We don't support short (8-bit) offsets at the moment, so the
* caller can assume the operand will be always 4 bytes.
What can I do to get around this limitation? It seems 2 byte relative jump instructions (meaning 8 bits of offset) would be used quite often in real world.