截取程序的网络封包(Delphi Hook API)

2017-08-13 16:30:28来源:oschina作者:伽罗kapple人点击

分享

有时候我们需要对其它应用程序发送和接收的网络数据进行拦截,比如要对IE发送的**头进行分析,得到请求的地址等.这次我们可以用一些例如WPE, Sniffer之类的工具来达到目的.但是工具功能有限,要想实现更强大的功能,还是我们自己动手来DIY吧.拦截网络数据封包的方法有三种,一是将网卡设为混杂模式,这次就可以监视到局域网上所有的数据包,二是HOOK目标进程的发送和接收的API函数,第三种方法是自己实现一个代理的DLL.在这里我们使用HOOK API的方法,这样易于实现,而且也不会得到大量的无用数据(如第一种方法就会监视到所有的网络数据).下面是一个尽量简化了的API HOOK的模版,原理是利用消息钩子将DLL中的代码注入到目标进程中,再用GetProcAddress得到API函数入口地址,将函数入口址改为自己定义的函数入口,这样就得到了API函数的相应参数,处理完后,再改回真实API函数入口地址,并调用它. HOOK.DLL的代码:


Delphi代码



收藏代码

libraryHook;uses
SysUtils,
windows,
Messages,
APIHookin'APIHook.pas';type
PData=^TData;
TData=record
Hook:THandle;
Hooked:Boolean;
end;var
DLLData:PData;{------------------------------------}
{过程名:HookProc
{过程功能:HOOK过程
{过程参数:nCode,wParam,lParam消息的相
{关参数
{------------------------------------}
procedureHookProc(nCode,wParam,lParam:LongWORD);stdcall;
begin
ifnotDLLData^.Hookedthen
begin
HookAPI;
DLLData^.Hooked:=True;
end;
//调用下一个Hook
CallNextHookEx(DLLData^.Hook,nCode,wParam,lParam);
end;{------------------------------------}
{函数名:InstallHook
{函数功能:在指定窗口上安装HOOK
{函数参数:sWindow:要安装HOOK的窗口
{返回值:成功返回TRUE,失败返回FALSE
{------------------------------------}
functionInstallHook(SWindow:LongWORD):Boolean;stdcall;
var
ThreadID:LongWORD;
begin
Result:=False;
DLLData^.Hook:=0;
ThreadID:=GetWindowThreadProcessId(sWindow,nil);
//给指定窗口挂上钩子
DLLData^.Hook:=SetWindowsHookEx(WH_GETMESSAGE,@HookProc,Hinstance,ThreadID);
ifDLLData^.Hook>0then
Result:=True//是否成功HOOK
else
exit;
end;{------------------------------------}
{过程名:UnHook
{过程功能:卸载HOOK
{过程参数:无
{------------------------------------}
procedureUnHook;stdcall;
begin
UnHookAPI;
//卸载Hook
UnhookWindowsHookEx(DLLData^.Hook);
end;{------------------------------------}
{过程名:DLL入口函数
{过程功能:进行DLL初始化,释放等
{过程参数:DLL状态
{------------------------------------}
procedureMyDLLHandler(Reason:Integer);
var
FHandle:LongWORD;
begin
caseReasonof
DLL_PROCESS_ATTACH:
begin//建立文件映射,以实现DLL中的全局变量
FHandle:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,$ffff,'MYDLLDATA');
ifFHandle=0then
ifGetLastError=ERROR_ALREADY_EXISTSthen
begin
FHandle:=OpenFileMapping(FILE_MAP_ALL_ACCESS,False,'MYDLLDATA');
ifFHandle=0thenExit;
endelseExit;
DLLData:=MapViewOfFile(FHandle,FILE_MAP_ALL_ACCESS,0,0,0);
ifDLLData=nilthen
CloseHandle(FHandle);
end;
DLL_PROCESS_DETACH:
begin
ifAssigned(DLLData)then
begin
UnmapViewOfFile(DLLData);
DLLData:=nil;
end;
end;
end;
end;{$R*.res}
exports
InstallHook,UnHook,HookProc;begin
DLLProc:[email protected];
MyDLLhandler(DLL_PROCESS_ATTACH);
DLLData^.Hooked:=False;
end.----------------------------------------------------------------------------------------
APIHook.Pas的代码:unitAPIHook;interfaceuses
SysUtils,
Windows,WinSock;type
//要HOOK的API函数定义
TSockProc=function(s:TSocket;varBuf;len,flags:Integer):Integer;stdcall;PJmpCode=^TJmpCode;
TJmpCode=packedrecord
JmpCode:BYTE;
Address:TSockProc;
MovEAX:Array[0..2]ofBYTE;
end;//--------------------函数声明---------------------------
procedureHookAPI;
procedureUnHookAPI;var
OldSend,OldRecv:TSockProc;//原来的API地址
JmpCode:TJmpCode;
OldProc:array[0..1]ofTJmpCode;
AddSend,AddRecv:pointer;//API地址
TmpJmp:TJmpCode;
ProcessHandle:THandle;
implementation{---------------------------------------}
{函数功能:Send函数的HOOK
{函数参数:同Send
{函数返回值:integer
{---------------------------------------}
functionMySend(s:TSocket;varBuf;len,flags:Integer):Integer;stdcall;
var
dwSize:cardinal;
begin
//这儿进行发送的数据处理
MessageBeep(1000);//简单的响一声
//调用直正的Send函数
WriteProcessMemory(ProcessHandle,AddSend,@OldProc[0],8,dwSize);
Result:=OldSend(S,Buf,len,flags);
JmpCode.Address:[email protected];
WriteProcessMemory(ProcessHandle,AddSend,@JmpCode,8,dwSize);
end;{---------------------------------------}
{函数功能:Recv函数的HOOK
{函数参数:同Recv
{函数返回值:integer
{---------------------------------------}
functionMyRecv(s:TSocket;varBuf;len,flags:Integer):Integer;stdcall;
var
dwSize:cardinal;
begin
//这儿进行接收的数据处理
MessageBeep(1000);//简单的响一声
//调用直正的Recv函数
WriteProcessMemory(ProcessHandle,AddRecv,@OldProc[1],8,dwSize);
Result:=OldRecv(S,Buf,len,flags);
JmpCode.Address:[email protected];
WriteProcessMemory(ProcessHandle,AddRecv,@JmpCode,8,dwSize);
end;{------------------------------------}
{过程功能:HookAPI
{过程参数:无
{------------------------------------}
procedureHookAPI;
var
DLLModule:THandle;
dwSize:cardinal;
begin
ProcessHandle:=GetCurrentProcess;
DLLModule:=LoadLibrary('ws2_32.dll');
AddSend:=GetProcAddress(DLLModule,'send');//取得API地址
AddRecv:=GetProcAddress(DLLModule,'recv');
JmpCode.JmpCode:=$B8;
JmpCode.MovEAX[0]:=$FF;
JmpCode.MovEAX[1]:=$E0;
JmpCode.MovEAX[2]:=0;
ReadProcessMemory(ProcessHandle,AddSend,@OldProc[0],8,dwSize);
JmpCode.Address:[email protected];
WriteProcessMemory(ProcessHandle,AddSend,@JmpCode,8,dwSize);//修改Send入口
ReadProcessMemory(ProcessHandle,AddRecv,@OldProc[1],8,dwSize);
JmpCode.Address:[email protected];
WriteProcessMemory(ProcessHandle,AddRecv,@JmpCode,8,dwSize);//修改Recv入口
OldSend:=AddSend;
OldRecv:=AddRecv;
end;{------------------------------------}
{过程功能:取消HOOKAPI
{过程参数:无
{------------------------------------}
procedureUnHookAPI;
var
dwSize:Cardinal;
begin
WriteProcessMemory(ProcessHandle,AddSend,@OldProc[0],8,dwSize);
WriteProcessMemory(ProcessHandle,AddRecv,@OldProc[1],8,dwSize);
end;end.

--------------------------------------------------------------------------------------------- 编译这个DLL后,再新建一个程序调用这个DLL的InstallHook并传入目标进程的主窗口句柄就可:


Delphi代码



收藏代码

unitfmMain;interfaceuses
Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,
Dialogs,StdCtrls;type
TForm1=class(TForm)
Button1:TButton;
Button2:TButton;
Edit1:TEdit;
procedureButton1Click(Sender:TObject);
procedureButton2Click(Sender:TObject);
private
{Privatedeclarations}
public
{Publicdeclarations}
end;var
Form1:TForm1;
InstallHook:function(SWindow:THandle):Boolean;stdcall;
UnHook:procedure;stdcall;
implementation{$R*.dfm}procedureTForm1.Button1Click(Sender:TObject);
var
ModuleHandle:THandle;
TmpWndHandle:THandle;
begin
TmpWndHandle:=0;
TmpWndHandle:=FindWindow(nil,'目标窗口的标题');
ifnotisWindow(TmpWndHandle)then
begin
MessageBox(self.Handle,'没有找到窗口','!!!',MB_OK);
exit;
end;
ModuleHandle:=LoadLibrary('Hook.dll');
@InstallHook:=GetProcAddress(ModuleHandle,'InstallHook');
@UnHook:=GetProcAddress(ModuleHandle,'UnHook');
ifInstallHook(FindWindow(nil,'Untitled'))then
ShowMessage('HookOK');
end;procedureTForm1.Button2Click(Sender:TObject);
begin
UnHook
end;end.

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台