[Post] gloomy Analysis of Windows kernel (studying CreateProcess)

Source: Internet
Author: User

I will give an example of decompiling Win32 API function CreateProcess to demonstrate the study of subsystem technology.
Shows how Win32 works with the execution system of Windows NT.

Get the function prototype from msdn:

Bool CreateProcess (
Lptstr lpapplicationname, // pointer to name of executable module
Lptstr lpcommandline, // pointer to command line string
Lpsecurity_attributes lpprocessattributes, // process security attributes
Lpsecurity_attributes lpthreadattributes, // thread security attributes
Bool binherithandles, // handle inheritance flag
DWORD dwcreationflags, // creation flags
Lpvoid lpenvironment, // pointer to new environment Block
Maid directory, // pointer to current directory name
Lpstartupinfo, // pointer to startupinfo
Lpprocess_information lpprocessinformation // pointer to process_information
);

All parameters in the function are not described in detail. Soon, in the first few lines, the exception handling _ except_h was created.
Andler3 (the struct in the stack corresponds to the struct in Visual C ). Then proceed according to dwcreationflags
Interesting processing. In any case, the create_no_window flag will be removed from dwcreationflags (For me
). Then check the disallowed flag combination detach_process | create_new_console. If
When some bits are set at the same time, an error is returned. Select a priority from the new process priority (except one, clear all
In dwcreationflags ). If the priority is real_time but cannot be assigned to the processor, Set
Set to high_priority. The following describes the lpapplicationname, lpcommandline, and lpenvironment parameters.
. The analysis result indicates that the createprocessw function is actually stated in the document. Therefore
The command line and application names are different. The dos style is the complete path. Use unpublished NTDLL. dll
Functions in:

Ntsysapi
Boolean
Ntapi
RtlDosPathNameToNtPathName_U (char * lppath,
Rtl_string * ntpath,
Boolean allocflag,
Rtl_string * Reserved );

The result will be /?? //: The path of the sample. Then, fill in the public object_attributes struct, in objectnam
Put the pointer to the obtained path in the E domain and call the undisclosed function:

Ntsysapi
Iostatus
Ntapi
Ntopenfile (Out DWORD * handle, in access_mask desiredaccess,
Object_attributes * objattr, pio_status_block iostatusblock,
DWORD publish access, DWORD openoptions );

The access is synchronyze | file_execute. Get the handle to open the file to call another undisclosed
Function:

Ntsysapi
Ntstatus
Ntapi
Ntcreatesection (
Out phandle sectionhandle,
In access_mask desiredaccess,
In pobject_attributes objectattributes optional,
In plarge_integer maximumsize optional,
In ulong protect,
In ulong attributes,
In handle filehandle optional
);

Most undisclosed system functions are called by open Win32 APIs. API function createfilemappin
G is the encapsulation of ntcreatesection. In fact, even if the system calls these functions directly, no one will interfere (and
Also saves ). Interestingly, ntcreatesection is a major parameter generated by API functions:

Desiredaccess = (flprotectlow = page_readwrite )? Standard_rights_required | 7:
Standart_rights_required | 5;

Desiredaccess can only take two values. The calling method from createprocessw is as follows:

Ntcreatesection (& sectionhandle, standard_rights_required | 0x1f,
Null, & qwmaximumsize,
Page_executeread, sec_image, ntfilehandle );

In this way, the image is obtained and the file-image source-is closed. This is done using the public ntclose function. Laifen
Analyze the code returned by ntcreatesection. We will not discuss error handling here, otherwise it will be very complicated,
A large number of secondary functions need to be discussed. We will study the absence of errors and the image is a PE image. Call the famous
Undisclosed functions:

Ntsysapi ntstatus ntapi
Ntquerysection (
In handle sectionhandle,
In sectioninfoclass sectioninformationclass,
Out pvoid sectioninformation,
In ulong sectioninformationlength,
Out Pulong returnlength optional
);

