为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

一个Windows进程抓包器的C++实现

2011-02-27 4页 pdf 203KB 68阅读

用户头像

is_247033

暂无简介

举报
一个Windows进程抓包器的C++实现 广西科学院学报 Journal of Guangxi Academy of Sciences 2007,23(4):266~269 Vo1.23,No.4 November 2007 一 个 Windows进程抓包器的 C++实现 Impl ementation of the W indows Process Packetcapture Based on C+ + 胡小春 ,陈 燕。,何潜航。,李陶深。 HU Xiao—chun ,CHEN Yan。,HE Qian—hang。,LI Tao—shen...
一个Windows进程抓包器的C++实现
广西科学院学报 Journal of Guangxi Academy of Sciences 2007,23(4):266~269 Vo1.23,No.4 November 2007 一 个 Windows进程抓包器的 C++实现 Impl ementation of the W indows Process Packetcapture Based on C+ + 胡小春 ,陈 燕。,何潜航。,李陶深。 HU Xiao—chun ,CHEN Yan。,HE Qian—hang。,LI Tao—shen。 (1.广西财经学院计算机与信息管理系,广西南宁 530003;2,广西大学计算机与电子信息学 院,广西南宁 530004) (1 Department of Computer and Information Management,Guangxi University of Finance& Economics,Nanning,Guangxi,530003,China;2. School of Computer,Electronics and Information,Guangxi University,Nanning,Guangxi,530004,China) 摘要:对 Windows进程中的模块 WS2 — 32.dll和 wsock32.dll代码段进行修改,通过 C++的 API函数编程 实现进程抓包器,并以实现 IEXPLORE浏览器抓包的过程为例,给出了进程抓包器的具体编程。 关键 词:Windows进程 抓包 数据包 中图法分类号 :TP393.2 文献标识码 :A 文章编 号:1002—7378(2007)04—0266—04 Abstract:By modifying the codes of WS 32.dl1 and wsock32.dl1 windows models。this paper describes how to implement the process packetcapture based on the C + + API function programming and shows how tO program the process packetcapture by taking the example of how tO implement the IEXPLORE packetcapture. Key words:W indows process,packetcapture,datapacket Windows是一个开放 的系统,一个进程可以对 其它进程进行控制 ,包括内存的访问和读取、虚拟内 存的控制、系统权限的控制等,甚至可以调试其它进 程控制 目标进程的运行 1 ]。要实现这些功能的控制 首先要分析、研究 Windows系统的内核对象管理, 然后研究利用 Win32 ASM对 Windows进程的具体 实现进行分析 、研究 。通过对进程运行的机器码反编 译来分析程序,了解其逻辑结构并加以修改,就可以 让 目标进程按照设定的程序来运行 “]。对于一个经 过加密的进程数据包 ,目前互联网上的软件并不能 截取到进程的明文数据包 。本文通过对 Windows进 程中的模块 WS2 32.dll和 wsock32.dll代码段进 行修改,编程实现进程抓包器,并以 VC++.NET 实现 IEXPLORE浏览器抓包的过程为例 ,介绍进程 抓包器的具体编程实现。 收稿 日期:2007—09—18 作者简介:胡小春(1974一),男,讲师,主要从事计算机网络与并行分 布式计算研究。 *广西大学院 校共 管项 目(X061002)和广西大学创新学分项 目联合 资助 。 l 进程抓包器的实现过程[。] 抓包器实现的目的为了查看和了解进程中数据 包 的 内容 和结构 ,它的 实现主要 是通过 C++的 API函数实现。实现抓包器 的主要过程如下。 (1)在目标进程的窗口中再生成一个窗口,实现 “注入”目标进程的内部 窗 口用于显示截取到的数 据包内容。“注入”的操作就是把一个模块或者 自己 编写功能代码段潜入到目标进程 中去 。“注入”的方 法有远端线程注入、系统内核级注入等,最常用的是 在 系 统 上 安 装 “钩 子 (HOOK)”。API的 函数 SetWindowsHookEx可 以实施 一个钩子的安装 ,并 且可以把相应的消息传送到指定的回调函数处理。 系统发送给各种程序窗口的消息都要先经过钩子处 理之后再送到 目的窗 口,而在钩子处理到来的消息 之前 Windows已经 自动把 “钩子”“钩”在 了消息 目 的进程窗口上了,也就是说此时“钩子”已经“混入” 了目的窗口的内部。利用HOoK可以把一个或几个 模块加载进入目标进程,并截取目标进程的窗口消 息。钩子设定成功后,当系统有键盘消息要传给目标 维普资讯 http://www.cqvip.com 胡小春等:一个Windows进程抓包器的c++实现 267 进 程 窗 口时 ,键 盘 消 息 就 会 先 经 过 回 调 函 数 KeyboardProc进行处理 ;而模块 g hlnstance就会 在钩子设定成功后,系统传给目标进程窗口第一个 键盘消息的时候被注入到目标进程。 (2)修 改 目标 进 程 的模 块 WS2 32.dll和 wsock32.dll数据包传输函数的代码段,使得程序跳 转到设计好的数据包处理 函数里执行 ,完成之后再 跳转回原来的代码执行 。设计的函数主要完成数据 包过滤,并把过滤的信息在数据包窗口中显示出来。 模块 WS2 32.dll中数据包的发送和接收函数分别 是 send和 recv,模块 wsock32.dll中数据包 的接收 函数是 recv。Windows socket中有两个接收函数 ,由 于不可能预先知道 目标进程将用哪个模块 中的接收 函数,所 以在设计时同时处理 。 (3)最后,在用 自己定义的 mysend()函数时要 先把 send函数的代码还原,然后再调用,之后如果 想继续截取 send函数 的数据 ,就再次修 改 send函 数的代码 。 通过 以上 3个 过程 ,可 以截取到进程发送 的数 据包,也可以截取该进程任何函数的数据。以下是用 到的两个关键 函数 。 ①回调函数: LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM 1Param ){ B0OL bKeyUp一 (BOOL)1Param & (1< < 31); if(bKeyUp&& wParam — VK H0ME&& nCode — HC ACT10N)//截取到按下 HOME键的消息 1 ⋯ ⋯ ; //按下 H()ME键后的处理代码 ,生成数据包 显示窗口 ) ) ②SetWindowsHookEx函数: SetWindowsHookEx(W H — KEYBOARD, (HOOKPROC)KeyboardProc, g — hInstance, wThreadID);//KEYBOARD是 指定 是 键 盘消 息 ; (HO0KPROC)KeyboardProc是消息处理的回调 函 数 ;g hlnstance 指 定 要 注 入 的 模 块 基 址; dwThreadID是 目标进程窗 口线程 ID。 2 进程抓包器的具体实现 2.1 抓包器注入模块的实现 抓包器 的注入模块通过以下 7个步骤实现。 (1)用 VC++.NET新建一个解决,在方 案里添加一个 MFC DLL工程 ,命名 为 Packet。在 Packet中添加窗 口 ID为 IDD DIALOG MAIN。 然后为这个 窗 口添加类 CMainWnd继承 CDialog。 窗 口中三个勾选框 Send,Recv2,Recvs分别表示是 否 打 开对 wS2 32.dll中 send,WS2 32.dll中 recv,wsock32.dll中 recv行数 的拦截。 (2)新 建 类 CJmpHookApi,对 应 的 文 件 为 JmpHookApi.cpp和 JmpHookApi.h。CJmpHookApi 类 目的是获得 IE的句柄、得到 IE的控制权 ,并在其 中实现抓包的最终目的。 @JmpHookApi.h文件的主要代码 : public: FARPROC In lpOldFunc;//要钩的目标的函数 FARPROC m lpNewFunc;//新的函数 CJmpHookApi(): virtual~CJmpHookApi(); BOOL InitMemory();//初始化得到内存数据 (模块名,函数名 ,新函数 FARPROC) void SetHookOn();//启用 新函数 void SetHookOff();//不启用 新 函数 void UnLock(); void Lock(); protected: HANDLE In hProc;//进程句柄 BYTE ITI bO1dData[5];//内存旧数据 BYTE ITI bNewData~5 ;//内存新数据 CRITICAL SECTION ITI CS;};//CRITICAL SECTION 属于轻量级的线程同步对象 ②JmpHookApi.cpp里几个重要的函数实现代 码 : CJmpHookApi::CJmpHookApi() //得到当前进程的伪句柄,并初始化 CRITICAL SECTION BOOL CJmpHookApi::InitMemory() { DWORD dwOldF!ag;//修改旧函数内存前 5 字节为 PAGE READWRITE if(VirtualProtectEx(m — hProc,ITI — lpOldFunc,5, PAGE READWRITE,g>dwOldFlag)) { //调入旧函数内存前 5字节 if(ReadProcessM ernory(m hProc,ITI lpOldFunc, Ill — bOldData,5,O)) { //取得旧函数内存前 5字节内存数据 if(VirtualProtectEx (ITI — hProc,ITI — lpOldFunc, 5,dwOldFlag,g>dwOldFlag)) 维普资讯 http://www.cqvip.com 268 广西科学院学报 第 23卷 第 4期 2007年 11月 { m bNewData[03—0xE9;//JMP指 令 DW ORD pNewFuncAddress: //得到新函数的地址 · · · · · · 、 void CJmpHookApi::SetHoOkOn() //修改旧函数内存前 5字节为新的内容 void CJmpHookApi::SetHookOff() //修改旧函数内存前 5字节为原来内容 void CJmpHookApi::Lock()//多线程下使用 进 入临界区 void CJmpHookApi::UnLock()//多线程下使用离 开临界区 (3)新建文件Globa1.h和 Globa1.cpp,主要是定 义全局变量和 自定义的函数实现,例如 mysend、 myrecv、myrecvs函数的实现。Globa1.h的几个主要 变量 : typedef int (W SAAPI * FUNW S2 32) (IN SOCKET,IN const char FAR *,IN int,IN int); extern FUNWS2 32 funRecv;//WS2 32.dll原 recv函数基址 extern FUNWS2 32 funRecvs;//wsock32.dll原 recv函数基址 extern FUNWS2 32 funSend;//WS2 32.dll原 send函数基址 extern SOCKET g Socket;//上 次 send函数 的 SOCKET extern CMainW nd g — pMainWnd;//抓包器 窗 体指针 //新的数据包处理函数声明 int stdcall FAR mysend (SOCKET S,const char FAR * buf,int len,int flags); int stdcall FAR myrecv (S0CKET S,const char FAR * buf,int len,int flags); int stdcall FAR myrecvs(SOCKET S,const char FAR * buf,int len,int flags); BOOL HooklnitMemory(void);//内存初始化 void ShowPack(char pData,int len,int type);// 显示数据包 BOOL CheckFilter(const char FAR pData,int nFlag);//判断数据包第一个字节的过滤器 BOOL CheckFilterLen(int nLen,int nFlag); //N 断数据包长度的过滤器 int StringToHex(char* strIn,char* strOut); //字符串转换为数据 void Char2Cstring(char* buf,int len,CString Str);//数据转换为字符 串 CString GetConfigFileName();//获得保存的配置 文件名 BOOL GetCListCtrl(CListCtrl pList,CString strListKey,int nColCount,CString strFileName) //读取并设定 List控件内容 BOOL SaveCListCtrl(CListCtrl pList,CString strListKey,int nColCount,CString strFileName) //保存 List控件 内容 (4)新建文件 Hook.h和 Hook.cpp,主要实现 Hook成功后的回调函数的处理 ,代码如下 : ||Hook.cpp extern HINSTANCE g — hlnstance;//当前模块的基 址 BOOL declspec(dllexport)W INAPI tnstallHook (DWORD dwThreadId);//安装勾子 B0()L declspec (dllexport ) WINAPI UninstallHook(void);//取消勾子 LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam,LPARAM 1Param);//消息处 理回调函数 ||Hook.cpp #include”stdafx.h” #include"Globa1.h,, #include Hook.h” HHOOK g — hhook—NULL;//勾子 HINSTANCE g ~ hlnstance— NULL;//当前模 块 的基址 //HOOK成功后 处 理 WH KEYBOARD 消息的 回调函数 LRESULT CALLBACK KeyboardProc(int nCode, W PARAM wParam ,LPARAM 1Param ) ( if(bKeyUp 8L& wParam — VK — HOME 8L8L nCode=HC ACTION)//截取到按下 HOME键的 消息 {if(g — pMainWnd一一 NULL)//窗口生成代 码 {CWnd::GetForegroundWindow();//找到 当前窗口 if(pCW nd! 一NULL) {g — pMainW nd — new CM ainW nd(). g — pMainW nd 一 > Create (CM ainW nd:: IDD, pCW nd); 维普资讯 http://www.cqvip.com 胡小春等:一个 Windows进程抓包器的c++实现 269 ⋯ ⋯ //在当前窗 口创建抓包器窗口 } (5)在 Packet.cpp中包括文件 Hook.h,添加函 数 Initlnstance()和 ExitInstance()。 #inc1ude”Hook.h , BOOL CPacketApp::Initlnstance() { AfxInitRichEdit(); CW inAPP::Initlnstance(); g—hInstance-二 theApp.m — hInstance; //得到当前模块的基址 if(!AfxSocketInit()) {AfxMessageBox(IDP — SOCKETS — INIT — FAILED): return FALSE;} return TRUE; } BOOL CPacketApp::Exitlnstance() { JmpSend.SetHookOff(); //还原代码段 JmpRecv.SetHookOff(); //还原代码段 UninstallHook(); //清理钩子 } (6)在解决方案的配置处选择 Release,并把工 程 Packet的输出 目录改为 out。 (7)用 Release生成工程 Packet,生成后 ,在../ out目录可以看到 Packet.dll和 Packet.1ib文件。 2.2 抓包器注入程序的实现 抓包器的注入程序通过 以下 3个步骤实现 。 (1)在解决方案添加一个 MFC应用程序工程, 作为简单的CDialog应用程序,命名为Begin。在窗 体中添加开始按钮 ,按钮执行的代码段如下: #include ../Packet/Hook.h”//勾 子 函数定 义文 件 void CBeginDlg::OnBnC1ickedButtonBegin()//开始 按钮 {DW0RD dwThreadlD 一 0x0; CW nd pCW nd — FindW indow ( T ( IEFrame”),NULL);//打开 IE浏览器 if(dwThreadID ! ===0x0) {InstallHook(dwThreadlD);//安装钩子 OutputDebugString(’ InstallHook(dwThreadID) ’); CString outM sg; outMsg.Format(”目标 :%08x”,dwThreadlD); SetW indowText(outMsg); GetDlgltem (IDC — BUTTON — BEGIN ) 一 > EnableW indow(FALSE) } else MessageBox( 没有找到目标 ,”提示”,MB — UK); } (2)把 Begin的输 出 目录也 改为../out,并输 入 ,附加依赖../out/Packet.1ib。 (3)用 Release生成 Begin。 2.3 抓包器应用测试 按以下步骤对抓包器进行测试。 (1)运行 2.2中生成的 Begin.exe程序,点击开 始 ,如果没有 打开 IE,则提示找不到 目标。如果 IE 已经 打开,则可 以看到 Begin的窗 口标变 为:目 标 :0X000xxxx。找到目标之后 ,在 IE里按下 HOME 键 ,就可以看到抓包器的窗 口了。 (2)用调试器 OllyICE调试 。重新打开 IE,然后 打 开调试器 ,动态加载 IE进程 。加载完成后察看 OllyICE的模块列表 。 (3)运行 Begin程序,点击开始,然后在被调试 的 IE里按 下 HOME键 ,可以看 到调试器 OllylCE 的模块列表里面增加了Packet.dll模块,已经 成功注入抓包器模块了。 (4)在调试器 OllyICE中查找所有模块 中的名 称 ,找到 WS2 32.dll中的 send函数,双击 send函 数转到CPU视图的send函数的基址。然后钩选抓 包器 中的 send,可以在 OllyICE里看到 WS2 32.dll 中的send函数的前 5个字节的指令被改为:JMP Packet.XXXX,取消抓包器的 send的钩选,这条指令 又会被还原。可以用 同样的方法测试其它两个 recv 函数 。 3 结束语 利 用 HOOK 来 截 取 Windows的 消 息 是 Windows核心编程的基础知识,可以利用 HOOK实 现丰 富的 Windows程序 效果。更 重要 的是 ,通过 HOOK可以实现 Windows进程对象的控制,进一步 了解 Windows对内核对象的管理原理。 参考 文献: [1] 孟庆倩 ,李清宝.基于 Windows环境进程监控的设计 与实现[J].信息工程大学学报,2007,8(1):26—29. [2] 王峰,董亮卫.Windows(2000/XP)下隐藏进程的检测 机制EJ].计算机工程,2006,32(2O):95—96,99. [3] 周炎涛.Windows中的多线程编程技术和实现EJ].计 算技术与 自动化 ,2002,21(3):109—116. [4] 梁骥.防火墙与入侵检测系统(IDS)互动模型的构建 EJ].广西科学院学报,2007,23(2):80—81,84. (责任编辑:韦廷宗) 维普资讯 http://www.cqvip.com
/
本文档为【一个Windows进程抓包器的C++实现】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索