Why does calling ProcessGroupPolicyEx callback cause an access violation? - windows

I'm trying to help a colleague with some code in a client side extension. Since adding in a call to the callback, the function seems to complete ok, but an event in the Windows Event log complains about an access violation whilst processing the group policy object.
After removing existing code, with just the added call to the callback, it still reports this access violation.
Can you please help identify what we might be missing?
//
// Entry point for processing group policy objects.
//
// For full details, see http://msdn.microsoft.com/en- us/library/windows/desktop/aa374383(v=vs.85).aspx.
//
extern "C" DWORD CALLBACK ProcessGroupPolicyEx (
__in DWORD dwFlags,
__in HANDLE hToken,
__in HKEY hKeyRoot,
__in PGROUP_POLICY_OBJECT pDeletedGPOList,
__in PGROUP_POLICY_OBJECT pChangedGPOList,
__in ASYNCCOMPLETIONHANDLE pHandle,
__in BOOL *pbAbort,
__in PFNSTATUSMESSAGECALLBACK pStatusCallback,
__in IWbemServices *pWbemServices,
__out HRESULT *pRsopStatus)
{
if(pStatusCallback)
pStatusCallback (FALSE, L"Aaaaargh!");
return (0);
}
This code has been tried using a static string, an array of bytes on the stack, a array of bytes that's been new'd and deliberately leaked - in case the method was taking ownership of the memory. Also been CoTaskMemAlloc'd, just in case. All produce the same problem.
The (redacted) error in the eventlog is:
Windows cannot process Group Policy Client Side Extension Exception 0xc0000005.
To make things interesting, this is just on some OS's, fully patched XP 32bit is one of the definite problems. 2008R2 works fine.
Yes - we need it to work on XP 32bit.
Other weird behaviour that may have a bearing here:
If we call this function multiple times, it fails on the 3rd call. No exception is thrown, no text is shown, none of our code after the call is executed, no additional errors in the event log. Timing is not a factor here: it happens if you call it 3 times in a row, or 3 times over 5 minutes.
This does not happen if we wrap the calls in a generic try/catch block. No exception is caught - all the text is shown. All the code is run.
We still get the error in the event log, however.

Looks like we've found the issue with this.
The problem is that the callback needs to be made with __stdcall calling convention.
By default, visual studio creates projects with the __cdecl calling convention.
If you add the /Gz flag to your project, it will use __stdcall by default. We couldn't do that, however, since we're pulling in other modules with different calling conventions.
The underlying problem is that UserEnv.h defines the callback like this:
typedef DWORD (*PFNSTATUSMESSAGECALLBACK)(__in BOOL bVerbose, __in LPWSTR lpMessage);
This is a strange definition. All other windows callbacks are defined like this:
typedef INT_PTR (CALLBACK* DLGPROC)(HWND, UINT, WPARAM, LPARAM);
That CALLBACK is important, it expands like this:
#define CALLBACK __stdcall
This means that by default, all windows callbacks are defined to use __stdcall calling conventions, except this one, for some reason.
If we create our own callback defintion:
typedef DWORD (CALLBACK *PFNSTATUSMESSAGECALLBACK_STDCALL)(__in BOOL bVerbose, __in LPWSTR lpMessage);
And assign our function pointer to it:
PFNSTATUSMESSAGECALLBACK_STDCALL pStatusCallback = (PFNSTATUSMESSAGECALLBACK_STDCALL)pRawStatusCallback;
Then we can use the pStatusCallback function pointer with the __stdcall calling convention and have things work properly.

Related

How to use the undocumented procedure ZwCreateThread?

I'm trying to invoke ZwCreateThread(). But since it is a undocumented function I don't know how to do it. The 3rd, 5th, 6th and 7th argument of the function?
How to initialize those structures to use them in ZwCreateThread()?
The question is a loaded one
I don't fully agree with the assessment by Basile in the comments that - if something is undocumented - it should not be used. But it requires extra caution for sure.
There is also a relevant bit of information missing from your question: kernel or user mode?!
Resources
I cannot answer regarding fasm, but if you know how to read C function prototypes and make those work for you, you can use one of the following resources to find the prototypes:
undocumented.ntinternals.net
the phnt offspring of the Process Hacker (mind the license!)
ReactOS tries to be a fairly faithful functional clone of Windows (the target version has been adjusted over the years)
The desired information is part of the NDK inside psfuncs.h
The Windows Research Kernel and its documentation have leaked and were available in several shapes and forms all over the web (IIRC this was based on Windows 2003 Server)
Microsoft documents some functions and structs as part of their Windows Driver Kits (WDKs, formerly Device Driver Kits [DDKs])
winternl.h is one of the headers
"Windows NT/2000 Native API Reference" by Gary Nebbett
"Undocumented Windows 2000 Secrets" by Sven B. Schreiber; IIRC the author made this available on his website as several PDFs some years ago
"Undocumented Windows NT" by Prasad Dabak, Sandeep Phadke, and Milind Borate
The syscall tables (j00ru/windows-syscalls) as a reference of sorts for availability of functions from user mode
For structs as found from the PDBs (debugging symbols) made available by Microsoft: Vergilius Project
Yet again for structs, but more useful for user mode: Terminus Project by ReWolf
Windows NT, Secret APIs and the Consequences by Bruce Ediger
To a lesser extent the "Windows Internals" books from Microsoft Press
A code search or GitHub/GitLab/etc search for some of your desired function names or related functions
E.g. in the source code to several debuggers or other very low-level tools, to binary instrumentation frameworks etc ...
Books and resources for related topics such as sandboxes, rootkits, bootkits, malware ...
Useful knowledge
ZwCreateThread and NtCreateThread are identical in user mode (you can even verify this by using dumpbin on ntdll.dll and checking the RVA of the two exports. This is true for most (if not all) Zw* and Nt* functions
This means their prototype is identical!
In kernel mode they differ, one of them does more checking and is supposed to receive calls via the SSDT from user mode, the other is supposed to be called from kernel mode.
The identical prototype notion also holds true here
... let's try to answer it
Up front: if what you are trying to achieve is to create a user mode thread, in all likelihood RtlCreateUserThread() is more likely what you are looking for (for reference phnt)!
The prototype for ZwCreateThread is as follows:
// source: ntzwapi.h from https://github.com/processhacker/phnt
NTSYSCALLAPI
NTSTATUS
NTAPI
ZwCreateThread(
_Out_ PHANDLE ThreadHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_ HANDLE ProcessHandle,
_Out_ PCLIENT_ID ClientId,
_In_ PCONTEXT ThreadContext,
_In_ PINITIAL_TEB InitialTeb,
_In_ BOOLEAN CreateSuspended
);
// for reference, Nebbett gives the prototype as:
NTSYSAPI
NTSTATUS
NTAPI
ZwCreateThread(
OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN HANDLE ProcessHandle,
OUT PCLIENT_ID ClientId,
IN PCONTEXT ThreadContext,
IN PUSER_STACK UserStack,
IN BOOLEAN CreateSuspended
);
You probably noticed the difference in the parameter 7 (starting at 1) immediately: PUSER_STACK vs. PINITIAL_TEB. TEB stands for Thread Environment Block and is the extension of the TIB (IIRC: Thread Information Block). Compare Nebbett's take on the USER_STACK struct:
typedef struct _USER_STACK {
PVOID FixedStackBase;
PVOID FixedStackLimit;
PVOID ExpandableStackBase;
PVOID ExpandableStackLimit;
PVOID ExpandableStackBottom;
} USER_STACK, *PUSER_STACK;
... with the INITIAL_TEB from undocumented.ntinternals.net you will notice they're the same (also for reference phnt). Nebbett took a guess at the name at the time of his writing. But this right there is the reason why Basile cautions not to use undocumented functions. You have to put in your own research and can't blindly rely on others' research. Also you should apply a very defensive coding style when using those functions.
Either way, Nebbett lists CreateThread() and CreateRemoteThread() as related Windows APIs. The latter is obviously a superset of the former and ZwCreateThread() uses ProcessHandle for the target process. It's always worthwhile looking for and looking at related Windows APIs.
3rd parameter: _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes
The _In_opt (see SAL) tells you, that you may pass a NULL pointer here. But if you insist on passing the object attributes and know what to put in them: InitializeObjectAttributes() - a macro - is there to help.
5th parameter: _Out_ PCLIENT_ID ClientId
The _Out_ tells you that you supply the space for this info to be filled. The CLIENT_ID combines process and thread ID into a struct. The struct can be found in the headers of the WDKs/DDKs (e.g. wdm.h or ntddk.h) and looks like this in C:
typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID;
6th parameter: _In_ PCONTEXT ThreadContext
The CONTEXT is indeed a documented struct and used in official APIs such as SetThreadContext(). Its definition depends on the target architecture, but can be found in official MS headers.
This struct also plays a big role in exception handling, e.g. when resuming execution after an exception.
For ZwCreateThread() this defines the initial state of the thread, especially the initial address of the instruction pointer and the initial CPU register states (which explains why it depends on the target architecture).
7th parameter: _In_ PINITIAL_TEB InitialTeb
By now you should have an idea that you need to supply the space and initial values for this struct as well.
Conclusion
And this complicated "having to know and fill in all details" explains why in all likelihood you want to use:
typedef NTSTATUS (NTAPI *PUSER_THREAD_START_ROUTINE)(
_In_ PVOID ThreadParameter
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateUserThread(
_In_ HANDLE Process,
_In_opt_ PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
_In_ BOOLEAN CreateSuspended,
_In_opt_ ULONG ZeroBits,
_In_opt_ SIZE_T MaximumStackSize,
_In_opt_ SIZE_T CommittedStackSize,
_In_ PUSER_THREAD_START_ROUTINE StartAddress,
_In_opt_ PVOID Parameter,
_Out_opt_ PHANDLE Thread,
_Out_opt_ PCLIENT_ID ClientId
);
// again taken from phnt
This is much closer to CreateRemoteThreadEx and similar APIs. You don't have to care about the initial CONTEXT and don't have to deal with OBJECT_ATTRIBUTES or INITIAL_TEB.

Error LNK2019 in visual studio in win32 application?

I have making an attempt at writing my first program in Visual Studio, however am being troubled by an error.
It says: -
Error 3 error LNK2019: unresolved external symbol _wWinMain#16 referenced in function ___tmainCRTStartup
E:\Documents\Programming\Software Development\Microsoft Development\Microsoft Development\MSVCRTD.lib(wcrtexew.obj)
Microsoft Development
On researching I found similar errors, but none have helped me solve the problem.
I have changed the entry point to
wWinMainCRTStartup
the character set to Unicode
the subsystem to console. The project is a win32 application. The code is as follows: -
#include <windows.h>
#include <stdio.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MessageBox(NULL, "Hello World!", "Note", 1/*MB_OK*/);
printf("nCmdShow = %d\n", nCmdShow);
return 0;
}
How do I fix this issue?
P.S. I am using Visual Studio Ultimate 2013
For a Unicode build your code needs to be more like this:
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTR lpCmdLine, int nCmdShow)
{
MessageBox(NULL, L"Hello World!", L"Note", 1/*MB_OK*/);
printf(L"nCmdShow = %d\n", nCmdShow);
return 0;
}
At least by default this will be set to use the Windows subsystem (because the entry point is named a variant of WinMain). You can force that to the console subsystem (-subsystem:console flag to the linker) or get it to happen by default by changing the entry point to a variant of main instead:
int wmain(int argc, wchar_t **argv) { // ...
Obviously you won't be able to print nCmdShow using this though (not that it really means anything in a console program). For that matter, since you're not using the command line arguments anyway, you can simplify this somewhat to:
int wmain(){ // ....
Actually, nCmdShow is basically obsolete even for windowed programs. The first time a windowed program calls ShowWindow, it normally passes nCmdShow as the parameter. Windows, in turn, ignores the value passed in the first call to ShowWindow, and instead uses the value from the process' STARTUPINFO structure. Only in subsequent calls to ShowWindow is the parameter used (and for these subsequent calls, you're not supposed to pass nCmdShow either--you're supposed to pass one of the defined constants such as SW_SHOWNORMAL).
Reference: MSDN entry for ShowWindow
A Win32 application starts at WinMain. A console application starts at main. Your question implies you have a confused mixture of the two.
Just use the File, New, Project menu command to let Visual Studio build a skeleton of the type of application you have in mind.

Difference between HANDLE and HWND in Windows API?

I'm trying to use function SetForegroundWindow(HWND hWnD). I have some handles but it's not working as parameter of above function. My handle is a thread and I want to run it in foreground.
What are the differences between a HWND and a HANDLE?
They are just abstract data types.
According to MSDN, HANDLE and HWND are defined as:
HANDLE is a handle to an object.
HWND is a handle to a window.
So, a HWND is a HANDLE, but not all HANDLEs are HWND. In fact:
typedef void *PVOID;
typedef PVOID HANDLE;
typedef HANDLE HWND;
Example
You should only pass HWND to SetForegroundWindow unless you know what you are doing.
HWND hWnd = FindWindow(NULL, "Calculator");
SetForegroundWindow(hWnd);
This first gets the handle to a window titled "Calculator" with FindWindow and then brings that window to foreground.
A "handle" is the general term used to refer to a token that identifies a resource on the system (a menu, a DLL module, a block of memory, etc). Often referred to as a "magic cookie", it's normally returned when you first create the resource. You then pass that handle to other functions in the API responsible for processing the resource. You normally need not know what the handle is however. Sometimes it may be a pointer, other times a number, perhaps a structure, or whatever. That's why they hide it using names like HWND which is simply the handle used to identify a window (returned by the API function "CreateWindow()"). You therefore don't convert a "handle" to an HWND and back again since an HWND is already a "handle" (one that merely identifies windows you create).
Found here http://forums.codeguru.com/showthread.php?135438-Handle-and-HWND
You can use FindWindow to get the hwnd from an application http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499(v=vs.85).aspx
This should allow you to get the HWND provided you have the handle to what you're looking for C++ Handle as HWND?
The HWND is also a HANDLE, but a global one.
I.e. a HWND valid in the context of one process is also valid in the context of another process.
Some undocumented info at https://winterdom.com/dev/ui/wnd/.

Simple way to hook registry access for specific process

Is there a simple way to hook registry access of a process that my code executes? I know about SetWindowsHookEx and friends, but its just too complex... I still have hopes that there is a way as simple as LD_PRELOAD on Unix...
Read up on the theory of DLL Injection here: http://en.wikipedia.org/wiki/DLL_injection
However, I will supply you with a DLL Injection snippet here: http://www.dreamincode.net/code/snippet407.htm
It's pretty easy to do these types of things once you're in the memory of an external application, upon injection, you might as well be a part of the process.
There's something called detouring, which I believe is what you're looking for, it simply hooks a function, and when that process calls it, it executes your own function instead. (To ensure that it doesn't crash, call the function at the end of your function)
So if you were wanting to write your own function over CreateRegKeyEx
(http://msdn.microsoft.com/en-us/library/ms724844%28v=vs.85%29.aspx)
It might look something like this:
LONG WINAPI myRegCreateKeyEx(HKEY hKey, LPCTSTR lpSubKey, DWORD Reserved, LPTSTR lpClass, DWORD dwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition)
{
//check for suspicious keys being made via the parameters
RegCreateKeyEx(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
}
You can get a very well written detour library called DetourXS here: http://www.gamedeception.net/threads/10649-DetourXS
Here is his example code of how to establish a detour using it:
#include <detourxs.h>
typedef DWORD (WINAPI* tGetTickCount)(void);
tGetTickCount oGetTickCount;
DWORD WINAPI hGetTickCount(void)
{
printf("GetTickCount hooked!");
return oGetTickCount();
}
// To create the detour
oGetTickCount = (tGetTickCount) DetourCreate("kernel32.dll", "GetTickCount", hGetTickCount, DETOUR_TYPE_JMP);
// ...Or an address
oGetTickCount = (tGetTickCount) DetourCreate(0x00000000, hGetTickCount, DETOUR_TYPE_JMP);
// ...You can also specify the detour len
oGetTickCount = (tGetTickCount) DetourCreate(0x00000000, hGetTickCount, DETOUR_TYPE_JMP, 5);
// To remove the detour
DetourRemove(oGetTickCount);
And if you can't tell, that snippet is hooking GetTickCount() and whenever the function is called, he writes "GetTickCount hooked!" -- then he executes the function GetTickCount is it was intended.
Sorry for being so scattered with info, but I hope this helps. :)
-- I realize this is an old question. --
Most winapi calls generate symbol table entries for inter modular calls, this makes it pretty simple to hook them, all you need to do is overwrite the IAT addresses. Using something such as MSDetours, it can be done safely in a few lines of code. MSDetours also provides the tools to inject a custom dll into the target process so you can do the hooking
SetWindowsHookEx won't help at all - it provides different functionality.
Check if https://web.archive.org/web/20080212040635/http://www.codeproject.com/KB/system/RegMon.aspx helps. SysInternals' RegMon uses a kernel-mode driver which is very complicated way.
Update: Our company offers CallbackRegistry product, that lets you track registry operations without hassle. And BTW we offer free non-commercial licenses upon request (subject to approval on case by case basis).

How do I provide ReadFileEx()'s completion routine with context information?

Win32 ReadFileEx is defined as:
BOOL WINAPI ReadFileEx(
__in HANDLE hFile,
__out_opt LPVOID lpBuffer,
__in DWORD nNumberOfBytesToRead,
__inout LPOVERLAPPED lpOverlapped,
__in_opt LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
I am trying to figure out how to make the completion routine (the last argument) invoke a dynamic function pointer when the operation completes. There doesn't seem to be a way to pass in user-data. Any ideas?
The lpOverlapped function passed into ReadFileEx is passed into the lpCompletionRoutine function.
You can embed the lpOverlapped in your own structure and then use that to find the pointer to your context:
struct ReadFileExContext
{
OVERLAPPED _Overlapped;
LPVOID MyContext;
};
Then in your callback function you cast the LPOVERLAPPED to a ReadFileContext and you're good to go.
Was doing some IO work today and noticed in the WSA and File read/write functions it is stated that the hEvent of the OVERLAPPED structure is not used if you are using a completion routine, e.g. from ReadFileEx
The ReadFileEx function ignores the OVERLAPPED structure's hEvent member. An application is free to use that member for its own purposes in the context of a ReadFileEx call. ReadFileEx signals completion of its read operation by calling, or queuing a call to, the completion routine pointed to by lpCompletionRoutine, so it does not need an event handle.
You could use Thread Local Storage... Just create a slot and store a pointer to whatever data you want. Since lpCompletionRoutine runs on the calling thread, you should be fine.

Resources