www.pudn.com > ·â°ü½ØÈ¡µÄÔ´ÂëÖµµÃѧϰVC.rar > madCHook.h
// ***************************************************************
// madCHook - dynamic.h version: 2.1 · date: 2004-03-07
// -------------------------------------------------------------
// API hooking, code hooking
// -------------------------------------------------------------
// Copyright (C) 1999 - 2004 www.madshi.net, All Rights Reserved
// ***************************************************************
// 2004-03-07 2.1 (1) seperate header file for dynamic and static lib
// (2) NO_MIXTURE_MODE flag added
// (3) CreateIpcQueueEx added with additional parameters
// 2003-10-05 2.0a changed initialization/finalization logic to fix memory leak
// 2003-08-10 2.0 (1) HookCode parameters changed -> only one flags parameter
// (2) (Un)InjectLibrary: user/session/system wide injection!
// (3) InjectLibrary2 replaced by InjectLibrary (auto detect)
// (4) static lib for Microsoft C++ added
// (5) CreateIpcQueue + SendIpcMessage + DestroyIpcQueue added
// (6) AmSystemProcess + AmUsingInputDesktop added
// (7) GetCurrentSessionId + GetInputSessionId added
// (8) GetCallingModule function added
// (9) ProcessIdToFileName added
// (a) Create/OpenGlobalMutex + Event + FileMapping added
// (b) WideToAnsi + AnsiToWide functions added
// (c) RenewHook function added
// (d) madCodeHook.dll -> madCHook.dll (8.3 dos name logic)
// (e) UnhookAPI added (= UnhookCode, added just for the look)
// (f) AddAccessForEveryone added
// 2002-10-03 1.3e (1) InjectLibraryW added
// (2) InjectLibrary2(W) added for use in CreateProcess(W) hooks
// 2002-09-22 1.3d CreateProcessExW added
// 2002-03-24 1.3c CollectHooks/FlushHooks speed up mixture initialization
// 2002-02-24 1.3b LPSTARTUPINFO -> LPSTARTUPINFOA
// 2002-01-21 1.3a ProcessHandleToId exported
// 2001-07-08 1.3 new functions (1) AllocMemEx & FreeMemEx
// (2) CopyFunction
// (3) CreateRemoteThread and
// (4) InjectLibrary added
// 2001-04-20 1.2a you can now force HookCode/API to use the mixture mode
// 2001-04-16 1.2 new function CreateProcessEx -> dll injecting
// ***************************************************************
#if !defined(MADCHOOK_H)
#define MADCHOOK_H
#ifdef __cplusplus
extern "C" {
#endif
#define madCHookApi(rt) __declspec(dllimport) rt WINAPI
// ***************************************************************
// by default madCodeHook counts how many times any thread is currently
// running inside of your callback function
// this way unhooking can be safely synchronized to that counter
// sometimes you don't need/want this counting to happen, e.g.
// (1) if you don't plan to ever unhook, anyway
// (2) if the counting performance drop is too high for your taste
// (3) if you want to unhook from inside the hook callback function
// in those cases you can set the flag "DONT_COUNT"
#define DONT_COUNT (DWORD) 0x00000001
// madCodeHook implements two different API hooking methods
// the mixture mode is the second best method, it's only used if the main
// hooking method doesn't work for whatever reason (e.g. API code structure)
// normally madCodeHook chooses automatically which mode to use
// you can force madCodeHook to use the mixture mode by specifying the flag:
#define MIXTURE_MODE (DWORD) 0x00000002
// if you don't want madCodeHook to use the mixture mode, you can say so
// however, if the main hooking mode can't be used, hooking then simply fails
#define NO_MIXTURE_MODE (DWORD) 0x00000010
// under win9x you can hook code system wide, if it begins > $80000000
// or if the code section of the to-be-hooked dll is shared
// the callback function is in this case automatically copied to shared memory
// use only kernel32 APIs in such a system wide hook callback function (!!)
// if you want an easier way and/or a NT family compatible way to hook code
// system wide, please use InjectLibrary(ALL_SESSIONS) instead of these flags:
#define SYSTEM_WIDE_9X (DWORD) 0x00000004
#define ACCEPT_UNKNOWN_TARGETS_9X (DWORD) 0x00000008
// hook any code or a specific API
madCHookApi(BOOL) HookCode(
PVOID pCode,
PVOID pCallbackFunc,
PVOID *pNextHook,
#ifdef __cplusplus
DWORD dwFlags = 0
#else
DWORD dwFlags
#endif
);
madCHookApi(BOOL) HookAPI(
LPCSTR pszModule,
LPCSTR pszFuncName,
PVOID pCallbackFunc,
PVOID *pNextHook,
#ifdef __cplusplus
DWORD dwFlags = 0
#else
DWORD dwFlags
#endif
);
// some firewall/antivirus programs kill our hooks, so we need to renew them
madCHookApi(BOOL) RenewHook(
PVOID *pNextHook
);
// unhook again
madCHookApi(BOOL) UnhookCode( PVOID *pNextHook );
madCHookApi(BOOL) UnhookAPI ( PVOID *pNextHook );
// putting all your "HookCode/API" calls into a "CollectHooks".."FlushHooks"
// frame can eventually speed up the installation of the hooks
madCHookApi(VOID) CollectHooks ();
madCHookApi(VOID) FlushHooks ();
// ***************************************************************
// same as CreateProcess
// additionally the dll "loadLibrary" is injected into the newly created process
// the dll is loaded right before the entry point of the exe module is called
madCHookApi(BOOL) CreateProcessExA(
LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation,
LPCSTR lpLoadLibrary
);
madCHookApi(BOOL) CreateProcessExW(
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation,
LPCWSTR lpLoadLibrary
);
// ***************************************************************
// memory allocation in the specified processes (shared memory in win9x)
// if the processHandle is 0, the memory is allocated or freed in the shared
// area (in win9x) or in our own process (in winNT)
madCHookApi(PVOID) AllocMemEx(
DWORD dwSize,
#ifdef __cplusplus
HANDLE hProcess = 0
#else
HANDLE hProcess
#endif
);
madCHookApi(BOOL) FreeMemEx(
PVOID pMem,
#ifdef __cplusplus
HANDLE hProcess = 0
#else
HANDLE hProcess
#endif
);
// ***************************************************************
// copy (and relocate) any function to a new location in any process
// if the processHandle is 0, the function is copied to shared area (in win9x)
// or to another memory location in our own process (in winNT)
// don't forget to free the function with FreeMemEx, if you don't it anymore
madCHookApi(PVOID) CopyFunction(
PVOID pFunction,
#ifdef __cplusplus
HANDLE hProcess = 0,
BOOL bAcceptUnknownTargets = FALSE,
PVOID *pBuffer = NULL
#else
HANDLE hProcess,
BOOL bAcceptUnknownTargets,
PVOID *pBuffer
#endif
);
// ***************************************************************
// like CreateRemoteThread, but 3 changes:
// (1) this one also works perfectly in win9x!!
// (2) this one also works on other sessions in winNt
// (3) the DACL of the current thread is copied in winNt (if threadAttr = nil)
madCHookApi(HANDLE) CreateRemoteThreadEx(
HANDLE hProcess,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
// ***************************************************************
// this is how your remote function must look like
typedef DWORD (WINAPI *PREMOTE_EXECUTE_ROUTINE)( LPVOID pParams );
// executes the specified function in the context of another process
// this works only if the function follows some specific rules
// e.g. it must not use global variables, nor C++ private functions
// only win32 APIs are allowed
// if "dwSize" > 0, the "pParams" block will be copied to the other process
// after the remote function is finished, the "pParams" block is copied back
// so you can use the "pParams" block for both "in" and "out" parameters
// if "dwSize" = 0, the "pParams" value is just given into the remote function
madCHookApi(BOOL) RemoteExecute(
HANDLE hProcess,
PREMOTE_EXECUTE_ROUTINE pFunc,
DWORD *dwFuncResult,
#ifdef __cplusplus
PVOID pParams = NULL,
DWORD dwSize = 0
#else
PVOID pParams,
DWORD dwSize
#endif
);
// ***************************************************************
// (un)inject the specified dll into (from) all current and future processes
// these flags can be used for both UninjectLibrary + InjectLibrary
#define ALL_SESSIONS 0xFFFFFFED // apps of all sessions
#define CURRENT_SESSION 0xFFFFFFEC // apps of current session
#define CURRENT_USER 0xFFFFFFEB // apps of current user
// the following flags may only be used in combination with the first 3 flags
#define SYSTEM_PROCESSES 0x10 // include this flag to include system processes + services
#define CURRENT_PROCESS 0x08 // exclude this flag to exclude injection into yourself
// same as LoadLibrary, but is able to load the library in any process
madCHookApi(BOOL) InjectLibraryA(
DWORD dwProcessHandleOrSpecialFlags,
LPCSTR pLibFileName,
#ifdef __cplusplus
DWORD dwTimeOut = 7000
#else
DWORD dwTimeOut
#endif
);
madCHookApi(BOOL) InjectLibraryW(
DWORD dwProcessHandleOrSpecialFlags,
LPCWSTR pLibFileName,
#ifdef __cplusplus
DWORD dwTimeOut = 7000
#else
DWORD dwTimeOut
#endif
);
// same as InjectLibrary(CURRENT_SESSION, ...), but you can choose the session
madCHookApi(BOOL) InjectLibrarySessionA(
DWORD dwSession,
BOOL bSystemProcesses,
LPCSTR pLibFileName,
#ifdef __cplusplus
DWORD dwTimeOut = 7000
#else
DWORD dwTimeOut
#endif
);
madCHookApi(BOOL) InjectLibrarySessionW(
DWORD dwSession,
BOOL bSystemProcesses,
LPCWSTR pLibFileName,
#ifdef __cplusplus
DWORD dwTimeOut = 7000
#else
DWORD dwTimeOut
#endif
);
// stop the "virus" injection effect (can be used for UninjectLibrary only)
#define STOP_VIRUS (HANDLE) 0xFFFFFFFA
// same as FreeLibrary, but is able to free the library from any process
madCHookApi(BOOL) UninjectLibraryA(
DWORD dwProcessHandleOrSpecialFlags,
LPCSTR pLibFileName,
#ifdef __cplusplus
DWORD dwTimeOut = 7000
#else
DWORD dwTimeOut
#endif
);
madCHookApi(BOOL) UninjectLibraryW(
DWORD dwProcessHandleOrSpecialFlags,
LPCWSTR pLibFileName,
#ifdef __cplusplus
DWORD dwTimeOut = 7000
#else
DWORD dwTimeOut
#endif
);
// same as UninjectLibrary(CURRENT_SESSION, ...), but you can choose the session
madCHookApi(BOOL) UninjectLibrarySessionA(
DWORD dwSession,
BOOL bSystemProcesses,
LPCSTR pLibFileName,
#ifdef __cplusplus
DWORD dwTimeOut = 7000
#else
DWORD dwTimeOut
#endif
);
madCHookApi(BOOL) UninjectLibrarySessionW(
DWORD dwSession,
BOOL bSystemProcesses,
LPCWSTR pLibFileName,
#ifdef __cplusplus
DWORD dwTimeOut = 7000
#else
DWORD dwTimeOut
#endif
);
// ***************************************************************
// which processId belongs to the specified process handle?
// undocumented function, works in all windows 32 bit systems
madCHookApi(DWORD) ProcessHandleToId(
HANDLE dwProcessHandle
);
// find out what file the specified process was executed from
// the file name buffer must have a size of MAX_PATH characters (or more)
madCHookApi(BOOL) ProcessIdToFileName(
DWORD dwProcessId,
LPSTR pFileName
);
// ***************************************************************
// is the current process a service/system process? (win9x -> always false)
madCHookApi(BOOL) AmSystemProcess (VOID);
// is the current thread's desktop the input desktop? (win9x -> always true)
// only in that case you should show messages boxes or other GUI stuff
// but please note that in XP fast user switching AmUsingInputDesktop may
// return true, although the current session is currently not visible
// XP fast user switching is implemented by using terminal server logic
// so each fast user session has its own window station and input desktop
madCHookApi(BOOL) AmUsingInputDesktop (VOID);
// the following two functions can be used to get the session id of the
// current session and of the input session
// each terminal server (or XP fast user switching) session has its own id
// the "input session" is the one currently shown on the physical screen
madCHookApi(DWORD) GetCurrentSessionId (VOID);
madCHookApi(DWORD) GetInputSessionId (VOID);
// ***************************************************************
// which module called me? works only if your function has a stack frame
madCHookApi(DWORD) GetCallingModule (VOID);
// ***************************************************************
// global = normal + "access for everyone" + "non session specific"
madCHookApi(HANDLE) CreateGlobalMutex(
LPCSTR pName
);
madCHookApi(HANDLE) OpenGlobalMutex(
LPCSTR pName
);
madCHookApi(HANDLE) CreateGlobalEvent(
LPCSTR pName,
BOOL bManual,
BOOL bInitialState
);
madCHookApi(HANDLE) OpenGlobalEvent(
LPCSTR pName
);
madCHookApi(HANDLE) CreateGlobalFileMapping(
LPCSTR pName,
DWORD dwSize
);
madCHookApi(HANDLE) OpenGlobalFileMapping(
LPCSTR pName,
BOOL bWrite
);
// ***************************************************************
// convert strings ansi <-> wide
// the result buffer must have a size of MAX_PATH characters (or more)
// please use these functions in nt wide API hook callback functions
// because the OS' own functions seem to confuse nt in hook callback functions
madCHookApi(VOID) AnsiToWide(
LPCSTR pAnsi,
LPWSTR pWide
);
madCHookApi(VOID) WideToAnsi(
LPCWSTR pWide,
LPSTR pAnsi
);
// ***************************************************************
// ipc (inter process communication) message services
// in contrast to SendMessage the following functions don't crash NT services
// this is how you get notified about incoming ipc messages
// you have to write a function which fits to this type definition
// and then you give it into "CreateIpcQueue"
// your callback function will then be called for each incoming message
// CAUTION: each ipc message is handled by a seperate thread, as a result
// your callback will be called by a different thread each time
typedef VOID (WINAPI *PIPC_CALLBACK_ROUTINE)(
LPCSTR pIpc,
PVOID pMessageBuf,
DWORD dwMessageLen,
PVOID pAnswerBuf,
DWORD dwAnswerLen
);
// create an ipc queue
// please choose a unique ipc name to avoid conflicts with other programs
// only one ipc queue with the same name can be open at the same time
// so if 2 programs try to create the same ipc queue, the second call will fail
// you can specify how many threads may be created to handle incoming messages
// if the order of the messages is crucial for you, set "maxThreadCount" to "1"
// in its current implementation "maxThreadCount" only supports "1" or unlimited
// the parameter "maxQueueLen" is not yet implemented at all
madCHookApi(BOOL) CreateIpcQueueEx(
LPCSTR pIpc,
PIPC_CALLBACK_ROUTINE pCallback,
#ifdef __cplusplus
DWORD dwMaxThreadCount = 16,
DWORD dwMaxQueueLen = 0x1000
#else
DWORD dwMaxThreadCount,
DWORD dwMaxQueueLen
#endif
);
madCHookApi(BOOL) CreateIpcQueue(
LPCSTR pIpc,
PIPC_CALLBACK_ROUTINE pCallback
);
// send an ipc message to whomever has created the ipc queue (doesn't matter)
// if you only fill the first 3 parameters, SendIpcMessage returns at once
// if you fill the next two parameters, too, SendIpcMessage will
// wait for an answer of the ipc queue owner
// you can further specify how long you're willing to wait for the answer
// and whether you want SendIpcMessage to handle messages while waiting
madCHookApi(BOOL) SendIpcMessage(
LPCSTR pIpc,
PVOID pMessageBuf,
DWORD dwMessageLen,
#ifdef __cplusplus
PVOID pAnswerBuf = NULL,
DWORD dwAnswerLen = 0,
DWORD dwAnswerTimeOut = INFINITE,
BOOL bHandleMessage = TRUE
#else
PVOID pAnswerBuf,
DWORD dwAnswerLen,
DWORD dwAnswerTimeOut,
BOOL bHandleMessage
#endif
);
// destroy the ipc queue again
// when the queue owning process quits, the ipc queue is automatically deleted
// only the queue owning process can destroy the queue
madCHookApi(BOOL) DestroyIpcQueue(
LPCSTR pIpc
);
// ***************************************************************
// this function adds some access rights to the specified target
// the target can either be a process handle or a service handle
madCHookApi(BOOL) AddAccessForEveryone(
HANDLE hProcessOrService,
DWORD dwAccess
);
// ***************************************************************
// this is the header for the dynamic lib
// you don't need to use InitializeMadCHook + FinalizeMadCHook
// so the functions are just empty stubs
VOID InitializeMadCHook() {}
VOID FinalizeMadCHook() {}
// ***************************************************************
#ifdef UNICODE
#define CreateProcessEx CreateProcessExW
#define InjectLibrary InjectLibraryW
#define UninjectLibrary UninjectLibraryW
#define InjectLibrarySession InjectLibrarySessionW
#define UninjectLibrarySession UninjectLibrarySessionW
#else
#define CreateProcessEx CreateProcessExA
#define InjectLibrary InjectLibraryA
#define UninjectLibrary UninjectLibraryA
#define InjectLibrarySession InjectLibrarySessionA
#define UninjectLibrarySession UninjectLibrarySessionA
#endif
#ifdef __cplusplus
}
#endif
#endif