Process
Let us first look at the definition of the process in Windows, the following content leads from "Windows Core Programming":
The process is usually defined as an instance of a running program, which consists of two parts:
l One is an operating system to manage the kernel object (K32 object) of the process. The kernel object is also a system used to store statistics about process statistics.
l The other is the address space, which contains all the code and data of all executable modules or DLL modules. It also contains space for dynamic memory allocation. For example, thread stack and heap allocation space.
The process is not alive. To make the process complete an action, it must have a thread running in its environment, which is responsible for executing the code contained in the process address space. In fact, a single process may contain multiple threads, all of these threads are "simultaneously" executing code in the process address space. In addition, each thread has its own set of CPU registers and its own stack. Each process has at least one thread to execute the code in the address space of the process. When creating a process, the system automatically creates its first thread called the main thread. The thread can then create additional threads, and these threads can create more threads.
When you need to mention, the thread in a process is definitely the end of the process, and there is no process that does not contain any threads.
The process is actually a collection of ownership of a large number of objects. That is, the process has an object. The process can have memory (more precisely with memory context), you can have file handle, you can have a thread, you can have a string DLL module (loaded to the address space of the process)
Need to pay attention, the process does not represent execution (thread is). The process is not an Exe file. An EXE file is just a program before loading is loaded. Windows only produces a process and a main thread after being loaded.
Once Windows produces a process, it also generates a MEMORY Context to accommodate the process of the process being executed therein. In addition, Windows also produces the first thread, that is, the main thread, is used to execute the process itself. If necessary, the process can generate threads. The system also generates a file handle table, and the process can hold some open files. Finally, it is also the most important. Windows generates a Process Database (ie process kernel object, also known as K32 object) to express the process.
Process Database is a K32 object that contains a lot of information related to the process. We will discuss the detailed structure of Process Database (PDB) in detail later. The memory used by Process Database comes from Kernel32 HEAP, so all Process Database can be seen by other processes.
Process Database contains a series of threads, a series of loaded modules, is predetermined in the Process HEAP, pointing to the Process Handle Table, and pointers pointing to Memory Context. There are more things.
What is Process Handle? What is the Process ID?
Before proceeding, I need to clarify the process handle and process IDs that are often confused. Two look similar WIN32 functions: getCurrentProcess and getCurrentProcessid confused many programmers. It is easy to distinguish between facts.
Process Handle is basically the same as File Handle. It is a value that is not clear, you can't say it is a pointer to anything. The internal system is in fact the Handle of the K32 object as the index of the Process Handle Table. Using this index from Process Handle Table, it is a k32 object pointer. Then, since the application does not need to process the Handle Table directly, Process Handle is useless. Remember, because every application has its own handle table, so different processes have the same Process Handle in their respective address spaces. For example, every process has a process handle represents yourself, its value is 1. That is, Process Handle is not a data that can be discriminated. Another example is: If the program opens another Process Handle for your own process, then there are two Handle, corresponding to the same process.
In the pseudo code of the getCurrentProcess function, you can determine that Process Handle is not the data that can be used to discriminate the process.
Pseudo code for the getCurrentProcess function:
// Normally this function does Nothing. It appers to be there
// for the benefit of the kernel32 development
X_logsomekerNelfunction (Function Number Fro getcurrentProcess);
Return 0x7fffffff;
Yes, the fact that "it calls other functions" is ignored, and getCurrentProcess is only fixed to the 0x7ffffffffff. No matter who calls the function, he gets 0x7fffffff. 0x7fffffff is a magic number, and the kernel32 explains it as "the current process." Faced with 0x7fffffff, those who need Process Handle's kernel32 function will replace it with the current Process Handle. This requires more evidence to prove that Process Handle only does it only in your CONTEXT? I don't want it!
Now let's take a look at Process IDs, early Windows 95's base address of Process Database as a process ID. Since Process Database is in shared memory, the base address guarantee of Process Database will never be the same.
supplement:
In subsequent versions such as Windows 98 / NT / 2000 / XP, the specific implementation of Process IDs is still so, unknown.
In the new version of Windows 95, the Kernel32 group changed the implementation of getCurrentProcessid:
GetCurrentProcessID function virtual code:
X_logsomekerneLNCTION (Function Number for getCurrentProcessID);
Return PDBTOPID (PPCurrentProcess);
Once again, if we ignore it to call other functions, getCurrentProcessId is only transmitted to the PDBTOPID function to a global variable PPCurrentProcess. Let us stop more about it, because it is very important for follow-up chapters. PpCurrentProcess is a pointer to the current Process Database. In C language, ** PPCurrentProcess points to the current Process Database. The reason why you need to indirectly point again, based on a confusing reason, I will mention it in Chapter 6. Now, just remember that PPCurrentProcess is the global variable in kernel32.dll, allowing kernel32 to search for Process Database for the current process. In order to simplify things as much as possible, I will use PPCurrentProcess in the virtual code, I assume it a pointer to the Process Database, not a pointer.
Ok, if kernel32 is pointed by a pointer, pointing to the current process database, why getting it back directly from directly? Let's take a look at PDBTOPID:
PDBTOPID function virtual code:
// Parameters:
// process_database * ppdb
IF (obsfucatordword == false)
{
_Debugout ("pdbtopid () called to yet initialized!");
Return 0;
}
IF (PPDB & 1)
{
_Debugout ("PDBTOPID: this PDB Looks Like A PID (0% 1xH) Do a Stack TRACE Reporting AS bug.");
}
// here's the key! Xor the obsfucator dword with the process database
// Pointer to make the pid value
Return PPDB ^ obsfucatordword;
Oh, is this true? Yes it is! The word "obsfucator" actually naked naked in Microsoft's binary code. In addition to checking, the basic behavior of PDBTOPID is to make both the current Process Database pointer and ObsFucatorDword. This attempt is very obvious, Microsoft hopes to block the behavior of the internal data structure of the system.
If you are surprised where ObsFucatorDword comes, you will find that it is generated when it starts every time the system starts. This is a better protection for the system. In fact, not just Process Database is protected, Thread Database is also protected. Later I will show you in the getCurrentThreadID function, getCurrentThreadID and GetCurrentProcessid have near mysterious similarities.
Let me make a summary, a process handle is like a file handle. Don't make senses outside of its processes. As for a process ID, it is a value that is unique between the processes. It is a pointer to point to the Process Database structure.
If you have seen Toolhelp32's Process32First and Process32Next two functions, you will pay attention to the TH32ProcessID member in the Processentry32 structure. Is this relationship with the things that GetCurrentProcessID? Fortunately, the answer is YES. Windows 95 Process Database (PDB)
Each Process Dabase of Windows 95 is a memory that is allocated from the Kernel32 HEAP. Kernel32 typically represents Process Database as a PDB abbreviation. Each PDB is a first byte 5 (k32obj_process) K32 object. Let us take a closer look at each member:
00h dword Type
This value must be 5 (K32Obj_Process)
04h dwodd create
Reference count, that is, the number of times this PDB is used
supplement:
Use CloseHandle to reduce the reference to a K32 object
08h DWORD UN1
This member is true and unknown. It seems to always 0
0ch dword someevent
This is a pointer to the K32OBJ_EVENT object. EVENT object is used for WaitForsingleObject such a function.
supplement:
This Event is used when waiting for a process to end with WaitForsingleObject.
10h DWord TerminationStatus
When you use getExitcodeProcess, it is this value. The so-called exit code is the return value of Main or WinMain. It can also be specified by EXITPROCESS or TERMINATEPROCESS. This member value is 0x103 (STILL_ACTIVE) when a process is still executed.
14h DWORD UN2
This member of this member is true and unknown, it seems to always 0.
18h DWord DefaultHeap
The default process privately has the address. GetProcessHeap returns this value.
1CH DWORD MEMORYCONTEXT
A pointer, pointing to the Memory Context of the process. The so-called Memory Context, which contains Page Directory Mapping to provide a private area in the 4GB address space. There are more descriptions of Memory Context in Chapter 5.
20h DWord Flags
24h DWORD PPSP
This value is the linear address of the DOS PSP of this process. All Win16 and Win32 programs will set this member. This linear address is always below 1MB (the highest address that the DOS code can be accessed). Please refer to the 28H structure member.
28H Word Pspselector
This is a Selector, pointing to the DOS PSP of this process. Win16 and Win32 programs have DOS PSP. Please refer to the 24h structure member.
2AH Word MTEINDEX
Here is the index value of a global module table (PMoDuletableArray). This process can be taken out by this index value.
2Ch Word Cthreads
This location records the number of threads owned by this process
2Eh Word CNottermthreads
This location records belong to the number of threads that have not ended in the process.
30H Word Un3
This location is true and unknown, it seems to always 0.
32H Word CRING0THREADS
This location records the number of RING0 threads managed by VMM32.vxd. For general procedures, its value should be the same as CThreads. However, in Kernel32.dll, this value is more than CTHREADS 1.34H Handle Heaphandle
This location is a Heap Handle, which contains a table belonging to the process (or something else). Here is the Shared Heap Handle of the kernel32.
38h htask w16tdb
This is a Selector, pointing to the process-related Win16 Task Database (TDB). All Win16 and Win32 programs have TDB Selector and maintain a legitimate TDB.
3ch DWord Memmapfiles
A pointer points to the first node in the "Link list composed of the memory map used in this process". Each memory mapping file is a node in the list. The format of this node is:
DWORD memory map file base address
DWORD points to the next node, or 0
40H Penvironment_Database PEDB
A pointer, pointing to Environment Database. Environment Database contains current subdirectory, environment variables, process command line parameters, standard handle (for example, stdin), and other projects. I will describe in detail in the [Environment Database] section.
44H Phandle_Table Phandletable
A pointer pointing to Process Handle Table. All Handles is here, including File Handles, EventHandles, Process Handles, and more. The peer in the DOS / WIN16 environment is the SYSTEM FILE TABLE (SFT) of the DOS.
48h struct _process_database * parentpdb
A pointer pointing to Process_Database of the Parent Process. Parent processes for general procedures are Windows Explorer (Explorer). Msgsrv32 is also the parent process of Explorer and Initial Service Processes.
4ch Pmodref ModreFlist
This location points to the header of the module linked list of the process. This is also the MODREFS linked list mentioned earlier.
50h dword threadlist
A pointer points to the linked list of threads owned by the process. At present, I don't know the true format of the list.
54h dword debuggeecb
This is a context that is debugged. When a process is in a debug state, this position points to one area of 2GB or more, which contains a pointer, pointing to the PROCESS DATABASE of the adjuster.
58h DWord LocalheapFreehead
This pointer points to the header of the free block linked list of the default Heap of the process. Chapter 5 will describe its format in detail.
5ch dword initialring0ID
This location meaning is unknown, it seems to always 0.
60h critical_section CRST
This location is a cricical_section that is used by various APIs to synchronize each thread in the same process. Will you see the role of this Cricital Section in many virtual code.
78H DWORD UN4 [3]
These three DWORD true meaning unknown, it seems to always 0.
84H dword pconsole
If this process uses console (that is, this is a program program program), this location is pointing to a console object (K32Obj_console) for output.
88h dword tisinusebits1
This 32-bit unit represents the index of the 32 TLS (Thread Local Storage). If a bit is set, the corresponding TLS index is used. Each TLS index constantly adds its value, for example:
TLS INDEX: 0 = 0x00000001
TLS INDEX: 1 = 0x00000002
TLS INDEX: 2 = 0x00000004
Terminal will discuss TLS later
8ch dword tisinusebits2
This DWORD represents the state of the 32-63 index in TLS.
90H DWORD ProcessDword
This location meaning is unknown. There is an unappromable function (getProcessDword) to get the value of the bit.
94h struct _process_database * processgroup
This location is either 0, or you will point to the primary process in a "process group". The so-called "process group" is a group of processes, echoes each other. When a group is destroyed, all of them are also destroyed. Note that every process considers yourself in your "process group", so this location points to your own PDB. If the process is in debug, it belongs to the debugger "process group".
98H DWORD PEXEMODREF
This location points to the Modref of Exe. In general, the modRef of Exe is a header in the module linked list, so this location is usually consistent with the location 4ch unless the process is loaded with LoadLibrary or LoadModule. Other DLLs.
supplement:
If the LoadModule function is reserved in the Win16, in Windows NT / 2000 / XP and its subsequent versions, it is recommended to use createProcess to replace.
9ch DWord TopExcfilter
The "Top Exception Filter" of this DWORD memory process. If the process does not have any exception handling routines, then the one pointed to by this bit. This routine can be specified by the SetunhandExceptionFilter function. Structured exception will be discussed later.
A0H DWORD BASEPRIORITY
This DWORD is stored is the basic priority of the process. Windows 95 supports 32 priorities, divided into four levels:
Idle 4
Normal 8
HIGH 13
Realtime 18
A4H DWORD HeapownList
This location points to the "Links forming the HEAPS used in the process". By default, there is only one HEAP for each process, you can get getProcessHeap. However, the process can also call HeapCreate to generate another HEAP. These HEAPs are placed in this list. Chapter 5 will have more narratives for this topic.
A8H DWORD HeapHandleblockList
The movable block in HEAP is managed by moveable handle table. Each HEAP corresponds to a table. Many such TABLE form a linked list. This location points to the header of the linked list. Chapter 5 has more narratives for moveable handle table.
ACH DWORD PSOMEHEAPPTR
The true meaning of this location is not very clear. Usually it is 0, if not 0, then a pointer, pointing to the default hendle table of the process. See a A8H position before.
B0H DWORD PCONSOLEPROVIDER
This location is 0. Either a pointer, pointing to the console object of Kernel32 (K32Obj_console). This bit seems to always be 0 for Win32 Console programs.
B4H Word Environselector This is a selector, pointing to the environment block of the process. This Selector's base address is the same as the pszenvironment of Environment Database, and the ENVIRONFASE.
B6H Word ErrorMode
This location contains the value set by SETERRORMODE. The SETERRORMODE of Kernel32 will move down the same name function of KRNL386, so this location reflects the Win16 error mode code. They may be:
0
SEM_FAILCRIRALRORS
SEM_NOALIGNMENTFAULTEXCEPT
SEM_NOGPFAULTERRORBOX
SEM_NOOPENFILEERRORBOX
B8H dword pevtleadfinished
This location points to the Event Object (K32Obj_event) of Kernel32. This Event is activated when the process is created.
BCH Word UtState
This location is unknown. Usually 0.
GextExitcodeProcess and IgetExitcodeProcess
GetExitCodeProcess acquires the end of the process. It requires an HPROCESS parameter. The main function of the function is actually just confirming whether the second parameter is a legal pointer. Real action is handed over to IgetExitcodeProcess. The latter uses HProcess to find the corresponding pointer (pointing to Process_Database). Since HProcess is a Handle, the above action means first using the index into the Handle Table, and then remove the process pointer. X_CounvertHandletok32Object is responsible for "increasing the reference count of Process Database", etc.
With the Process_Database pointer, the function can take the value of the TerminationStatus member and store it in a buffer specified by the caller. IgetExitCodeProcess reduces the reference count of Process Database and leaves the "Must Complete" status.
GetExitcodeProcess virtual code:
// Parameters
// Handle HProcess;
// LPDWORD LPDWEXITCODE;
Set up structured exception handling frame
IF (LPDWEXITCODE) // if a non-null Pointer Was Passed, Verify
EAX = * lpdwexitcode; // That The Dword It Points to Can Be Written.
REMOVE STRUCTEDUREPTION HANDLING FRAME
Goto IgetExitcodeProcess;
IGETEXITCODEPROCESS virtual code:
// Parameters
// Handle HProcess;
// LPDWORD LPDWEXITCODE;
// local:
// process_database PPDB;
// Bool RetValue;
RetValue = true; // Assume Successful Return
X_EntermustComplete (); // prevent US from Being Interrupted.
// increments PTDBX-> MustCompleteCount.
X_logsomekernelFunction (Function Number for getExitcodeProcess); // Get a Pointer to the process_database struct
PPDB = X_CONVERTHANDLETOK32Object (HProcess, 0x80000010, 0);
IF (PPDB)
{
// Save Away Exit Status
* LPDWEXITCODE = PPDB-> TerminationsTatus;
X_UNUSEObjectWrapper (PPDB); // Decrement Usage Count
}
Else
{
RetValue = false;
}
// Call the API logging function again (???)
X_logsomekernelFunction (function number for getExitcodeProcess);
LeavemustComplete (); // Decremestics PTDBX-> MustCompletecount
Return RetValue;
}
SetunhandledExceptionFilter
This function sets the UNHANDEXCEPTIONFILTER function address of the Kernel32 - the latter will be used when there is no other exception filter (Exception Filter) is used to handle exception conditions. This function saves the current value of TOPEXCFILTER in Process Database and replaces the value in the parameter and returns the original value.
SetunhandledExceptionFilter virtual code:
// Parameters:
// lptop_level_exception_filter lptoplevelexceptionFilter
// locals:
// lptop_level_exception_filter prevvalue
// Save Old Value
Prevvalue = ppcurrentprocess-> topExcfilter;
//Stuff in new value
PpCurrentProcess-> topExcfilter = lptoplevelexceptionFilter;
Return Prevvalue; // Return Old Value