Internet Explorer has reported that hackers have used the "buffer overflow" and zero-day vulnerability attacks. Have you ever tried it? This article will fully use the C # language to explore the secrets that are unknown.
1. This article describes how to use the stack buffer overflow to dynamically modify the memory in C # To change the application execution process.
2. If you are a master, please point out the shortcomings in this article.
3. In order to make this article easy to understand, the code will be extremely streamlined.
Start now
We know that when the array subscript is out of bounds ,. NET will automatically throw StackOverflowException, so that we can safely read and write the memory, so do we have to go beyond this automatic detection barrier to achieve our very operational purpose? The answer is yes, and we can modify some key variables such as the if and switch judgment values, the for loop variable I value, and even the method return values, of course, in theory, code can also be injected and transferred to the code execution block, provided that it must be in the unsafe code.
When the method is called, The system performs the following operations: Putting the method into the stack, adding parameters to the stack, returning the address to the stack, and controlling the code area to the stack (EIP in the stack ). We want to access the stack address of the method. The conventional managed code is not good. We can only use the unsafe code, but it does not mean that you must be proficient in C/C ++ language and pointer operations, the examples in this article are very simple. You can think of pointers as C # arrays in the lite version.
Change the value of a Temporary Variable
First, give a piece of code, and then explain the principle in detail.
1. static unsafe void Main (string [] args)
2 .{
3. // apply for a memory segment that can only save one int32 on the stack
4. int * p = stackalloc int [1];
5.
6. for (var I = 0; I <30; I ++)
7 .{
8. System. Threading. Thread. Sleep (200 );
9.
10. Console. WriteLine ("{0} \ n", I );
11. p [I] = 0;
12 .}
13.
14. Console. ReadLine ();
15 .}
This is simple, but it is intriguing for developers who have never tried to write code like this. C # (including C/C ++) if the offset of pointer p is not checked, the code will be compiled and run smoothly. Will the for loop be executed 30 times? Or ......
Haha... please wait...
The conclusion is that this will be an endless loop, because p is constantly incrementing by 1 offset, and the value of all nearby memory is changed to 0, while the local variable I is the closest variable to p, when the offset address of p [I] is equal to the address of I, code p [I] = 0 is equivalent to I = 0, in fact, when I = 6 in the test, the I value is overwritten with 0, and I added Thread in the code. sleep (200) and Console. writeLine ("{0} \ n", I) is to let everyone see the program execution process more intuitively, of course, here can also be changed to p [I] = 1, p [I] = 2 and other numbers
Search for memory values and modify them
Or give the code first
1. static unsafe void Main (string [] args)
2 .{
3. Console. WriteLine (Change_Result ());
4. Console. ReadLine ();
5 .}
6.
7. static unsafe int Change_Result ()
8 .{
9.
10. int I = 0;
11. // variable result, default Return Value
12. int result = 123;
13. // apply for a stack memory segment. The size can be set at will.
14. int * p = stackalloc int [1];
15. // start from the current stack address and look down for the address that matches the function return value. If it matches, it is changed to 10000.
16. while (true)
17 .{
18. if (p [+ + I] = 123)
19 .{
20. p [I] = 10000;
21. break;
22 .}
23 .};
24. return result;
25 .}
The default value of the result variable as the return value of the method is 123, and there is no Code explicitly modifying its value. The key is here
1. while (true)
2.
3 .{
4. if (p [++ I] = 123)
5 .{
6. p [I] = 10000;
7. break;
8 .}
9 .}
In this Code, find the memory address with a value of 123 (which may be the address of the result variable) and change the value to 10000. Of course, the return value of the function will certainly not be the original 123.
This is two examples of the classic StackOverFlow, hoping that it is easy to understand and acceptable to everyone. In addition, the buffer overflow does not just change the memory value. In the hands of experts, he can also execute arbitrary code, this is because there will always be a pointer pointing to the next instruction to be executed by the method. If this pointer is controlled, the process will be controlled.