There are some functions (not public) Like ntqueryinformationxxxxx in the system ). It is not public
Ntddk. h describes the prototype of some functions and the struct information used to call these functions. Matt pietrek
Ntqueryinformati in ntddk. H is described in the Microsoft Systems Journal (in msdn ).
The main functions of onprocess. Unfortunately, the information about the ntquerysection function does not exist. All of these
All functions have the same prototype and process objects in the operating system. Ntquerysection returns two types of information (sect
Ioninformationclass can be 0 or 1 ). The size of the struct is 16 or 58 bytes.
The information class of the sectioninformation parameter called by createprocessw is 1.

Struct section_info_class1 {
DWORD entrypoint;
DWORD field_4;
DWORD stackreserved;
DWORD stackcommited;
DWORD subsystem;
DWORD imageversionminor;
DWORD imageversionmajor;
DWORD unknown1;
DWORD characteristics;
DWORD machine;
DWORD unknown [4];
};

We can see that this information is obtained from the header of the PE image. Output in the main domain characteristics is
Object Type (whether it is executable ). Then check the machine type, parse the subsystem domain, and check the image version. And most
Call undisclosed functions:

Ntcreateprocess (
Out phandle processhandle,
In access_mask desiredaccess,
In pobject_attributes objectattributes,
In handle parentprocess, //-1
In Boolean inherithandles,
In handle sectionhandle,
In handle debugport optional, // null
In handle exceptionport optional // null
);

This creates a process object for Windows NT. Close the image because it is no longer needed. Next, set the object attributes,
Call the undisclosed function ntsetinformationprocess

Ntsysapi
Ntstatus
Ntapi
Ntsetinformationprocess (
In handle processhandle,
Processinfoclass classinfo,
In pvoid information,
In ulong length,
);

In ntddk. h, there is an enumeration value of _ processinfoclass, which describes the information class. Adjust the value of the information class: proces
Sdefaultharderrormode, processbasepriority. For these classes, the information struct itself is a 32
DWORD. Call an undisclosed function. Matt pietrek introduced this function in his article:

Ntsysapi
Ntstatus
Ntapi
Ntqueryinformationprocess (
In handle processhandle,
In processinfoclass processinformationclass,
Out pvoid processinformation,
In ulong processinformationlength,
Out Pulong returnlength optional
);

The obtained information is processbasicinfo, which is described in ntddk. h.

Typedef struct _ process_basic_information {
Ntstatus exitstatus;
Ppeb pebbaseaddress;
Kaffinity affinitymask;
Kpriority basepriority;
Ulong uniqueprocessid;
Ulong inheritedfromuniqueprocessid;
} Process_basic_information;

For createprocessw, the required information is the peb address. Because after obtaining this information, you can call
Function _ basepushprocessparameters. Judging from the parameter, its purpose is to adjust the IP address generated only by the Process
. Next, call two internal complex functions. Call _ basecreatestack first. _ Basecreatestack
Adjust the process stack. First, select the values used for reservrd and commited stacks. In addition, if
If the sizereserved and sizecommited values are 0, they must be obtained from the header of the PE file that issued the CreateProcess process.
These values. Then trim these values and keep the memory in the address space generated by the process. This uses an undisclosed letter.
Ntallocatevirtualmemory (corresponding to the Win32 API function virtualallocex, virtualallocex is
It is very simple encapsulation, and the parameters of these two functions are identical ). Then, make two calls and use the following pseudo
Code can be more concise description:

Freereserved = sizereserv-sizecommited;
Reservedaddr + = freereserved;
If (sizereserved <= sizecommited) FL = 0;
Else {
Reservedaddr-= delta;
Sizecommited + = delta;
FL = 1;
}
Ntallocatevirtualmemory (Han, & reservedaddr, 0, sizecommited, 1000,4 );

// [Skipped]

Ntprotectvirtualmemory
(Prochan, & reservedaddr, Delta, page_readwrite | page_guard, & oldprot );
/* Encapsulation of virtualprotectex */

