Friday, September 9, 2011

Hook Specials 32 : Api hook analyze in detail

Author:Alex(Yock.W)
Preface rudimentary knowledge

The article will overall analyze a fews api hook's method .

What is Hook?
 
Hook, is platform of windows message dispose machine-made, Application program may set sub program to keep watch on some kind of message of specials window above, and window of be kept watch on is created by other process. When message go to , Realize it on realize function of target window . Hook machine-made allow application program to intercept and capture for realize message of window or specials event.

Hook infact is program segment about dispose message, Through system call it, and load it on system. Whenever special message is sent, hook program catch the message before not go to aim window, That is hook function first get control power. Hook function may cure (change) the message now, passable not cure to continue and pass on the message, or force finished to pass on message.

Hook theory

Each Hook have a  related chain table, by system maintenance, Chain table point  callback function of is call by hook sub program .

LRESULT WINAPI HookCallBack(
int nCode,
WPARAM wParam,
LPARAM lParam);
nCode //Even code事件代码
wParam //message type
lParam //include message

When take place be hooked type related message, The message is passed on hook sub program of chain table point by system, Sub program dispose message inside.

Hook install and unlaod

Use API SetWindowsHookEx on window to install Hook chain table, set up hook lies  header of hook chain table.

HHOOK SetWindowsHookEx(
int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId);
idHook //hook type安装的钩子类型
lpfn // sub function pointer子程函数指针
hMod // Application program instance handle
dwThreadId // Hook related thread identifier 

When message type of be hooked take place, System call hook sub program with related chain table header. By sub program decide whether pass on the event to next sub program. Hook sub program pass on event to next hook need call API CallNextHookEx by Windows iffered.

LRESULT CallNextHookEx(
HHOOK hhk,
int nCode,
WPARAM wParam,
LPARAM lParam);
hhk //current handle of hook, by SetWindowsHookEx return
nCode //event code
wParam //type message
lParam // include message
 
Hook finish, need call UnHookWindowsHookEx to unload.

UnHookWindowsHookEx(
HHOOK hhk);
A few methods of Api Hook

One. Modify address space of function procedure mapping

Api Hook:

You know, When call function, first Call 0xFFFFFF, Go to function mapping to address space of memory , at this time, Esodic paramter had push, So we only modify header of function, jump to our custom procedure, Such we can reach  to keep watch on  api function aim. Like that, how much space to write code  for jump to our custom procedure?
 
Descend upon , Only five bytes , Why?  Watch code:

jmp 0xFFFFFFFF
jmp command only 1 byte, address is four bytes, So only five bytes.

Some people likely ask, Why use Call?

Because Call command will through ret to return call under command to continue execute after realize jump , and that Sub program control after Jmp command realize to jump .

We know above method through modify header of function to reach our aim, So We need get address of header first, Through LoadLibrary and GetProcAddress to get our address pointer of custodial function on memory mapping. Through MessageBoxA  to example:

typedef int (__stdcall *TMessageBoxA)(HWND hWnd,LPSTR lpText,LPSTR lpCaption,int uType);

extern "C" TMessageBoxA __fastcall GetPFuncAddr(LPSTR DllName,const char* FullName);

TMessageBoxA __fastcall GetPFuncAddr(LPSTR DllName,const char* FullName)
{
void *DllModule;
DllModule = LoadLibrary(DllName);
TMessageBoxA PAddr = (TMessageBoxA)GetProcAddress(DllModule,FullName);
return PAddr;
}
After point function header pointer of  memory mapping, Then read out five bytes of function header. Why read out five bytes of function header? of course write data for recover.
ReadProcessMemory:

BOOL ReadProcessMemory(
HANDLE hProcess,
LPCVOID lpBaseAddress,
LPVOID lpBuffer,
DWORD nSize,
LPDWORD lpNumberOfBytesRead);
hProcess //Process handle
lpBaseAddress //Read memory start address
lpBuffer 保存数据的指针
nSize 数据大小
lpNumberOfBytesRead //address of number of bytes read

BYTE *pFuncData = new BYTE[5];
LPDWORD iRead;

ReadProcessMemory((void *)GetCurrentProcess(),PMessageBoxA,pFuncData,5,iRead);

After save data of original entry point, Write to point address of our function   onself.

BYTE AsmCode[5];

AsmCode[0] = 0xE9;
__asm
{
lea eax, MyMessageBoxA
mov ebx,PMessageBoxA
sub eax,ebx
sub eax,5
mov dword ptr[AsmCode+1],eax
}
WriteProcessMemory((void *)GetCurrentProcess(),PMessageBoxA,AsmCode,5,iWrite);

MyMessageBoxA is created function by oneself:

int WINAPI MyMessageBoxA(HWND hWnd,LPSTR lpText,LPSTR lpCaption,int uType)
{
//Show messagebox, change eisodic caption paramter
//So first recover MessageBoxA
WriteProcessMemory((void *)GetCurrentProcess(),PMessageBoxA,pFuncData,5,iWrite);
int Result = MessageBoxA(hWnd,lpText,"ApiHook Test",uType);
WriteProcessMemory((void *)GetCurrentProcess(),PMessageBoxA,AsmCode,5,iWrite);
return Result;
}
Recover original entry data of API:

WriteProcessMemory((void *)GetCurrentProcess(),PMessageBoxA,pFuncData,5,iWrite);
Prevent to modify function entry data to proceed API HOOK:

Program start to save hinge five bytes of API entry, periodical inspection, if be modify, modify return.

----------------------------------------------------------------


No comments:

Post a Comment