PDA

View Full Version : Not quite hooking...


FrankRizzo
06-18-2008, 11:55 PM
I'm messing around with the DebugAPI, and would like to be able to find where in a "slave" program it calls various windows APIs.

I understand that I can do a GetProcAddress function to find the addresses of the functions that I want to find, but how do I locate them within the slave?

At first I thought it might be through parsing the IAT, but that would just tell me that they DO in fact call them.

Is there a way other than to brute force search the whole image for references?

dELTA
06-19-2008, 04:00 AM
The cross-reference feature of IDA Pro will do this for you, as long as the imported API is statically imported (i.e. is in the IAT).

To complete it with also the dynamically imported APIs, you must dynamically hook all API functions in all loaded modules, and then take a look at the return address on the call stack for each call to these functions.

There are many readily available API call loggers though, see the following CRCETL category for more info about these:

http://www.woodmann.com/collaborative/tools/index.php/Category:API_Monitoring_Tools

FrankRizzo
06-19-2008, 09:10 AM
Doh! I left out that I want to do this at RUNTIME. Not from a static listing.

Arcane
06-19-2008, 12:54 PM
well its fairly simpel..the only thing you really can do is search the .txt for FF15 calls ( Call DWORD PTR[IAT REFERENCE] ) ..thou the risk of false positives is present..thats the easiest way ...next you can improve the results by using a Dissassembler library..

hope i understand your request correctly

dELTA
06-19-2008, 02:27 PM
My tips above still apply, except the IDA Pro one then, and they are most likely the most reliable method to do it.

1.
Enumerate all loaded modules in the process space of the target process, and hook all the exports of these.

2.
Set a special hook on the LoadLibrary function. As soon as it is called on a new module, hook all the exports of this new module before you return control to the target program.

3.
In the hook function of each export, log the return address on the stack (together with the name of the export of course).

You will then have a complete log list of all called imports of the program, and all the addresses at which they are called.

And again, many readily available API loggers will do this, or similar things, for you.

FrankRizzo
06-19-2008, 05:29 PM
OK, enough with me being generic. Let me explain what I'm trying to do.

Primary note, this app is for personal use only, so I won't be releasing it.

I do "requests" for friends from time to time, and 1 friend has me "fix" the same program for him over and over. (Everytime a new release comes out, he gets it, and sends it to me).

Over the years, yes, I'm serious, there has been 1 constant in these programs. A call to WriteProcessMemory. There is only 1 of them, but they move around when the code is changed.

This is a straight call from the code, not a GetProcAddress kind of situation. What I want to do, is to figure out how to, in my "fixer" program, find the call to WriteProcessMemory, and be able to modify some bytes around it in order to fix this app. I want to make an app for him that he can run on every release of this app from now until they change things too much for this to work.

Does that make more sense? I was trying to be generic above, but I guess I was TOO generic.

dELTA
06-19-2008, 06:00 PM
I don't quite understand why you need to do it during runtime, since you seem to have the static application? If it is packed, you will of course need to dump it first to be able to patch it at all, and in that case you can as well perform static analysis on the unpacked executable.

Are you trying to create a loader, or do you just want the info for a static patch?

Anyway, given that you still want to do it during runtime, and that you can somehow get the program to break at OEP (or rather, any point in time where no code important to you has still executed, while the imported modules of the executable have still been loaded in memory and the IAT has been populated), do the following:

1.
Resolve the address to the WriteProcessMemory API inside the memory space of the application (either by injecting a GetProcAddress call, or by manually parsing the IAT of the process).

2.
Hook this function by patching/redirecting the first bytes of it in memory.

3.
Log the return address of the call(s) to it from your hook function, from the stack.

4.
For extra credit, let your hook function analyze the bytes around the call location on the fly, and output the information necessary to patch the static executable to work as you want.

Done.

FrankRizzo
06-25-2008, 11:49 PM
I've gotten A TON of stuff working now. Got the API Hooking working, got the "backtrace" from the stack working, and I even patch the bytes in memory, which lets it act as a loader for many different versions of his app.

Thanks Guys!


But, now that the API Hooking genie is out of the bottle, I've starting tinkering with using it for other things, which brings me to my question of the week:

How does one go about API Hooking in a packed program with a mangled IAT?

My first thought was that I might need to rebuild it in memory, and THEN hook what I want.

Keep in mind that I want to do this at RUNTIME without deadlisting the code, and using a dumper, IAT fixer, etc.

My first thought as to a way in, would be to monitor DLL loads, and the first load that happens after the code starts running, is from INSIDE, and that would be the time to launch the IAT fixer, and then the API Hooking.

