拦截聊天记录--Hook技巧简介【原创】

一、    战场环境

[兵工场]:VC6.0

[兵器谱]: Detours Express 2.1、Windbg6.11、OllyDBG

二、    战术分析

Hook从字面上理解就是钩子的意思,当然这个钩子不是用来钓鱼的。它是用来挂钩程序用的,程序一但被挂钩就可以改变程序原有的流程。例如Hook之前的流程如下:

Hook后的流程如下:

拦截XX聊天信息的基本原理就是挂钩XX的聊天记录函数,使得我们可以中途处理聊天记录。

要改变程序的流程有很多汇编指令可以使用,常用的有两种:JMP、CALL

下面是用OllyDBG反汇编MessageBox得到的头部代码:

77D5050B >    8BFF          MOV EDI,EDI

77D5050D  /.  55            PUSH EBP

77D5050E  |.  8BEC          MOV EBP,ESP

这五个字节的指令是保护堆栈用的。我们要攻击的地方就是这5个字节。

Hook后那5个字节是怎么样的呢?在调试过程中发现Hook后OD不稳定,Hook的5个字节变成了下面的样子:

77D5050B >- E9 FA0A2B98     JMP HookDll.1000100A

77D50510    833D 1C04D777 0>CMP DWORD PTR DS:[77D7041C],0

77D50517    74 24           JE SHORT USER32.77D5053D

77D50519    64:A1 18000000  MOV EAX,DWORD PTR FS:[18]

 

跟进跳转看看做了什么……

一个很大的跳转,继续跟进跳转到下面,我们自己写的代码

100010C0    55              PUSH EBP

100010C1    8BEC            MOV EBP,ESP

100010C3    83EC 44         SUB ESP,44

100010C6    53              PUSH EBX

100010C7    56              PUSH ESI

100010C8    57              PUSH EDI

100010C9    8D7D BC         LEA EDI,DWORD PTR SS:[EBP-44]

100010CC    B9 11000000     MOV ECX,11

100010D1    B8 CCCCCCCC     MOV EAX,CCCCCCCC

100010D6    F3:AB           REP STOS DWORD PTR ES:[EDI]

100010D8    8BF4            MOV ESI,ESP

100010DA    8B45 14         MOV EAX,DWORD PTR SS:[EBP+14]

100010DD    50              PUSH EAX

100010DE    68 30E00210     PUSH HookDll.1002E030

100010E3    68 1CE00210     PUSH HookDll.1002E01C

100010E8    8B4D 08         MOV ECX,DWORD PTR SS:[EBP+8]

100010EB    51              PUSH ECX

100010EC    FF15 306C0310   CALL DWORD PTR DS:[10036C30]

100010F2    3BF4            CMP ESI,ESP

100010F4    E8 971D0000     CALL HookDll.10002E90

100010F9    8945 FC         MOV DWORD PTR SS:[EBP-4],EAX

100010FC    8B45 FC         MOV EAX,DWORD PTR SS:[EBP-4]

100010FF    5F              POP EDI

10001100    5E              POP ESI

10001101    5B              POP EBX

10001102    83C4 44         ADD ESP,44

10001105    3BEC            CMP EBP,ESP

10001107    E8 841D0000     CALL HookDll.10002E90

1000110C    8BE5            MOV ESP,EBP

1000110E    5D              POP EBP

1000110F    C2 1000         RETN 10

 

看到红色那句没?执行后后回到了原调用MessageBox后面的代码,也就是上面的代码段B

这里提下windbg调试器,掌握了它,windows的秘密再也就是秘密了

下面是对程序的分析结果:

看到没有加载了两个DLL,Hook要成功的一个重要前提是能够读写进程的内存,否则没办法写任何字节。通常的方法是写一个DLL注意的进程的空间。网上有一大堆这种DLL注入器,这里就不一一介绍了。

一、    实弹演练

我八成猜到看到这的人已经云里雾里了,放心微软放出了Detours Express 2.1(XX聊天拦截我没用这玩意,根据原理自己实现的)专门干这事的。由于我国有明确的法律规定,不能发行恶意代码,所以XX聊天记录拦截代码就不放出来了。下面以我写的一个Demo为例来介绍。DEMO的功能是通过加载HookDll.dll实例挂钩USER32.DLL里的MessageBox.  HookDll里实现所有的挂钩操作。

1.加载DLL前,弹框内容如下:

      

  

2。加载DLL后,弹框内容如下:

MessageBox弹框内容已经被修改。

3.卸载DLL后,弹框内容如下:

下面讲解一下Detours Express 2.1库的使用:

Detours的几个核心API如下:

用到的几个API简要说明下:
DetourTransactionBegin: 开始一个新的detours事务。
DetourUpdateThread:一个线程入队等待更新

DetourAttach:将目标进程(MessageBox)和替换它的函数NEW_MessageBox绑定。第一个参数是一个指针,这个指针指向目标函数的指针(有点绕…)。
DetourTransactionCommit: 事务提交,如果不提交之前的更改是不会生效的。这个函数会返回一个值,如果是NO_ERROR 表明是成功,如果是其他的表示失败。
DetourDetach:解除目标进程和替换函数的绑定,参数和DetourDetach一摸一样。

下面是Hook代码:

VOID Hook() 

  DetourRestoreAfterWith(); 

  DetourTransactionBegin(); 

  DetourUpdateThread(GetCurrentThread()); 

 

  //这里可以连续多次调用DetourAttach,表明HOOK多个函数 

  DetourAttach(&(PVOID&)TrueMessageBox,NEW_MessageBoxA); 

 

  DetourTransactionCommit(); 

  OutputDebugString("Hook Success!\n");

原始函数MessageBoxA由windows.h声名了,直接用下面的方式使用

static int (WINAPI* TrueMessageBox)(HWND hWnd , LPCSTR lpText, LPCSTR lpCaption, UINT uType)=MessageBoxA;

 

我们定义的新MessageBoxA如下:

int WINAPI NEW_MessageBoxA(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType) 

      

       //修改输入参数,调用原函数 

       int ret=TrueMessageBox(hWnd,"该函数已经被Hook","[测试]",uType); 

       return ret; 

在完成了任务之后一定要把钩子摘掉:

VOID UnHook() 

       DetourTransactionBegin(); 

       DetourUpdateThread(GetCurrentThread()); 

      

       //这里可以连续多次调用DetourDetach,表明撤销多个函数HOOK 

       DetourDetach(&(PVOID&)TrueMessageBox,NEW_MessageBoxA); 

      

       DetourTransactionCommit(); 

       OutputDebugString("UnHook Success!\n"); 

}

 

 

注意:我们如果要拦截非windows API的话,通常用下面两个函数实现原有函数地址的导出:

LoadLibrary()

GetProcAddress()

 

程序下载地址:

http://pan.baidu.com/netdisk/singlepublic?fid=434312_4232810461

 

 

http://blog.csdn.net/liujiayu2/article/details/50625337

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值