failing to hook from service child process

c++ / delphi package - dll injection and api hooking
Post Reply
Bevan Collins
Posts: 42
Joined: Fri Jul 07, 2006 2:50 am

failing to hook from service child process

Post by Bevan Collins »

Hi,

The project I am working on has 3 components:
launcher.exe. Is run by user, grants user "user1" access to window station and desktop. Opens a named pipe to...
service.exe. Running as local system account, it creates a process running as user "user1" but in the same session as launcher.exe called...
foo.exe. When this process runs, any API it attempts to hook fails with GetLastError of 0.

If I run foo.exe as the regular user, it hooks fine.
Here is how I am launching foo.exe from service.exe:

Code: Select all

HANDLE user;
PROFILEINFO userProfile;
ULONG sessionId;
STARTUPINFOA si = {0};
PROCESS_INFORMATION pi;

GetNamedPipeClientSessionId(pipe, &sessionId);
LogonUser("user1", ".", "password", LOGON32_LOGON_SERVICE, LOGON32_PROVIDER_DEFAULT, &user);
LoadUserProfile(user, &userProfile);
SetTokenInformation(user, TokenSessionId, &sessionId, sizeof(sessionId));   // removing this line allows HookAPI in foo.exe to work.
si.cb = sizeof(si);
CreateProcessAsUserA(user, 0, "foo.exe", 0, 0, FALSE, 0, 0, 0, &si, &pi);
And here is the code for foo.exe:

Code: Select all

BOOL WINAPI createProcessAHook(LPCSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCSTR, LPSTARTUPINFOA, LPPROCESS_INFORMATION);

void main() {
  InitializeMadCHook();

  LPVOID hook = 0;
  BOOL rc = HookAPI("kernel32.dll", "CreateProcessA", createProcessAHook, &hook, 0);  // fails with GetLastError() 0
}
If I don't set the token session ID in the service, HookAPI works from foo.exe, but I need it to run in the same session as launcher.exe.
I can replicate this problem on 32bit XP and 64bit Windows 7.
Any way I can get detailed information on why HookAPI is failing?

Thanks
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: failing to hook from service child process

Post by madshi »

That sounds quite weird. HookAPI() is not an API which is likely to be affected by different user rights, session IDs or things like that. How do you test whether HookAPI() succeeds or fails? And how do you log the failure? Is it possible that HookAPI() doesn't fail, after all, and that you're just thinking it fails for some reason? I know, it's a somewhat stupid question, but I've seen weirder things than that...
Bevan Collins
Posts: 42
Joined: Fri Jul 07, 2006 2:50 am

Re: failing to hook from service child process

Post by Bevan Collins »

Missing from the code above is the macro that I use that checks the return value of HookAPI and writes GetLastError to the event log.

Code: Select all

BOOL rc = HookAPI("kernel32.dll", "CreateProcessA", createProcessAHook, &hook, 0);
TS_ASSERT_GETLASTERROR(rc);
HookAPI is returning FALSE when the process is launched by the service. When run by the user directly it doesn't return FALSE.
Could it be that something in the call to InitializeMadCHook that is failing to initialise?
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: failing to hook from service child process

Post by madshi »

How is the macro defined and how are you writing to the event log? Can I see that code, please?

I can't imagine why either InitializeMadCHook or HookAPI would fail, depending on the user.
Bevan Collins
Posts: 42
Joined: Fri Jul 07, 2006 2:50 am

Re: failing to hook from service child process

Post by Bevan Collins »

Code: Select all

#define TS_ASSERT_GETLASTERROR(x) \
{ \
	if (!(x)) \
	{ \
		unsigned long dwAssertErr; \
		char debugBuffer[128]; \
		dwAssertErr = GetLastError(); \
		wsprintfA(debugBuffer, "%s(%d): [%d %d] error=%d\n", __FILE__ , __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), dwAssertErr); \
		TS_MESSAGEA(debugBuffer); \
		SetLastError(dwAssertErr); \
	} \
}

#define SBASSERT_MESSAGE                 0xCA000000L

#define TS_MESSAGEA(x) { \
	HANDLE hEvtSource = RegisterEventSourceA(NULL, "SBASSERT"); \
	if (hEvtSource) \
	{ \
		LPCSTR lpStrings[1]; \
		lpStrings[0] = x; \
		ReportEventA(hEvtSource, EVENTLOG_ERROR_TYPE, 0, SBASSERT_MESSAGE, NULL, sizeof(lpStrings)/sizeof(*lpStrings), 0, lpStrings, NULL); \
		DeregisterEventSource(hEvtSource); \
	} \
}
Bevan Collins
Posts: 42
Joined: Fri Jul 07, 2006 2:50 am

Re: failing to hook from service child process

Post by Bevan Collins »

I finally found the cause of this. It was because "user1" didn't have access to the session BaseNamedObjects (see http://social.msdn.microsoft.com/Forums ... n-creation). Madcodehook must be using a named mutex, event, or some other kernel object.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: failing to hook from service child process

Post by madshi »

I'm happy to hear that you found the cause of the problem. Yes, madCodeHook does use named objects.

So basically everything's alright with madCodeHook? Nothing for me to do here?
Post Reply