比如:我想把所有的进程都列出来。选择我要拦接数据包的应用程序的进程,进行拦接数据包。请问怎样实现,说说方法、或是举举便也可以。。(就像wpe一样,能够直接通过选择进程来拦接数据包)

解决方案 »

  1.   

    网上有名字为“捕获IP数据包的小程序”的delphi的例子,在www.2ccc.com和www.playicq.com都应该有,你可以下载下来看看!!拦截网络数据封包的方法有三种,一是将网卡设为混杂模式,这次就可以监视到局域网上所有的数据包,二是HOOK目标进程的发送和接收的API函数,第三种方法是自己实现一个代理的DLL.在这里我们使用HOOK API的方法,这样易于实现,而且也不会得到大量的无用数据(如第一种方法就会监视到所有的网络数据).下面是一个尽量简化了的API HOOK的模版,原理是利用消息钩子将DLL中的代码注入到目标进程中,再用GetProcAddress得到API函数入口地址,将函数入口址改为自己定义的函数入口,这样就得到了API函数的相应参数,处理完后,再改回真实API函数入口地址,并调用它.
    HOOK.DLL的代码:
    library Hook;uses
      SysUtils,
      windows,
      Messages,
      APIHook in 'APIHook.pas';type
      PData = ^TData;
      TData = record
        Hook: THandle;
        Hooked: Boolean;
      end;
      
    var
      DLLData: PData;{------------------------------------}
    {过程名:HookProc
    {过程功能:HOOK过程
    {过程参数:nCode, wParam, lParam消息的相
    {         关参数
    {------------------------------------}
    procedure HookProc(nCode, wParam, lParam: LongWORD);stdcall;
    begin
      if not DLLData^.Hooked then
      begin
        HookAPI;
        DLLData^.Hooked := True;
      end;
      //调用下一个Hook
      CallNextHookEx(DLLData^.Hook, nCode, wParam, lParam);
    end;
    {------------------------------------}
    {函数名:InstallHook
    {函数功能:在指定窗口上安装HOOK
    {函数参数:sWindow:要安装HOOK的窗口
    {返回值:成功返回TRUE,失败返回FALSE
    {------------------------------------}
    function InstallHook(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);
      if DLLData^.Hook > 0 then
        Result := True  //是否成功HOOK
      else
        exit;
    end;{------------------------------------}
    {过程名:UnHook
    {过程功能:卸载HOOK
    {过程参数:无
    {------------------------------------}
    procedure UnHook;stdcall;
    begin
      UnHookAPI;
      //卸载Hook
      UnhookWindowsHookEx(DLLData^.Hook);
    end;{------------------------------------}
    {过程名:DLL入口函数
    {过程功能:进行DLL初始化,释放等
    {过程参数:DLL状态
    {------------------------------------}
    procedure MyDLLHandler(Reason: Integer);
    var
      FHandle: LongWORD;
    begin
      case Reason of
        DLL_PROCESS_ATTACH:
        begin            //建立文件映射,以实现DLL中的全局变量
          FHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, $ffff, 'MYDLLDATA');
          if FHandle = 0 then
          if GetLastError = ERROR_ALREADY_EXISTS then
          begin
            FHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 'MYDLLDATA');
            if FHandle = 0 then Exit;
          end else Exit;
          DLLData := MapViewOfFile(FHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
          if DLLData = nil then
            CloseHandle(FHandle);
        end;
        DLL_PROCESS_DETACH:
        begin
          if Assigned(DLLData) then
          begin
            UnmapViewOfFile(DLLData);
            DLLData := nil;
          end;
        end;
      end;
    end;{$R *.res}
    exports
      InstallHook, UnHook, HookProc;begin
      DLLProc := @MyDLLHandler;
      MyDLLhandler(DLL_PROCESS_ATTACH);
      DLLData^.Hooked := False;
    end.----------------------------------------------------------------------------------------
    APIHook.Pas的代码:unit APIHook;interfaceuses
      SysUtils,
      Windows, WinSock;type
      //要HOOK的API函数定义
      TSockProc = function (s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;  PJmpCode = ^TJmpCode;
      TJmpCode = packed record
        JmpCode: BYTE;
        Address: TSockProc;
        MovEAX: Array [0..2] of BYTE;
      end;  //--------------------函数声明---------------------------
      procedure HookAPI;
      procedure UnHookAPI;var
      OldSend, OldRecv: TSockProc;      //原来的API地址
      JmpCode: TJmpCode;
      OldProc: array [0..1] of TJmpCode;
      AddSend, AddRecv: pointer;        //API地址
      TmpJmp: TJmpCode;
      ProcessHandle: THandle;
    implementation{---------------------------------------}
    {函数功能:Send函数的HOOK
    {函数参数:同Send
    {函数返回值:integer
    {---------------------------------------}
    function MySend(s: TSocket; var Buf; 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 := @MySend;
      WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize);
    end;{---------------------------------------}
    {函数功能:Recv函数的HOOK
    {函数参数:同Recv
    {函数返回值:integer
    {---------------------------------------}
    function MyRecv(s: TSocket; var Buf; 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 := @MyRecv;
      WriteProcessMemory(ProcessHandle, AddRecv, @JmpCode, 8, dwSize);
    end;{------------------------------------}
    {过程功能:HookAPI
    {过程参数:无
    {------------------------------------}
    procedure HookAPI;
    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 := @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;
    var
      dwSize: Cardinal;
    begin
      WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);
      WriteProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);
    end;end.
    -----------------------------------------------------------------------------------------
      

  2.   

    编译这个DLL后,再新建一个程序调用这个DLL的InstallHook并传入目标进程的主窗口句柄就可:
    unit fmMain;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        Edit1: TEdit;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
      
    var
      Form1: TForm1;
      InstallHook: function (SWindow: THandle):Boolean;stdcall;
      UnHook: procedure;stdcall;
    implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
      ModuleHandle: THandle;
      TmpWndHandle: THandle;
    begin
      TmpWndHandle := 0;
      TmpWndHandle := FindWindow(nil, '目标窗口的标题');
      if not isWindow(TmpWndHandle) then
      begin
        MessageBox(self.Handle, '没有找到窗口', '!!!', MB_OK);
        exit;
      end;
      ModuleHandle := LoadLibrary('Hook.dll');
      @InstallHook := GetProcAddress(ModuleHandle, 'InstallHook');
      @UnHook := GetProcAddress(ModuleHandle, 'UnHook');
      if InstallHook(FindWindow(nil, 'Untitled')) then
        ShowMessage('Hook OK');
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      UnHook
    end;end.
      

  3.   

    procedure TForm1.Button1Click(Sender: TObject);
    var
      ModuleHandle: THandle;
      TmpWndHandle: THandle;
    begin
      TmpWndHandle := 0;
      TmpWndHandle := FindWindow(nil, '目标窗口的标题');
      if not isWindow(TmpWndHandle) then
      begin
        MessageBox(self.Handle, '没有找到窗口', '!!!', MB_OK);
        exit;
      end;
      ModuleHandle := LoadLibrary('Hook.dll');
      @InstallHook := GetProcAddress(ModuleHandle, 'InstallHook');
      @UnHook := GetProcAddress(ModuleHandle, 'UnHook');
      if InstallHook(FindWindow(nil, 'Untitled')) then
        ShowMessage('Hook OK');
    end;
    这部份可不可以通过进程,得到了我不希望通过找窗口来得到,因为我想每次都要取得窗口标题才行。
      

  4.   

    这个程序有问题的啊
    第一:只能对send有效
    第二:取消hook后,不能把入口改回原样高手救命啊
      

  5.   

    呵呵 看起来好象又一个做外挂的 记住win不同进程函数地址是保护的 那有你想象的这么容易