These are mature things. I have looked at them over the past few days and summarized them.
This article discusses several methods of hook Functions in Windows. Provides a complete example of hook TextOutA. The CreateRemoteThread method is used to inject the hook dll into a common application. Hooking Imported Functions by name callSteps/implementation for imported functions
The methods for calling functions introduced from other modules in a program are different from those for calling common functions. For common function calls, use
Call address, but
Imported functions
, During compilation
Compiler/link
I don't know the actual function implementation will be loaded to that address, and the function implementation will be determined only when that address is running. For
Imported functions
First
Call
Introduce a function in the table, initialize the import table at runtime, and use
Jmp
Jump to the real function implementation.
Import table:
The PE fileIMAGE_IMPORT_DESCRIPTORStructure, which holds all the information about functions imported from a specific DLL, has pointers to two arrays in the executable. these arrays are called import address tables (IATs), or sometimes thunk data arrays. the first pointer references the real IAT, which the program loader fixes up when the executable is loaded. the second pointer references the original IAT, which is untouched by the loader and lists the imported functions.
Implementation Principle
Find
PE
File
Image_Import_Descriptor
Structure
Find
Original LAT
And
Real LAT.
Pass
Hook
The function name is
Original LAT
Find
Hook
Of
Imported function
In the array
Index.
Save and modify
Real LAT
In the corresponding
Index
Of
Function address
(refer to John Robbins, BugsLayerUtil.dll)
Hooking Imported Functions by ordinalPrinciples and
Hook Imported functions by name
The same is because
Hook
Function
Ordinal
In
Original LAT
.
Index.
Hooking a function in this dllWhen
DLL
Yes
LoadLibrary
When loading, we cannot pass
Hook imported function
Method
Hook
In
Function
. There are two possible solutions to this situation:
The first method is to traverse the process space and discover
Call
Replace the specified function
Call hookFunction.
It is too troublesome and insecure.
Method 2: rewrite
Hook
Functions
FuncA
. Better Method
- Implementation
HookFuncA
, The final implementation pad
N
Items
Nop. - Find
Hook
Functions
FuncA
Absolute address, before Rewriting
5
Bytes:
Jmp hookFuncA (
Assume that
5
Bytes:
N
Complete commands
)
Set
FuncA
Before
5
Bytes copied
HookFuncA
Followed by a commandJmp funcA + 5.
---- Code of HookDLL. dll, you can use CreateRemoteThread to inject the hook dll into a common application.
// HookDLL. cpp: Defines the entry point for the DLL application.
//
# Include "stdafx. h"
# Include "HookDLL. h"
# Include "Log. h"
// Forward declare.
Lresult winapi InstallTextoutHook ();
Lresult winapi UninstallTextoutHook ();
Bool apientry DllMain (HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
Switch (ul_reason_for_call)
{
Case DLL_PROCESS_ATTACH:
If (InstallTextoutHook ())
{
WriteLog ("Install hook success .");
} Else
{
WriteLog ("Intall hook failed .");
}
Break;
Case DLL_THREAD_ATTACH:
Break;
Case DLL_THREAD_DETACH:
Break;
Case DLL_PROCESS_DETACH:
If (UninstallTextoutHook ())
{
WriteLog ("Uninstall hook success .");
} Else
{
WriteLog ("Unintall hook failed .");
}
Break;
}
Return TRUE;
}
# Define DWORD_PTR DWORD *
# Define _ LOCAL_SIZE 40 h
# Define NAKED_PROLOG ()
DWORD_PTR dwRet;
DWORD_PTR dwESI;
{
_ Asm push ebp/* Set up the standard frame .*/
_ Asm mov ebp, ESP
_ Asm sub esp, _ LOCAL_SIZE/* Save room for the local */
/* Variables .*/
_ Asm mov eax, EBP/* EBP has the stack coming */
/* Into the fn. in it .*/
_ Asm add eax, 4/* Account for push ebp */
_ Asm mov eax, [EAX]/* Get return address .*/
_ Asm MOV [dwRet], EAX/* Save return address .*/
_ Asm MOV [dwESI], ESI/* Save ESI so chkesp in dbg */
/* Builds works .*/
} // The common epilog part that can be shared between the stdcall and
// Cdecl hook functions.
# Define EPILOG_COMMON ()
{
_ Asm mov esi, [dwESI]/* Restore ESI .*/
_ Asm add esp, _ LOCAL_SIZE/* Take away local var space */
_ Asm mov esp, EBP/* Restore standard frame .*/
_ Asm POP EBP
}
# Define COPY_CODE_LENGTH 5
BYTE g_abOriCode [COPY_CODE_LENGTH];
BYTE g_abJmpCode [COPY_CODE_LENGTH];
PROC g_oriTextout;
BOOL g_blHooked = FALSE;
Lresult winapi InstallTextoutHook ()
{
If (g_blHooked)
Return TRUE;
// Get TextOutAs address.
HMODULE hGdi32 =: LoadLibrary (_ T ("Gdi32.dll "));
G_oriTextout = GetProcAddress (hGdi32, _ T ("TextOutA "));
If (NULL = g_oriTextout)
Return FALSE;
// Get the hooka address.
HMODULE hModule = GetModuleHandle (_ T ("HookDLL. dll "));
If (NULL = hModule)
Return FALSE;
DWORD dwHookAddr = NULL;
_ Asm
{
Mov esi, offset HookLabel;
Mov edi, 0x10000000; // 0x10000000 is the dlls base address.
Sub esi, edi;
Add esi, hModule;
Mov [dwHookAddr], esi;
}
// Get the NOPs address.
DWORD dwNOPAddr = NULL;
_ Asm
{
Mov esi, offset NOPLabel;
Mov edi, 0x10000000; // 0x10000000 is the dlls base address.
Sub esi, edi;
Add esi, hModule;
Mov [dwNOPAddr], esi;
}
// Save the first 5 byte of TextOutA to g_abOriCode
_ Asm
{
Mov esi, g_oriTextout;
Lea edi, g_abOriCode;
Cld;
Movsd;
Movsb;
}
// Generate the jmp Hook function.
G_abJmpCode [0] = 0xe9;
_ Asm
{
Mov eax, dwHookAddr;
Mov ebx, g_oriTextout;
Add ebx, 5;
Sub eax, ebx;
Mov dword ptr [g_abJmpCode + 1], eax;
}
// Write the jump instruction to the textoutA.
DWORD dwProcessId = GetCurrentProcessId ();
HANDLE hProcess = OpenProcess (PROCESS_ALL_ACCESS,
FALSE, dwProcessId );
If (NULL = hProcess)
Return FALSE;
DWORD dwOldFlag;
VirtualProtectEx (hProcess, g_oriTextout, 5, PAGE_READWRITE, & dwOldFlag );
WriteProcessMemory (hProcess, g_oriTextout, g_abJmpCode, sizeof (g_abJmpCode), NULL