So, that being the case, how would YOU do it?

dELTA
06-26-2008, 07:06 AM
I still re-suggest my initial suggestion , namely:

Quote:
1.
Enumerate all loaded modules in the process space of the target process, and hook all the exports of these.

2.
Set a special hook on the LoadLibrary function. As soon as it is called on a new module, hook all the exports of this new module before you return control to the target program.
The IAT is irrelevant (or at least unrealiable, due to the numerous ways to mess up or hide and IAT), I would instead recommend hooking the code directly inside the exported function code inside each module (which is also why I say "hook all the exports of this new module" instead of "hook all imported functions from each module"), i.e. by patching in your hook over their first instruction. This will require some analysis of this first instruction/instructions though, although in most cases it will be one out of a very few alternatives, so no full disassembler should be needed to cover most of them.

There are some packers (e.g. Asprotect) that even try to counter this kind of thing though (and the similar/related breakpointing of API calls), by emulating the first bunch of instructions of imported functions separately, and then skipping these instructions inside the imported module code, and jumping directly a bunch of bytes into it. Just keep this in mind if your hooks would seem to fail sometimes. To counter this, you could of course integrate a full disassembler inside your own code, which instead places your hook at the first conditional branch instruction inside the imported function. This in turn brings with it problems with exceptions and similar to solve though...

FrankRizzo
06-26-2008, 10:23 AM
Hooking the exports becomes more of a "system-wide hook" since you're modifying the code inside the DLL, (in memory). Right?

Admiral
06-26-2008, 12:43 PM
Wrong

