Delphi 从winsock recv hook保存缓冲区(PChar到AnsiString)
我知道这是一个愚蠢的问题,但有时我真的陷入了Ansi/Unicode的泥潭,我尝试了每一次该死的转换(PChar/AnsiString/PAnsiChar…),但仍然无法读取缓冲区。这就是我的情况。我正在挂接“recv”函数,我只想将缓冲区内容保存到一个文件中,但我只将中文/不可读字符保存到该文件中。我的回调函数是:Delphi 从winsock recv hook保存缓冲区(PChar到AnsiString),delphi,Delphi,我知道这是一个愚蠢的问题,但有时我真的陷入了Ansi/Unicode的泥潭,我尝试了每一次该死的转换(PChar/AnsiString/PAnsiChar…),但仍然无法读取缓冲区。这就是我的情况。我正在挂接“recv”函数,我只想将缓冲区内容保存到一个文件中,但我只将中文/不可读字符保存到该文件中。我的回调函数是: function Interceptrecv(s: TSocket; Buffer: Pointer; BuffLength: in
function Interceptrecv(s: TSocket;
Buffer: Pointer;
BuffLength: integer;
Flags: integer): Integer; stdcall;
var
MyBuff: PChar;
pFileHandle, dWrite: cardinal;
sText: string;
begin
Result:= recvNext(s, Buffer, BuffLength, Flags);
GetMem(MyBuff,sizeof(Buffer));
ZeroMemory(MyBuff, sizeof(Buffer));
CopyMemory(MyBuff,Buffer,sizeof(Buffer)-1);
SetLength(sText, SizeOf(MyBuff));
CopyMemory(@sText[1], MyBuff, SizeOf(MyBuff));
pFileHandle := CreateFile(PChar('C:\' + 'log.txt'),GENERIC_WRITE,0,nil,OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL,0);
if pFileHandle <> INVALID_HANDLE_VALUE then
begin
SetFilePointer(pFileHandle,0,nil, FILE_END);
Windows.WriteFile(pFileHandle,sText,SizeOf(sText),dWrite,nil);
CloseHandle(pFileHandle);
end;
end;
功能拦截recv(s:TSocket;
缓冲区:指针;
BuffLength:整数;
标志:整数):整数;stdcall;
变量
MyBuff:PChar;
pFileHandle,dWrite:红衣主教;
sText:字符串;
开始
结果:=recvNext(s、缓冲区、BuffLength、标志);
GetMem(MyBuff,sizeof(Buffer));
零内存(MyBuff,sizeof(Buffer));
CopyMemory(MyBuff,Buffer,sizeof(Buffer)-1);
设置长度(sText,SizeOf(MyBuff));
CopyMemory(@sText[1],MyBuff,SizeOf(MyBuff));
pFileHandle:=CreateFile(PChar('C:\'+'log.txt'),GENERIC\u WRITE,0,nil,始终打开,文件属性\u NORMAL,0);
如果pFileHandle\u HANDLE\u值无效,则
开始
SetFilePointer(pFileHandle,0,nil,FILE_END);
WriteFile(pFileHandle、sText、SizeOf(sText)、dWrite、nil);
闭合手柄(pFileHandle);
结束;
结束;
如何使此缓冲区易读?代码失败的原因是您完全误用了
SizeOf()
。您需要使用返回值recvNext()
:
function Interceptrecv(s: TSocket;
Buffer: Pointer;
BuffLength: integer;
Flags: integer): Integer; stdcall;
var
MyBuff: PAnsiChar;
pFileHandle: THandle;
dWrite: DWORD;
sText: AnsiString;
begin
Result := recvNext(s, Buffer, BuffLength, Flags);
if Result <= 0 then Exit;
GetMem(MyBuff, Result);
try
ZeroMemory(MyBuff, Result);
CopyMemory(MyBuff, Buffer, Result);
SetLength(sText, Result);
CopyMemory(PAnsiChar(sText), MyBuff, Result);
pFileHandle := CreateFile(PChar('C:\log.txt'), GENERIC_WRITE, 0, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if pFileHandle <> INVALID_HANDLE_VALUE then
begin
SetFilePointer(pFileHandle, 0, nil, FILE_END);
Windows.WriteFile(pFileHandle, PAnsiChar(sText), Result, dWrite, nil);
CloseHandle(pFileHandle);
end;
finally
FreeMem(MyBuff);
end;
end;
功能拦截recv(s:TSocket;
缓冲区:指针;
BuffLength:整数;
标志:整数):整数;stdcall;
变量
MyBuff:PAnsiChar;
pFileHandle:THandle;
德怀特:德沃德;
sText:AnsiString;
开始
结果:=recvNext(s、缓冲区、BuffLength、标志);
如果结果是在日志文件中,我得到90%的不可读内容和类似内容:HTTP/1.1 200 OK Date:Sun,2014年7月13日13:02:27 GMT Variable:Accept Encoding P3P:policyref=“”,CP=“ALL DSP COR CUR OUR IND PUR”Pragma:无缓存控制:无缓存注入浏览器。我相信也有HTML代码,您确定我不应该在保存缓冲区之前处理它吗?因为您直接挂接recv()
,所以您看到的是原始数据,在本例中是HTTP会话。HTTP是文本和二进制数据的混合体。您必须解析HTTP数据以忽略您不想要的内容,并保留您想要的内容。您必须考虑到HTTP数据将跨越多个recv()
调用和多个套接字连接,因此请跟踪每个套接字正在解析的内容。这将是一项艰巨的工作。挂钩recv()
可能不是最好的解决方案。你想实现什么?我只是在学习更多关于钩子的知识,现在决定控制进入谷歌浏览器的html代码的流量。但我有一个非常奇怪的行为,因为有些网站我在日志中清楚地看到了HTML源代码,但其他网站却没有出现在日志中。总是出现相同的站点,而其他站点则不会。看起来chrome有时使用recv,而其他人则不使用。但这对我来说毫无意义。一些网站可能已经在浏览器的缓存中,因此它不必从服务器检索它们。或者可能站点被压缩,在遇到空字节后日志停止显示。。。关于空字节的这件事很有意义。我尝试清理历史记录,这样缓存就不会有问题了。但是空字节可以是。。。如果可以,请尝试告诉我如何修复此问题并删除空字节以保存完整日志。我也会做一个调查。谢谢。
function Interceptrecv(s: TSocket;
Buffer: Pointer;
BuffLength: integer;
Flags: integer): Integer; stdcall;
var
pFileHandle: THandle;
dWrite: DWORD;
begin
Result := recvNext(s, Buffer, BuffLength, Flags);
if Result <= 0 then Exit;
pFileHandle := CreateFile('C:\log.txt', FILE_APPEND_DATA, 0, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if pFileHandle <> INVALID_HANDLE_VALUE then
begin
Windows.WriteFile(pFileHandle, Buffer^, Result, dWrite, nil);
CloseHandle(pFileHandle);
end;
end;