|
|
@@ -95,29 +95,14 @@ instruction lengths & offsets. |
|
|
|
|
|
|
|
|
|
|
|
0026 | 48 83 E0 01 | and rax,1 |
|
|
|
002A | 74 17 | je test_cases.0043 ----+ |
|
|
|
002C | 48 31 C0 | xor rax,rax | |
|
|
|
002F | 90 | nop | |
|
|
|
0030 | 90 | nop | |
|
|
|
0031 | 90 | nop | |
|
|
|
0032 | 90 | nop | |
|
|
|
0033 | 90 | nop | |
|
|
|
0034 | 90 | nop | |
|
|
|
0035 | 90 | nop | |
|
|
|
0036 | 90 | nop | |
|
|
|
0037 | 90 | nop | |
|
|
|
0038 | 90 | nop | |
|
|
|
0039 | 90 | nop | |
|
|
|
003A | 90 | nop | |
|
|
|
003B | 90 | nop | |
|
|
|
003C | 90 | nop | |
|
|
|
003D | 90 | nop | |
|
|
|
003E | 90 | nop | |
|
|
|
003F | 90 | nop | |
|
|
|
0040 | 90 | nop | |
|
|
|
0041 | 90 | nop | |
|
|
|
0042 | 90 | nop | |
|
|
|
0043 | C3 | ret <-----------------+ |
|
|
|
002A | 74 17 | je test_cases.0043 --+ |
|
|
|
002C | 48 31 C0 | xor rax,rax | |
|
|
|
002F | 90 | nop | |
|
|
|
0030 | 90 | nop | |
|
|
|
... | |
|
|
|
0041 | 90 | nop | |
|
|
|
0042 | 90 | nop | |
|
|
|
0043 | C3 | ret <----------------+ |
|
|
|
|
|
|
|
|
|
|
|
This function has a branch in the first 5 bytes. Hooking it detour-style isn't |
|
|
@@ -198,27 +183,46 @@ instructions that have been overwritten. Consider this: |
|
|
|
There's only 3 bytes that can be safely overwritten. Right after that is the |
|
|
|
destination of the jump backwards. This is a very simple (and kinda pointless) |
|
|
|
function so detecting that the loop might lead to problems shouldn't be a |
|
|
|
problem. Basically the same applies for the next example: |
|
|
|
|
|
|
|
public _tail_recursion |
|
|
|
_tail_recursion: |
|
|
|
test ecx, ecx |
|
|
|
je @is_0 |
|
|
|
mov eax, ecx |
|
|
|
dec ecx |
|
|
|
@loop: |
|
|
|
test ecx, ecx |
|
|
|
jz @tr_end |
|
|
|
problem. But consider what happens with MHook (and all the others): |
|
|
|
|
|
|
|
mul ecx |
|
|
|
dec ecx |
|
|
|
_loop original: |
|
|
|
|
|
|
|
jnz @loop |
|
|
|
jmp @tr_end |
|
|
|
@is_0: |
|
|
|
mov eax, 1 |
|
|
|
@tr_end: |
|
|
|
ret |
|
|
|
008C | 48 89 C8 | mov rax,rcx |
|
|
|
008F | 48 F7 E1 | mul rcx |
|
|
|
0092 | 90 | nop |
|
|
|
0093 | 90 | nop |
|
|
|
0094 | 90 | nop |
|
|
|
0095 | E2 F8 | loop test_cases.008F |
|
|
|
0097 | C3 | ret |
|
|
|
|
|
|
|
_loop hooked: |
|
|
|
|
|
|
|
008C | E9 0F 69 23 00 | jmp <MHook_Hooks::hookLoop> |
|
|
|
0091 | E1 90 | loope test_cases.0023 |
|
|
|
0093 | 90 | nop |
|
|
|
0094 | 90 | nop |
|
|
|
0095 | E2 F8 | loop test_cases.008F |
|
|
|
0097 | C3 | ret |
|
|
|
|
|
|
|
trampoline: |
|
|
|
|
|
|
|
00007FFF7CD200C0 | 48 89 C8 | mov rax,rcx |
|
|
|
00007FFF7CD200C3 | 48 F7 E1 | mul rcx |
|
|
|
00007FFF7CD200C6 | E9 C7 96 DC FF | jmp test_cases.0092 |
|
|
|
|
|
|
|
then executes: |
|
|
|
|
|
|
|
0092 | 90 | nop |
|
|
|
0093 | 90 | nop |
|
|
|
0094 | 90 | nop |
|
|
|
0095 | E2 F8 | loop test_cases.008F |
|
|
|
|
|
|
|
But that jumps back into the middle of the jump and thus executes: |
|
|
|
|
|
|
|
008F | 23 00 | and eax,dword ptr ds:[rax] |
|
|
|
0091 | E1 90 | loope test_cases.0023 |
|
|
|
|
|
|
|
Which isn't right and will crash horribly. |
|
|
|
|
|
|
|
(Preliminary) Results |
|
|
|
===================== |