If you want to hook an API in another process (e.g. Notepad) or if you want
to do system wide API hooking in both OS families (9x/NT), 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 there whatever you want it to do.
There's no documented possibility 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.
The package madCodeHook offers various injection related functions, which
work without any of the mentioned disadvantages. The function "InjectLibrary"
is able to inject your DLL into any already running 32bit process. You can
specify one specific target process or any of the special flags. Those
special flags work only if you have administrator rights, otherwise
"InjectLibrary" will fail and GetLastError will report ERROR_ACCESS_DENIED.
All special flags result in your DLL being injected into some (or all)
currently running and in the future created processes. This injection system
stays alive until the next reboot (or until you call UninjectLibrary),
regardless of whether your application continues to run or not. Besides: As
long as your DLL is actively injected, is can't be unloaded. FreeLibrary
will return "false" and ERROR_ACCESS_DENIED.
For C++ programmers: If you're using the dynamic lib, the target process(es)
must not only be able to locate your hook DLL, but it/they must also be able
to locate "madCHook.dll". In order to solve that you can either put
"madCHook.dll" into the system directory or you can use the static lib or
you can first call "InjectLibrary(whatever, "madCHook.dll")" before
injecting your own dll. The static lib comes only with the commercial
version of madCodeHook.
 |
const
ALL_SESSIONS = $FFFFFFED;
CURRENT_SESSION = $FFFFFFEC;
CURRENT_USER = $FFFFFFEB;
SYSTEM_PROCESSES = $10;
CURRENT_PROCESS = $8;
function InjectLibrary (processHandle : dword;
libFileName : string;
timeOut : dword = 7000) : boolean;
function InjectLibrarySession (session : dword;
systemProcesses : bool;
libFileName : string;
timeOut : dword = 7000) : boolean;
InjectLibrary((ALL_SESSIONS or SYSTEM_PROCESSES) and (not CURRENT_PROCESS), 'your.dll');
|
|
You can undo the DLL injection by calling "UninjectLibrary". It works
similar to "InjectLibrary", except that it removes your DLL from the
specified process(es). There's one additional flag which you can use, namely
"STOP_VIRUS". If you specify this flag, the injection into newly created
processes is stopped, but your DLL is not unloaded from the running
processes. Please note that for security reasons only the very same module
(exe/dll) which injected a specific DLL can later uninject it again.
For C++ programmers there's one potential problem when calling
UninjectLibrary(SomeSpecialFlag, "madCHook.dll") in win9x. Uninjecting a DLL
system wide will in win9x really result in the DLL being removed from each
and every process - regardless of whether the DLL was statically or
dynamically linked! So if your application builds on and needs
"madCHook.dll" to run you must not uninject it at all in win9x. You can
solve this problem by either using the static lib, or by putting
"madCHook.dll" into the system directory. In that case you neither need to
inject nor to uninject it.
 |
function UninjectLibrary (processHandle : dword;
libFileName : string;
timeOut : dword = 7000) : boolean;
function UninjectLibrarySession (session : dword;
systemProcesses : bool;
libFileName : string;
timeOut : dword = 7000) : boolean;
|
|
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 a way, that it behaves as if it would have a "LoadLibrary"
call right in the first line of it's source code.
 |
function CreateProcessEx (applicationName, commandLine : pchar;
processAttr, threadAttr : PSecurityAttributes;
inheritHandles : bool;
creationFlags : dword;
environment : pointer;
currentDirectory : pchar;
const startupInfo : TStartupInfo;
var processInfo : TProcessInformation;
loadLibrary : string ) : boolean;
|
|