hooking getaddrinfo - desperate help - please...

c++ / delphi package - dll injection and api hooking
Post Reply
mikec
Posts: 166
Joined: Sun Jul 16, 2006 9:01 pm
Location: UK

hooking getaddrinfo - desperate help - please...

Post by mikec »

Hi all, in desperate need of some help. Had a product that was due for release next week when I discovered a problem with one of the hooks. There seems to be an instability when hooking WinINet InternetConnectA, which causes IE to randomly crash. It didn't seem to be confined to my code so i reported it to madshi and posted on the forum.

Because I got no replies, I started to at alternatives, specifically in winsock. I've successfully hooked the gethostbyname() but i now need to hook getaddrinfo(). I've got my hook working and my IPC notification but i don't seem to be able to touch the return structure that holds the data about the intended / target IP address. Every time I try to access the structure, the target process crashes with an Access Violation.

Does anyone have any suggestions or examples - I'm in desperate need of some help. I'm running 2.5.7.1 beta, and Delphi 7 Enterprise. My code looks like this:

Code: Select all

function WSGetAddrInfoCallback(const nodename : PAnsiChar; const servname : PAnsiChar; const hints : PAddrInfo; var res : PAddrInfo) : Integer; stdcall;
var
   iIPCRtn    : Integer;
   szPacket   : string;
   iIPAddr    : Cardinal;
   AI         : PAddrInfo;

begin
  if (nodename <> nil) then
  begin
    result := WSGetAddrInfoNxt(nodename, servname, hints, res);

    if ((result <> 0)) then 
    begin
      iIPCRtn  := 0;
      AI := res;
      if ((AI^.ai_family = PF_INET) or (AI^.ai_family = PF_INET6)) then
      begin
         move(AI^.ai_addr.sin_addr.S_addr, iIPAddr, sizeof(iIPAddr));
         szPacket := string(IntToStr(QUERY_URL_EXEC_ID)+ #01 +
                                    IntToStr(ACTION_QUERY_)        + #01 + 
                                    IntToStr(API_GET_ADDR_INFO) + #01 + 
                                    IntToStr(GetCurrentProcessId())+ #01 + 
                                    string(nodename)                     + #01 +
                                    IntToStr(iIPAddr)                      + #0D);

         if (not (SendIpcMessage(IPC_QUEUE_CONTROL_NAME, PChar
                                            (szPacket), Length(szPacket), @iIPCRtn,
                                            sizeof(iIPCRtn), SEND_IPC_TIMEOUT)) 
                                            or (iIPCRtn = 0)) then
         begin;
            //freeaddrinfo(res);
            SetLastError(ERROR_ACCESS_DENIED);
            WSASetLastError(WSAEACCES);
            result := WSAEACCES;
         end;
      end;
    end;
  end
  else
     result := WSGetAddrInfoNxt(nodename, servname, hints, res)
end;

   
WSGetAddrInfoNxt         : function(const nodename : PAnsiChar;
                                       const servname : PAnsiChar;
                                       const hints    : PAddrInfo;
                                       var res        : PAddrInfo
                                      ) : Integer; stdcall;


HookAPI('ws2_32.dll',  'getaddrinfo', @WSGetAddrInfoCallback, @WSGetAddrInfoNxt);
jonny_valentine
Posts: 109
Joined: Thu Dec 30, 2004 9:59 pm
Location: UK

Post by jonny_valentine »

Didnt read your code, but in c++ if i touch the original data, it will crash like you are saying, so i use memcpy to copy the original data into a temp var then mess with that.
mikec
Posts: 166
Joined: Sun Jul 16, 2006 9:01 pm
Location: UK

thanks but still having problems..

Post by mikec »

Hay John,

Thanks for the reply - this is exactly what i'm seeing. The minute i touch the res return structure, it all crashes. Problem is, I'm coding this in pascal / delphi and it's not my native language - so basically i don't really know what i'm doing 100%. I've tried to use the move() funciton and CopyMemory() api but always it crashes.

Do you have any kind of demo code that you could send me to i could try it out on my test bed? I'd be much happier knowing that it was actually possible rather than just sitting the the dark having know idea.

Many thanks,

Mike C
jonny_valentine
Posts: 109
Joined: Thu Dec 30, 2004 9:59 pm
Location: UK

Post by jonny_valentine »

Here is an example in C++ for my Send() hook.. i make my own var and use memcpy to copy the data into it, i can then mess around with the data in my own var and leave the original.
Dont know about pascal/delphi, sorry.

Code: Select all

PCHAR mybuf;
mybuf = (PCHAR) LocalAlloc(LPTR, len+1);
memcpy(mybuf,buf,len);
mikec
Posts: 166
Joined: Sun Jul 16, 2006 9:01 pm
Location: UK

follow up

Post by mikec »

Hay Jonney,

thanks for the reply and appoligies for the late responce. As you have stated, this does seem to be the problem. I have tested this with a C++ implimentation of my library and if i copy the return res structure (as you have shown), I can access the copy.

However, my live lnjection library is written in Delphi / Pascal becuase of an issue that we had with Windows Update. My knowledge of Delphi is limited and i can see how to achieve the same thing in pascal. I have tried the move() function but still it does the minute i touch the copied structure.

Can any delphi experts shead some light on this..

Many thanks,

Mike C
dcsoft
Posts: 380
Joined: Sat Dec 11, 2004 2:11 am
Location: San Francisco Bay Area, CA USA
Contact:

Post by dcsoft »

BTW, what does Windows Update have to do with it? If you static link your DLL, you should be unaffected by Windows Update changes.

-- David
mikec
Posts: 166
Joined: Sun Jul 16, 2006 9:01 pm
Location: UK

windows update issues

Post by mikec »

I' ve reported this issue in a previous post to this forum, injecting system wide, with eithere a delphi or bcb injection library, causes some windows updates to crash. Even injecting with a blank BCB library causes some windows update to crash.

The only way i could avoid it was to use Delphi, and deteremine what the target and parent processes were.

Mike C
softtouch
Posts: 111
Joined: Sat Jun 20, 2009 10:08 am
Contact:

Post by softtouch »

Is this thread still alive?

I have also an almost similar issue with GetAddrInfoA/W.

The hook itself is fine, as long as I do not access the "nodename" variable.
When I do, the browser will do nothing when clicking refresh, or typing an url. And when I exit the browser, the browser window disappear, but the process keep running and I have to kill the process.

This below works with no browser issues:

function GetAddrInfoACallBack(const nodename : PAnsiChar; const servname : PAnsiChar; const hints : PAddrInfo; var res : PAddrInfo) : Integer; stdcall;
begin
result:=GetAddrInfoANext(nodename,servname,hints,res);
RenewHook(@GetAddrInfoANext);
end;

Inserting there

pi.id:=MSGTYPE_GETADDRINFO;
lstrcpy(pi.target,nodename);
SendIpcMessage(pchar('ProtexProc'),@pi,sizeOf(pi),@result,sizeOf(result));

and the issue is there, but when I do not use the nodename variable, and just enter a text to copy to pi.target, no issues.

I am hooking GetAddrInfoA and W, and under Vista, the hook is called (with the mentioned issues), but under XP, the hook is not called, at least, I did not receive anything via IPC under XP.

The reason why I hook this api's is that I need the host/url. I also hook connect, and tried using gethostbyaddr to get the url, which works, but it is so slow that browsing is impossible (take long until gethostbyaddr return on my pc), and only the IP does not help me.
dcsoft
Posts: 380
Joined: Sat Dec 11, 2004 2:11 am
Location: San Francisco Bay Area, CA USA
Contact:

Post by dcsoft »

Code: Select all

pi.id:=MSGTYPE_GETADDRINFO;
lstrcpy(pi.target,nodename);
SendIpcMessage(pchar('ProtexProc'),@pi,sizeOf(pi),@result,sizeOf(result)); 
Does it crash if you don't call SendIpcMessage()? The problem maybe you are overrunning the pi.target buffer (you don't check the size) in the lstrcpy.

