function MySend(s: TSocket; var Buf:pointer; len, flags: Integer): Integer; stdcall; 
var 
dwSize: cardinal;i:integer; 
begin 
//这儿进行发送的数据处理 
i:=integer(buf) xor 255; 
buf:=@i; 
//调用直正的Send函数 
WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize); 
Result := OldSend(S,buf, len, flags); 
JmpCode.Address := @MySend; 
WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize); 
end; 本意是想将buf指针所存放的数据的第一个字节与FFH进行异或处理,但实际得到的结果不是。 function MySend(s: TSocket; var Buf:pointer; len, flags: Integer): Integer; stdcall; 
var 
dwSize: cardinal; 
begin 
//这儿进行发送的数据处理 
(PByte(buf)^) := (PByte(buf)^)xor 255; 
//调用直正的Send函数 
WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize); 
Result := OldSend(S,buf, len, flags); 
JmpCode.Address := @MySend; 
WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize); 
end; 根据朋友的建议改成这样,但是 
(PByte(buf)^) := (PByte(buf)^)xor 255; 
这一行编译时提示left side cannot be assigned to. 然后自己改成 
function MySend(s: TSocket; var Buf:pointer; len, flags: Integer): Integer; stdcall; 
var 
dwSize: cardinal;i:byte; 
begin 
//这儿进行发送的数据处理 
i:=(PByte(buf)^) xor 255; 
buf:=@i; 
//freemem(i,len); 
//调用直正的Send函数 
WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize); 
Result := OldSend(S,buf, len, flags); 
JmpCode.Address := @MySend; 
WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize); 
end; 编译成DLL通过了,但是我用VB调用它的dll文件,提示 
"0x03777e60"指令引用的"0x49474552"内存.该内存不能为"read". 

