HookAPI fail but callback is well run.

c++ / delphi package - dll injection and api hooking
Post Reply
dhdnjscks
Posts: 4
Joined: Mon Jun 13, 2016 2:38 am

HookAPI fail but callback is well run.

Post by dhdnjscks »

I use madCHook HookAPI Function.

Code: Select all

if (!HookAPI("ntdll.dll", "NtCreateKey", CHookRegistry::HookNtCreateKey, (PVOID*)&OrignalNtCreateKey))
{
	OutputDebugString(_T("Proc Hook : ZwCreate Hook fail\n"));
}
(I think Nt is equal Zw in user mode)

When I execute that, I can see debug message. but Function named HookZwCreateKey is well run.
What is mean?

And
When I hook svchost.exe, It is well running. But somewhat later, bluescreen of death is bringing up randomly.
Is it my fault in code or "HookAPI fail" problem?
or something else?
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: HookAPI fail but callback is well run.

Post by iconic »

Yes, Nt and Zw are equivalent in usermode only. Not sure about your 3rd parameter "CHookRegistry::HookNtCreateKey" though. Can we see what it consists of as well as the original function prototype (param 4)? Pretty sure HookApi() doesn't want a class type in param 3...

P.S: What does "well run" mean exactly? :confused:

--Iconic
dhdnjscks
Posts: 4
Joined: Mon Jun 13, 2016 2:38 am

Re: HookAPI fail but callback is well run.

Post by dhdnjscks »

I'm sorry. my question is so rough

Code: Select all

NTSTATUS(NTAPI *OrignalNtCreateKey)(
	PHANDLE            KeyHandle,
	ACCESS_MASK        DesiredAccess,
	POBJECT_ATTRIBUTES ObjectAttributes,
	ULONG              TitleIndex,
	PUNICODE_STRING    Class,
	ULONG              CreateOptions,
	PULONG             Disposition
	);
that is OrignalNtCreateKey.

and

3 param is static function.

Code: Select all

static NTSTATUS WINAPI HookNtCreateKey(
		_Out_      PHANDLE            KeyHandle,
		_In_       ACCESS_MASK        DesiredAccess,
		_In_       POBJECT_ATTRIBUTES ObjectAttributes,
		_Reserved_ ULONG              TitleIndex,
		_In_opt_   PUNICODE_STRING    Class,
		_In_       ULONG              CreateOptions,
		_Out_opt_  PULONG             Disposition
		);

Code: Select all