I have running code that does something similar to what you're doing... sendipcmesage of the nodename, and it works fine. But its written in C++.

-- David
mikec
Posts: 166
Joined: Sun Jul 16, 2006 9:01 pm
Location: UK

Post by mikec »

Hay guys,

I gave up on this a long time ago. I opted to hook the send requests because i can look at the different send requests and filter for GET or POSTS.

I'd be interested to know if anyone gets this working...

Mike C
softtouch
Posts: 111
Joined: Sat Jun 20, 2009 10:08 am
Contact:

Post by softtouch »

dcsoft wrote:

Code: Select all

pi.id:=MSGTYPE_GETADDRINFO;
lstrcpy(pi.target,nodename);
SendIpcMessage(pchar('ProtexProc'),@pi,sizeOf(pi),@result,sizeOf(result)); 
Does it crash if you don't call SendIpcMessage()? The problem maybe you are overrunning the pi.target buffer (you don't check the size) in the lstrcpy.

I have running code that does something similar to what you're doing... sendipcmesage of the nodename, and it works fine. But its written in C++.

-- David
The buffer is just fine. No "overrun". Also my app does not crash, works normal. Just the browser cannot browse any longer. When clicking refresh, or entering an url in the browser, nothing happen at all in the browser. And when closing the browser, the window disappear, but the browser process keeps running and I manually have to kill the browser process. But as I said, my app get the url just fine, and works without freezing.
softtouch
Posts: 111
Joined: Sat Jun 20, 2009 10:08 am
Contact:

Post by softtouch »

Anybody has an idea how else I could get the host from the IP without hooking this function, and without using gethostbyaddr (which takes too long)?

I am stuck now and cannot find a solution. Google was no help too.

GetAddrInfo would be the perfect solution, if it only would work...
Hooking "connect" does not bring anything, I would have to do a reverse lookup via gethostbyaddr in the dll, which will take far too long. There must be sure any other api which is called with the host, before the host gets translated to the ip address, but I cannot find any (yet).
Post Reply