Log in

View Full Version : Not quite hooking...


FrankRizzo
June 18th, 2008, 23:55
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
June 19th, 2008, 04:00
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/Category:API_Monitoring_Tools

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

Arcane
June 19th, 2008, 12:54
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
June 19th, 2008, 14:27
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
June 19th, 2008, 17:29
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
June 19th, 2008, 18:00
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
June 25th, 2008, 23:49
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
June 26th, 2008, 07:06
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
June 26th, 2008, 10:23
Hooking the exports becomes more of a "system-wide hook" since you're modifying the code inside the DLL, (in memory). Right?

Admiral
June 26th, 2008, 12:43
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
June 26th, 2008, 19:54
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
June 27th, 2008, 03:24
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
June 27th, 2008, 10:27
Hey darawk, nice tools!

I added them all to the CRCETL:

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

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

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


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

FrankRizzo
June 29th, 2008, 00:43
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
June 29th, 2008, 06:00
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
August 22nd, 2008, 16:40
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
August 23rd, 2008, 14:47
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
August 24th, 2008, 22:27
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
August 25th, 2008, 17:05
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 <stdio.h>
#include <windows.h>
#include <tlhelp32.h>

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
August 25th, 2008, 20:24
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
September 15th, 2008, 15:48
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
September 15th, 2008, 21:58
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
September 16th, 2008, 20:43
Don't let my post stop anyone from testing this on their own!

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

aqrit
September 19th, 2008, 13:36
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
September 19th, 2008, 14:43
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
September 19th, 2008, 17:54
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
September 19th, 2008, 19:48
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
September 20th, 2008, 06:01
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.

FrankRizzo
December 23rd, 2008, 23:50
As it turns out, I didn't actually NEED to catch, or patch anything. I was trying to get around GetLastInputInfo, and, as it turns out, a simple "GetCursorPos/SetCursorPos" resets the timer. And now it works.

dELTA
December 27th, 2008, 21:49
That's such a boring solution.

FrankRizzo
December 29th, 2008, 14:22
Quote:
[Originally Posted by dELTA;78383]That's such a boring solution.


TRUE! But since I was seemingly unable to properly define what it was that I needed help with, and was unable to work it out myself, I had to look for OTHER avenues, and this one just happened to be available to me.

It was amazing how much my source was cleaned up once I removed the 6 types of hooking that I had in it. And all their support functions, and whatnot.

dELTA
December 29th, 2008, 18:38
Hehe, it's completely right though, the path of the reverser is the one of least resistance, anything else is superfluous. For educational or entertainment purposes it could be comparatively boring sometimes though, as e.g. in this case.

FrankRizzo
December 29th, 2008, 18:42
Completely boring, I admit. I would have liked to have done it the other way, but it was not to be.

Much like flowing water, we must take the path of least resistance.

FrankRizzo
January 4th, 2009, 22:07
Well, I'm 99.99% of the way there. Here's the latest twist.

Did you know that if you Logout of windows all your cursor, and key routines fail, causing you to timeout? I certainly didn't until now!

Here's the deal, as long as I'm logged in, my "Timeout stopper" works just fine, but if the user logs out, the timeout timer starts running, and my code can't reset it.

Weird, huh?

Ideas?

dELTA
January 5th, 2009, 05:33
Quote:
[Originally Posted by FrankRizzo;78533]Ideas?
Don't log out of Windows while playing the game you're trying to cheat in?

FrankRizzo
January 5th, 2009, 10:41
Quote:
[Originally Posted by dELTA;78540]Don't log out of Windows while playing the game you're trying to cheat in?


He he he.

Believe it or not, it's not a game, I'm just raping an internet radio station.

FrankRizzo
November 13th, 2012, 23:24
Anyone care if I resurrect my own thread?

A long time ago, I mentioned circumventing ASPR via EAT hooking. Well, time marches on, and here I am again. Staring at a target packed with ASPR, the target calls a DLL which is also packed. This DLL calls WriteProcessMemory to update some bytes in the "slave app" that gets launched by the main app, which is a launcher.

So, main app "Launcher", and DLL used to do WriteProcessMemory, both protected with ASPR.
The launcher launches an app suspended, and dittles with it before releasing it to run.

I can't find my old EAT hooking code, so I grabbed CHook, and started from there. Since I ONLY need EAT hooking, I grabbed the function, and gutted all the unneeded stuff from it.

Now. In my app, I hook the EAT for WriteProcessMemory, and then execute the launcher, (which loads the DLL, which calls WriteProcessMemory).

My replacement function is never called.

Here's the code (Everything except for the #define that would give you the target name)

Code:
int _tmain(int argc, _TCHAR* argv[])
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE hProcess;
DWORD exitValue;