NTSTATUS NTAPI CHookRegistry::HookNtCreateKey(
	_Out_      PHANDLE            KeyHandle,
	_In_       ACCESS_MASK        DesiredAccess,
	_In_       POBJECT_ATTRIBUTES ObjectAttributes,
	_Reserved_ ULONG              TitleIndex,
	_In_opt_   PUNICODE_STRING    Class,
	_In_       ULONG              CreateOptions,
	_Out_opt_  PULONG             Disposition
	)
{
	CString name = ObjectAttributes->ObjectName->Buffer;
	//OutputDebugString(_T("DLL Hooked NtCreateKey!\n"));

	if (name.Find(_T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\TaskCache\\Tree")) != -1)
	{	
		OutputDebugString(name + _T("\n"));
	}

	NTSTATUS status = OrignalNtCreateKey(
		KeyHandle,
		DesiredAccess,
		ObjectAttributes,
		TitleIndex,
		Class,
		CreateOptions,
		Disposition
		);


	return status;
}
"well run" is
I think if HookAPI function is failed, 3rd param function is not work.
but debug message is printed well. I think that is Hooking is success. but HookAPI() is return failed... what is mean?
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: HookAPI fail but callback is well run.

Post by madshi »

You're saying HookAPI() returns FALSE, but the hook still works? That seems weird. Are you 100% sure about that? What does GetLastError() say after HookAPI() returned false?

"NTSTATUS NTAPI CHookRegistry::HookNtCreateKey" does not sound like a good idea. Class methods have an additional first hidden "this" parameter. So your hook callback function has a different number of parameters compared to the original API. That won't work properly. Your hook callback function must have exactly the same definition as the original API. See hooking rule 1:

http://help.madshi.net/HookingRules.htm

A blue screen is usually the result of your hook dll doing something bad inside the context of a service or (user mode) system process.
dhdnjscks
Posts: 4
Joined: Mon Jun 13, 2016 2:38 am

Re: HookAPI fail but callback is well run.

Post by dhdnjscks »

In My First question's code, debug message is seen when HookAPI() is FALSE.
I always see that. so I think it is FALSE.
And GetLastError() return nothing. it is not error but HookAPI normally return FALSE.

and I can also see callback function's debug message. That is mean callback is work.

Hidden parameter "this" is looked for the first time. Thanks.
But debug message's "ObjectAttributes->ObjectName->Buffer" is well printed. so I think it is no problem.
But I don't know exactly, I remove class. but still same problem.


I only print debug message. but why blue screen is bringing up?
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: HookAPI fail but callback is well run.

Post by madshi »

Your debug message doesn't really say from which process it comes. Maybe HookAPI() sometimes returns true and sometimes false? Please try to also write a debug message when HookAPI() succeeds. And if it fails, please log the GetLastError() value. Are you saying it's 0?

I'm not sure where the blue screen comes from. I'd suggest that you try with an "empty" hook callback function. Meaning: The hook callback function should only have "return OrignalNtCreateKey(...)" in it. If you still get a blue screen, please post your whole code.
dhdnjscks
Posts: 4
Joined: Mon Jun 13, 2016 2:38 am

Re: HookAPI fail but callback is well run.

Post by dhdnjscks »

Yes, GetLastError() return 0.

BlueScreen is occur when new process create.
I hook svchost.exe.
and I detect Before blue screen, New svchost.exe created and Hookdll attach that.

my fail debug message is same as svchost.exe process number.

Code: Select all

CHookRegistry::CHookRegistry()
{
	if (!HookAPI("ntdll.dll", "NtCreateKey", HookNtCreateKey, (PVOID*)&OrignalNtCreateKey))
	{
		DWORD err = GetLastError();
		CString debug; debug.Format(_T("err = 0x%x\n"), err);
		OutputDebugString(debug);
		OutputDebugString(_T("Proc Hook : NtCreate Hook fail\n"));
	}
}


CHookRegistry::~CHookRegistry()
{
	UninstallHookCode(&OrignalNtCreateKey);
}

NTSTATUS NTAPI HookNtCreateKey(
	_Out_      PHANDLE            KeyHandle,
	_In_       ACCESS_MASK        DesiredAccess,
	_In_       POBJECT_ATTRIBUTES ObjectAttributes,
	_Reserved_ ULONG              TitleIndex,
	_In_opt_   PUNICODE_STRING    Class,
	_In_       ULONG              CreateOptions,
	_Out_opt_  PULONG             Disposition
	)
{
	
	CString name = ObjectAttributes->ObjectName->Buffer;

	if (name.Find(_T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\TaskCache\\Tree\\")) != -1)
	{
		OutputDebugString(name + _T("\n"));
	}

	NTSTATUS status = OrignalNtCreateKey(
		KeyHandle,
		DesiredAccess,
		ObjectAttributes,
		TitleIndex,
		Class,
		CreateOptions,
		Disposition
		);
	
	
	return status;
}

Code: Select all

CHookRegistry* m_pHookNT;
BOOL CHookRegistryKeyApp::InitInstance()
{
	CWinApp::InitInstance();
	OutputDebugString(_T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
	m_pHookNT = new CHookRegistry();
	 
	return TRUE;
}

int CHookRegistryKeyApp::ExitInstance()
{
	// TODO: Add your specialized code here and/or call the base class
	if (m_pHookNT)
		delete m_pHookNT;
	OutputDebugString(_T("nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnna"));
	return CWinApp::ExitInstance();
}

and In MFC project LoadInjectionDriver, InjectLibrary,
In visual studio 2013
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: HookAPI fail but callback is well run.

Post by madshi »

Did you call InitializeMadCHook() in your hook dll, before calling HookAPI?

Try these things:

1) Comment out the HookAPI() call. Does the blue screen still occur? If yes, it must be something other than API hooking.
2) If no, put the HookAPI() call back in, but remove all code from your "HookNtCreateKey" function, except the call to OrignalNtCreateKey. Does the blue screen still occur?
3) If yes, change all parameters in both HookNtCreateKey and OrignalNtCreateKey to "PVOID" to make sure the compiler transports all 8 bytes (in 64bit). Some params are defined as ULONG which are only 4 bytes. Sometimes things like that can produce problems. Using PVOID everywhere makes sure that the compiler doesn't drop anything, but forwards the complete 8 byte of each parameter to OrignalNtCreateKey.
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: HookAPI fail but callback is well run.

Post by iconic »

CString name = ObjectAttributes->ObjectName->Buffer;

if (name.Find(_T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\TaskCache\\Tree\\")) != -1)
{
OutputDebugString(name + _T("\n"));
}
I see a problem with your code. ObjectAttributes->ObjectName->Buffer might be NULL and also UNICODE_STRINGs (is a native structure of a "counted" unicode string) do not have to contain a null-terminator, it's the whole reason why the Length and MaximumLength structure members exist within the structure. I'm fairly positive that the Find() method will not like this and if the search algorithm overruns the pointer bad things happen to good processes. You should validate first and use a different function to scan for the registry key name. Lose the OOP and classes stuff especially when hooking native API

Code: Select all

if (ObjectAttributes && ObjectAttributes->ObjectName && ObjectAttributes->ObjectName->Buffer)
{
  // Scan for key name
}
--Iconic
Post Reply