Environment:
Gcc
The test C code is as follows: overflow. C:
# Include <stdio. h> <br/> void print () <br/>{< br/> printf ("Hello/N "); <br/>}< br/> void Foo () <br/>{< br/> char buf1 [4]; <br/>}< br/> void main () <br/>{< br/> Foo (); <br/>}
The purpose of the exercise is to overflow the array in Foo and let the program print hello.
First: gcc-g-fno-Stack-Protector overflow. C-o Overflow
Check again: objdump-D Overflow
View the disassembly of the two functions as follows:
080483a4 <print >:< br/> 80483a4: 55 push % EBP <br/> 80483a5: 89 E5 mov % ESP, % EBP <br/> 80483a7: 83 EC 08 Sub $0x8, % ESP <br/> 80483aa: C7 04 24 B0 84 04 08 movl $0x80484b0, (% ESP) <br/> 80483b1: e8 Fe FF call 80482b4 <puts @ PLT> <br/> 80483b6: C9 leave <br/> 80483b7: C3 RET <br/> 080483b8 <Foo>: <br/> 80483b8: 55 push % EBP <br/> 80483b9: 89 E5 mov % ESP, % EBP <br/> 80483bb: 83 EC 10 sub $0x10, % ESP <br/> 80483be: C9 leave <br/> 80483bf: C3 RET <br/>
Test the stack usage in Foo () and modify Foo () as follows:
Void Foo () <br/>{< br/> char buf1 [4]; <br/> buf1 [0] = 'a '; <br/> buf1 [1] = 'a'; <br/> buf1 [2] = 'a'; <br/> buf1 [3] = 'a '; </P> <p> buf1 [4] = 'a'; <br/>}
Re-disassemble to check the stack usage in Foo (), as shown below:
080483b8 <Foo >:< br/> 80483b8: 55 push % EBP <br/> 80483b9: 89 E5 mov % ESP, % EBP <br/> 80483bb: 83 EC 10 sub $0x10, % ESP <br/> 80483be: C6 45 FC 61 movb $0x61, 0 xfffffffc (% EBP) <br/> 80483c2: c6 45 FD 61 movb $0x61, 0 xfffffffd (% EBP) <br/> 80483c6: C6 45 Fe 61 movb $0x61, 0 xfffffffe (% EBP) <br/> 80483ca: C6 45 ff 61 movb $0x61, 0 xffffffff (% EBP) <br/> 80483ce: c6 45 00 61 movb $0x61,0x0 (% EBP) <br/> 80483d2: C9 leave <br/> 80483d3: C3 RET
In this way, we can see that the position of buf1 in the stack is the 4 bytes starting from the current stack bottom pointer % ebp-0xc.
What's strange is that buf1 [4] points to the location of % EBP (why is this strange? Isn't the array in C Language continuously stored? According to my original understanding, buf1 [4] would be % ebp-0x10); but this would be able to deduce the value of buf1 [N.
The objective is to change the return address of main () to the print () Address 0x080483a4 when calling the Foo () function. The returned address should be Stack-pressed when Foo () is called, the position in the stack is current % EBP + 0x4 (because after calling Foo, foo first places the original % EBP on the stack ), therefore, you only need to change the value of % EBP + 0x4 in the stack to the entry address 0x80483a4 of print.
In the small-end system, the low byte is low. Therefore, modify Foo () as follows:
Void Foo () <br/>{< br/> char buf1 [4]; </P> <p> buf1 [8] = 0xa4; <br/> buf1 [9] = 0x83; <br/> buf1 [10] = 0x04; <br/> buf1 [11] = 0x08; <br/>}
After compilation, run:./overflow and enter the following:
Hello <br/> segmentation fault
"Hello" is printed, but a segment error occurs. If you do not want to see the disconnection error, you can call buf1 [8] = 0xaa (that is, the part that calls the system print () function) of Foo ), in this case, you can output "hello" without the disconnection error:
Hello