Hello everybody,
First: I will release this only when it's completely ready
I happily present to you: A new hooking method!!!
If the good old memory, IAT, and inline hooks(detours) won't do it for you anymore, I've got some new stuff for you to try!
I'm unsure if this has already done before, but I'm sure that it'll be the first time this is shared on this site.
What does it do?
It's very easy, I made an hook function to change all calls to a certain function in a range of addresses to your hooked function. For example if you wanted to relay all calls residing in the memory range 0x10000-x0FFFFF to your own function, it means you can!
How does it do what it does?
This is also fairly simple although it cost me an headache to write and think it all out. I think it's clearest if I show a piece of pseudo code:
The function will look for calls inside the memory range you've given, if it finds a call it compares the destination of that call to the address you've given. If the call matches the api writes a jump/call combination to your own function wherever it is in memory. Then it continues searchingCode:/* Where AddressToStart is the address to start looking for calls AddMemoryAddressToStartAddress() a function to get to the destination address of the call CompareAddresses() a function to see if the function you want to hook and the call address are the same WriteJumpAndPatchCode() a function to write the patch to your own code, over writing the previous call to a jmp which inturn jumps to the your hook */ for ( in i = 0; AddressToStart[i] != 0x0E8; i++){ } AddMemoryAddressToStartAddress(i); CompareAddresses(AddressToCompareTo, i); NotMatch(StartOver); Match(WriteJumpAndPatchCode); StartOver;
On success the return value is the amount of calls patched
On failure the return value is 0
Technicalities:
Due to a the fact that the processor has the liberty to walk the opcode scheme and calculate calls & jumps flawlessly, and I can't, the call/jump combination is always a little off (1 to 8 bytes off actually)
That's why one needs to append nops & the windows preamble (saving the stack) manually, because the real preamble is probably not going to be executed
This is hook function is only local for now, but since Call/jumps can be calculated as well intermodule calls will be added later on, hence the reason why this is a Prerelease
-SCHiM
Tell me what you guys think, is it good? Has it already been done before? Any suggestions/questions?
Last edited by .::SCHiM::.; 01-22-2011 at 11:12 AM.
I'm SCHiM
Morals derive from the instinct to survive. Moral behavior is survival behavior above the individual level.
Polymorphic engine
Interprocess callback class
SIN
Infinite-precision arithmetic
Hooking dynamic linkage
(sloppy)Kernel mode Disassembler!!!
Semi debugger
I don't see what this would accomplish. What would be the point of using this instead of the inline hooks you mention? If you are trying to avoid detection, the whole module is usually scanned anyway.
Then inline would also be detected wouldn't it? But because this is something they haven't seen before maybe it slips undetected. And this is not as much a point of avoiding detection but more of an just being an alternative.
A more easy alternative since I can easily turn this into an nice lib that you can include and call without needing to know more than how to use variables while inlinehooks are harder to do
I'm SCHiM
Morals derive from the instinct to survive. Moral behavior is survival behavior above the individual level.
Polymorphic engine
Interprocess callback class
SIN
Infinite-precision arithmetic
Hooking dynamic linkage
(sloppy)Kernel mode Disassembler!!!
Semi debugger
I don't wanna be the jerk this time someone else tell him, but nice job SCHiM. It's good to see people trying to create something new rather then the same-ole, same-ole.
"Every gun that is made, every warship launched, every rocket fired signifies, in the final sense, a theft from those who hunger and are not fed, those who are cold and are not clothed. This world in arms is not spending money alone. It is spending the sweat of its laborers, the genius of its scientists, the hopes of its children. The cost of one modern heavy bomber is this: a modern brick school in more than 30 cities. It is two electric power plants, each serving a town of 60,000 population. It is two fine, fully equipped hospitals. It is some fifty miles of concrete pavement. We pay for a single fighter plane with a half million bushels of wheat. We pay for a single destroyer with new homes that could have housed more than 8,000 people. This is, I repeat, the best way of life to be found on the road the world has been taking. This is not a way of life at all, in any true sense. Under the cloud of threatening war, it is humanity hanging from a cross of iron."- Dwight D. Eisenhower
I'm SCHiM
Morals derive from the instinct to survive. Moral behavior is survival behavior above the individual level.
Polymorphic engine
Interprocess callback class
SIN
Infinite-precision arithmetic
Hooking dynamic linkage
(sloppy)Kernel mode Disassembler!!!
Semi debugger
Meh it's just that that's the standard way a hook is done. The function is patched with a jump to the alternate code and then that code jumps back. Perhaps your actually patching the call rather then the first bytes of the functions, in which case you should know your only patching one call to the function and not hooking the function itself. But you said hooking the function, so I assumed it was the later. If so this is the standard procedure by which all function are hooked, for SetWindowsHook() to Detours.lib.
Hmmm... rereading your function it seems like it does the former. Never mind then that is unique, cut me some slack I was tired when I saw this. You confused me when you started talking about preamble or stack frame since that would not be cut if you only patched the call, maybe just a few bytes after the call.
But one thing you should know not all calls to functions are hardcoded. you may just as easily get something like this:
In which case the code would fail. Just something to keep in mind. Might also want to patch jmps to code as well. In any case Goodjob. Turned out I spoke to soon.Code:call EBX
Also I don't get why your jmps would be 1 to 8 bytes off of the actual call, they should be exact. If not I would like to see how your calculating this.
"Every gun that is made, every warship launched, every rocket fired signifies, in the final sense, a theft from those who hunger and are not fed, those who are cold and are not clothed. This world in arms is not spending money alone. It is spending the sweat of its laborers, the genius of its scientists, the hopes of its children. The cost of one modern heavy bomber is this: a modern brick school in more than 30 cities. It is two electric power plants, each serving a town of 60,000 population. It is two fine, fully equipped hospitals. It is some fifty miles of concrete pavement. We pay for a single fighter plane with a half million bushels of wheat. We pay for a single destroyer with new homes that could have housed more than 8,000 people. This is, I repeat, the best way of life to be found on the road the world has been taking. This is not a way of life at all, in any true sense. Under the cloud of threatening war, it is humanity hanging from a cross of iron."- Dwight D. Eisenhower
Ok good,
For other's information: I really patch the calls, not the function itself, so if you have a call:
I really change the number of instructions to moveCode:E8 01000000
Code:E8 10000000But patching all calls in the image would hook the function right?Perhaps your actually patching the call rather then the first bytes of the functions, in which case you should know your only patching one call to the function and not hooking the function itself
I don't know why it's off, I assume it is because the processor & call operations in general only change the EIP. And while the processor can check how long the last instruction was I cannot, so that's why the call/jump can be a little offYou confused me when you started talking about preamble or stack frame since that would not be cut if you only patched the call, maybe just a few bytes after the call.
I would like to test it on D3D sometimes, but I don't know enough about it's functions and workings to make a reliable test, care to help?
-SCHiM
I'm SCHiM
Morals derive from the instinct to survive. Moral behavior is survival behavior above the individual level.
Polymorphic engine
Interprocess callback class
SIN
Infinite-precision arithmetic
Hooking dynamic linkage
(sloppy)Kernel mode Disassembler!!!
Semi debugger
so instead of detouring with the jmp instruction youre detouring with the call instruction?
I'm SCHiM
Morals derive from the instinct to survive. Moral behavior is survival behavior above the individual level.
Polymorphic engine
Interprocess callback class
SIN
Infinite-precision arithmetic
Hooking dynamic linkage
(sloppy)Kernel mode Disassembler!!!
Semi debugger
when i said detour i meant the literal meaning, you're changing the call instruction to call your own function instead of the original. in your function you're probably going to call the original function so that you can return without crashing.
so lets see.
original: call -> original -> return
your modified version: call -> your function -> original -> return
when you call a function the return address is set in the stack to be the next instruction. They reasons your describing aren't making since. Can I see just specifically the code you used to write over the call, because I think that's where the problem lies.
EDIT:
Here's an example of a call. (Taken from Olly)
As you can see at address 0x00433222 the program calls the function at address 0043334F. A call is essentially a jmp where the return address, which is the location of the next opcode is pushed on the stack.Code:00433222 |. E8 28010000 CALL dumpRedi.0043334F
Here I stepped into the call and you can see the address pushed
The call took up 5 bytes so notice that the return address is 0x00433222 + 5.Code:0012FF00 00433227 RETURN to dumpRedi.<ModuleEntryPoint>+6F from dumpRedi.0043334F
Also noticed the opcodes that the call consists of (I bolded them)
The call is a long jump which mean it jumps a certain distance. The distance is the last DWORD, which is written in reverse byte order or (little Endian)converted to the normal way we represent numbers (big-Endian), biggest number first we get.... 0x00000128 or 128 bytes. So I did the math with a hex calculator and found that the calling address 0x00433222 + 0x128 = 0x0043334A NOT 0x0043334F (our destination)!Code:E8 28010000
What this means is the instruction CALL automatically adds 5 bytes to the distance to jump. This could be so that call does not land within itself, but whatever the reason you should make sure you add the distance (0x128 in this case) + 5 (bytes) whenever you calculate function locations using CALL!
Last edited by why06; 01-23-2011 at 09:45 PM.
"Every gun that is made, every warship launched, every rocket fired signifies, in the final sense, a theft from those who hunger and are not fed, those who are cold and are not clothed. This world in arms is not spending money alone. It is spending the sweat of its laborers, the genius of its scientists, the hopes of its children. The cost of one modern heavy bomber is this: a modern brick school in more than 30 cities. It is two electric power plants, each serving a town of 60,000 population. It is two fine, fully equipped hospitals. It is some fifty miles of concrete pavement. We pay for a single fighter plane with a half million bushels of wheat. We pay for a single destroyer with new homes that could have housed more than 8,000 people. This is, I repeat, the best way of life to be found on the road the world has been taking. This is not a way of life at all, in any true sense. Under the cloud of threatening war, it is humanity hanging from a cross of iron."- Dwight D. Eisenhower
So you want to look for every call to a certain function and patch the call so that it goes to your own function?
I can tell why this won't work at all. If you come across a call where it's operand is a register, the only way of finding out which address it's calling to is by breaking at that call and checking the contents of the register.
So everytime you see this:
You're going to have to break, check what ebx is, decide whether or not you want to patch, and move on.Code:mov ebx,address call ebx
Disregarding everything I've just said, you can always manually find the address of the call you need to hook and use MS detours to detour that single instruction to your own function ( this is how most CA hacks were undetected for a while ).
So yeah, good luck with all that.
P.S: This is not new.
Thanks why06!
I thought calls would only changed the EIP, it seems I was wrong. Btw the call calculation & call verification:
Code:push eax mov al, byte ptr[ebx+esi] inc esi cmp al, 0E8h je @1 xor eax, eax add eax, ebx add eax, esi cmp eax, edx jne BeforeEaxReturn pop eax ret @1: ;address receive routine mov eax, dword ptr[ebx+esi] push eax push esi add esi, ebx add esi, eax mov eax, esi add eax, 5d pop esi push ecx @2: sub ecx, eax cmp ecx, 9 ja BeforeSecondEaxReturn ; it's not the correct function that we want to patch
So I must add 5 to the address to call to...
(did I mention it's written in assembler?)
Did you know that when you call a function like that, the opcode changes?mov ebx,address
call ebx
I can easily find out if the call made will use a register or an imminent operand as a value. In case of the register, I could trace back mov/add/sub instructions with that particular register (second operand denotes what register to check for) and patch the function. It's possible, I just haven't done it yet
Last edited by .::SCHiM::.; 01-24-2011 at 12:16 AM.
I'm SCHiM
Morals derive from the instinct to survive. Moral behavior is survival behavior above the individual level.
Polymorphic engine
Interprocess callback class
SIN
Infinite-precision arithmetic
Hooking dynamic linkage
(sloppy)Kernel mode Disassembler!!!
Semi debugger
I don't think that's right, but it's hard for me to tell since you let the beginning out. Can you label the important mov and compare instructions and let me know what ebx starts off as?
"Every gun that is made, every warship launched, every rocket fired signifies, in the final sense, a theft from those who hunger and are not fed, those who are cold and are not clothed. This world in arms is not spending money alone. It is spending the sweat of its laborers, the genius of its scientists, the hopes of its children. The cost of one modern heavy bomber is this: a modern brick school in more than 30 cities. It is two electric power plants, each serving a town of 60,000 population. It is two fine, fully equipped hospitals. It is some fifty miles of concrete pavement. We pay for a single fighter plane with a half million bushels of wheat. We pay for a single destroyer with new homes that could have housed more than 8,000 people. This is, I repeat, the best way of life to be found on the road the world has been taking. This is not a way of life at all, in any true sense. Under the cloud of threatening war, it is humanity hanging from a cross of iron."- Dwight D. Eisenhower
I'm SCHiM
Morals derive from the instinct to survive. Moral behavior is survival behavior above the individual level.
Polymorphic engine
Interprocess callback class
SIN
Infinite-precision arithmetic
Hooking dynamic linkage
(sloppy)Kernel mode Disassembler!!!
Semi debugger