Get the real process/thread handle and get the thread handle
First, we will introduce the simplest process/thread handle obtaining method before starting the body. That is, you can obtain the handle when creating a process/thread.
The process/thread is used to obtain the handle.
// Process Creation Function
BOOL CreateProcess (
PCTSTR pszApplicationName,
PTSTR pszCommandLine,
PSECURITY_ATTRIBUTES psaProcess,
PSECURITY_ATTRIBUTES psaThread,
BOOL bInheritHandles,
DWORD fdwCreate,
PVOID pvEnvironment,
PCTSTR pszCurDir,
PSTARTUPINFO psiStartInfo,
PPROCESS_INFORMATION ppiProcInfo);
There are a lot of parameters. If you want to know the specific meaning of the parameters, you can go to MSDN. This article will not elaborate on these parameters, except for the last parameter, it can be used to obtain the Kernel Handle and ID of the process and main thread. Let's take a look at the PPROCESS_INFORMATION structure:
Typedef struct _ PROCESS_INFORMATION {
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessID;
DWORD dwThreadID;
} PROCESS_INFORMATION;
Before creating a process, we first need to define a PROCESS_INFORMATION variable, and then use its address to call the CreateProcess () function. before returning the CreateProcess function, an error occurs to the structure member. In this way, we can get the handle and ID of the process and the main thread.
PROCESS_INFORMATION pi;
CreateProcess(……,&pi);
Next, you can use pi to obtain the handle and ID of the process and the main thread.
// Create a thread function
HANDLE CreateThread (
PSECURITY_ATTRIBUTES psa,
DWORD cbStackSize,
PTHREAD_START_ROUTINE pfnStartAddr,
PVOID pvParam,
DWORD dwCreateFlags,
PDWORD pdwThreadID
);
The return value of this function is the handle of the new thread. The last parameter is the thread ID.
Next, we will introduce how to obtain the pseudo handle of processes/threads in Windows.
Windows provides two functions to obtain pseudo handles of processes/threads.
HANDLE GetCurrentProcess (); // get the pseudo HANDLE of the process
HANDLE GetCurrentThread (); // gets the thread pseudo HANDLE
Calling these two functions will return a pseudo handle of the Process/thread kernel object, and will not create a new handle in the Process Handle table, nor increase the process/thread Kernel Object count.
Of course, if you use a pseudo handle to call the CloseHandle () function, CloseHandle ignores this call.
Next we will introduce how to convert a pseudo handle to a real handle.
// Copy the kernel object handle Function
BOOL DuplicateHandle (
HANDLE hSourceProcess,
HANDLE hSource,
HANDLE hTargetProcess,
HANDLE phTarget,
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwOptions
);
This function obtains a record item in a process handle table, and then creates a copy of this record item in another handle table.
The first parameter hSourceProcess and the third parameter hTargetProcess are Kernel Object handles and must be process kernel objects.
The second hSource parameter can be the handle of any type of kernel object, but it must be related to the process represented by the first parameter.
The fourth parameter is used to receive the copied handle value.
The last three parameters are used to specify the access permission and inheritance flag used by the kernel object in the target process.
If the last parameter is set to DUPLICATE_SAME_ACCESS, the copied handle has the same access permission as the original handle.
// Obtain the thread handle
HANDLE hThread;
DuplicateHandle(
GetCurrentProcess(),
GetCurrentThread(),
GetCurrentProcess(),
&hThread,
0,
FALSE,
DUPLICATE_SAME_ACCESS
);
// Obtain the Process Handle
HANDLE hProcess;
DuplicateHandle(
GetCurrentProcess(),
GetCurrentProcess(),
GetCurrentProcess(),
&hProcess,
0,
FALSE,
DUPLICATE_SAME_ACCESS
);
As you can see, the process to be retrieved and the thread handle are different only from the second parameter passed in DuplicateHandle. But this function will increase the kernel object count, so after using the handle, you need to call CloseHandle () to reduce the handle count by one.