关于用钩子截取Socket数据包(200分)

  • 主题发起人 主题发起人 go2u
  • 开始时间 开始时间
G

go2u

Unregistered / Unconfirmed
GUEST, unregistred user!
代码如下:(两个单元)
========== Hook单元 ============
library Hook;
uses
SysUtils,
windows,
Messages,
APIHook in 'APIHook.pas';

type
PData = ^TData;
TData = record
Hook: THandle;
Hooked: Boolean;
end;

var
DLLData: PData;
FHandle: THandle=0;
oldexit:pointer=nil;
pdatas1:ptdatas=nil;

procedure unMapSelf;
begin
unMapMem;
if DLLData<>nil then unMapviewoffile(DLLData);
if fHandle>0 then CloseHandle(FHandle);
if oldexit<>nil then exitproc:=oldexit;
end;

procedure HookProc(nCode, wParam, lParam: LongWORD);stdcall;
begin
if not DLLData^.Hooked then
begin
HookAPI;
DLLData^.Hooked := True;
end;
CallNextHookEx(DLLData^.Hook, nCode, wParam, lParam);
end;

function InstallHook(SWindow:LongWORD):ptdatas;stdcall;
var
ThreadID: LongWORD;
begin
DLLData^.Hook := 0;

ThreadID := GetWindowThreadProcessId(sWindow, nil);
DLLData^.Hook := SetWindowsHookEx(WH_GETMESSAGE, @HookProc, Hinstance, ThreadID);
if DLLData^.Hook > 0 then
Result := pdatas1 //是否成功HOOK
else
Result := nil;
end;

procedure UnHook;stdcall;
begin
UnHookAPI;
//卸载Hook
UnhookWindowsHookEx(DLLData^.Hook);
end;

procedure MyDLLHandler(Reason: Integer);
//var
//FHandle: LongWORD;
begin
case Reason of
DLL_PROCESS_ATTACH:
begin //建立文件映射,以实现DLL中的全局变量
FHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, pchar('MYDLLDATA'));
if FHandle = 0 then
FHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, $ffff, pchar('MYDLLDATA'));
if FHandle = 0 then 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;
pdatas1:=Map_Mem;
oldexit:=exitProc;
exitProc:=@unMapSelf;
end.
========== APIHook单元 =============
unit APIHook;

interface

uses
SysUtils,Windows,WinSock,StrUtils,classes;

type
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;

bufdata=record
dindex:cardinal;
//dflag:cardinal;
dway:boolean;
dlen:cardinal;
bdata:array[0..10240] of char;
end;
tmpdata=array[0..9] of bufdata;
ptdatas=^tmpdata;

function Map_Mem:ptdatas;
procedure unMapMem;

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;

MaptxtfileHandle: THandle=0;
pdatas:ptdatas=nil;
oldindex,oldpos:cardinal;
//ls:boolean;
//rS:TSocket;
implementation
//Mapfile-----------
function Map_Mem:ptdatas;
begin
Result:=nil;
if pdatas=nil then
begin
MaptxtfileHandle:= OpenFileMapping(FILE_MAP_ALL_ACCESS,false, pchar('mapdatas'));
if MaptxtfileHandle = 0 then
MaptxtfileHandle:=CreateFileMapping($FFFFFFFF,nil,page_readwrite,0,$fffff,pchar('mapdatas'));
if MaptxtfileHandle = 0 then exit;
pdatas:=MapViewOfFile(MaptxtfileHandle,File_Map_All_Access,0,0,0);
if pdatas= nil then exit;
end;
Result:=pdatas;
oldindex:=1;
oldpos:=0;

end;

procedure unMapMem;
begin
if pdatas<>nil then unMapviewoffile(pdatas);
if MaptxtfileHandle>0 then CloseHandle(MaptxtfileHandle);
end;

function MyRecv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
dwSize: cardinal;
begin
pdatas^[oldpos].dindex:=oldindex;
//pdatas^[oldpos].dflag:=flags;
pdatas^[oldpos].dway:=false;
pdatas^[oldpos].dlen:=len;
move(buf,pdatas^[oldpos].bdata[0],len);
oldindex:=oldindex+1;
if oldpos<9 then oldpos:=oldpos+1 else oldpos:=0;
WriteProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);
Result := OldRecv(S, Buf, len, flags);
JmpCode.Address := @MyRecv;
WriteProcessMemory(ProcessHandle, AddRecv, @JmpCode, 8, dwSize);
end;

function MySend(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
dwSize: cardinal;
begin
pdatas^[oldpos].dindex:=oldindex;
//pdatas^[oldpos].dflag:=flags;
pdatas^[oldpos].dway:=true;
pdatas^[oldpos].dlen:=len;
pdatas^[oldpos].bdata:='';
move(buf,pdatas^[oldpos].bdata[0],len);
WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);
Result := OldSend(S, Buf, len, flags);
JmpCode.Address := @MySend;
WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize);
end;

procedure HookAPI;
var
DLLModule: THandle;
dwSize: cardinal;
begin
ProcessHandle := 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);
ReadProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);
JmpCode.Address := @MyRecv;
WriteProcessMemory(ProcessHandle, AddRecv, @JmpCode, 8, dwSize);
OldSend := AddSend;
OldRecv := AddRecv;
end;

procedure UnHookAPI;
var
dwSize: Cardinal;
begin
WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);
WriteProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);
end;

end.


问题:
1)在function MyRecv 和 MySend 截取socket收发的数据(Var Buf)后,我把他存放到一个array[0..10240] of char字符数组里面,然后通过内存映射读出bdata:array[0..10240] of char中的数据,但是显示一串符号,如何像wpe一样显示16进制串?
2)如何编写合法的数据,直接通过 MySend 发送?
3)以上代码Hook特定的程序窗口后,特定程序正常运行,但是Unhook后,那程序就会出错关闭.请高手指出以上代码错漏之处.

回答请尽量具体代码,谢谢
 
帮顶一下吧
 
请大家各抒己见.
 
2ccc.com 上有个 CaptureIP 的演示
 
问题1和2简单的说,就是如何显示通过socket收到的数据,和如何通过socket发数据.
 
问题1
for s:=0 to pdatas^[oldpos].dlen-1 do
begin
fmtStr(Str1,'%2.2X',[ord(pdatas^[oldpos].bdata)]);
tmpStr:=tmpStr+' '+str1;
end;
 
盒子上有个 CaptureIP
 
后退
顶部