Dll Injection 

www.madshi.net

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' ***

// start a process and inject your hook DLL into it

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.

// inject a DLL into one specific process

*** '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' ***

// (de)activate the injection driver

// option 1: dynamically load the driver without installing it
// the driver will be loaded and start running at once
// it will stay active only until the next reboot
// you may prefer this technique if you want your product to not require any
// installation and uninstallation procedures
function LoadInjectionDriver (driverName, fileName32bit, fileName64bit: PWideChar) : bool; stdcall;

// option 2: permanently install your injection driver
// after installation it will automatically start running at once
// it will survive reboots, it will stay installed until you uninstall it
// for a clean uninstall call StopInjectionDriver first, then Uninstall
function   InstallInjectionDriver (driverName, fileName32bit, fileName64bit, description: PWideChar) : bool; stdcall;
function UninstallInjectionDriver (driverName: PWideChar) : bool; stdcall;

// stopping the driver may not work, depending on how it was configured
// call Stop + Start to update an installed driver to a newer version
// call Stop + Load  to update a  loaded    driver to a newer version
function  StopInjectionDriver (driverName: PWideChar) : bool; stdcall;
function StartInjectionDriver (driverName: PWideChar) : bool; stdcall;

// Example:
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' ***

// inject a DLL into all running processes

const
  // flags for injection/uninjection "session" parameter
  ALL_SESSIONS    : dword = dword(-1);
  CURRENT_SESSION : dword = dword(-2);

// (un)injects a library to/from all processes of the specified session(s)
// driverName:      name of the driver to use
// libFileName:     full file path/name of the hook dll
// session:         session id into which you want the dll to be injected
//                  "-1" or "ALL_SESSIONS" means all sessions
//                  "-2" or "CURRENT_SESSION" means the current session
// systemProcesses: shall the dll be injected into system processes?
// includeMask:     list of exe file name/path masks into which the hook dll shall be injected
//                  you can use multiple masks separated by a "|" char
//                  you can either use a full path, or a file name, only
//                  leaving this parameter empty means that all processes are "included"
//                  Example: "c:\program files\*.exe|calc.exe|*.scr"
// excludeMask:     list of exe file name/path masks which shall be excluded from dll injection
//                  the excludeMask has priority over the includeMask
//                  leaving this parameter empty means that no processes are "excluded"
// excludePIDs:     list of process IDs which shall not be touched
//                  when used, the list must be terminated with a "0" PID item
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;

// Example:
// we inject both a 32bit and a 64bit hook DLL
// let madCodeHook worry about choosing the right DLL for any given process
// this will only work if you call this from within a 64bit process
// you can't inject 64bit hook DLLs from within a 32bit process
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' ***

// inject a DLL system wide

const
  // flags
  ALL_SESSIONS     = $FFFFFFED;  // apps of all sessions
  CURRENT_SESSION  = $FFFFFFEC;  // apps of current session
  SYSTEM_PROCESSES = $10;  // include this flag to include system processes + services
  CURRENT_PROCESS  = $8;   // exclude this flag to exclude injection into yourself

// inject a DLL session/system wide
function (Un)InjectLibraryA/W (flags       : dword;
                               libFileName : PAnsi/WideChar;
                               timeOut     : dword = 7000) : boolean;

// same as InjectLibrary(CURRENT_SESSION), but you can specify the target session
function (Un)InjectLibrarySessionA/W (session         : dword;
                                      systemProcesses : bool;
                                      libFileName     : PAnsi/WideChar;
                                      timeOut         : dword = 7000) : boolean;

// Example:
InjectLibraryA((ALL_SESSIONS or SYSTEM_PROCESSES) and (not CURRENT_PROCESS), 'your.dll');