打印本文 打印本文 关闭窗口 关闭窗口
Delphi Winsock Hooking Example by Aphex
作者:武汉SEO闵涛  文章来源:敏韬网  点击数1366  更新时间:2009/4/23 18:41:47  文章录入:mintao  责任编辑:mintao

{
  Delphi Winsock Hooking Example by Aphex
  http://www.iamaphex.cjb.net
  unremote@knology.net

  This example shows you how to hook winsock functions
  of a target process and control incomming and outgoing
  data. It is based on send and recv but it will work the
  same way applied to sendto and recvfrom.

  The output file is a CPL (Control Panel Extension) which
  is simply a special DLL that is loaded when it is double
  clicked. This saves us from having to write a seperate
  loader for the hook library.

  The example shows how to hook the needed functions and
  perform some simple manipulation of the data, using two
  different methods of accessing the data. The second, which
  uses pointers, is more flexible but also more complex.
}

library Project1;

uses
  Windows,
  Winsock,
  SysUtils,
  madCodeHook;

{$R *.RES}

{$E CPL}

var
  sendNextHook: function(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
  recvNextHook: function(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
  DataSocket: TSocket;

const
  szTargetExe: string = ''''GAME.EXE'''';

function ConvertDataToAscii(Buffer: pointer; Length: Word): string;
var
  Iterator: integer;
  AsciiBuffer: string;
begin
  AsciiBuffer := '''''''';
  for Iterator := 0 to Length - 1 do
  begin
    if char(pointer(integer(Buffer) + Iterator)^) in [#32..#127] then
      AsciiBuffer := AsciiBuffer + '''' '''' + char(pointer(integer(Buffer) + Iterator)^) + '''' ''''
    else
      AsciiBuffer := AsciiBuffer + '''' . '''';
  end;
  Result := AsciiBuffer;
end;

function ConvertDataToHex(Buffer: pointer; Length: Word): string;
var
  Iterator: integer;
  HexBuffer: string;
begin
  HexBuffer := '''''''';
  for Iterator := 0 to Length - 1 do
  begin
    HexBuffer := HexBuffer + IntToHex(Ord(char(pointer(integer(Buffer) + Iterator)^)), 2) + '''' '''';
  end;
  Result := HexBuffer;
end;

function recvHookProc(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
  AsciiBuffer: string;
  HexBuffer: string;
  DataBuffer: pchar;
begin
  //call the real winsock function
  Result := recvNextHook(s, Buf, len, flags);
  //allocate memory for our copy of the data
  GetMem(DataBuffer, Result);
  try
    //get our copy of the data
    CopyMemory(DataBuffer, @Buf, Result);
    //using the data as a byte array
    DataBuffer[0] := chr(10);  //changing first byte
    DataBuffer[1] := chr(20);  //changing second byte
    DataBuffer[2] := chr(30);  //changing thrid byte
    //using the data as a pointer to other data sizes
    word(pointer(DataBuffer)^) := 10; //changing first 2 bytes
    dword(pointer(integer(DataBuffer) + 2)^) := 20; //changing next 4 bytes
    word(pointer(integer(DataBuffer) + 6)^) := 30; //changing next 2 bytes
    //overwrite the original data with our new data
    CopyMemory(@Buf, DataBuffer, Result);
  finally
    FreeMem(DataBuffer);
  end;
  //convert data to readable ascii suitable for logging
  AsciiBuffer := ConvertDataToAscii(@Buf, Result);
  //convert data to readable hex suitable for logging
  HexBuffer := ConvertDataToHex(@Buf, Result);
end;

function sendHookProc(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
  AsciiBuffer: string;
  HexBuffer: string;
  DataBuffer: pchar;
begin
  Result := 0;
  //save the socket so we can send data too
  DataSocket := s;
  //allocate memory for our copy of the data
  GetMem(DataBuffer, Result);
  try
    //get our copy of the data
    CopyMemory(DataBuffer, @Buf, Result);
    //using the data as a byte array
    DataBuffer[0] := chr(10);  //changing first byte
    DataBuffer[1] := chr(20);  //changing second byte
    DataBuffer[2] := chr(30);  //changing thrid byte
    //using the data as a pointer to other data sizes
    word(pointer(DataBuffer)^) := 10; //changing first 2 bytes
    dword(pointer(integer(DataBuffer) + 2)^) := 20; //changing next 4 bytes
    word(pointer(integer(DataBuffer) + 6)^) := 30; //changing next 2 bytes
    //overwrite the original data with our new data
    CopyMemory(@Buf, DataBuffer, Result);
  finally
    FreeMem(DataBuffer);
  end;
  //convert data to readable ascii suitable for logging
  AsciiBuffer := ConvertDataToAscii(@Buf, Result);
  //convert data to readable hex suitable for logging
  HexBuffer := ConvertDataToHex(@Buf, Result);
  //call the real winsock function
  Result := sendNextHook(s, Buf, len, flags);
end;

procedure EntryPoint(Reason: dword); stdcall;
var
  lpFileName: array [0..MAX_PATH - 1] of char;
  StartInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
begin
  if Reason = DLL_PROCESS_ATTACH then
  begin
    //check if we are injected inside the target
    if lstrcmpi(pchar(Copy(ParamStr(0), Length(ParamStr(0)) - Length(szTargetExe) + 1, Length(szTargetExe))), pchar(szTargetExe)) = 0 then
    begin
      //if we are then we hook the needed functions
      DataSocket := 0;
      HookCode(@send, @sendHookProc, @sendNextHook);
      HookCode(@recv, @recvHookProc, @recvNextHook);
    end
    else
    begin
      //if not then load the target and inject ourself
      GetModuleFileName(hInstance, @lpFileName, MAX_PATH);
      ZeroMemory(@StartInfo, SizeOf(TStartupInfo));
      ZeroMemory(@ProcInfo, SizeOf(TProcessInformation));
      StartInfo.dwFlags := STARTF_USESHOWWINDOW;
      StartInfo.wShowWindow := SW_SHOW;
      CreateProcess(PChar(ExtractFilePath(lpFileName) + szTargetExe), nil, nil, nil, False, 0, nil, nil, StartInfo, ProcInfo);
      Sleep(3000);
      InjectLibrary(ProcInfo.hProcess, lpFileName);
    end;
  end;
end;

begin
  DLLProc := @EntryPoint;
  EntryPoint(DLL_PROCESS_ATTACH);
end.

打印本文 打印本文 关闭窗口 关闭窗口