首页 电脑 电脑学堂 查看内容

详解截取封包的原理

2012-4-24 15:29 593 0

摘要: 最近帮人写一个截取封包改发封包的东西,由于起初什么都不懂也就开始疯狂的查资料,但是网上都千篇一律的。。。。就是这个转那个,但是那些都把基础的讲到了,但是对于像我这种什么都还不懂的人就困难了。。。。我安...
关键词: nbsp 封包 757 024 dword push eax Integer ProcessHandle JmpCode

最近帮人写一个截取封包改发封包的东西,由于起初什么都不懂也就开始疯狂的查资料,但是网上都千篇一律的。。。。就是这个转那个,但是那些都把基础的讲到了,但是对于像我这种什么都还不懂的人就困难了。。。。我安装网上说的用hook技术写了一个小程序,就是hook ws2_32的send 与recv  函数数而实现的,但是我问题就出现了,hook到他的解收和发送封包又怎么用呢??????想必刚刚开始你也有这样的疑问吧。。。。下面我就详细讲一下我所理解的下面首先是在网上的源码,进过小小的改动//////////////////////////////////////////////////////////////////////////////////////////首先是创建dll文件用来hook程序安装钩子 library mydll; { Important note about DLL memory management: ShareMem must be the  first unit in your library's USES clause AND your project's (select  Project-View Source) USES clause if your DLL exports any procedures or  functions that pass strings as parameters or function results. This  applies to all strings passed to and from your DLL--even those that  are nested in records and classes. ShareMem is the interface unit to  the BORLNDMM.DLL shared memory manager, which must be deployed along  with your DLL. To avoid using BORLNDMM.DLL, pass string information  using PChar or ShortString parameters. } uses  SysUtils,  Classes,  messages,  Variants,  windows,  hookapi_pas in 'hookapi_pas.pas';   typePData = ^TData;TData = recordHook: THandle;Hooked: Boolean;end; varDLLData: PData;{$R *.res}  {------------------------------------}{过程名:HookProc{过程功能:HOOK过程{过程参数:nCode, wParam, lParam消息的相{ 关参数{------------------------------------}procedure HookProc(nCode, wParam, lParam: LongWORD);stdcall;beginif not DLLData^.Hooked thenbeginHookAPI;DLLData^.Hooked := True; end; //调用下一个HookCallNextHookEx(DLLData^.Hook, nCode, wParam, lParam); end;  {------------------------------------}{函数名:InstallHook{函数功能:在指定窗口上安装HOOK{函数参数:sWindow:要安装HOOK的窗口{返回值:成功返回TRUE,失败返回FALSE{------------------------------------}function InstallHook(SWindow: LongWORD):Boolean;stdcall;varThreadID: LongWORD;beginResult := False;DLLData^.Hook := 0;ThreadID := GetWindowThreadProcessId(sWindow, nil);//给指定窗口挂上钩子DLLData^.Hook := SetWindowsHookEx(WH_GETMESSAGE, @HookProc, Hinstance, ThreadID);if DLLData^.Hook > 0 thenResult := True //是否成功HOOKelseexit;end; {------------------------------------}{过程名:UnHook{过程功能:卸载HOOK{过程参数:无{------------------------------------}procedure UnHook;stdcall;beginUnHookAPI;//卸载HookUnhookWindowsHookEx(DLLData^.Hook);end; {------------------------------------}{过程名:DLL入口函数{过程功能:进行DLL初始化,释放等{过程参数:DLL状态{------------------------------------}procedure MyDLLHandler(Reason: Integer);varFHandle: LongWORD;begincase Reason ofDLL_PROCESS_ATTACH:begin //建立文件映射,以实现DLL中的全局变量fhandle:=createfilemapping($ffffffff,nil,page_readwrite,0,$ffff,'mydlldata'); if FHandle = 0 thenif GetLastError = ERROR_ALREADY_EXISTS thenbeginFHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False,'mydlldate');if FHandle = 0 then Exit;end else Exit;DLLData := MapViewOfFile(FHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);if DLLData = nil thenCloseHandle(FHandle);end;DLL_PROCESS_DETACH:beginif Assigned(DLLData) thenbeginUnmapViewOfFile(DLLData);DLLData := nil;end;end;end;end; {$R *.res}exportsInstallHook, UnHook, HookProc; beginDLLProc := @MyDLLHandler;MyDLLhandler(DLL_PROCESS_ATTACH);DLLData^.Hooked := False;end. 再在dll文件创建一个.pas的文件<这个是用来hook你想hook的api>unit hookapi_pas; interfaceusesSysUtils,Windows, WinSock,dialogs; type//要HOOK的API函数定义 TSockProc = function (s: TSocket; Buf:integer; len, flags: Integer): Integer; stdcall;PJmpCode = ^TJmpCode;TJmpCode = packed recordJmpCode: BYTE;Address: TSockProc;MovEAX: Array [0..2] of BYTE;end;procedure hookapi;procedure unhookapi;procedure saveinfo(ss:string);stdcall;function recvout(var Rbuf;RLen:Integer):string; varii:integer=1;OldSend, OldRecv: TSockProc; //原来的API地址JmpCode: TJmpCode;OldProc: array [0..1] of TJmpCode;AddSend, AddRecv: pointer; //API地址TmpJmp: TJmpCode;ProcessHandle: THandle; buf_f:array [1..100] of byte   ; implementation   procedure saveinfo(ss:string);stdcall;varf:file;filename:string;begin  filename:='d:\test.txt';  assignfile(f,filename);   closefile(f);  end ;  function recvout(var Rbuf;RLen:Integer):string;Varbuf1:pchar;i:integer;ss:string;Beginss:='';buf1:=@Rbuf;for i:=3 to 4 doBegin ss:=ss+inttohex(byte(buf1^),2)+' '  ;buf1:=buf1+1;End;result:=ss;  End;   function MySend(s: TSocket;  Buf,len, flags: Integer): Integer; stdcall;vardwSize: cardinal;tmp:string ;i:integer;begin//这儿进行发送的数据处理 MessageBeep(1000); //简单的响一声 //调用直正的Send函数WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);Result := OldSend(S, Buf, len, flags);JmpCode.Address := @MySend;WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize);end; {---------------------------------------}{函数功能:Recv函数的HOOK{函数参数:同Recv{函数返回值:integer{---------------------------------------}function MyRecv(s: TSocket;  Buf, len, flags: Integer): Integer; stdcall;vardwSize: cardinal;mc: byte;m_buf:pchar;i:integer; begin    ////////这里可以加入你处理封包的代码我用接受封包来讲解:首先用od加载我要的游戏,转到recv函数处,  MessageBeep(1000); //简单的响一声 WriteProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);Result := OldRecv(S, Buf, len,flags); JmpCode.Address := @MyRecv; WriteProcessMemory(ProcessHandle, AddRecv, @JmpCode, 8, dwSize); MessageBeep(1000);      end; {------------------------------------}{过程功能:HookAPI{过程参数:无{------------------------------------}procedure HookAPI;varDLLModule:thandle;dwSize: cardinal;beginProcessHandle := GetCurrentProcess;DLLModule:= LoadLibrary('ws2_32.dll');addsend:=getprocaddress(dllmodule,'send');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 := @MySend;WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize); //修改Send入口ReadProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);JmpCode.Address := @MyRecv;WriteProcessMemory(ProcessHandle, AddRecv, @JmpCode, 8, dwSize); //修改Recv入口OldSend := AddSend;OldRecv := AddRecv;end; {------------------------------------}{过程功能:取消HOOKAPI{过程参数:无{------------------------------------}procedure UnHookAPI;vardwSize: Cardinal;beginWriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);WriteProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);end; end.   ///////通过上面得编译你便能够编译出你的dll文件了我们都知道dll文件时不可能单独运行的,所以我们要用exe用来加载你的dll文件了 这个就自己写<网上一查便能查到了>  好我们hook socket 的程序便写好了 这个是没有处理封包的过程。下面我来讲一下如何处理封包了首先看一下他的原理是什么。我用一个棋牌游戏来说明757B47DF >  8BFF            mov edi,edi                              ; recv的入口点757B47E1    55              push ebp757B47E2    8BEC            mov ebp,esp757B47E4    83EC 10         sub esp,0x10757B47E7    53              push ebx757B47E8    33DB            xor ebx,ebx757B47EA    813D 48707D75 3>cmp dword ptr ds:[0x757D7048],WS2_32.757>757B47F4    56              push esi757B47F5  ^ 0F85 F4EEFFFF   jnz WS2_32.757B36EF757B47FB    391D 70707D75   cmp dword ptr ds:[0x757D7070],ebx757B4801  ^ 0F84 E8EEFFFF   je WS2_32.757B36EF757B4807    FF35 44707D75   push dword ptr ds:[0x757D7044]757B480D    FF15 48127B75   call dword ptr ds:[<&API-MS-Win-Core-Pro>; kernel32.TlsGetValue757B4813    8945 F8         mov dword ptr ss:[ebp-0x8],eax757B4816    3BC3            cmp eax,ebx757B4818  ^ 0F84 D1EEFFFF   je WS2_32.757B36EF757B481E    895D FC         mov dword ptr ss:[ebp-0x4],ebx757B4821    FF75 08         push dword ptr ss:[ebp+0x8]757B4824    E8 47E8FFFF     call WS2_32.757B3070757B4829    8BF0            mov esi,eax757B482B    3BF3            cmp esi,ebx757B482D  ^ 0F84 E1EEFFFF   je WS2_32.757B3714757B4833    8B4D F8         mov ecx,dword ptr ss:[ebp-0x8]757B4836    8B45 10         mov eax,dword ptr ss:[ebp+0x10]757B4839    57              push edi757B483A    83C1 08         add ecx,0x8757B483D    8D55 FC         lea edx,dword ptr ss:[ebp-0x4] 当我注入自己的hook时再看一下recv处得代码 757B47DF >  B8 88C74504     mov eax,024CC788  ; recv的入口点757B47E4    FFE0            jmp eax                                            ;  跳到我自己的代码处757B47E6    0053 33         add byte ptr ds:[ebx+0x33],dl757B47E9    DB81 3D48707D   fild dword ptr ds:[ecx+0x7D70483D]757B47EF    75 36           jnz short WS2_32.757B4827757B47F1    337B 75         xor edi,dword ptr ds:[ebx+0x75]757B47F4    56              push esi757B47F5  ^ 0F85 F4EEFFFF   jnz WS2_32.757B36EF757B47FB    391D 70707D75   cmp dword ptr ds:[0x757D7070],ebx757B4801  ^ 0F84 E8EEFFFF   je WS2_32.757B36EF757B4807    FF35 44707D75   push dword ptr ds:[0x757D7044]757B480D    FF15 48127B75   call dword ptr ds:[<&API-MS-Win-Core-Pro>; kernel32.TlsGetValue757B4813    8945 F8         mov dword ptr ss:[ebp-0x8],eax757B4816    3BC3            cmp eax,ebx757B4818  ^ 0F84 D1EEFFFF   je WS2_32.757B36EF757B481E    895D FC         mov dword ptr ss:[ebp-0x4],ebx757B4821    FF75 08         push dword ptr ss:[ebp+0x8]757B4824    E8 47E8FFFF     call WS2_32.757B3070757B4829    8BF0            mov esi,eax757B482B    3BF3            cmp esi,ebx757B482D  ^ 0F84 E1EEFFFF   je WS2_32.757B3714757B4833    8B4D F8         mov ecx,dword ptr ss:[ebp-0x8]757B4836    8B45 10         mov eax,dword ptr ss:[ebp+0x10]757B4839    57              push edi  我再在od中转到我的代码处:这里就是  mov eax,024CC788                 jmp eax     跳到我们自己的代码:             024CC788  /.  55            push ebp                                 ;  WS2_32.select024CC789  |.  8BEC          mov ebp,esp024CC78B  |.  83C4 F8       add esp,-0x8024CC78E  |.  53            push ebx024CC78F  |.  56            push esi024CC790  |.  57            push edi024CC791  |.  8B5D 10       mov ebx,[arg.3]024CC794  |.  8B75 0C       mov esi,[arg.2]024CC797  |.  8D45 F8       lea eax,[local.2]024CC79A  |.  50            push eax                                 ; /pBytesWritten024CC79B  |.  6A 08         push 0x8                                 ; |BytesToWrite = 8024CC79D  |.  68 ECFB4C02   push mydll.024CFBEC                      ; |Buffer = mydll.024CFBEC024CC7A2  |.  A1 F8FB4C02   mov eax,dword ptr ds:[0x24CFBF8]         ; |024CC7A7  |.  50            push eax                                 ; |Address => 757B47DF024CC7A8  |.  A1 FCFB4C02   mov eax,dword ptr ds:[0x24CFBFC]         ; |024CC7AD  |.  50            push eax                                 ; |hProcess => FFFFFFFF024CC7AE  |.  E8 1999FBFF   call <jmp.&kernel32.WriteProcessMemory>  ; \WriteProcessMemory024CC7B3  |.  8B45 14       mov eax,[arg.4]024CC7B6  |.  50            push eax                                 ; /Flags024CC7B7  |.  53            push ebx                                 ; |BufSize024CC7B8  |.  56            push esi                                 ; |Buffer024CC7B9  |.  8B45 08       mov eax,[arg.1]                          ; |024CC7BC  |.  50            push eax                                 ; |Socket024CC7BD  |.  FF15 D8FB4C02 call dword ptr ds:[0x24CFBD8]            ; \recv024CC7C3  |.  8BF8          mov edi,eax024CC7C5  |.  B8 88C74C02   mov eax,mydll.024CC788024CC7CA  |.  A3 DDFB4C02   mov dword ptr ds:[0x24CFBDD],eax024CC7CF  |.  8D45 F8       lea eax,[local.2]024CC7D2  |.  50            push eax                                 ; /pBytesWritten024CC7D3  |.  6A 08         push 0x8                                 ; |BytesToWrite = 8024CC7D5  |.  68 DCFB4C02   push mydll.024CFBDC                      ; |Buffer = mydll.024CFBDC024CC7DA  |.  A1 F8FB4C02   mov eax,dword ptr ds:[0x24CFBF8]         ; |024CC7DF  |.  50            push eax                                 ; |Address => 757B47DF024CC7E0  |.  A1 FCFB4C02   mov eax,dword ptr ds:[0x24CFBFC]         ; |024CC7E5  |.  50            push eax                                 ; |hProcess => FFFFFFFF024CC7E6  |.  E8 E198FBFF   call <jmp.&kernel32.WriteProcessMemory>  ; \WriteProcessMemory上面的就是我们下面代码的反汇编代码:unction MyRecv(s: TSocket;  Buf, len, flags: Integer): Integer; stdcall;vardwSize: cardinal;mc: byte;m_buf:pchar;i:integer; begin/简单的响一声 ///showmessage(inttostr(buf))  ; //MessageBeep(1000); //简单的响一声WriteProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);Result := OldRecv(S, Buf, len,flags);JmpCode.Address := @MyRecv;WriteProcessMemory(ProcessHandle, AddRecv, @JmpCode, 8, dwSize);if (len=21) thenbegin                               /////这里是我处理封包的函数i:=buf ;asmpush eaxmov  eax,imov byte[eax],$c0mov byte [eax+1],0pop eaxend;MessageBeep(1000);end;  end;只要你hook了他的recv后当封包发过来后便首先跳到你的代码,当你把封包处理后再到ws2_32的recv   所有只要你在myrecv处加入你的代码便可以做自己想做的事情了  但是现在的封包都有加密,所以一般都要解密。解密的方法在这里就不再说了,因为每个程序加密方式都不太同我希望我的理解能给你们有用。我也想通过这篇文章申请注册码
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部