We need to create a hanker program through stack overflow. After the foo program is executed, the Goto program is sent to the hacker program without sound information. After the hanker is executed, return to the place where foo is called accurately.
First, you need to clarify the following points.
1. the following code usually starts and ends with a function (except main:
Pushl % EBP <br/> movl % ESP, % EBP <br/> subl $ XX, % ESP <br/>... <br/> Leave <br/> RET
2. During Foo call bar, the EIP is first pushed to the stack, then the parameter is pushed to the stack (if any), and then the code at the beginning of the bar is jumped;
3. Bar will first press the EBP stack, and then assign the ESP value to the EBP to generate a new stack frame. Then, the ESP value is subtracted from a Value XX, allocate stack space for temporary variables, and then run your own code;
4. There are two commands at the end of Bar: Leave and ret. Leave clears the current stack frame, which is equivalent to mov ESP, EBP, and then pop EBP; RET command is clear parameter, then pop EIP.
The code for the problem raised at the beginning of implementation is as follows:
/* $ Hongwu, 10/01/17. $ */</P> <p> # include <stdio. h> </P> <p> int eip4returnmain = 0; <br/> int ebp4returnmain = 0; </P> <p> void changehackerebp () {<br/> int D = 0; </P> <p> int * addr4ebp = & D + 1; <br/> * addr4ebp = * addr4ebp-4; <br/>}</P> <p> void hacker () <br/>{< br/> int C = 0; <br/> printf ("/N --- hack succeed! /N "); </P> <p> // Do anything you want here ^ 6 ^ <br/> // </P> <p> // put main's stack frame back, then it will come back to main after "RET" <br/> int * addr4eip = & C + 1; <br/> * addr4eip = eip4returnmain; <br/> * (addr4eip-1) = ebp4returnmain; </P> <p> // subtract 4 from hacker's EBP, because the EIP wasn' t pushed into stack when go in hacker <br/> changehackerebp (); <br/>}</P> <p> void Foo () <br/>{< br/> I NT B = 0; <br/> int * addr4eip = & B + 2; /* | EIP | <br/> | EBP | <br/> | B | <br/> */<br/> printf ("/n ---- foo! /N "); </P> <p> // remember the EIP & EBP of main's stack frame <br/> eip4returnmain = * addr4eip; <br/> ebp4returnmain = * (addr4eip-1); </P> <p> // change the EIP of main's stack frame, then hacker will be call silently <br/> * addr4eip = (INT) hacker; <br/>}</P> <p> int main () <br/>{< br/> Foo (); </P> <p> printf ("/n ---- return to main succeed! /N "); </P> <p> return 0; <br/>}
It is easy to steal data from Foo to hacker. It takes several hours for hacker to return to main, and the hacker finally understands it. At first, it was not clear about the stack changes before and after the call. Those in the textbooks mentioned too many textbooks ^ 6 ^, and then there was no way to get the number of EIPs in the stack, I thought that the ESP value would be reduced by 4 through embedded assembly, but this stack is automatic. If you increase the stack to four, the stack will be scaled back to four when it returns, but in the end, after thinking about it, it's exactly half past one.
The GCC 4.3 used by the compiler.