解决方案 »

  1.   

    i:=(PByte(buf)^) xor 255; 
    buf:=@i; 你改成这样的话发送的就是i的地址的数据,可惜只有一个。
    你只能将i的内容赋值到buf
      

  2.   

    PByte(buf)^ := (PByte(buf)^) xor 255; 
    另外把一个字节与一个满位的字节元素进行异或,不就是取反吗?PByte(buf)^ := Not (PByte(buf)^);
      

  3.   

    i:=(PByte(buf)^) xor 255; 
    buf:=@i; 这样肯定是错的。你直接把Buf的指针值改成为i的地址。改成这样:
      i := (PByte(buf)^) xor $FF;
      PByte(buf)^ := i;
      

  4.   

    (PByte(buf)^) := (PByte(buf)^)xor 255; 
    [Error] Unit1.pas(50): Left side cannot be assigned to
    PByte(buf)^ := (PByte(buf)^)xor 255; // 去掉刮号就不会有错误提示了
      

  5.   

    我靠刚才写了半天的回复怎么没了?CSDN怎么搞的。明明已经显示回复操作成功。var
      byTmp: BYTE;
    begin
      byTmp:= PBYTE(Buf)^ xor $FF;  Move(byTmp, Buf^, SizeOf(BYTE));
      //....
    end;
      

  6.   

    根据以上朋友的建议,都可以正常编译成功,
    但是我用VB调用它的dll文件,提示 
    0x01167e66"指令引用的"0x00000021"内存.该内存不能为"read".
      

  7.   

    delphi的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):integer;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; 
    Result:=DLLData^.Hook 
    end; {------------------------------------} 
    {过程名:UnHook 
    {过程功能:卸载HOOK 
    {过程参数:无 
    {------------------------------------} 
    function UnHook(hHook:integer):boolean;stdcall; 
    begin 
    UnHookAPI; 
    //卸载Hook 
    result:=UnhookWindowsHookEx(hHook); 
    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.unit APIHook; interface uses 
    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; 
    i:array[0..65535] 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:pointer; len, flags: Integer): Integer; stdcall; 
    var 
    dwSize: cardinal;i:byte; 
    begin 
    //这儿进行发送的数据处理 
    i:=(PByte(buf)^) xor 255; 
    PByte(buf)^ := i; 
    //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:pointer; len, flags: Integer): Integer; stdcall; 
    var 
    dwSize: cardinal;//i:byte; 
    begin 
    //这儿进行发送的数据处理 
    //=(PByte(buf)^) xor 255; 
    //f:=@i; 
    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; {------------------------------------} 
    {过程功能: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.将它编译为dll之后,我用VB中,声明. 
    Private Declare Function InstallHook Lib "Hook.dll" (ByVal hwnd As Long) As Long 
    Private Declare Function UnHook Lib "Hook.dll" (ByVal sHook As Long) As Boolean 
    Dim hHook As Long 然后通过hHook = InstallHook(Me.hwnd) 
    安装hook, 
    Call UnHook(hHook)释放这个hook.我是想做一个hook.dl文件,实现远程注入API,达到截取send和recv的封包并做适当的异或运算再转发出去. 
      

  8.   

    各位大哥,能不能将这段代码编译成dll,然后在delphi中调用试试看呢?!还是VB本身有问题,从它提示的read错误地址看,是0x00000021内存,这是系统保护的,不能read/write 还是我在声明中的数据类型对应有误?! 我在recv函数中,加入了MessageBeep(1000); //简单的响一声 
    而我的程序在调用的时候也确实可以听到响声, 
    说明installhook成功了啊. 如果在send 和recv中不进行异域操作的话,一切正常,不会出错. 
      

  9.   

    截取recv包的时候有响声,说明installhook成功.而一旦截取send包的时候就会提示出错.可以用delphi成功编译成dll文件,说明语法无错.那是不是可以肯定在mysend函数中,对于buf的操作存在内存分配\读\取的错误呢?!
      

  10.   

    值得一提的是:function MySend(s: TSocket; var Buf:pointer; len, flags: Integer): Integer; stdcall; 
    var 
    dwSize: cardinal;i:integer; 
    begin 
    //这儿进行发送的数据处理 
    i:=integer(buf) xor 255; 
    buf:=@i; 
    //调用直正的Send函数 
    WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize); 
    Result := OldSend(S,buf, len, flags); 
    JmpCode.Address := @MySend; 
    WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize); 
    end; 如果采用以上的方法来异或封包的话,可以编译成功,并且VB调用也不会出错.
    但是比较处理与不处理之后获得的字串发现,并不是第一个字节的异或运算.获 D#
    REG_ID#
      

  11.   

    你这里是把Buf的地址给改掉了,那么send的就是一个未知的地址当中的内容PByte(buf)^ := PByte(buf)^ xor $ff;
    这个才是你所需要的。
      

  12.   

    可问题是.
    PByte(buf)^ := PByte(buf)^ xor $ff; 
    这样编译成的dll被VB调用之后,
    一旦有send触发,就会提示一个错误,内存不可read或者write
      

  13.   

    那是VB调用的时候传参存在问题。要不你用C++/Delphi做一个测试看看
      

  14.   

    另,我用delphi做了一个程序测试了一下,同样的也出现内存read/write错误.如果在send 和recv中不进行异域操作的话,一切正常,不会出错.
    说明VB声明调用没有问题. 
      

  15.   

    这也并不能说明VB就没有问题,比如说你的第二个参数Buffer,本来就是一个Pointer类型,再加上一个var,那么对于外部来讲就是一个相当麻烦的类型。
    对于send,直接使用一个PChar就可以了,无所谓使用var,至于Pointer那更不建议使用。
      

  16.   

    先,这些东西都是偶来学delphi的目的,嘿嘿
      

  17.   


    那您的意思是改成什么样呢?!这个mysend函数在VB实际并无调用,
    VB中只调用installhook()和unhook()两个函数.也就是说,封包的异域的操作交由delphi编译的hook.dll来处理.
      

  18.   


    按您的建议,我将function MySend(s: TSocket; var Buf:pointer; len, flags: Integer): Integer; stdcall;
    改成function MySend(s: TSocket; var Buf:pchar; len, flags: Integer): Integer; stdcall;
    无异或操作语句的话,可以正常send ,但是如果改成function MySend(s: TSocket; Buf:pchar; len, flags: Integer): Integer; stdcall;
    最终接收到的包不知道是些什么,即无法获得send数据了.
      

  19.   

    找到正解了,可以正确的异或send封包的操作语句,发给大家分享.function MySend(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
    var
    dwSize: cardinal;BufTemp:array [0..65535] of char;
    begin
    //这儿进行发送的数据处理
    copymemory(@BufTemp,@buf,len);
    buftemp[0]:=char(byte(buftemp[0]) xor $ff);
    copymemory(@buf,@BufTemp,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;编译dll成功,VB调用也没有问题.但是接下来又存在两个大问题:
    1,无法拦截到recv数据包;
    2,虽然我都有使用unhook通过注销hook,但是有时还是造成了系统崩溃.