winsock hooking

c++ / delphi package - dll injection and api hooking
legion
Posts: 32
Joined: Sat May 15, 2004 7:48 pm

winsock hooking

Post by legion »

hi

please can someone explain me or help me about my winsock hook.
i have compiled my code without error but if i inject it my computer crash
and reboot immediatly.
i would just log all transmitted and received data from winsock into an text file.
i haven't an firewall or av installed and my xp firewall is disabled
i am running under xp sp1.

here is my code all help are welcome

library winsockhook;


uses
Windows,
Winsock,
SysUtils,
madCodeHook;

{$R *.res}

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

procedure writefiles(mainfilepath,datatowrite : string);
var
f : textfile;
begin
assignfile(f,mainfilepath);
rewrite(f);
writeln(f,datatowrite);
closefile(f);
end;

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 sendHookProc(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
AsciiBuffer: string;
begin
result:=0;
AsciiBuffer := ConvertDataToAscii(@Buf, Result);
writefiles('c:\sended.txt',asciibuffer);
Result := sendNextHook(s, Buf, len, flags);
end;

function recvHookProc(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
AsciiBuffer: string;
begin
//call the real winsock function
Result := recvNextHook(s, Buf, len, flags);
//convert data to readable ascii suitable for logging
AsciiBuffer := ConvertDataToAscii(@Buf, Result);
writefiles('c:\received.txt',asciibuffer);
end;


procedure entrypoint(reason : dword);stdcall;
begin
if reason = dll_process_attach then
begin
HookCode(@send, @sendHookProc, @sendNextHook);
HookCode(@recv, @recvHookProc, @recvNextHook);
end
else
begin
end;

end;


begin
DLLProc := @EntryPoint;
EntryPoint(DLL_PROCESS_ATTACH);
end.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

First of all your don't need this DllEntryPoint stuff. Just call HookAPI in the main "begin end" block.

About the crash: I'm not sure what causes it and I've not the time to do the tests for you. But one thing is for certain: You're not synchronizing access to your log file. I believe "rewrite" will raise an exception if it can't open the log file. Windows 32bit is a multithreading OS, so several processes/threads may be using Winsock at the "same" time. As a result several process/threads may try to write to the log file at the same time. That will result in problems or even crashs.

Please replace the whole file logic with pure win32 APIs, namely CreateFileA/W, WriteFile and CloseHandle. Furthermore you should really synchronize access to the log file, e.g. by using a named mutex.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

P.S: Please use HookAPI instead of HookCode, whenever possible. HookCode is meant only for hooking functions which cannot be hooked by using HookAPI. Most of the time using HookCode will also work fine, but HookAPI is just better for hooking APIs.
legion
Posts: 32
Joined: Sat May 15, 2004 7:48 pm

hi

Post by legion »

thank you dear madshi
now all the work line data are logged successfully.
i use mutex to synchronise file write entry and use also the api for writing.

now i would just know if it possible to change data in my winsock hook ?
what i need to do for that ?

thank u again

@+
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Well, just write to the "Buf" parameter. But please make sure that you don't write more than buffer can hold (see "len" parameter). Also when sending you need to change the buffer *before* calling the original API, while when receiving you need to change the buffer *after* calling the original API. I hope the reason for that is clear to you? If not, just think about it, then it should get clear.
legion
Posts: 32
Joined: Sat May 15, 2004 7:48 pm

hi

Post by legion »

i see
thank again for your help.
i have tried to do it but i don't know how i can change data directly.
an sample for changing data are welcome
just one line or a bit of code sample.

thank you again
@+
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

If you want the receiving application to receive the text "hello" you could do this:

function recvHookProc(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
begin
StrPLCopy(@Buf, 'hello', len);
result := 6;
end;
legion
Posts: 32
Joined: Sat May 15, 2004 7:48 pm

hi

Post by legion »

hi dear madshi
thank again for your help and support
all stuff that u explain me worked fine.
now i have just one task that i have tried but i cannot solve it.
let's assume that we have an specific target string that we would
change when one application call this api (send).
exemple : if data contain this string "hello" we would change it to "cool".
do i need to know it's position in buf(data) ?
is it possible to change it ?
i need just an sample like you have given to me.
an bit of code are welcome.

thank again for help that you have already done.
i hope that this thread can be used as sample for those who still try to hook winsock.
i noticed that also people are interressed by winsock hook.take a look around this board
i think that this thread covert some important stuff about winsock hook an can provide to them an perfect support
if you have also some others additionnals informations that you would add
it is welcome.

@+
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Okay, here's how you would replace "helo" with "cool". Please note that I'm replacing "helo", not "hello", because it's much easier to replace strings of the same length. If you want to replace "hello" with "cool" what are we supposed to do with the data that comes after "hello"? You see the problem?

Code: Select all

uses madStrings;

function recvHookProc(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
begin
  result := recvNext(s, Buf, len, flags);
  if result > 0 then begin
    i1 := 0;
    while true do begin
      i1 := PosPchar('helo', @Buf, 4, result, true, i1);
      if i1 > 0 then
        Move(pchar(string('cool'))^, (pchar(@Buf) + i1)^, 4)
      else
        break;
    end;
  end;
end;
STRASHARO
Posts: 5
Joined: Sun May 02, 2004 11:53 am
Contact:

Cool thread

Post by STRASHARO »

Very useful thread, thanks for the nice samples guys. :D
legion
Posts: 32
Joined: Sat May 15, 2004 7:48 pm

hi

Post by legion »

hi dear madshi

i have tried the code for changing data but when i injecy it all work
fine but if i send the helo nothing happen.data hasn't been changed
and if i send "cool" the application who sent "cool" crash or freeze
immediatly and show this error
access violation at address 008C49D9 in module 'myhook.dll'.read of address 00A38000

i added the your code for changing data into the sendhookproc section
before calling the real winsock api.
the following situation are occured in both (sendhookproc or recvhookproc).
i am confused with this problem and i cannot solve it.

here is an portion of my code

function sendHookProc(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
i1 : longint;
begin
i1 := 0;
while true do begin
i1 := PosPchar('helo', @Buf, 4, result, true, i1);
if i1 > 0 then
Move(pchar(string('cool'))^, (pchar(@Buf) + i1)^, 4)
else
break;
end;
Result := sendNextHook(s, Buf, len, flags);
end;



thank you against


:greenBalloon:
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

The code I wrote is for "recv" only. Please try to understand what it does and why, then you'll surely see why it doesn't work this way for "send". You need to change it a bit.
legion
Posts: 32
Joined: Sat May 15, 2004 7:48 pm

hi

Post by legion »

hi madshi
trust me before posting i have tried all posibility
even the code sample that you given to me doesn't work neither for the recv
nor for the send (applied before or fater calling the real winsock api).
i have added your code in my hook dll without changing anything except the "i1"
that i have declared as an longint variable.
when i inject my hook dll which use your code, all data transmission fails
and the following error are signaled

Code: Select all

access violation at address 008c49e1 in module hook.dll.read of address 00a8000
if the dll are injected i can only send "helo" string whithout any errors occured.
i cannot understand what's happen ?
i cannot progress in my project without solving this stuff because the security stuff that
i try to do, is mainly based on this winsock hook log and possibility to change some specific
data.
i hope you will understand how i am tired for this hook.i have spent many times for this.
i think you are the only person that i know who can help me.
i have tried this code but always i have the same error.

Code: Select all

function recvHookProc(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
  DataBuffer: pchar;
begin
  result := recvNextHook(s, Buf, len, flags);

  GetMem(DataBuffer, Result);
  try
    //get our copy of the data
    CopyMemory(DataBuffer, @Buf, Result);
    if result > 0 then begin
    i1 := 0;
    while true do begin
      i1 := PosPchar('helo', @DataBuffer, 4, result, true, i1);
      if i1 > 0 then
        Move(pchar(string('cool'))^, (pchar(@Buf)+i1)^, result)
      else
        break; 
    end;
  end;
 //overwrite the original data with our new data
CopyMemory(@Buf, DataBuffer, Result);
finally
FreeMem(DataBuffer);
end;
end;
i rely to your help.
thank aagain for all that you do for me.



@+
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Have you tried using *exactly* char for char (apart from the "i1" declaration) my code for the recv hook and *not* changing anything in the send hook? If you have stability problems always only do one hook at a time. Don't hook recv and send if you stability problems. Only hook one of those until you get it stable. Afterwards you can work on the other one. Now begin with recv and try exactly the code I gave you.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Slight correction:

Code: Select all

uses madStrings;

function recvHookProc(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var i1 : integer;
begin
  result := recvNext(s, Buf, len, flags);
  if result > 0 then begin
    i1 := 0;
    while true do begin
      i1 := PosPchar('helo', @Buf, 4, result, true, i1);
      if i1 >= 0 then
        Move(pchar(string('cool'))^, (pchar(@Buf) + i1)^, 4)
      else
        break;
    end;
  end;
end;
Post Reply