Complete local variable access parsing through memory Layout

Source: Internet
Author: User

First, let's look at a piece of code:

Void A () {int arr [10]; int I; for (I = 0; I <10; I ++) {arr [I] = I; // initialize the array arr []} void B () {int arr2 [10]; int I; for (I = 0; I <10; I ++) {printf ("% d", arr2 [I]); // arr2 [] is not initialized, directly output its value} // The result is output 0123456789} int _ tmain (INT argc, _ tchar * argv []) {A (); B ();}

C language students know that this code is problematic. The initialization of ARR [] in function a () is completed with the execution of function, the local variable on the stack is released, and the variable arr [] "does not exist". function B () uses it if it does not initialize the value of array arr2, the value is random. Run the above Code in vs2005 and vs2010. The output is

It turned out to be the value of the array arr []. It was a blue sky. Isn't it "The local variable in the () function actually got access in the B () function ", of course, this statement is wrong. We decided to study this issue in depth. Let's take a look at it together when we say "one compilation, the truth is clear.

The following is the assembly code of function a (). If you have learned the assembly, you should know the implementation of the built-in stack mechanism of the CPU, that is, the SS: IP, push, pop operations correspond to the corresponding SS: IP address change.

In the following code, EBP and ESP are the stack bottom address and stack top address of the stack in function.

Void ()
{

00401030 push EBP // press EBP to stack
00401031 mov EBP, esp // assign the value at the top of the stack to the bottom pointer of the stack, that is, initialize the stack. (The compilation meaning is the value of mov register ESP to EBP)
00401033 sub ESP, 2ch // reduce the top pointer of the stack by 2ch, that is, allocate a piece of memory for the variable used in function ().

// The base-10 value for 2ch is 44, which is 44 bytes. Each Int Is 4 bytes. Arr [10] occupies 40 bytes, And I occupies 4 bytes.
Int arr [10];
Int I;
For (I = 0; I <10; I ++)
00401036 mov dword ptr [I], 0
0040103d jmp a + 18 h (401048 H)
0040103f mov eax, dword ptr [I]
00401042 add eax, 1
00401045 mov dword ptr [I], eax
00401048 cmp dword ptr [I], 0ah
0040104c jge A + 2ah (40105ah)
{
Arr [I] = I; // initialize the array arr []
0040104e mov ECx, dword ptr [I]
00401051 mov edX, dword ptr [I]
00401054 mov dword ptr arr [ECx * 4], EDX
00401058 jmp a + 0fh (40103fh)
}
}
0040105a mov ESP, EBP // destroy the stack of function ()
0040105c pop EBP // restore the EBP value of the previous Stack
0040105d RET

 

In fact, after function a () is executed, the memory layout is

0x0012ff68 10 // Value of variable I
0x0012ff64 9
0x0012ff60 8
0x0012ff5c 7
0x0012ff58 6
0x0012ff56 5
0x0012ff52 4
0x0012ff48 3
0x0012ff44 2
0x0012ff40 1
0x0012ff3c 0 // Array arr []

Here, EBP is 0x0012ff68 and ESP is 0x0012ff3c (these memory addresses are allocated based on the situation of each PC, and the above addresses are the memory addresses of my PC). Function execution ends at the end

0040105a mov ESP, EBP // destroy the stack of function ()
Pay the EBP value pointing to the bottom of the stack to ESP (the value at the top of the stack). This stack is empty and there is no variable in it. From the function perspective, all the local variables "do not exist". We should not use the local variables of the function as the return value, but we can see that

0040105c pop EBP // restore the EBP value of the previous Stack
0040105d RET

Restore the EBP value, and then RET (the Assembly command corresponds to the call to control the Cs: IP value), but we should note that, this section of memory space is 0x0012ff68 to 0x0012ff3c, which is not rewritten or randomized (in fact, there is no such statement). Then let's look at the code of function B:

Void B ()
{
00401060 push EBP
00401061 mov EBP, ESP
00401063 sub ESP, 2ch
Int arr2 [10];
Int I;
For (I = 0; I <10; I ++)
00401066 mov dword ptr [I], 0
0040106d jmp B + 18 h (401078 H)
0040366f mov eax, dword ptr [I]
00401072 add eax, 1
00401075 mov dword ptr [I], eax
00401078 cmp dword ptr [I], 0ah
00401_c jge B + 35 h (401095 H)
{
Printf ("% d", arr2 [I]); // arr2 [] is not initialized and its value is directly output.
00401_e mov ECx, dword ptr [I]
00401081 mov edX, dword ptr arr2 [ECx * 4]
00401085 push edX
00401086 push offset ___ xt_z + 120 h (41db5ch)
00401_ B call printf (4010d1h)
00401090 add ESP, 8
00401093 jmp B + 0fh (40366fh)
}
// Output 0123456789
}

EBP is 0x0012ff68, ESP is 0x0012ff3c, that is, the memory layout of the local variable stack of function B (), which is the same as that of function a () (which has been released, it is also used by function B (), so the result shows that function B () outputs the value of function.

Any change to the memory layout of function a () or function B () will affect the results of the above Code, for example, defining arrays or variables only in function, or if multiple arrays or variables (int x; int arr1 [10]) are defined in function B (), the output of function B () is changed. You can also think about it, why did the variables defined by main () not change the output result, but changed the values of EBP and ESP.

In short, the above Code uses the memory layout to complete the impossible access, but the specific programming should not use this method, 1. it is too unconventional. 2. it has a lot to do with the compiler. The output of some versions of the above Code on GCC is a random number, so this is still an "error method ".

 

Reference http://topic.csdn.net/u/20110324/19/b2c6a156-7b7e-41d1-933d-34f34b240034.html

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.