Each process loads a local copy of every DLL it uses. This has been the case since the Windows 95 kernel was ditched in favour of NT. I suggest you use an existing solution to this common problem. Microsoft Detours is a good option. My home-grown equivalent would also do the trick (http://www.ring3circus.com/downloads/dll-injection-framework/). These both hook the functions at their entry-points, rather than the caller at the reference-point as you initially asked, but I gather that this constraint has fallen by the wayside.

FrankRizzo
06-26-2008, 07:54 PM
I don't mind being wrong! That's the way I learn.

I have "caller hooking" working as long as I can parse the IAT. Now that the IAT is destroyed in some packed programs, I'm looking for an alternate method. I worked out how to do it in my head today, and I'll give it a shot. If it should fail, I'll look at your framework, and Microsoft as a last resort, as I assume that their Detours is probably not the lightest weight solution available.

darawk
06-27-2008, 03:24 AM
This is my hooking library that performs a variety of different types of hooks:

- IAT hooking
- EAT hooking
- Debug register hooking
- Thread-safe jmp patch hooking using a length-disassembler engine and a code thunk that masks the problem of jumping back to the original function

http://download.yousendit.com/9B7148B859485D9E

Also, here's a library I wrote for dll injection by 'manually mapping' a PE file into the remote address space of a process. Instead of calling LoadLibrary or using SetWindowsHookEx (which also essentially calls LoadLibrary internally), this code parses the PE file itself, fixes up the relocs, maps the sections, and builds the import table. It also redirects APIs like GetModuleHandle and GetProcAddress so that manualmap'd modules are visible to each other, but are not visible to any other modules in the process:

http://download.yousendit.com/2B06DBBE621E3DDC

If you're not interested in using ManualMap for stability or other reasons, here's an article I wrote on the other three major methods of DLL injection, which incldues code examples of each:

http://www.edgeofnowhere.cc/viewtopic.php?t=308049

This is also a description of the impetus for writing the manualmap and CHook libraries and general musings on the problems of defeating game-hack detection systems:

http://www.rootkit.com/newsread.php?newsid=360

Another snippet of code you might be interested in is this KiFastSystemCall hook I wrote that hooks all user-mode APIs by replacing the SYSENTER MSR. This library isn't as flushed out, but it does work even on multi-processor systems and should be easy to extend into a fully functional library if you want to:

http://download.yousendit.com/FD4D3FEE6C467564

EDIT:

Quote:
Each process loads a local copy of every DLL it uses. This has been the case since the Windows 95 kernel was ditched in favour of NT.


That's not *entirely* true. It is effectively true, but until a modification is made, most dll's that are mapped into more than one process actually do point to the same pages in physical memory. As soon as a page is modified in one process though, it's copied out and then that process will retain its own version of that specific page. This mechanism is referred to as 'copy-on-write', and is better explained here:

http://en.wikipedia.org/wiki/Copy-on-write

dELTA
06-27-2008, 10:27 AM
Hey darawk, nice tools!

I added them all to the CRCETL:

http://www.woodmann.com/collaborative/tools/index.php/CHook

http://www.woodmann.com/collaborative/tools/index.php/ManualMap

http://www.woodmann.com/collaborative/tools/index.php/FastSystemCallHook


Feel free to improve their descriptions and other info if you want.

FrankRizzo
06-29-2008, 12:43 AM
Quote:
[Originally Posted by dELTA;75411]
There are some packers (e.g. Asprotect) that even try to counter this kind of thing though (and the similar/related breakpointing of API calls), by emulating the first bunch of instructions of imported functions separately, and then skipping these instructions inside the imported module code, and jumping directly a bunch of bytes into it.


The app that I was playing with was ASPR protected, and I got around it's defenses by using EAT Hooking. (The packed app was loading a DLL that it was making calls to, I hooked the function in the EAT, and redirected them to me, and I was golden!)

Also, FWIW, this DLL loaded itself into memory, and then the app checksummed it's "in memory image", and this checksum passes even with the EAT hook in place.

dELTA
06-29-2008, 06:00 AM
I'm glad it all worked out for you. And yes, EAT hooks are non-detected by memory integrity checks 99% of the time, because it will be too hard for applications to analyze arbitrary new versions of the code in all imported DLLs.

Oh, and Asprotect only emulates some APIs, not all (and only in some Asprotect versions and with some settings activated).

FrankRizzo
08-22-2008, 04:40 PM
I'm not sure if this is ME, or what, so here goes.

Latest app I'm messing with makes a call to an API in user32.dll, and I'd like to hook it. Sounds simple enough, but when I call my hooking function, it fails. Over and Over.

A little deeper digging has shown that the call comes not from the app itself, but from a DLL that it uses. I'm PRETTY sure it's one that gets loaded by windows at load-time, not a LoadLibrary one.

(What I believe is happening, is that the DLL calls the function in user32, NOT the main program, so when the main program's IAT is parsed, there is no call to the function, thus hooking fails).

So, that being the case, this is what I'm thinking of doing, as always, if there is a better/easier way, please point it out!

Using CreateProcess to load the app, and presumably all the DLLs into memory, use snapshot, and associated ModuleFirst/ModuleNext functions to FIND the info on the DLL, and try to patch IT'S IAT, instead of the IAT from the main program.

Thoughts? Opinions?

FrankRizzo
08-23-2008, 02:47 PM
Well, an update of sorts.

I loaded the app via CreateProcess, with it suspended, and did the snapshot, and Module32First ALWAYS tells me that there are no modules.

So, looking into my toolbox, I figured I would just hook the EAT, instead of the IAT. So, I whipped out this code:

Code:

FARPROC Address;
HMODULE Module;

Module = GetModuleHandle("user32.dll");
if(Module == NULL)
{
MessageBox(NULL, "GetModuleHandle Failed", "Sucks", MB_OK);
return FALSE;
}

Address = GetProcAddress(Module, "GetLastInputInfo");
if(Address == NULL)
{
MessageBox(NULL, "GetProcAddress Failed", "Sucks", MB_OK);
return FALSE;
}

if(HookEat(Address, (FARPROC)&EAT_GetLastInputInfo) != true)
{
MessageBox(NULL, "Injection Failed", "Sucks", MB_OK);
return FALSE;
}


Everything passes, but my function "EAT_GetLastInputInfo" never gets called.

Any ?

FrankRizzo
08-24-2008, 10:27 PM
Still fighting this bastard. I invite anyone with sufficient hooking skills to give this a shot.

Make an app that is linked with a DLL. Inside that DLL call an API from the system, say, GetLastInputInfo from user32.dll.

Now, try to hook that API, and always return a constant value.

Thus far "This > me".

blabberer
08-25-2008, 05:05 PM
Quote:

Make an app that is linked with a DLL


you mean like this

Code:

.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
includelib frizzo.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

FrizzBox PROTO

.code
start:
invoke FrizzBox
invoke ExitProcess,NULL
end start


Quote:

Inside that DLL call an API from the system, say, GetLastInputInfo from user32.dll.


you mean like this

Code:

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib


LASTINPUTINFO STRUCT
cbSize DWORD ?
dwTime DWORD ?
LASTINPUTINFO ENDS
PLASTINPUTINFO typedef PTR LASTINPUTINFO


.data
deb_det db "calling FrankRizzo hello hello",0
caption db "hooktesting",0
format db "LastInput Was At %x",0

.data?

plii LASTINPUTINFO <>
string db 100 dup (?)

.code

DllEntry proc hInstance:HINSTANCE, reasonWORD, reserved1WORD
.if reason==DLL_PROCESS_ATTACH
call FrizzBox
mov plii.cbSize,sizeof(LASTINPUTINFO)
invoke GetLastInputInfo,addr plii
invoke wsprintf,addr string,addr format,plii.dwTime
invoke MessageBoxA,NULL,addr string,addr caption,NULL
.elseif reason==DLL_PROCESS_DETACH
call FrizzBox
mov plii.cbSize,sizeof(LASTINPUTINFO)
invoke GetLastInputInfo,addr plii
invoke wsprintf,addr string,addr format,plii.dwTime
invoke MessageBoxA,NULL,addr string,addr caption,NULL
.elseif reason==DLL_THREAD_ATTACH
call FrizzBox
mov plii.cbSize,sizeof(LASTINPUTINFO)
invoke GetLastInputInfo,addr plii
invoke wsprintf,addr string,addr format,plii.dwTime
invoke MessageBoxA,NULL,addr string,addr caption,NULL
.else
call FrizzBox
mov plii.cbSize,sizeof(LASTINPUTINFO)
invoke GetLastInputInfo,addr plii
invoke wsprintf,addr string,addr format,plii.dwTime
invoke MessageBoxA,NULL,addr string,addr caption,NULL
.endif
mov eax,TRUE
ret
DllEntry Endp

FrizzBox proc
invoke MessageBox ,NULL,offset deb_det,offset caption, NULL
ret
FrizzBox endp

End DllEntry



Quote:

Now, try to hook that API, and always return a constant value.


hook with what ? my hooker

and what or who should return constant value ? my hooker should return a constant value ? what constant are you expecting from hookers ?

whatever

i'd have been glad if i could have atleast understood the requirements

anyway i can suspend and find the resolved address in remote process module with code like below

Code:

#include
#include
#include

int main (void)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
MODULEENTRY32 mod32;
HANDLE prochand;
HANDLE hSnap;
BOOL modnext = TRUE;
CHAR getaddlast[16] = {0};

printf("creating and hooking getlast\n");
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );

if( !CreateProcess( NULL,"frizzoxe.exe",NULL,NULL,FALSE,0,NULL,NULL,&si,&pi ) )
{
printf( "CreateProcess failed (%d)\n", GetLastError() );
return 0;
}
prochand = pi.hProcess;
WaitForInputIdle(pi.hProcess,INFINITE);
Sleep(3000);
SuspendThread(pi.hThread);
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pi.dwProcessId);
if((LONG)hSnap == -1)
{
printf( "CreateToolhelp32SnapShot Failed (%d)\n", GetLastError() );
return 0;
}
ZeroMemory(&mod32,sizeof(mod32));
mod32.dwSize = sizeof(mod32);
if(!Module32First(hSnap,&mod32))
{
printf( "Module32FirstFailed (%d)\n", GetLastError() );
return 0;
}
printf("first module is %s\n",mod32.szModule);
while(modnext==TRUE)
{
ZeroMemory(&mod32,sizeof(mod32));
mod32.dwSize = sizeof(mod32);
modnext = Module32Next(hSnap,&mod32);
printf("next module is %s\n",mod32.szModule);
if((strcmp(mod32.szModule,"frizzo.dll")) == 0)
{
printf("th32ModuleId = %x\n",mod32.th32ModuleID);
printf("th32ProcessId = %x\n",mod32.th32ProcessID);
printf("gibl = %x\n",mod32.GlblcntUsage);
printf("procCUNT = %x\n",mod32.ProccntUsage);
printf("modbase = %x\n",mod32.modBaseAddr);
printf("modsize = %x\n",mod32.modBaseSize);
printf("hMod = %x\n",mod32.hModule);
printf("szmod = %s\n",mod32.szModule);
printf("szExe = %s\n",mod32.szExePath);
ReadProcessMemory(prochand,mod32.modBaseAddr+0x2000,getaddlast,4,NULL);
printf("GetLastInputInfo has been Resolved to %x in frizzo.dll\n",*(DWORD *)getaddlast);
}
}
printf("did a round robin of all modules in remote process\n");
ResumeThread(pi.hThread);
CloseHandle(hSnap);
CloseHandle(prochand);
return 1;
}


