满分请教!!!实在解决不了了特来求助... HOOK 的 WSASEND函数对lpBuffers.buf 数据进行修改后发送如果修改后的数据长度小于或等于原来的长度,发送一切正常,程序无任何问题但是如果修改后的数据大于原数据长度,发送也是正常的(接收端接收到了完整的数据包),但是程序就不再继续发包了...不知道大家看明白没有百度 谷歌翻遍了 遇到此问题的也不在少数 但没找到答案希望高人解答 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 ............HookAPI('wsock32.dll','WSASocket',@WSASocketHook,@WSASocketOrigin); HookAPI('ws2_32.dll','WSASend',@WSASendHook,@WSASendOrigin); HookAPI('ws2_32.dll','Send',@mylogSend,@oldsend); HookAPI('wsock32.dll','Send',@mylogSend,@oldsend); HookAPI('ws2_32.dll','Recv',@mylogrecv,@oldrecv); HookAPI('ws2_32.dll','WSARecv',@WSARecvHook,@WSARecvOrigin); HookAPI('ws2_32.dll','Socket',@SocketHook,@SocketOrigin); 这些是madcodehook中的函数 我HOOK了这些函数。其中wsarecv可以获得,别的不能获得 其中,wsarecv和send的函数定义及实现为以下,其中wsarecv可以捕获,send不能捕获 var WSARecvOrigin:function(s:TSocket;lpBuffers:LPWSABUF; dwBufferCount:dword;lpNumberOfBytesRecvd:LPDWORD; dwFlags:DWORD;lpOverlapped:LPWSAOVERLAPPED; lpCompletionROUTINE:LPWSAOVERLAPPED_COMPLETION_ROUTINE):integer;stdcall; function WSARecvHook(s:TSocket;lpBuffers:LPWSABUF; dwBufferCount:dword;lpNumberOfBytesRecvd:LPDWORD; dwFlags:DWORD;lpOverlapped:LPWSAOVERLAPPED; lpCompletionROUTINE:LPWSAOVERLAPPED_COMPLETION_ROUTINE):integer;stdcall; begin WSARecvHook:=WSARecvOrigin(s,lpBuffers,dwBufferCount, lpNumberOfBytesRecvd,dwFlags,lpOverlapped,lpCompletionROUTINE); MyRecv(lpBuffers.buf,lpNumberOfBytesRecvd^); if GameSocket<>s then GameSocket:=s; end; 这个可以获得 var oldsend:function (s: TSocket; var Buf:pchar; len, flags: Integer): Integer; stdcall; function MylogSend(s: TSocket; var Buf:pchar; len, flags: Integer): Integer; stdcall; var dwSize: cardinal; begin MessageBeep(1000); //简单的响一声 //调用直正的Send函数 mylogsend:=oldsend(s,buf,len,flags); if GameSocket<>s then GameSocket:=s; end; 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; { } {函数功能:Send函数的HOOK {函数参数:同Send {函数返回值:integer { } function MySend(s: TSocket; var Buf:pchar; len, flags: Integer): Integer; stdcall; var x1,dwSize: cardinal; text:array[0..128] of char; begin //hooksend(buf,len); copychar(@text[0],buf,len); prolog(@text[0],len); //这儿进行发送的数据处理 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; ........................... to 居士我不是在问如何HOOK 我是问如何修改HOOK到得lpBuffers.buf数据 可以正常通讯遇到的问题适当修改后的数据长度小于或等于原数据时一切正常但是修改后的数据长度大于原数据时 就不能正常通讯了 你還是找找關於madCodeHook方面的東東確認有沒有没有madCHook.dll這個文件... TO 居士我根本不是用的madCodeHook 找madCodeHook.dll有何用 如果我的表达不够清楚你可以看看类似的问题http://topic.csdn.net/u/20100730/09/a20494a9-961b-48b9-8886-17acffaf36af.htmlhttp://topic.csdn.net/u/20081011/12/9fa946f1-3f20-4701-a2ae-e2c12fa9a907.html 解决方案1.只处理一次能发出的包,也就是尽量避免会产生WSAEWOULDBLOCK的包。具体,可咨询我。2.Send以后,返回值,仍使用原始包长度,而不要使用改变后的包长度。 to CaesarDM能详细说下吗1.只处理一次能发出的包,也就是尽量避免会产生WSAEWOULDBLOCK的包。具体,可咨询我。2.Send以后,返回值,仍使用原始包长度,而不要使用改变后的包长度。我就是只处理了一次啊 返回值是哪个参数呢 通过跟踪发现 正常情况下 和我现在不正常情况的返回值都是-1function MyWSASEND(s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD; var lpNumberOfBytesSent: DWORD; dwFlags: DWORD; lpOverlapped: LPWSAOVERLAPPED; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall;var dwSize: cardinal; tmp: AnsiString; newlpBuffers: LPWSABUF; tmplength: DWORD;begin setlength(tmp, lpBuffers.len); move(lpBuffers.buf^, tmp[1], lpBuffers.len); tmp := tmp + 'aaaa'; //随便举个例子 增加封包长度 New(newlpBuffers); newlpBuffers.len := Length(tmp); //写回现在的长度 GetMem(newlpBuffers.buf, newlpBuffers.len); Move(tmp[1], newlpBuffers.buf^, newlpBuffers.len); //写回改变后的封包 //调用直正的Send函数 WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize); Result := OldSend(s, newlpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine); DebugOutStr('Result:' + inttostr(Result)); //此处的返回值 全都是 -1 JmpCode.Address := @MyWSASEND; WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize); FreeMem(newlpBuffers.buf); Dispose(newlpBuffers);end; var pData, pOldData:PChar; dwLen, dwOldLen:DWORD; bDataChanged:Boolean;begin bDataChanged := False; //多个包的情况,不改变。因为。危险 。 if dwBufferCount=1 then begin //太大的包也不处理 pData := nil; if LPWSABUFS(lpBuffers)[0].len<=1500 then begin dwLen := LPWSABUFS(lpBuffers)[0].len +5; //增加5个字节长度 pData := AllocMem(dwLen); .... //给pData赋值 pOldData := LPWSABUFS(lpBuffers)[0].buf; dwOldLen := LPWSABUFS(lpBuffers)[0].len; LPWSABUFS(lpBuffers)[0].buf = pData; LPWSABUFS(lpBuffers)[0].len = dwLen; //标识数据已改变 bDataChanged := True; end; end; Result := OldSend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine); if bDataChanged then begin lpNumberOfBytesSent := dwLen; LPWSABUFS(lpBuffers)[0].buf = pOldData; LPWSABUFS(lpBuffers)[0].len = dwOldLen; end; if pData<>nil then FreeMemory(pData);end; 感谢CaesarDM回复,我先测试下你的例子有问题再来请教 请教大大LPWSABUFS是在哪里定义的 结构是什么 我的WinSock2里面没有这个定义还有 if bDataChanged then begin lpNumberOfBytesSent := dwLen; LPWSABUFS(lpBuffers)[0].buf = pOldData; LPWSABUFS(lpBuffers)[0].len = dwOldLen; end;你不是说2.Send以后,返回值,仍使用原始包长度,而不要使用改变后的包长度。怎么会是改变后的长度而且我通过跟踪发现 不论成功与否这个参数的值是不变的 就是说赋值多少 下次还是多少,没有赋值的话始终是0 CaesarDM大大的例子是否做过测试呢 还是只是随手写的?测试无效果 还是跟我的一样发包之后 返回的包 他并不处理... 错了,是WSABUFS=array[0..0] of WSABUF;LPWSABUFS = ^WSABUFS; 跟踪过了 所有的包数量都是只有一个 bDataChanged := False; //多个包的情况,不改变。因为。危险 。 if dwBufferCount=1 then begin //太大的包也不处理 pData := nil; if lpBuffers.len<=1500 then begin setlength(tmp, lpBuffers.len); move(lpBuffers.buf^, tmp[1], lpBuffers.len); tmp := tmp + 'aaaa'; //测试增大封包 dwLen := Length(tmp); pData := AllocMem(dwLen); Move(tmp[1], pData^, dwLen); //写回加密后的封包 pOldData := lpBuffers.buf; dwOldLen := lpBuffers.len; lpBuffers.buf := pData; lpBuffers.len := dwLen; //标识数据已改变 bDataChanged := True; end; end; WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize); Result := OldSend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine); if bDataChanged then begin lpNumberOfBytesSent := dwOldLen; lpBuffers.buf := pOldData; lpBuffers.len := dwOldLen; end; if pData <> nil then FreeMemory(pData); JmpCode.Address := @MySend; WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize);IdWinSock2单元并没有LPWSABUFS的定义我是Delphi2010 Indy 10.5.5 恩 如果那样的话 LPWSABUFS(lpBuffers)[0].buf 跟我写的不就是一样的!! 很不一样,请参阅MSDN,以后慢慢体会 想问下CaesarDM大大是否有做过测试 或做过这方面的程序呢?还是说仅仅是根据理论书写的代码? WSABUFS=array[0..0] of WSABUF;LPWSABUFS = ^WSABUFS;lpBuffers: LPWSABUF;LPWSABUFS(lpBuffers)[0].buf 和 lpBuffers.buf 有何不同了 写错了 是lpBuffers.buf^ Send可以一次发多个缓冲,所以,嗯,那啥。其实MSDN文档里描述的很清楚这种方式一个潜在的问题是使用IOCP的程序,可能会受影响。非理论。 这是我记录的正常通讯各参数返回值18:19:21 包数量:118:19:21 原长度lpBuffers.len:6418:19:21 Result:-118:19:21 lpNumberOfBytesSent:018:19:21 dwFlags:018:19:21 lpOverlapped.Internal:018:19:21 lpOverlapped.InternalHigh:6418:19:21 lpOverlapped.Offset:018:19:21 lpOverlapped.OffsetHigh:018:19:21 lpOverlapped.hEvent:46818:19:21 包数量:118:19:21 原长度lpBuffers.len:1018:19:21 Result:-118:19:21 lpNumberOfBytesSent:018:19:21 dwFlags:018:19:21 lpOverlapped.Internal:018:19:21 lpOverlapped.InternalHigh:1018:19:21 lpOverlapped.Offset:018:19:21 lpOverlapped.OffsetHigh:018:19:21 lpOverlapped.hEvent:468你的例子中修改lpNumberOfBytesSent参数 不知道意义何在 正常通讯全部返回值是0 唯一一处有包长纪录的lpOverlapped.InternalHigh 我也试着改过了 依然无效 这是改过包长后的记录18:31:32 包数量:118:31:32 原长度lpBuffers.len:6418:31:32 Result:-118:31:32 lpNumberOfBytesSent:018:31:32 dwFlags:018:31:32 lpOverlapped.Internal:018:31:32 lpOverlapped.InternalHigh:12818:31:32 lpOverlapped.Offset:018:31:32 lpOverlapped.OffsetHigh:018:31:32 lpOverlapped.hEvent:46818:31:32 lpOverlapped.InternalHigh改:6418:31:32 包数量:118:31:32 原长度lpBuffers.len:429496723218:31:32 Result:-118:31:32 lpNumberOfBytesSent:0第一个包正常 第二个包就变了 listview CnWizards怎么用 初学DELPHI,请教高人COM调用的问题。 有个问题没搞清楚 一个资源和一个类是如何联系在一起的 关于TTrayNotifyIcon(托盘图标)的问题? 困扰了三天的问题,急!帮帮忙吧,高手。 用backup database备份数据库的时候如何获取SQL返回的操作信息 两个表的问题 难题,细心的高手请进?这个错误怎么解决 ? delphi中调用外部应用程序的方法有几种?有没有可以带参数的方法? 关于TList(TThreadList)类和TThread类的一些疑问 酒店宾馆洗浴娱乐一卡通系统哪个公司的做的好
...........................
1.只处理一次能发出的包,也就是尽量避免会产生WSAEWOULDBLOCK的包。具体,可咨询我。
2.Send以后,返回值,仍使用原始包长度,而不要使用改变后的包长度。
2.Send以后,返回值,仍使用原始包长度,而不要使用改变后的包长度。我就是只处理了一次啊 返回值是哪个参数呢 通过跟踪发现 正常情况下 和我现在不正常情况的返回值都是-1
function MyWSASEND(s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD; var lpNumberOfBytesSent: DWORD; dwFlags: DWORD; lpOverlapped: LPWSAOVERLAPPED; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall;
var
dwSize: cardinal;
tmp: AnsiString;
newlpBuffers: LPWSABUF;
tmplength: DWORD;
begin
setlength(tmp, lpBuffers.len);
move(lpBuffers.buf^, tmp[1], lpBuffers.len);
tmp := tmp + 'aaaa'; //随便举个例子 增加封包长度
New(newlpBuffers);
newlpBuffers.len := Length(tmp); //写回现在的长度
GetMem(newlpBuffers.buf, newlpBuffers.len);
Move(tmp[1], newlpBuffers.buf^, newlpBuffers.len); //写回改变后的封包 //调用直正的Send函数
WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);
Result := OldSend(s, newlpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine);
DebugOutStr('Result:' + inttostr(Result)); //此处的返回值 全都是 -1
JmpCode.Address := @MyWSASEND;
WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize);
FreeMem(newlpBuffers.buf);
Dispose(newlpBuffers);
end;
pData, pOldData:PChar;
dwLen, dwOldLen:DWORD;
bDataChanged:Boolean;
begin
bDataChanged := False;
//多个包的情况,不改变。因为。危险 。
if dwBufferCount=1 then
begin
//太大的包也不处理
pData := nil;
if LPWSABUFS(lpBuffers)[0].len<=1500 then
begin
dwLen := LPWSABUFS(lpBuffers)[0].len +5;
//增加5个字节长度
pData := AllocMem(dwLen);
.... //给pData赋值
pOldData := LPWSABUFS(lpBuffers)[0].buf;
dwOldLen := LPWSABUFS(lpBuffers)[0].len;
LPWSABUFS(lpBuffers)[0].buf = pData;
LPWSABUFS(lpBuffers)[0].len = dwLen; //标识数据已改变
bDataChanged := True;
end; end; Result := OldSend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine); if bDataChanged then
begin
lpNumberOfBytesSent := dwLen;
LPWSABUFS(lpBuffers)[0].buf = pOldData;
LPWSABUFS(lpBuffers)[0].len = dwOldLen;
end; if pData<>nil then
FreeMemory(pData);
end;
if bDataChanged then
begin
lpNumberOfBytesSent := dwLen;
LPWSABUFS(lpBuffers)[0].buf = pOldData;
LPWSABUFS(lpBuffers)[0].len = dwOldLen;
end;
你不是说2.Send以后,返回值,仍使用原始包长度,而不要使用改变后的包长度。怎么会是改变后的长度而且我通过跟踪发现 不论成功与否这个参数的值是不变的 就是说赋值多少 下次还是多少,没有赋值的话始终是0
WSABUFS=array[0..0] of WSABUF;
LPWSABUFS = ^WSABUFS;
//多个包的情况,不改变。因为。危险 。
if dwBufferCount=1 then
begin
//太大的包也不处理
pData := nil;
if lpBuffers.len<=1500 then
begin
setlength(tmp, lpBuffers.len);
move(lpBuffers.buf^, tmp[1], lpBuffers.len);
tmp := tmp + 'aaaa'; //测试增大封包
dwLen := Length(tmp);
pData := AllocMem(dwLen);
Move(tmp[1], pData^, dwLen); //写回加密后的封包 pOldData := lpBuffers.buf;
dwOldLen := lpBuffers.len;
lpBuffers.buf := pData;
lpBuffers.len := dwLen; //标识数据已改变
bDataChanged := True;
end;
end;
WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);
Result := OldSend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine);
if bDataChanged then
begin
lpNumberOfBytesSent := dwOldLen;
lpBuffers.buf := pOldData;
lpBuffers.len := dwOldLen;
end;
if pData <> nil then FreeMemory(pData);
JmpCode.Address := @MySend;
WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize);
IdWinSock2单元并没有LPWSABUFS的定义我是Delphi2010 Indy 10.5.5
LPWSABUFS = ^WSABUFS;lpBuffers: LPWSABUF;LPWSABUFS(lpBuffers)[0].buf 和 lpBuffers.buf 有何不同了
其实MSDN文档里描述的很清楚这种方式一个潜在的问题是使用IOCP的程序,可能会受影响。非理论。
18:19:21 原长度lpBuffers.len:64
18:19:21 Result:-1
18:19:21 lpNumberOfBytesSent:0
18:19:21 dwFlags:0
18:19:21 lpOverlapped.Internal:0
18:19:21 lpOverlapped.InternalHigh:64
18:19:21 lpOverlapped.Offset:0
18:19:21 lpOverlapped.OffsetHigh:0
18:19:21 lpOverlapped.hEvent:46818:19:21 包数量:1
18:19:21 原长度lpBuffers.len:10
18:19:21 Result:-1
18:19:21 lpNumberOfBytesSent:0
18:19:21 dwFlags:0
18:19:21 lpOverlapped.Internal:0
18:19:21 lpOverlapped.InternalHigh:10
18:19:21 lpOverlapped.Offset:0
18:19:21 lpOverlapped.OffsetHigh:0
18:19:21 lpOverlapped.hEvent:468你的例子中修改lpNumberOfBytesSent参数 不知道意义何在 正常通讯全部返回值是0 唯一一处有包长纪录的lpOverlapped.InternalHigh 我也试着改过了 依然无效
18:31:32 原长度lpBuffers.len:64
18:31:32 Result:-1
18:31:32 lpNumberOfBytesSent:0
18:31:32 dwFlags:0
18:31:32 lpOverlapped.Internal:0
18:31:32 lpOverlapped.InternalHigh:128
18:31:32 lpOverlapped.Offset:0
18:31:32 lpOverlapped.OffsetHigh:0
18:31:32 lpOverlapped.hEvent:468
18:31:32 lpOverlapped.InternalHigh改:6418:31:32 包数量:1
18:31:32 原长度lpBuffers.len:4294967232
18:31:32 Result:-1
18:31:32 lpNumberOfBytesSent:0第一个包正常 第二个包就变了