pfWriteProcessMemory = (pWriteProcessMemory) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll"), "WriteProcessMemory";
if(HookEAT(GetProcAddress(GetModuleHandle(TEXT("kernel32.dll"), "WriteProcessMemory", (FARPROC) &EAT_WriteProcessMemory) == FALSE)
{
error("Can't Hook";
return 0;
}

ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );

if(CreateProcess(filename, NULL, NULL, NULL, false, NULL, NULL, NULL, &si, &pi) == 0)
{
error("CreateProcess";
return 0;
}

hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, pi.dwProcessId);
if(hProcess == NULL)
{
error("OpenProcess";
return 0;
}

for(;
{
GetExitCodeProcess(hProcess, &exitValue);
if(exitValue != STILL_ACTIVE)
{
break;
}
else
{
Sleep(500);
}
}

return 0;
}


BOOL WINAPI EAT_WriteProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten)
{
// Maybe listening to Dub side of the moon isn't good while writing code. ;-)
MessageBox(NULL, "Money is power", "HA!", MB_OK);

return pfWriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten);
}



///////////////////////////////////////////////// Hooking code below here ////////////////////////////////////

// Matt Pietrek's function
IMAGE_SECTION_HEADER *GetEnclosingSectionHeader(u32 rva)
{
IMAGE_SECTION_HEADER *section = IMAGE_FIRST_SECTION(ntHd);
for (u32 i = 0; i < ntHd->FileHeader.NumberOfSections; i++, section++ )
{
// This 3 line idiocy is because Watcom's linker actually sets the
// Misc.VirtualSize field to 0. (!!! - Retards....!!!)
u32 size = section->Misc.VirtualSize;
if ( 0 == size )
size = section->SizeOfRawData;

// Is the RVA within this section?
if ( (rva >= section->VirtualAddress) &&
(rva < (section->VirtualAddress + size)))
return section;
}

return NULL;
}

unsigned long GetMappedSectionOffset(IMAGE_SECTION_HEADER *seHd)
{
IMAGE_SECTION_HEADER *section = IMAGE_FIRST_SECTION(ntHd);
u32 offset = MakeDelta(u32, section, dosHd);
for(u32 i = 0; i < ntHd->FileHeader.NumberOfSections; i++, section++)
{
if(section->Name == seHd->Name)
{
offset = MakeDelta(u32, section->VirtualAddress, section->PointerToRawData);
break;
}
}

return offset;
}

// This function is also Pietrek's, with a modification by me so that it can handle
// images that are mapped into memory.
void *GetPtrFromRVA(u32 rva, bool mapped)
{
IMAGE_SECTION_HEADER *pSectionHdr = GetEnclosingSectionHeader(rva);
s32 offset = 0;

if(mapped)
offset = GetMappedSectionOffset(pSectionHdr);
if (!pSectionHdr)
return 0;

s32 delta = (s32)(pSectionHdr->VirtualAddress-pSectionHdr->PointerToRawData);
return (void *) ( (u8 *)dosHd + rva - delta + offset);
}

bool HookEAT(FARPROC hookFrom, FARPROC hookTo)
{
u32 i;
HMODULE target;
u32 oldprot, oldprot2;

if(!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)hookFrom, &target))
{
return false;
}

dosHd = (IMAGE_DOS_HEADER *)target;
ntHd = MakePtr(IMAGE_NT_HEADERS *, target, dosHd->e_lfanew);
IMAGE_EXPORT_DIRECTORY *ied = (IMAGE_EXPORT_DIRECTORY *)GetPtrFromRVA(ntHd->OptionalHeader.DataDirectory[IMAGE_EXPORT].VirtualAddress, true);

FARPROC *funcs = (FARPROC *)GetPtrFromRVA(ied->AddressOfFunctions, true);

for(i = 0; i < ied->NumberOfFunctions; i++)
{
if(MakePtr(FARPROC, target, funcs[I]) == hookFrom)
{
break;
}
}

if(i >= ied->NumberOfFunctions)
{
return false;
}

VirtualProtect(&funcs[I], sizeof(u32), PAGE_READWRITE, (DWORD *)&oldprot);
funcs[I] = MakeDelta(FARPROC, hookTo, target);
VirtualProtect(&funcs[I], sizeof(u32), oldprot, (DWORD *)&oldprot2);

return true;
}




////////////////////////////////// Utility Functions below here ///////////////////////////////////

void error(LPSTR lpszFunction)
{
LPVOID lpMsgBuf;

if (!FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL ))
{
// Handle the error.
return;
}

MessageBox(NULL, (LPCTSTR)lpMsgBuf, lpszFunction, MB_OK);

// Free the buffer.
LocalFree( lpMsgBuf );
}


Anyone see anything obviously stupid that I'm doing?

aqrit
November 13th, 2012, 23:53
you seem to be hooking WPM in your own process instead of the target process

FrankRizzo
November 13th, 2012, 23:56
Quote:
[Originally Posted by aqrit;93679]you seem to be hooking WPM in your own process instead of the target process






:facepalm:

Works fine. Thanks aqrit. Clear as the nose on my face when you pointed it out, but the prior 2 hours had yielded nothing. You take 3 years off, and stuff like this happens. :-)