and output is like

Code:

F:\frizzo>loadandhookgetlast.exe
creating and hooking getlast
first module is frizzoxe.exe
next module is ntdll.dll
next module is kernel32.dll
next module is frizzo.dll
th32ModuleId = 1
th32ProcessId = 0
gibl = ffff
procCUNT = ffff
modbase = 10000000
modsize = 5000
hMod = 10000000
szmod = frizzo.dll
szExe = F:\frizzo\frizzo.dll
GetLastInputInfo has been Resolved to 77d49519 in frizzo.dll
next module is user32.dll
next module is GDI32.dll
next module is uxtheme.dll
next module is msvcrt.dll
next module is ADVAPI32.dll
next module is RPCRT4.dll
next module is RPCRT4.dll
did a round robin of all modules in remote process

F:\frizzo>


and attaching the whole baggage here just for no reason

FrankRizzo
08-25-2008, 08:24 PM
LMAO blabberer!

OK, I'm trying to do either an IAT hook, or an EAT hook on GetLastInputInfo, which is called from the DLL.

This hook will direct calls to MY routine, which returns a constant value to the caller. (It's value is actually acquired by calling GetTickCount(). In this particular case, an inactivity timeout is calculated by getting the current tick count, and subtracting the tick count of the last input to give them an idle time.) I'm trying to circumvent this timeout without stuffing a mouse-click, or key-press in the input buffer, as that should also stop the screensavers from kicking in.

dELTA
09-15-2008, 03:48 PM
Any luck yet Frank? (sorry for the late reply, still behind in posts after my August vacation...)

I suspect that your EAT hook is performed too late. Remember that the EAT is only used once, at the point the function is imported. It will then be stored locally in the module that imports it (in its IAT in the case of static imports, and in any arbitrary internal program variable in the case of dynamic imports).

You should try the next "hooking level" (direct code patching hooks) if you can't seem to get in with your EAT hooks in time for the moment of import (which might actually be a little challenge in the case of statically imported functions).

See what I mean?

FrankRizzo
09-15-2008, 09:58 PM
Not really dELTA, never done any direct code patching hooks. I'll look into that if I have to go back and work on that project again. (I was trying to manipulate a target without changing ANY bytes inside it. I finally got tired of farking with it, and just patched it). I always knew that was an option, I was just trying to be slick.

FrankRizzo
09-16-2008, 08:43 PM
Don't let my post stop anyone from testing this on their own!

I'd like to know if it's possible.

aqrit
09-19-2008, 01:36 PM
WriteProcessMemory is just a wrapper for NtWriteVirtualMemory
so no matter how messed up the call to WriteProcessMemory
you can always just hook the IAT of kernel32.dll where it imports
NtWriteVirtualMemory

aqrit
09-19-2008, 02:43 PM
Quote:
your EAT hook is performed too late


CreateProcess with the CREATE_SUSPENDED flag

the process is suspended after the IAT is fixed up but before
any code is exec'd so no modules can be loaded dynamically yet.

install your hooks now...

attached is a bad example of this method.. 1934

dELTA
09-19-2008, 05:54 PM
Quote:
[Originally Posted by aqrit;77068]...so no modules can be loaded dynamically yet.
Yes, but all imports from statically imported libraries will be toast at this point, which are actually the most common ones.

And don't give up now Frank, direct code patching hooks are really not that hard, c'mon, let's beat this target now! And I'm not referring to patching the program's own code, but rather the first bytes of the code of the imported functions, inside the imported DLLs (and the patching will of course still take place in memory, by way of a primary hook of the LoadLibrary API, as described previously in this thread). The code at these locations will under most circumstanced contain static or at least predictable code, and thus this method will assure your goal!

aqrit
09-19-2008, 07:48 PM
Quote:
all imports from statically imported libraries will be toast at this point


All the Import Tables for all the modules at this point will have the ProcAddress
of functions that they are importing

we just have to search for that address then overwrite it


I changed my test app's code to dynamically and statically link with a dll
that dynamically and statically calls MessageBoxA. Then I changed the first line
in my hook_dll from GetModuleHandle(NULL) to GetModuleHandle("somedll.dll")

It work fine.

dELTA
09-20-2008, 06:01 AM
Yes, I was referring to EAT-hooking, which is a requirement to cover all later dynamic imports, which the IAT hooks won't do.

But yes, it should be practically possible to:


First break at the point you are describing.
Then patch all EATs (which will take care of all dynamic imports from already statically loaded modules, which could otherwise be bypassed even if you hook the GetProcAddress API, since this is elementary to emulate for the process, contrary to the LoadLibrary API).
Then patch all IATs in all modules (to take care of all already statically imported functions).
Then hook the LoadLibrary function to take care of all dynamic imports in later dynamically loaded modules.

This leaves us only with the possible hole of dynamic imports made in the DLL init functions of any of the statically imported DLLs (in any of the modules), since these will still be stored in arbitrary program variables inside the DLL code. The advantage of this is also that you avoid any messy direct code patching hooks, which is indeed good.