HOOK 系统 API

来源:互联网 发布:centos架设web服务器 编辑:程序博客网 时间:2024/05/16 14:11


调用系统函数 MessageBoxA

 

VC

MessageBoxA(NULL,NULL,NULL,MB_OK)

CALL dword ptr [0040d244]

VC作了优化

ASM

invoke  MessageBoxA,NULL,NULL,NULL,MB_OK

Call 401abc

401abc :jmp dword ptr [0040d244]

未优化时,函数名代表了jmp dword ptr [0040d244]的地址

 

 

调用内部函数 (函数名就是一个标号,均代表一个地址,VC的标号指向JMP XXXXASM的标号则直接指向函数体)

 

VC

SetHook(lpAddr,MyMessageBox);

CALL 40100f

 40100f:jmp 401030(E91C000000)

1C0(步长)+40100f(本条地址)+5(本条所占地址)=401030

1C(步长)+5(本条所占地址) =本条地址到目标函数地址的距离

 

ASM

CALL _SubProc

Call 40170D

40170D:push ebp

        mov ebp,esp



例子:


#include <windows.h>

 

PROClpAdder = MessageBoxA;//存了E9 +步长的地址, E9 + 步长会跳转到 JMP DWORD PTR [AD]处 (VC6中会直接指向JMP DWORD PTR [XXXXXXXX] )

//【知识点】

//1运算时一定要先把地址存入指向指向单字节指针中

//2要取单字节就将地址存入指向单字节指针中,要取四字节就将地址存入指向四字节的指针中,之后用指针[0]输出即可

PROC SetHook(PROClpFucAdder, PROC pNewProc )

{

LPBYTE                lpByte;

LPDWORD                lpAddr;

DWORD                dwAddr;

 

lpByte= (LPBYTE) lpFucAdder;//【运算时一定要先把地址存入指向指向单字节指针中】

// JMP DWORD PTR [XXXXXXXX] => FF 25 XX XX XX XX ,由于JMP +DWORD PTR 操作码就变成了FF25

if(lpByte[0] == 0xFF && lpByte[1] == 0x25)

{

lpAddr        =(LPDWORD)(&lpByte[2]);

dwAddr        =lpAddr[0];//将XXXXXXXX存入dwAddr中

lpAddr        =(unsigned long *)dwAddr;//XXXXXXXX指向的就是函数体的4字节地址值,要修改函数体的四字节地址值,就要写上XXXXXXXX,见下方的WriteProcessMemory

dwAddr        =lpAddr[0];//将[XXXXXXXX]输出的系统API函数体的地址值存入dwAddr中

 

WriteProcessMemory(GetCurrentProcess(),lpAddr,&pNewProc,sizeof(DWORD),NULL);//修改[XXXXXXXX]输出的地址,即函数体地址

return(PROC)dwAddr;

}

 

returnNULL;

 

}

int APIENTRYMyMessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)

{

int ret= 0;

 

if(lpAdder != NULL)

ret =lpAdder(NULL,"new","new",MB_OK);

 

returnret;

}

 

void main()

 

{

//lpAdder=  MessageBoxA;//存了 " E9 + 步长 "的地址, E9 + 步长会跳转到 " JMP DWORD PTR [AD] " 处

 

LPBYTEpByte;

LPDWORD        pAddr;

DWORDdwAddr;

 

//从JMP后取出步长。先取出步长的地址然后存入LPDWORD的指针中,之后再输出即可得到步长

 

pByte =(LPBYTE) lpAdder;//将 " E9 + 步长 "的地址存入到字节的指针中,为了计算地址用【运算时一定要先把地址存入指向指向单字节指针中】

pAddr        =(LPDWORD)(&pByte[1]);//LPDOWD类型的pAddr是为了输取出4个字节的步长,&pByte[1]见指针逆向来理解【要取四字节就将地址存入指向四字节的指针中,之后用指针[0]输出即可】

dwAddr        =pAddr[0];//取出步长并存入dwAddr中

 

pByte +=5;//加上E9 + 步长所占的5个字节

pByte +=dwAddr;//加上步长,得到JMP DWORD PTR [AD]处的地址

 

//进行HOOK操作

lpAdder= SetHook((PROC)pByte, MyMessageBox);//pByte 指向了  ff 25 dc 73 0c 01 即 JMP DWORD PTR [XXXXXXXX]

 

//调用系统API时,进入MyMessageBox函数,实现HOOK系统API的效果

MessageBoxA(NULL,"old","old",MB_OK);

}


 

XX

 

 

XX

 

 

XX

 

 

XXX

 

 

XXX

 

 

XX

 

 

EDI

 

 

EDI

 

7674EA11

MOV

函数体

 

 

 

 

 

 

 

76

 

 

74

 

 

EA

 

0xDB73DC

11

 

 

 

 

 

 

 

 

00

 

 

DB

 

 

73

 

 

DC

 

 

DWORD PTR

 

0x1068428

JMP

1067045 + 13DE + 5 = 0x1068428

 

 

 

 

 

 

 

00

 

 

00

 

 

13

 

 

DE

 

(MessageBoxA)1067045

E9

E9DE13

0 0
原创粉丝点击