It can be seen that memory is allocated in the reserved area (at the end ). And the allocated memory is greater than delta. This part (large
The attributes of delta are page_guard and page_readwrite. Finally, the following struct is obtained:

* ** Stack ***
---------------? -Reservedaddr
|
|

|
| Reserved | <-sizereserved-(sizecommited + delta)
|
| -------------- |-Commitedaddr
| Guard page | <-Delta
| -------------- |
| Read_write | <-sizecommited
|
L----------------SS (ESP)

In this way, sizecommited bytes are allocated to the stack. Sizereserved is retained. Subsequent reservation differentiation under the stack
The configured memory is converted to the guard page (converting to this page can cause exceptions ). From the source code, we can see that the error d
The size of ELTA may have tragic consequences. This is a key piece of information-let's see where to find the Delt.
A value:

. Text: 77f04b99 mov eax, large FS: 18 h
. Text: 77f04b9f mov ECx, [eax + 30 h]; peb
. Text: 77f04ba2 mov eax, [ECx + 54 h]; read only data
; Readonlystaticserverdata
. Text: 77f04ba5 mov edX, [eax + 4]
[Skipped]
. Text: 77f04bb1 mov ESI, [edX + 128 H]; Delta

In this section, the eax register points to the global region used for all processes. This region can only be read. Of course
The higher level information about the stack is well known, and the authenticity of the information is proved in the source code.
. Result: Execute the basecreatestack function to fill in the stackinformation structure.

Typedef struct _ stackinformation
{
DWORD reserved0;
DWORD reserved1;
DWORD addressoftop;
DWORD commitaddress;
DWORD reservedaddress;
} Stackinformation;

The information obtained from this struct is essentially a parameter used to call the following interesting function baseinitializeco.
Ntext:

Baseinitializecontext (pcontext context, // 0x200 bytes
Ppeb peb,
Pvoid entrypoint,
DWORD stacktop,
Int type // Union (process, thread, fiber)
);

Several parameters of this function: The peb address, the stack entry point, and parameters define the context to be created (fiber, Process
, Thread ). The function fills in the fields of the context struct (in ntddk. h. One of these domains is very interesting.
(Basefiberstart, baseprocessstartthunk, basethreadstartthunk
). At this point, there is a thread for "childbirth", and the generated thread is executed in the new context. In fact, all three are biased.
The code for moving is very short-it is to fill in the corresponding stack image and convert it to one of the two functions. These two functions
They are _ baseprocessstart and _ basethreadstart. These two functions are very similar. We only look at _ baseproc
The essstart function.

This function creates the first exception handling in the linked list (see Teb ). When the memory is accessed incorrectly
Exception Handling calls the dialog box with OK and cancel. This handler ends the current process. But sometimes if
An exception is generated by an incorrect service thread. Only this thread is terminated.

Therefore, after baseinitializecontext is returned, the corresponding struct is filled. And this struct is used as a non-public
Parameters of the open ntcreatethread function. The prototype of ntcreatethread is as follows:

Ntsysapi
Ntstatus
Ntapi
Ntcreatethread (
Out phandle threadhandle,
In access_mask desiredaccess,
In pobject_attributes objectattributes optional,
In handle processhandle,
Out pclient_id clientid,
In pcontext context,/* See _ baseinitializecontext */
In stackinformation * stackinfo,/* See _ basecreatestack */
In Boolean createsuincluded/* = 1 */
);

Finally, after processing the data in the main domain of the PE image subsystem, the data is transferred to the Win32 service through LPC. Process should
This is only created under the Win32 subsystem. Some high-level information about this reason can be found in Halen Kaster's book.

For the CreateProcess function, the task that must be completed is to start the thread (of course, if
Set the create_suspend flag in ationflags ). The thread starts ntresumethread (for Win32 R
Esumethread encapsulation. Finished! Now, the rest are memory release and exit correctly.

The main analysis of the CreateProcess function of Win32 sub-system can conclude that the sub-system is usually
The NT execution body system works collaboratively. Most subsystems use undisclosed functions, and the subsystem uses its own server through the LPC.
Communication, many Win32 API functions are encapsulation of NT functions. All these are well known, but we need to use-
Assembly to confirm

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.