flat assembler
Message board for the users of flat assembler.
Index
> Windows > Simple JMP Hook. Goto page Previous 1, 2 |
Author |
|
Overflowz 17 Dec 2012, 11:38
I'm confused -.-
|
|||
17 Dec 2012, 11:38 |
|
f0dder 17 Dec 2012, 13:32
yoshimitsu wrote: you should probably just write a universal hook function which uses a length disassembler engine to securely save the instructions which need to get overwritten by the hook-jmp and save them to a different location and append a jmp back to the hooked function but behind the hook-jmp, creating a gate to call the original function without invoking the hook. typedef wrote: And one thing I didn't know about Win7 is that Registry APIs are now in kernel32.dll (Probably proxies as the real ones exist also in ADVAPI32.DLL ) _________________ - carpe noctem |
|||
17 Dec 2012, 13:32 |
|
l_inc 17 Dec 2012, 13:46
yoshimitsu
Quote:
That's good, you're reading the official documentation, but you should always be able to flexibly interpret it. Especially after you got a hint for that. If you look at the implementation of WriteProcessMemory, you'll see, that it first starts with modifying the permissions by means of ZwProtectVirtualMemory and only after that calls ZwWriteVirtualMemory. Thus in fact the function only fails, when it's unable to change the memory permissions (well, there are also other irrelevant in this context cases), but then calling VirtualProtect wouldn't help much either. And this behaviour holds at least since win2k. f0dder Quote: If you want to be on the safe side, you'll need to also add special handling for instructions with EIP-relative encoding. And also an AI-based code mutation engine, because the overwritten instructions can be referenced (e.g. as jump destination) by different code parts. |
|||
17 Dec 2012, 13:46 |
|
yoshimitsu 17 Dec 2012, 13:56
f0dder wrote:
Yeah, forgot to mention those. This is actually the reason I wrote the small disassembler engine I posted here in the first place. typedef wrote: And one thing I didn't know about Win7 is that Registry APIs are now in kernel32.dll (Probably proxies as the real ones exist also in ADVAPI32.DLL ) Just checked the imports and the exports: apparently, advapi32.dll contains proxies and the real functions do reside in kernel32.dll. l_inc wrote: That's good, you're reading the official documentation, but you should always be able to flexibly interpret it. Especially after you got a hint for that. If you look at the implementation of WriteProcessMemory, you'll see, that it first starts with modifying the permissions by means of ZwProtectVirtualMemory and only after that calls ZwWriteVirtualMemory. Thus in fact the function only fails, when it's unable to change the memory permissions (well, there are also other irrelevant in this context cases), but then calling VirtualProtect wouldn't help much either. And this behaviour holds at least since win2k. ah, ok. Didn't look into the implementation as I thought with accessible the current access rights are meant. Last edited by yoshimitsu on 17 Dec 2012, 15:56; edited 2 times in total |
|||
17 Dec 2012, 13:56 |
|
f0dder 17 Dec 2012, 14:19
l_inc wrote:
_________________ - carpe noctem |
|||
17 Dec 2012, 14:19 |
|
l_inc 17 Dec 2012, 14:53
f0dder
Well... GetTickCount64 looks on my Vista like this: Code: CPU Disasm Address Hex dump Command Comments 76825E3F /$ /EB 00 JMP SHORT 76825E41 ; kernel32.GetTickCount64(guessed void) 76825E41 |> \8B0D 2403FE7F /MOV ECX,DWORD PTR DS:[7FFE0324] 76825E47 |. 8B15 2003FE7F |MOV EDX,DWORD PTR DS:[7FFE0320] 76825E4D |. A1 2803FE7F |MOV EAX,DWORD PTR DS:[7FFE0328] 76825E52 |. 3BC8 |CMP ECX,EAX 76825E54 |. 75 34 |JNE SHORT 76825E8A 76825E56 |. A1 0400FE7F |MOV EAX,DWORD PTR DS:[7FFE0004] 76825E5B |. F7E2 |MUL EDX 76825E5D |. 0FACD0 18 |SHRD EAX,EDX,18 76825E61 |. 56 |PUSH ESI 76825E62 |. 57 |PUSH EDI 76825E63 |. C1EA 18 |SHR EDX,18 76825E66 |. 8BF0 |MOV ESI,EAX 76825E68 |. A1 0400FE7F |MOV EAX,DWORD PTR DS:[7FFE0004] 76825E6D |. 8BFA |MOV EDI,EDX 76825E6F |. F7E1 |MUL ECX 76825E71 |. 6A 00 |PUSH 0 ; /Arg4 = 0 76825E73 |. 68 00010000 |PUSH 100 ; |Arg3 = 100 76825E78 |. 52 |PUSH EDX ; |Arg2 76825E79 |. 50 |PUSH EAX ; |Arg1 76825E7A |. E8 C9E60300 |CALL __allmul ; \ntdll._allmul 76825E7F |. 03F0 |ADD ESI,EAX 76825E81 |. 13FA |ADC EDI,EDX 76825E83 |. 8BD7 |MOV EDX,EDI 76825E85 |. 5F |POP EDI 76825E86 |. 8BC6 |MOV EAX,ESI 76825E88 |. 5E |POP ESI 76825E89 |. C3 |RETN 76825E8A |> F390 |PAUSE 76825E8C \.^ EB B3 \JMP SHORT 76825E41 You may notice, that the address 76825E41 is referenced from two places: 76825E3F and 76825E8C. Thus you'll have a problem if you carelessly overwrite the beginning of the function with a 5-bytes jump (btw., it's hotpatchable). Besides there are also cases, when the beginning of a function is referenced by a relocation, which would be relevant for offline patching. |
|||
17 Dec 2012, 14:53 |
|
f0dder 17 Dec 2012, 15:16
l_inc wrote: Well... GetTickCount64 looks on my Vista like this: So, the safest is probably to start out by seeing if the function can be hotpatched (including, perhaps, support for hooking already-hotpatched functions - that can probably be handled robustly?), reverting to doing "fingers-crossed-LDE-and-a-little-extra" patching if the function hasn't been prepared for hotpatch? Doing full code trace for API hooking isn't feasible, IMHO. _________________ - carpe noctem |
|||
17 Dec 2012, 15:16 |
|
yoshimitsu 17 Dec 2012, 15:56
Interesting snippet, l_inc.
Hotpatching GetTickCount64 doesn't provide its full convenience, though, as the first two bytes are not dummy code and thus have to be saved (and further its offset needs to be adjusted and you likely have to transform it to a jmp rel32). But as you already explained in this example it'd be way more convenient than using a 5-byte hook. |
|||
17 Dec 2012, 15:56 |
|
yoshimitsu 31 Dec 2012, 02:46
l_inc wrote: yoshimitsu Was just using WriteProcessMemory and recalled what you wrote, so I stepped through the function to see what's going on: It calls ZwProtectVirtualMemory and modifies the rights to PAGE_EXECUTE_READWRITE, indeed, but directly after that it checks whether the old protection value specified PAGE_NOACCESS or PAGE_READONLY. And if so, it changes them back to the original value and aborts. If not, it continues, even if there were no write-rights. So it's not always sufficient to call WriteProcessMemory only. |
|||
31 Dec 2012, 02:46 |
|
l_inc 31 Dec 2012, 03:16
yoshimitsu
Quote: And if so, it changes them back to the original value and aborts. You're right. But this does not fit into the scope of applicability limited by the following statement: l_inc wrote: there are also other irrelevant in this context cases The patched memory is executable and therefore PAGE_NOACCESS and PAGE_READONLY are not really relevant in this context. |
|||
31 Dec 2012, 03:16 |
|
revolution 31 Dec 2012, 04:24
yoshimitsu wrote: ... I stepped through the function to see what's going on: |
|||
31 Dec 2012, 04:24 |
|
Goto page Previous 1, 2 < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.