📄 hookdll.txt
字号:
Format of hook library (Hooks.dll)
----------------------------------
All constants, structures and macros are in ApiHooks.inc and ApiHooks.h files.
DLL can be written in any language and must export ApiHookChain as the item
with
A) ordinal number 1 or
B) name 'ApiHookChain'
ApiHookChain is array of API_HOOK structures.
ApiHookChain must be terminated by HOOKS_END (-1) dword or
by API_HOOK with ModuleExport = HOOKS_END
If you want pass ApiHookChain as dynamic hooks to EsTablishApiHooks functions
ApiHookChain must begin with API_HOOK with ModuleExport = HOOKS_DYNAMIC.
If you write in ASM I recommend to use MkHook macro for building API_HOOK
structures.
API_HOOK structure
------------------
typedef struct _API_HOOK {
LPCSTR ModuleExport;
LPCSTR ApiNameOrOrd;
DWORD dwFlags;
LPCSTR ModuleImport;
PAPI_UNHOOK UnhookAddresses;
LPVOID HookAddress;
} API_HOOK, *PAPI_HOOK;
ModuleExport ... pointer to Ansi name of module which exports wanted API
NULL for main (.exe) module
HOOKS_END marks end of ApiHookChain
DYNAMIC_HOOKS marks dynamic hooks
ApiNameOrOrd ... ordinal number of wanted API or
pointer to the Ansi name of wanted API
dwFlags ... specifies how to hook, can be combination of the following
constants:
HOOK_EXPORT .. changes export item of ModuleExport, so GetProcAddress
will return HookAddress (useful for packed/crypted files)
and all newly loaded modules will have modified imports
according to ModuleExport's export
wanted export item is found according to ApiNameOrOrd
HOOK_IMPORT .. changes import item of ModuleImport
wanted import item is found according to ApiNameOrOrd
HOOK_BY_ADDRESS changes import items of ModuleImport
wanted import items are found according to the current API
address
HOOK_BY_ADDRESS mustn't be used together with HOOK_IMPORT
HOOK_HARD .. ignored under NT; when you want to hook modules laying above
2GB (system DLLs) in Windows 9x you must use this option
(see 9xGlobal.txt)
combined constants:
HOOK_EXACT = HOOK_EXPORT + HOOK_IMPORT
EXACT means that if I want to hook lstrcmpi, this and only
this will be hooked in both ModuleName and ModuleImport
HOOK_ALL = HOOK_EXPORT + HOOK_BY_ADDRESS
ALL means that if I want to hook lstrcmpi, this and only
this will be hooked in ModuleName but in ModuleImport
will be hooked lstcmpiA in addition (the same addresses)
HOOK_ALL is recommended for packed/protected modules
there are also shortcuts: H_E, H_I, H_B, H_H
ModuleImport .. pointer to module(s) which import(s) wanted API
NULL for main (.exe) module
ALL_MODULES for all modules in the process
UnhookAddresses . pointer to API_UNHOOK structure for storing addresses for
unhooking
can be NULL
HookAddress .. pointer to your hook procedure
if you are using C, your procedure should have format:
ResultType CallType MyApi(Par0, Par1,...) {
ResultType result;
// pre-orig-call actions: modify parameters
result = OrigApi(Par0, Par1,...); // can be excluded
// post-orig-call actions: modify parameters, result
return(result);
}
if you are using ASM or __declspec(naked) there are no limits
API_UNHOOK structure
--------------------
typedef struct _API_UNHOOK {
DWORD MaxNoAddr;
DWORD CurNoAddr;
PADDR_CONTENTS WhereWhat;
} API_UNHOOK, *PAPI_UNHOOK;
MaxNoAddr .. maximum number of ADDR_CONTENTS structures in array pointed by
WhereWhat
CurNoAddr .. (filled by ApiHooks) is the current number of ADDR_CONTENTS
structures used (can't be greater than MaxNoAddr)
WhereWhat .. pointer to array of ADDR_CONTENTS structures
array must have at least MaxNoAddr ADDR_CONTENTS structures
ADDR_CONTENTS structure
-----------------------
typedef struct _ADDR_CONTENTS {
DWORD *ReturnWhere;
DWORD ReturnWhat;
} ADDR_CONTENTS, *PADDR_CONTENTS;
ReturnWhere .. the address which was modified in hooking process
ReturnWhat .. the original contents of ReturnWhere (it mayn't be original
API address, don't use it for calls!!)
To unhook: *ReturnWhere = ReturnWhat;
If you write in ASM I recommend to use MkUnhook macro for building API_UNHOOK
+ ADDR_CONTENTS structures.
Unhooking
---------
Hooks vanish automatically with exit of process.
To unhook you have to specify pointer to API_UNHOOK structure in API_HOOK
definition or to declare UnhookMyAPI (for example by MkUnhook MyApi, 3) and use
MkHook macro with MyApi as __procedure. When unhooking is required then simply
read ADDR_CONTENTS structures pointed by API_UNHOOK.WhereWhat, apply
VirtualProtect to ReturnWhere to make it writeable, put ReturnWhat to
ReturnWhere and return page attributes again with VirtualProtect as is showed
in Unhook examples.
Unhooking is required before exit of process where is hooks.dll located and
some of hooks were used with HOOK_HARD option.
See examples of ApiHookChains in Examples subdirectory.
Using ASM macros
;-------------------------------------------------------------------------------
MkUnhook MACRO __procedure, __maxunhooks
MkUnhook WantedApi, 2
Macro defined UNHOOK_API structure named UnhookWantedApi and reserved
space for 2 ADDR_CONTENTS structures.
MkUnhook 21, 1
Macro defined UNHOOK_API structure named Unhook21 and reserved
space for 1 ADDR_CONTENTS structure.
;-------------------------------------------------------------------------------
MkHook MACRO __symbol, __module_export, __procedure, __method, __module_import
MkHook Hook0, USER32, MessageBoxA, HOOK_IMPORT
Macro defined API_HOOK structure with name Hook0:
ModuleName = sUSER32
ApiNameOrOrd = sMessageBoxA
dwFlags = HOOK_IMPORT
ModuleImport = ALL_MODULES
UnhookAddresses = NULL if UnhookMessageBoxA doesn't exist
= OFFSET UnhookMessageBoxA if UnhookMessageBoxA exists
HookAddress = NewMessageBoxA
;Import item of main (.exe) module for MessageBoxA is changed:
;If UnhookMessageBoxA exists, address (position) of item and item itself
;will be stored in UNHOOK_API structure
;Import item will be replaced with NewMessageBoxA address
;If the main module lays in kernel space import will not be changed
MkHook ,, 145
Macro defined noname API_HOOK structure with:
ModuleName = sKERNEL32
ApiNameOrOrd = 145
dwFlags = HOOK_BY_ADDRESS+HOOK_EXPORT = HOOK_ALL
ModuleImport = ALL_MODULES
UnhookAddresses = NULL if Unhook145 doesn't exist
= OFFSET Unhook1 if Unhook1 exists
HookAddress = New145
;Import items of main (.exe) module which are equal to current address of the
;KERNEL32.145 are changed:
;If Unhook145 exists, addresses (positions) of items and items themselves
;will be stored in UNHOOK_API structure
;Import items will be replaced with New145 address
;If the main module lays in kernel space import will not be changed
;Export item of KERNEL32 for 145th function is changed:
;If Unhook145 exists, address (position) of item and item itself
;will be stored in UNHOOK_API structure
;Export item will be changed to point to New145
;If KERNEL32 lays in kernel space export will not be changed
MkHook xxx, Sleep, H_E+H_B+H_H, USER32
Macro defined API_HOOK structure with name xxx:
ModuleName = sKERNEL32
ApiNameOrOrd = sSleep
dwFlags = HOOK_EXPORT+HOOK_BY_ADDRESS+HOOK_HARD
ModuleImport = sUSER32
UnhookAddresses = NULL if UnhookSleep doesn't exist
= OFFSET UnhookSleep if UnhookSleep exists
HookAddress = NewSleep
;Import items of USER32 which are equal to current address of Sleep
;of KERNEL32 are changed:
;If UnhookSleep exists, addresses (positions) of items and items themselves
;will be stored in UNHOOK_API structure
;Import items will be replaced with NewSleep address
;Even if USER32 lays in kernel space import will be changed
;Export item of KERNEL32 for Sleep function is changed:
;If UnhookSleep exists, address (position) of item and item itself
;will be stored in UNHOOK_API structure
;Export item will be changed to point to NewSleep
;Even if KERNEL32 lays in kernel space import will be changed
MkHook ,, CreateFileA, H_E+H_B+H_H
Macro defined noname API_HOOK structure with:
ModuleName = sKERNEL32
ApiNameOrOrd = sCreateFileA
dwFlags = HOOK_EXPORT+HOOK_BY_ADDRESS+HOOK_HARD
ModuleImport = ALL_MODULES
UnhookAddresses = NULL if UnhookCreateFileA doesn't exist
= OFFSET UnhookCreateFileA if UnhookCreateFileA exists
HookAddress = NewCreateFileA
;Import items of all modules in the process which are equal to current address
;of CreateFileA of KERNEL32 are changed:
;If UnhookCreateFileA exists, addresses (positions) of items and items
;themselves will be stored in UNHOOK_API structure
;Import items will be replaced with NewCreateFileA address
;Even if some modules lay in kernel space their import will be changed
;Export item of KERNEL32 for CreateFileA function is changed:
;If UnhookCreateFileA exists, address (position) of item and item itself
;will be stored in UNHOOK_API structure
;Export item will be changed to point to NewCreateFileA
;Even if KERNEL32 lays in kernel space import will be changed
ApiHookChain example:
---------------------
BeginOfHooks MyHooks ;defines public variable, which must be exported
API_HOOK <sKERNEL32, sGetVersionExW, HOOK_EXPORT OR HOOK_IMPORT, sSHELL32,\
UnhookGetVersionExW, NewGetVersionExW>
;API_HOOK above defined EXACT hook of kernel32!GetVersion in shell32.dll
;The contents and address of kernel32 export item for GetVersionExW will be
;stored in UNHOOK_API structure pointed by UnhookGetVersionExW
;The contents of kernel32 export will be replaced with NewGetVersionExW
;only if kernel32 lays in user space
;The contents and address of shell32 import item for GetVersionExW will be
;stored in UNHOOK_API structure pointed by UnhookGetVersionExW
;The contents of shell32 import will be replaced with NewGetVersionExW
;only if user32 lays in user space
MkHook ,ADVAPI32, RegOpenKeyExA
;Above is ALL hook of advapi32!RegOpenKeyExA in main module
;The contents and address of advapi32 export item for RegOpenKeyExA will be
;stored in UNHOOK_API structure pointed by UnhookRegOpenKeyExA if it exists
;The contents of advapi32 export item will be changed to point to
;NewRegOpenKeyExA only if advapi32 lays in user space
;The contents and address of main module import items with address=
;RegOpenKeyExA will be stored in UNHOOK_API structure pointed by
;UnhookRegOpenKeyExA if it exists
;The contents of main module import items with address=RegOpenKeyExA will be
;replaced with NewRegOpenKeyExA only if main module lays in user space
MkHook , , CreateFileA
;Above is ALL hook of kernel32!CreateFileA in main module
API_HOOK <sKERNEL32, 50, HOOK_EXPORT OR HOOK_IMPORT, NULL, OrgOrd50,\
NewOrd50>
;API_HOOK above defined EXACT hook of kernel32.50 (ordinal) in main module
MkHook , , FindFirstFileW, H_I, COMDLG32
;API_HOOK above defined IMPORT hook of kernel32!FindFirstFileW in comdlg32.dll
MkHook ,USER32, DialogBoxParamA, HOOK_ALL
;above is ALL hook of user32!DialogBoxParamA in main module
EndOfHooks ;HOOKS_END terminator
On the LINK command line should be switch: /EXPORT:MyHooks,@1,NONAME or
/EXPORT:MyHooks,@1 or
DEF file should contain:
NAME MyHooks.dll
EXPORTS MyHooks @1 NONAME
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -