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

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.

Related

Modifying the parameters before passing them to NtWriteFile after hooking the SSDT

I'm currently working on a lecture (and learning) about rootkits for Windows. I was able to hook the SSDT entry for NtWriteFile and display a simple message on WinDbg, but i'm now curious about what would be the best (and the safest) way of changing the parameters before passing them to the original function. In this example, i'm trying to change the buffer if it contains "My String". How could i swap the content of Buffer safely?
NTSTATUS ZwWriteFileHook(
IN HANDLE FileHandle,
IN HANDLE Event,
IN PIO_APC_ROUTINE ApcRoutine,
IN PVOID ApcContext,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset,
IN PULONG Key
)
{
...
if (!strncmp((PCHAR) Buffer, "My String", Length)) {
// Modify parameters here
}
ntStatus = ((PZwWriteFile) zwWriteFileOld)(FileHandle, Event,
ApcRoutine, ApcContext, IoStatusBlock, Buffer, Length, ByteOffset,
Key);
...
}
Thank you.
First of all, there is an issue with accessing (reading/writing) UserMode pointers directly like that, you first want to probe the pointer for READ, if you write to it, you also need to to probe for WRITE using the kernel APIs ProbeForRead and ProbeForWrite.
Second, I rather not write to the UserMode supplied buffer a modified value but allocate a new buffer and then free it afterwards, in my opinion it is the safest way.

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/.

Why does calling ProcessGroupPolicyEx callback cause an access violation?

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.

What's the differences between a Process ID and a Process handle

A process ID is a number that uniquely identifies a process. A process handle is also a number that uniquely identifys a process kernal object.
Why do we need them both since either of them can identify a process.
I think the answer may lie in the mapping relationship betweeen a process and a process kernel object. Is it true that more than one process kernel objects can be mapped to a single process? And each process kernel object has its own process handle. So that each of the process kernel object could represent different access mode or things like that.
This question came to me when I am using the MiniDumpWriteDump() function, which is declared like this:
BOOL WINAPI MiniDumpWriteDump(
__in HANDLE hProcess,
__in DWORD ProcessId,
__in HANDLE hFile,
__in MINIDUMP_TYPE DumpType,
__in PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
__in PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
__in PMINIDUMP_CALLBACK_INFORMATION CallbackParam
);
So it's parameters include both process id and process handle. I just don't know why it's necessary to have them both.
Many thanks for your insights.
Process Handle is
Arbitrary
Internal to process that acquired it. Private and can't be shared between threads/processes
It carries security access rights too
While Process ID is
Unique
Universal, public, so it can be shared between threads/processes
the difference is that 'id' is system-wide number which uniquely identifies the process. 'handle' on the other hand is an opaque value which connects process and access to that process to your program. you can potentially have multiple different handles to the same process.
I don't know why MiniDumpWriteDump takes both.

MiniDumpWriteDump() function's parameters: Why do we need a handle and an ID?

I checked the definition of MiniDumpWriteDump() method on MSDN as below:
BOOL WINAPI MiniDumpWriteDump(
__in HANDLE hProcess,
__in DWORD ProcessId,
__in HANDLE hFile,
__in MINIDUMP_TYPE DumpType,
__in PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
__in PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
__in PMINIDUMP_CALLBACK_INFORMATION CallbackParam
);
Parameters:
hProcess [in]
A handle to the process for which the information is to be generated.
ProcessId [in]
The identifier of the process for which the information is to be generated.
Since either a process handle or a process ID can identify a process, why do we need to pass them both? Can't we infer one of them from the other? So there should be some differences between them, what are they?
Thanks.
I think it's probably just for historical reasons. Note that the GetProcessId function, which lets you get a PID from a process handle, didn't exist prior to Windows Server 2003:
http://msdn.microsoft.com/en-us/library/ms683215%28v=vs.85%29.aspx

Resources