If you don't have these runtimes, the example will crash.
This little project of mine got influnce from many places. First was monoceres' example of hooking a local API call by modifying the IAT. Next was Ward's MemoryDll UDF, which formed a basis for my method. Lastly was a CodeProject article here -
which describes a hook engine, and from which I took the idea for the hook bridge, which allows a hooking function to call the real function without resetting the hook (makes this process thread-safe). I'm also using Distorm64 for the disassembly. The compiled distorm64 DLL is included and used via Ward's MemoryDll UDF.
What this archive contains -
Source for the testapp, example app, and DLL
The compiled DLL that is injected into the testapp to hook the MessageBoxW function
UDF source files include _WinApiHook (main UDF), and support files _Distorm, _Distorm_src (the DLL), _MemoryDll (from Ward)
In order to do remote hooking, a DLL must* be used. This method uses RtlCreateUserThread() to cause the remote process to call LoadLibraryA to load the remote DLL. Similarly, it can be made to call FreeLibrary, or any function in your injected DLL. This method can be used to retrieve a remote process's commandline, for example.
I hope the included sample DLL can show the functions needed and how to use them. 2 functions are requred for each API - 1 to do the actual hooking, and 1 to retrieve the Bridge address. This function must be called manually before setting the hook to provide the remote process with the address of the Bridge. Well, the 2nd function and manual call are only required if you want your hooking function to be able to call the original function.
* I said must above, but that's not 100% true. There is a way to do it without an external DLL using WriteProcessMemory, but it sill requires the binary data of compiled code, and the code must adhere to specific guidelines -
(among others, HERE under "Additional caveats")
- code must not use C/C++ runtimes
- code must not call other functions, unless they are also injected (those functions must adhere to the same guidelines)
This makes it pretty hard to do anything useful.
Update 1: 2009/01/06
- fixed small error in example
- added note about installing the VC++ 2008 SP1 Redistributable
Update 2: 2009/01/22
- fixed error in _HookApi_Get() trying to FreeLibrary the wrong address
- added function to find the base address of a module in a process (incorporated in main functions)
- _InjectDll and _FreeRemoteDll now search the remote process for the base address of kernel32.dll, instead of assuming the base address is constant in all processes
- removed compiled apps from archive to reduce its size
- _HookApi_Get creates hook backup by reading remote process memory, instead of assuming local code is identical
Update 3: 2009/09/25
- fixed virtual memory release errors: previously used _MemVirtualFree() with the $MEM_DECOMMIT flag instead of the correct $MEM_RELEASE flag
- changed inject/free functions to use RtlCreateUserThread() (original CreateRemoteThread option is still there, only commented out)
- minor changes to _MemoryDll UDF: now it allocates memory using _MemVirtualAlloc() with the $PAGE_EXECUTE_READWRITE flag to avoid any possible problems with DEP
Update 4: 2009/09/28
- added _GetPrivilege_SEDEBUG.au3 to zip file
Update 5: 2009/10/04
- updated injection functions to work on XP: it will use CreateRemoteThread() on XP and RtlCreateUserThread() on Vista+
Update 6: 2009/10/06
- new option in _InjectDll() and _FreeRemoteDll() to skip remotely locating the base address of 'kernel32.dll' - THIS IS DANGEROUS, USE AT YOUR OWN RISK!!!
- switched to use the CreateToolhelp32 API to enumerate remote modules (the PSAPI version is still included)
- much better error detection and return values in all UDFs
Update 7: 2009/10/06
- workaround for AutoIt < 22.214.171.124 bug
Edited by wraithdu, 06 October 2009 - 10:04 PM.