Compiler STACK operation

xiaoxiao2021-03-06  65

Compiler STACK operation

The title has a strange name, huh, in fact, this is not a big relationship with the game production, and it is a big relationship with the underlying driver.

It is well known to have a CRT, and he provides a lot of useful functions, such as Printf, such as strlen, etc. Some people know that in fact, the main function we write is not the first user state function that the system call is operated when the process is loaded, and these are all the hands and feet of the compiler link. Fortunately, all the MS provides all The complete CRT is realized, and it takes time to understand what additional operations have been made to the compiler.

One extra topic here is to let our program do not depend on the CRT provided by the compiler? The answer is certain, such as the Kernel Mode's Driver will not rely on the compiled CRT, but Driver Studio can use C Language, then how did he do it? Naturally, it provides the support of CRT. This is long, there is a lot of work to work, some simple (such as New delete implementation), some complex (C ) Exception's implementation), not here discussed, if you are interested in Google's search, you can find a lot of articles. Here is the main NT Kernel to manage the Stack of Thread.

One memory area has two operations inside Win32, a Calls called COMMIT, perform RESERVE for a memory does not trigger the memory allocation action of the operating system until the operating system is really The allocation of the memory descriptor, tag, detailed information can be referred to INSIDE Windows 2000 and Advanced Windows. In the compiler, there is also such an operation for Stack, / stack options can set threads to Stack Reserve and Commit The default value, but the above mentioned that the reserve must be used once, and the memory can be used, but we have not explicitly conduct Stack's CommTic COMMIT call in his own program. Nature This is also within the internal operation of the compiler. Maybe someone has encountered this error, the compiler tells the external symbol called _chkstk (VcHkesp) with a compiler, there is a different name, maybe called _chkesp) This function is the key. It is also the subject of this article to explain today.

Said so many nonsense, I don't know if you have dizzy. Let's work in an experiment, let you work on _chkstk. First, create a new project, choose Win32 Console, the simplest one _tmain function That kind of (vs.net 2003), then select Project -> Properties -> Links -> Enter -> Ignore So the default library, choose Yes, then linked -> Advanced-> Entrance point, type main, then select C / C -> code generation -> Basic runtime check, select the default, then open the CPP file, remove the _tmain function, click below

Int main () {Volatile Int A [10000]; A [9999] = 0;

Return 0;} f7, out of error, error lnk2019: External symbol __chkstk unable to resolve, this symbol is referenced in function "int __cdecl test (void" (? test @@ yahxz), explaining the function of this TEST This _chkstk function is called, then add the extern "c" void _cdecl _chkstk () {} in the file, this time, run, go wrong. Why is this? Carefully check, there is no syntax error A, the array has no cross-body, no reason, I don't say you should know, the problem is in the _chkstk function, since the compiler requires this function, this function is definitely not as we provide The function of nothing is as simple as the function, okay, now you should understand the _chkstk function, what is this function? Is it used to do? First look at his source code. New A project, or Win32 console, this time do not change, just add the content inside the above main function in the _tmain function, set a breakpoint in the beginning of the _tmain function, go to the disassembly, you can see similar The following code 00411A13 MOV EAX, 9D08H 00411A18 CALL @ ilt 250 (__ chkstk) (4110ffH) MOV has an EAX, then call the _chkstk function, track in, oh, it is a function that implements the assembly. Code I will not post it. , Look at this description of this description, you may have understood what this function is to use, simply, he is completed in the mating of the OS to complete Commit when needed, but he There is also no clear call to make a function of memory commit (there is no name for this Win32 API. His name is Virtualalloc), how is it finished? Top it, he is going to cooperate with the OS. Complete Stack operation. The two keywords OS and stack are not less. Then you may ask, how is the OS completed this operation? Look at that _chkstk function is just a loop every one to be accessed. One read operation (TEST [ECX], EAX), it's hard to hide anything? Unfortunately, I am in your words, the key is to operate on that test The above is said, the memory is not commit, and there is no appropriate descriptor. At this time, read and write this memory address will trigger a Page Fault exception. OS capture this exception, check certain conditions, suitable for it. Just put this memory page commit. This is the principle. You may ask, what is the difference between the two programs? OS is not using memory when reading memory? Why is the first program? Will it be wrong? The second program is also reading memory, how can it be wrong? Oh, the above also said, OS will check certain conditions, what is this condition? First, you can be automatically committed memory area It can only be Thread Stack, secondly, Stack must grow continuous growth, can't span the page. The first condition is easy to think about, the second is not so obvious. First look _________________________ | ESP's page, commit | ___________ | <- Next Page, Commit, set Guard Attribute | ____________

- One Page, RESERVE, the next page of the current use, sets the property of Guard, when accessing this page, the OS checks page guard property, found that there is this property, then put the first 3 Page Commit, and set the Guard property, complete the automatic commitality of Stack in this loop. If a page doesn't have a Guard property, but only reserve, this time OS will not perform automatic Commital, but cause a Accessing illegal exceptions. Like the program we have. The compiler is compiled, the default gives Thread Reserve 1M stack, and commit 2 Page, the second page has a Guard property, and our program uses The memory is not the second Page, but crossed it, accessed the back of Page, and the later PAGE is RESERVE, so that an illegally accessible exception is triggered. The program later, because of the use of a loop One visit to each page, so that the task of one commit page is completed with the help of the OS, understand? The fact is better than the else, let's see if it is such a thing. Another program is another program , Soft-Ice, don't say, Symbol Load loads the latter programs just compiled, automatic breakpoints to the entrance, F3 switch to source code and assembly code mixing mode, F8 single step entry _chkstk function inside, broken Point to Test [ECX], EAX this line. Page ECX, This page is present, g, breakpoint Page Ecx, no accident, this page should be no present, this time BPint 0e, in the X86 platform Above 0e is the Page Fault interrupt, then break down below the Test statement, record the value of this ECX, then g, um, breakpoint, in the 0E interruption, see if the value of CR2 is not the ECX just recorded The value is the same (because the Base of the SS is 0)?

转载请注明原文地址:https://www.9cbs.com/read-91395.html

New Post(0)