[请教]截取本机数据包目的地址再转发 API Hook Socket 发送10045错误(100)

  • 主题发起人 主题发起人 jamily
  • 开始时间 开始时间
J

jamily

Unregistered / Unconfirmed
GUEST, unregistred user!
代码:
要实现功能:要用 hook api socket connect函数得到本机的数据包,发现特定的发送包发送到指定的IP:端口(如就发送到本地的127.0.0.1).再从指定的IP:端口返回数据包(这个好做用Tserversocket 或indy server都可以做到.)起因:某软件要网络验证,现这软件已停止开发,连验证也不能成功.但我抓有验证成功的数据.想自已做个验证端.作用:192.168.0.251到8999端口数据转发到 192.168.0.101 8999端口(测试时可以用127.0.0.1转到本地.)我的代码是这样的 ,会出错,改变不了发送地址,转发不成功.会提示 socket 10045错误.//hook.dll代码如下library Hook;uses SysUtils, windows, Messages, APIHook in 'APIHook.pas'; //Unit1 in 'D:/Program Files/Borland/Delphi7/Lib/Unit1.pas';typePData = ^TData;TData = recordHook: THandle;Hooked: Boolean;end;varDLLData: PData;{------------------------------------}{过程名:HookProc{过程功能:HOOK过程{过程参数:nCode, wParam, lParam消息的相{ 关参数{------------------------------------}procedure HookProc(nCode, wParam, lParam: LongWORD);stdcall;beginif not DLLData^.Hooked thenbeginHookAPI;DLLData^.Hooked := True;end;//file://调用下一个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);//file://给指定窗口挂上钩子DLLData^.Hook := SetWindowsHookEx(WH_GETMESSAGE, @HookProc, Hinstance, ThreadID);if DLLData^.Hook > 0 thenResult := True //file://是否成功HOOKelseexit;end;{------------------------------------}{过程名:UnHook{过程功能:卸载HOOK{过程参数:无{------------------------------------}procedure UnHook;stdcall;beginUnHookAPI;//file://卸载HookUnhookWindowsHookEx(DLLData^.Hook);end;{------------------------------------}{过程名:DLL入口函数{过程功能:进行DLL初始化,释放等{过程参数:DLL状态{------------------------------------}procedure MyDLLHandler(Reason: Integer);varFHandle: LongWORD;begincase Reason ofDLL_PROCESS_ATTACH:begin // file://建立文件映射,以实现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, 'MYDLLDATA');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.//----apihook代码----------unit APIHook;interfaceusesSysUtils,Windows, WinSock;type//file://要HOOK的API函数定义TSockProc = function (s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;Tconnect = function (s: TSocket; var name: TSockAddr; namelen: Integer): Integer; stdcall;PJmpCode = ^TJmpCode;TJmpCode = packed recordJmpCode: BYTE;Address: TSockProc;MovEAX: Array [0..2] of BYTE;end;//file://--------------------函数声明---------------------------procedure HookAPI;procedure UnHookAPI;varOldSend, OldRecv: TSockProc;// file://原来的API地址OldConnect: Tconnect;JmpCode: TJmpCode;OldProc: array [0..2] of TJmpCode;AddSend, AddRecv,AddConnect: pointer; //file://API地址TmpJmp: TJmpCode;ProcessHandle: THandle;implementation{---------------------------------------}{函数功能:Send函数的HOOK{函数参数:同Send{函数返回值:integer{---------------------------------------}function MySend(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;vardwSize: cardinal;begin//file://这儿进行发送的数据处理MessageBeep(1000); //file://简单的响一声//file://调用直正的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;vardwSize: cardinal;begin//file://这儿进行接收的数据处理MessageBeep(1000); //file://简单的响一声//file://调用直正的Recv函数WriteProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);Result := OldRecv(S, Buf, len, flags);JmpCode.Address := @MyRecv;WriteProcessMemory(ProcessHandle, AddRecv, @JmpCode, 8, dwSize);end;{-------------------------------------------}{ 函数功能:Connect函数的HOOK{ 函数返回值integer {-------------------------------------------}function MyConnect(s:TSocket;var sa:TSockAddr;len:integer):integer;stdcall;var dwSize: cardinal; // Ip:string; // port:integer;begin // ip := inet_ntoa(sa.sin_addr); // port := ntohs(sa.sin_port); if sa.sin_port=htons(8999) then //符合条件,处理 begin sa.sin_addr.S_addr:=Inet_addr('192.168.0.101'); //这儿连接转向,呵呵 end; WriteProcessMemory(ProcessHandle, AddConnect, @OldProc[2], 8, dwSize); OldConnect(s,sa,len); JmpCode.Address:=@MyConnect; WriteProcessMemory(ProcessHandle, AddConnect, @JmpCode, 8, dwSize);end;{------------------------------------}{过程功能:HookAPI{过程参数:无{------------------------------------}procedure HookAPI;varDLLModule: THandle;dwSize: cardinal;beginProcessHandle := GetCurrentProcess;DLLModule := LoadLibrary('ws2_32.dll');AddSend := GetProcAddress(DLLModule, 'send'); //file://取得API地址AddRecv := GetProcAddress(DLLModule, 'recv');AddConnect:= GetProcAddress(DLLModule, 'connect');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); //file://修改Send入口ReadProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);JmpCode.Address := @MyRecv;WriteProcessMemory(ProcessHandle, AddRecv, @JmpCode, 8, dwSize); //file://修改Recv入口ReadProcessMemory(ProcessHandle, AddConnect, @OldProc[2], 8, dwSize);JmpCode.Address := @MyRecv;WriteProcessMemory(ProcessHandle, AddConnect, @JmpCode, 8, dwSize); //file://修改Recv入口OldSend := AddSend;OldRecv := AddRecv;OldConnect:= AddConnect;end;{------------------------------------}{过程功能:取消HOOKAPI{过程参数:无{------------------------------------}procedure UnHookAPI;vardwSize: Cardinal;beginWriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);WriteProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);WriteProcessMemory(ProcessHandle, AddConnect, @OldProc[2], 8, dwSize);end;end.///-----用来调用的hook.dll的代码-----其中用来 serversocket控件.{本地验证用,发送}unit U_HookForm;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,shellapi, ScktComp, IdBaseComponent, IdComponent, IdTCPServer;type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Edit1: TEdit; Label1: TLabel; Memo1: TMemo; TS1: TServerSocket; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure TS1ClientConnect(Sender: TObject; Socket: TCustomWinSocket); procedure TS1ClientRead(Sender: TObject; Socket: TCustomWinSocket); 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);varModuleHandle: THandle;TmpWndHandle: THandle;begin //打开程序 TS1.Port := StrtoInt(Edit1.Text); //socket服务器端口 ShellExecute(0, nil, 'project1.exe', nil, nil, SW_SHOWNORMAL); // timer1.Enabled:=true; //延时2秒 sleep(2000);TmpWndHandle := 0;TmpWndHandle := FindWindow(nil, 'Form1');if not isWindow(TmpWndHandle) thenbeginMessageBox(self.Handle, '没有找到窗口 Form1', '!!!', MB_OK);exit;end;ModuleHandle := LoadLibrary('Hook.dll');@InstallHook := GetProcAddress(ModuleHandle, 'InstallHook');@UnHook := GetProcAddress(ModuleHandle, 'UnHook');if InstallHook(FindWindow(nil, 'Form1')) then//ShowMessage('Hook OK'); TS1.active:=True;end;procedure TForm1.Button2Click(Sender: TObject);begin UnHook; TS1.Active := False;end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);begin TS1.Active := False;end;procedure TForm1.TS1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);begin memo1.Lines.Add('连上了.')end;procedure TForm1.TS1ClientRead(Sender: TObject; Socket: TCustomWinSocket);begin socket.SendText('YES');end;end.
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
937
SUNSTONE的Delphi笔记
S
后退
顶部