Introduction
If you want to hook some APIs in another process (e.g. Notepad) or if you
want to do system wide API hooking, you have to write a little DLL which
does all the hooking work. This DLL then needs to be loaded into the target
process(es) to do its work there. There's no official win32 API to inject a
DLL into another process. Often "SetWindowsHookEx" is misused for this
purpose, but doing so has several disadvantages: (1) It effects performance,
because you have to set up a real message hook, which then gets called all
the time, although you are not interested in the results at all. (2) It
works only for processes which handle messages, not all processes do so.
For example most console applications don't. (3) It works only if the target
process is not blocked, frozen or crashed. (4) The DLL might be loaded into
the target process later than expected. As a result you might miss some
important API calls. (5) It doesn't work for system processes. The package
madCodeHook offers various injection related functions, which work without
any of the mentioned disadvantages.
madCodeHook APIs for injecting a DLL into one specific process
The "CreateProcessEx" function basically works exactly like the well known
Windows API "CreateProcess". But it has one additional parameter that lets
you define a DLL which you want to have injected into the to-be-started
process. When called, "CreateProcessEx" starts the specified process, but
patches it in such a way, that it behaves as if it had a "LoadLibrary" call
right in the first line of it's source code.
With madCodeHook 2.x this API only works for starting new 32bit processes.
When using madCodeHook 3.0 you can use this API to start both 32bit and
64bit processes. The bitdepth of the target process
does not need to match the bitdepth of the process which calls
CreateProcessExA/W. However, the bitdepth of the hook DLL *always* needs to
match the bitdepth of the target process. Otherwise CreateProcessExA/W will
fail.
 |
*** 'madCodeHook 2.x and 3.0' ***
function CreateProcessExA/W (applicationName, commandLine : PAnsi/WideChar;
processAttr, threadAttr : PSecurityAttributes;
inheritHandles : bool;
creationFlags : dword;
environment : pointer;
currentDirectory : PAnsi/WideChar;
const startupInfo : TStartupInfoA/W;
var processInfo : TProcessInformation;
loadLibrary : PAnsi/WideChar ) : boolean;
|
|
The function "InjectLibrary" is able to inject your DLL into one specific
already running 32bit or 64bit process.
With madCodeHook 2.x only 32bit DLLs can be injected into 32bit processes.
With madCodeHook 3.0 you can inject 32bit DLLs into 32bit processes and
64bit DLLs into 64bit processes. Don't worry, you
can't do anything wrong. madCodeHook will simply refuse to inject a DLL with
a non-matching bitdepth. If you call this API from inside a 32bit process,
you cannot inject 64bit processes. If you call this
API from inside a 64bit process, you can inject
hook DLLs into both 32bit and 64bit processes. The bitdepth of the DLL and
the target process must always match, though.
 |
*** 'madCodeHook 3.0' ***
function (Un)InjectLibraryA/W (libFileName : PWide/AnsiChar;
processHandle : dword;
timeOut : dword = 7000) : boolean;
*** 'madCodeHook 2.x' ***
function (Un)InjectLibraryA/W (processHandle : dword;
libFileName : PWide/AnsiChar;
timeOut : dword = 7000) : boolean;
|
|
madCodeHook APIs for system wide DLL injection
You can also inject your hook DLL system (or session) wide. This works only
if you have administrator rights, though. System wide DLL injection
generally consists of two separate parts:
(1) Injection into already running processes and
(2) automatic injection into newly created processes.
Automatic injection into newly created processes is handled by a little
kernel mode driver. When using madCodeHook 3.0,
this driver is available as an external file
(or rather 2 files, one for 32bit OSs and one for
64bit OSs). You need to
configure this driver
and sign it afterwards, otherwise it won't
work. After you've done that, your program needs to activate the
driver by using the following APIs, all of which
need admin rights:
 |
*** 'madCodeHook 3.0 only' ***
function LoadInjectionDriver (driverName, fileName32bit, fileName64bit: PWideChar) : bool; stdcall;
function InstallInjectionDriver (driverName, fileName32bit, fileName64bit, description: PWideChar) : bool; stdcall;
function UninstallInjectionDriver (driverName: PWideChar) : bool; stdcall;
function StopInjectionDriver (driverName: PWideChar) : bool; stdcall;
function StartInjectionDriver (driverName: PWideChar) : bool; stdcall;
success := LoadInjectionDriver('yourFancyDriverName', 'your32.sys', 'your64.sys');
|
|
Once the injection driver has been activated
(see above), you can call the following APIs to inject your hook DLL system
or session wide. If you call these APIs from within a 32bit process, you can
only inject 32bit hook DLLs. If you call these APIs from within a
64bit process, you can inject both 32bit and 64bit
DLLs.
 |
*** 'madCodeHook 3.0 only' ***
const
ALL_SESSIONS : dword = dword(-1);
CURRENT_SESSION : dword = dword(-2);
function (Un)InjectLibraryA/W (driverName : PAnsi/WideChar;
libFileName : PAnsi/WideChar;
session : dword;
systemProcesses : bool;
includeMask : PAnsiChar = nil;
excludeMask : PAnsiChar = nil;
excludePIDs : TPCardinal = nil;
timeOut : dword = 7000) : bool; stdcall; overload;
InjectLibraryA('yourFancyDriverName', 'your32.dll', CURRENT_SESSION, false);
InjectLibraryA('yourFancyDriverName', 'your64.dll', CURRENT_SESSION, false);
|
|
When using madCodeHook 2.x, the kernel mode
driver, used for system/session wide DLL
injection, is embedded in the madCodeHook library and is automatically
loaded whenever it's needed. Here are the available madCodeHook 2.x APIs for
system/session wide DLL injection. Please note that these APIs are not
supported on 64bit OSs.
 |
*** 'madCodeHook 2.x only' ***
const
ALL_SESSIONS = $FFFFFFED;
CURRENT_SESSION = $FFFFFFEC;
SYSTEM_PROCESSES = $10;
CURRENT_PROCESS = $8;
function (Un)InjectLibraryA/W (flags : dword;
libFileName : PAnsi/WideChar;
timeOut : dword = 7000) : boolean;
function (Un)InjectLibrarySessionA/W (session : dword;
systemProcesses : bool;
libFileName : PAnsi/WideChar;
timeOut : dword = 7000) : boolean;
InjectLibraryA((ALL_SESSIONS or SYSTEM_PROCESSES) and (not CURRENT_PROCESS), 'your.dll');
|
|