Hook of InternetQueryDataAvailable leads to Access Violation

c++ / delphi package - dll injection and api hooking
Post Reply
DSp_nrg
Posts: 18
Joined: Mon Aug 04, 2014 10:26 am

Hook of InternetQueryDataAvailable leads to Access Violation

Post by DSp_nrg »

Hi,

I'm currently working on a hook for Wininet.dll. In the Hook of "InternetReadFile" method I'm required to call "InternetQueryDataAvailable" to determine if all data was fetched. To avoid including the Wininet.dll in my Hook.dll I just hooked it and call the original pointer. This works fine for methods like "InternetGetCookieA" or "InternetQueryOptionA", but once I'm adding

Code: Select all

if (!HookAPI("Wininet.dll", "InternetQueryDataAvailable", InternetQueryDataAvailableCallback, (PVOID*)&InternetQueryDataAvailableNext))
{
	errorStr += "Error in HookAPI of InternetQueryDataAvailable\n";
}
to my code, Internet Explorer crashes immediatly with an access violation. I'm trying to debug this for a while now, and can't find the issue on my side. Could this be a bug, or am I doing something completely wrong? :confused:
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: Hook of InternetQueryDataAvailable leads to Access Viola

Post by madshi »

If you have hooked one API of a dll and you get a callback, you already know that the dll is now loaded, so in that moment you could use GetModuleHandle + GetProcAddress to get access to the other APIs. Or you could even increase the dll reference counter by calling LoadLibrary. Of course the latter could in some very rare situations cause problems, so it might not be such a good idea. In any case, I like the GetProcAddress approach more than calling "alien" original pointers. Anyway, this is probably not the cause of the problem.

Have you double and triple checked that your InternetQueryDataAvailableCallback and InternetQueryDataAvailableNext definition are perfect? Double check both the params and the calling conversion and the return value. If everything looks perfect to you, try using an "empty" InternetQueryDataAvailableCallback function, which just forwards the call to InternetQueryDataAvailableNext without doing anything else. Does that make the crash go away? If not, change the InternetQueryDataAvailableCallback function to a "TerminateProcess(GetCurrentProcess())" call. Does that make the process silenly terminate itself? Finally, undo all those changes and then add that TerminateProcess() call directly after the offending HookAPI() call. Does the make the process terminate itself? These tests might bring us a few small steps nearer to find out where the problem is coming from.
DSp_nrg
Posts: 18
Joined: Mon Aug 04, 2014 10:26 am

Re: Hook of InternetQueryDataAvailable leads to Access Viola

Post by DSp_nrg »

Hi,

thanks for your quick reply. My definitions look good:

Code: Select all

BOOL (__stdcall *InternetQueryDataAvailableNext)(
  _In_   HINTERNET hFile,
  _Out_  LPDWORD lpdwNumberOfBytesAvailable,
  _In_   DWORD dwFlags,
  _In_   DWORD_PTR dwContext
);
BOOL InternetQueryDataAvailableCallback(
		_In_   HINTERNET hFile,
		_Out_  LPDWORD lpdwNumberOfBytesAvailable,
		_In_   DWORD dwFlags,
		_In_   DWORD_PTR dwContext
	)
{
	return InternetQueryDataAvailableNext(hFile, lpdwNumberOfBytesAvailable, dwFlags, dwContext);
}
Replacing the "InternetQueryDataAvailableNext" with the TerminateProcess call, prevents the access violation and kills the content tab. The problem seems to occur in call of "InternetQueryDataAvailableNext".
Placing TerminateProcess directly after the HookAPI call, kills the Internet Explorer on startup.

Here would be a stack trace from the error, maybe that helps you:
> ntdll.dll!_RtlpWaitOnCriticalSection@8() Unbekannt
ntdll.dll!_RtlEnterCriticalSection@4() Unbekannt
urlmon.dll!CINet::ReportResultAndStop(long,unsigned __int64,unsigned __int64,unsigned short *) Unbekannt
urlmon.dll!CINet::INetRead(void) Unbekannt
urlmon.dll!CINet::INetQueryInfo(void) Unbekannt
urlmon.dll!CINet::OnINetInternal(unsigned long) Unbekannt
urlmon.dll!CINetProtImpl::Continue(struct _tagPROTOCOLDATA *) Unbekannt
urlmon.dll!CINet::Continue(struct _tagPROTOCOLDATA *) Unbekannt
urlmon.dll!COInetProt::Continue(struct _tagPROTOCOLDATA *) Unbekannt
urlmon.dll!CTransaction::OnINetInternalCallback(class CTransPacket *) Unbekannt
urlmon.dll!CTransaction::OnINetCallback(int) Unbekannt
urlmon.dll!TransactionWndProc(struct HWND__ *,unsigned int,unsigned int,long) Unbekannt
user32.dll!_InternalCallWinProc@20() Unbekannt
user32.dll!_UserCallWinProcCheckWow@32() Unbekannt
user32.dll!_DispatchMessageWorker@8() Unbekannt
user32.dll!_DispatchMessageW@4() Unbekannt
ieframe.dll!CTabWindow::_TabWindowThreadProc(void *) Unbekannt
ieframe.dll!LCIETab_ThreadProc(void *) Unbekannt
iertutil.dll!CIsoScope::RegisterThread(unsigned long,enum _IsoThreadDispatchType,unsigned long,unsigned long,unsigned long *) Unbekannt
ieframe.dll!Detour_DefWindowProcA(struct HWND__ *,unsigned int,unsigned int,long) Unbekannt
kernel32.dll!@BaseThreadInitThunk@12() Unbekannt
ntdll.dll!___RtlUserThreadStart@8() Unbekannt
ntdll.dll!__RtlUserThreadStart@8() Unbekannt
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: Hook of InternetQueryDataAvailable leads to Access Viola

Post by madshi »

No, they don't look good. There's a __stdcall missing in your InternetQueryDataAvailableCallback definition. It must crash that way.
DSp_nrg
Posts: 18
Joined: Mon Aug 04, 2014 10:26 am

Re: Hook of InternetQueryDataAvailable leads to Access Viola

Post by DSp_nrg »

Of course you are right... Sorry I wasted your time, seems like I checked that part so often I were not able to see the missing __stdcall. Thank you very much, this solves the problem
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: Hook of InternetQueryDataAvailable leads to Access Viola

Post by madshi »

No worries, it's the most common mistake by a looooong mile, so it's always the first thing I check.
Post Reply