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

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.

Related

How to identify the window is belong to a specific process?

Win32 programs have an entry parameter HINSTANCE for the Win32 entry function WinMain(). When you create your own window, the CreateWindow() API call needs this parameter.
My first idea in my mind is that this HINSTANCE should be some unique identify to distinguish different windows belong to different processes. Until recently, in some occasions, I use this HINSTANCE. Wow! If you open the same Win32 program (EXE) twice, each process has the same HINSTANCE value.
Later I figured out, it was some resource identifier (memory address) in the process. It's a virtual address for the process which is related to its PE structure in memory.
Now, if I have the two windows' HWND handles, and I want to check whether the two windows are from the same process, what is the best choice?
You can use the GetWindowThreadProcessId function to retrieve the ID of the process that created a window, given that window's HWND.
Below is a brief C code snippet showing how. We check that the return value of each GetWindowThreadProcessId() call is not zero (see this answer or this blog by Raymond Chen), to ensure that we have passed valid HWND handles.
// win1 and win2 are both HWND handles to check...
DWORD proc1, proc2;
if (!GetWindowThreadProcessId(win1, &proc1)) { // Error (invalid HWND?)
//.. error handling
}
if (!GetWindowThreadProcessId(win2, &proc2)) {
//..
}
if (proc1 == proc2) {
// Windows created by same process
}
else {
// Windows created by different processes
}
GetWindowThreadProcessId can do the work. Record here.
An interactive way to do this would be to use Microsoft's Spy++, which lets you find the Process ID, Thread ID, and parents/children of a window by point-and-clicking its GUI.
You can also find window handles (and plenty of other window-specific data) in this way.

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.

How to pass a Window Handle to a sub-process?

I am working on a special project with an unusual design.
In my application/process, I will create a sub process to do some work. In my process, I need to get the feedback from sub process. I want to pass the Windows handle of my application/process to this sub process, so I am post message from this sub process.
How can I pass Window Handle to sub process? My sub process is an command line application without Window UI and with the main function like this:
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
Should I pass Window Handle to the main function? How?
Thanks
Window handles (HWNDs) are global to the system so you can just print the handle as a decimal number into a string buffer, pass it as a string on the command line when you spawn your sub-process with CreateProcess, and call _wtoi() or similar to convert the string back to a handle again.
Create a named mutex (global), so both processes could access it,
and take it.
Spawn the second process. It should wait for the mutex
to be freed.
You can then pass the window handle using any Inter-Process Communication method; the easiest one may be Shared Memory. Just write the duplicated handle into shared memory.
Release the mutex, so that second process could grab it.
Read the handle from the shared memory. It is now safe to use it.
The whole mutex manipulation is only to make sure second process will not read from shared memory before anything is written there.
(thanks to #JonathanPotter for comments)

Is there a way to know the thread id in another process which throws an exception?

I am trying to use MiniDumpWriteDump() API to dump a crashed process B from another process A. I am doing this because MSDN said so:
MiniDumpWriteDump should be called
from a separate process if at all
possible, rather than from within the
target process being dumped.
The MiniDumpWriteDump() is defined as 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
);
Especially, the ExceptionParam is of type PMINIDUMP_EXCEPTION_INFORMATION, which is defined as below:
typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
DWORD ThreadId;
PEXCEPTION_POINTERS ExceptionPointers;
BOOL ClientPointers;
} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
Now I am wondering how to prepare the following 2 parameters:
ThreadId
The identifier of the thread throwing the exception.
ExceptionPointers
A pointer to an EXCEPTION_POINTERS structure specifying a computer-independent description of the exception and the processor context at the time of the exception.
How could I get the faulting thread id and exception pointers in process B while running in process A?
Thanks.
A pointer to a MINIDUMP_EXCEPTION_INFORMATION structure describing the client exception that caused the minidump to be generated. If the value of this parameter is NULL, no exception information is included in the minidump file.
Despite the fact that the paramter is marked __in and not __in_opt you can indeed pass NULL here. To get that information in the first place from the target process your process would have to be debugging it anyway.
How and when does process A known to take a minidump of process B? If A is indeed debugging B, when WaitForDebugEvent returns with an EXCEPTION_DEBUG_EVENT, the information is available in the info structure.
If A isn't debugging B, then perhaps B is telling A through some IPC mechanism "Hey I'm crashing, take a minidump". In this case either B could take the dump itself or pass the exception information through the same IPC mechansim to A. Again though, this is problematic for the same reasons calling MiniDumpWriteDump in the crashing process is problematic, if things are blowing up, the thing that might have blown up may be what you need to tell A about it.
The other mechanism that might have A take a dump for B is A is installed as the JIT debugger, in which case, A will be debugging B and you can use the debugging APIs to get the exception information.
If A is just periodically taking minidumps of B, then there won't necessarily be any exceptions, so you can just pass NULL in this case.
Note that if you're intending on doing something like
WaitForSingleObject(handleToProcessB, INFINITE);
MiniDumpWriteDump(handleToProcessB, ...)
that this will not work. The OS keeps around a very few things, mainly the exit code for the process, not the virtual address space and the stacks which you need to take a minidump.
To have an automatic dump created on a given exception on a specific process name, my advise would be to use DebugDiag or AdPlus. Those are external (and free !) software that you can configure to do so.
If you really want to write the dump by yourself, you can do it in process B : MSDN warn you that is not a good idea, because nasty errors like out of memory, stack overflow, or stack corruption (list is not exhaustive) will certainly use memory and stack, and so you may ends up with no dump at all (and a very bad process crash). From my experience, this is pretty rare (I used to work on a very stressed distributed C++ software).
For others exception, it should be ok. In that case, you can use an exception translator (see _set_se_translator) or a vectored exception handler (see AddVectoredContinueHandler) or the function GetExceptionInformation() to get the EXCEPTION_RECORD structure (there may be others ways that I'm not aware of).
Creating the dump from process A after an exception in process B means that you have to copy all informations about the exception, and warn the process A that it has to dump something with this exception. This will consume memory and stack, and so you will have the same limitation than explained before.
Hope that will help

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