Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
Linux Kernel Booting Process (2) - For NLKB
Next

2

Share

02 - Introduction to the cdecl ABI and the x86 stack

* Brief description of the x86 ASI and cdecl ABI
* Data and code segregation
* Into cdecl
* The stack frame

Related Books

Free with a 30 day trial from Scribd

See all

02 - Introduction to the cdecl ABI and the x86 stack

  1. 1. The almighty stack Introduction to the cdecl ABI and the x86 stack Alex Moneger Security Engineer
  2. 2. Chapter structure © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 2
  3. 3. Chapter structure  Brief description of the x86 ASI and cdecl ABI  Data and code segregation  Into cdecl  The stack frame (holy noises)  Exercise © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 3
  4. 4. Bytes and AAAAAAhhhhhSM © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 4
  5. 5. All starts with ISA  ISA stands for Instruction Set Architecture  Specified by the CPU : 1. Registers (ie: eax, ebp, esp…) 2. Instruction set (ie: add, sub, mov, call)  Specifies the CPU capabilities © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 5
  6. 6. The ABI  ABI stands for Application Binary Interface  Specified by each OS  Can have multiple ABIs per OS  Specifies:  How the OS expects programs to use the ISA  What standard binaries must adhere to to run on the OS  How compilers need to compile programs to enable them to run © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 6
  7. 7. The x86 cdecl ABI  Used by Linux  Dictates how function calls are made:  eax holds the return value of the function  Function parameters are pushed on the stack by the caller  The callee is in charge of reserving space on the stack  The callee is in charge of freeing the reserved space on the stack  More on this later… © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 7
  8. 8. Code vs Data  In a binary, code (machine instructions) is segregated from data (values manipulated)  In short, code is RE, data is RW  Code (.text section, dynlibs, …) has it’s own space  Data (.data section, …) has it’s own space  Data and code are never mixed together: cisco@kali:~/src/seccon$ readelf -l ch2 | egrep -i "LOAD|Addr" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x08048000 0x08048000 0x00588 0x00588 R E 0x1000 LOAD 0x000588 0x08049588 0x08049588 0x0011c 0x00120 RW 0x1000 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 8
  9. 9. What about “dynamic” data?  What about runtime dynamic data?  Introduce the 2 dynamic memory sections: 1. The stack, contains data for which size is known at compile time. It is tracked by the compiler. 2. The heap, contains data which size is know at runtime. It is tracked by the libc.  Dynamic data is marked as RW: cisco@kali:~/src/seccon$ readelf -l ch2 | egrep -i "STACK|Addr" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 9
  10. 10. Introducing the stack  Stack is a LIFO structure. It grows towards lower addresses  Stack holds the return address (where the program needs to ret following a call)  Each function gets a space where it can store it’s local data => The stack frame  The amount of local storage a function needs determines the size of the stack frame  When function exits, the stack frame is removed (popped) from the stack © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 10
  11. 11. Stack: the high level view  Pseudocode:  Stack cisco@kali:~/src/seccon$ pygmentize -g ch2-pc.c void func3(void) { } void func2(void) { } void func1(void) { func2(); func3(); } int main(void) { func1(); } Top of stack (High address) ie: 0xbfffffff int main(void) void func1(void) void func3(func2(void) © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 11
  12. 12. I’m ESP, I’m really special  By convention, special registers are used to manage the stack: 1. EBP, the stack base pointer:  Used to index function parameters and local variables  Does not move during the life of the stack frame 2. ESP, always indexes the top of the stack  Controlled by pop, push instructions  Shifted down the stack at function entry to reserve space for local variables void func1(void) EBP ESP 0x01020304 0xffffffff ESP ESP cisco@kali:~/src/seccon$ pygmentize -g ch2-ex.asm push 0x01020304 push 0xffffffff pop eax pop ebx © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 12
  13. 13. Unwinding the frame  On function exit, the stack frame is removed  But how much space to remove?  But how does the code know where to return?  Enter Saved EBP and mostly Saved EIP  Saved EBP remembers where the previous frame pointer was  Saved EIP tells the ret instruction where to return:  Ret = pop eip; jmp eip © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 13
  14. 14. Unwinding the frame - 2  On function return:  esp = ebp => remove all local storage  pop ebp => Set the base stack pointer to the previous frame  leave = mov ebp, esp; pop ebp  Called function epilogue: mov esp,ebp pop ebp ret leave ret © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 14
  15. 15. Example: Winding the stack  Stack cisco@kali:~/src/seccon$ pygmentize -g ch2-pc.c void func1(int a) { // 0x080483dc char c = 'A'; } int main(void) { // 0x080483e8 func1(0x1234); } Top of stack (High address) ie: 0xbfffffff Saved EIP of main Saved EBP – (stack frame -1) 0x1234 0x080483e8 EBP=0xbffff6b4 0xbffff6b4 0x00000000 dahtah@kali:~/src/seccon$ objdump -d -j .text -M intel ch2-pc2 | grep 'func1>:' -A 15 080483dc <func1>: 80483dc: 55 push ebp 80483dd: 89 e5 mov ebp,esp 80483df: 83 ec 10 sub esp,0x10 80483e2: c6 45 ff 41 mov DWORD PTR [ebp-0x4],0x41 80483e6: c9 leave 80483e7: c3 ret 080483e8 <main>: 80483e8: 55 push ebp 80483e9: 89 e5 mov ebp,esp 80483eb: 83 ec 04 sub esp,0x4 80483ee: c7 04 24 34 12 00 00 mov DWORD PTR [esp],0x1234 80483f5: e8 e2 ff ff ff call 80483dc <func1> 80483fa: c9 leave 80483fb: c3 ret EBP=0xbffff6c4 ESP 0x00000041 0x00000000 0x00000000 0x00000000 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 15
  16. 16. Example: Unwinding the stack  Stack cisco@kali:~/src/seccon$ pygmentize -g ch2-pc.c void func1(int a) { // 0x080483dc char c = 'A'; } int main(void) { // 0x080483e8 func1(0x1234); } Top of stack (High address) ie: 0xbfffffff Saved EIP of main Saved EBP – (stack frame -1) 0x1234 0x080483e8 EBP=0xbffff6b4 0xbffff6b4 dahtah@kali:~/src/seccon$ objdump -d -j .text -M intel ch2-pc2 | grep 'func1>:' -A 15 080483dc <func1>: 80483dc: 55 push ebp 80483dd: 89 e5 mov ebp,esp 80483df: 83 ec 10 sub esp,0x10 80483e2: c6 45 ff 41 mov DWORD PTR [ebp-0x4],0x41 80483e6: c9 leave 80483e7: c3 ret 080483e8 <main>: 80483e8: 55 push ebp 80483e9: 89 e5 mov ebp,esp 80483eb: 83 ec 04 sub esp,0x4 80483ee: c7 04 24 34 12 00 00 mov DWORD PTR [esp],0x1234 80483f5: e8 e2 ff ff ff call 80483dc <func1> 80483fa: c9 leave 80483fb: c3 ret ESP ESP EBP=0xbffff6c4 ESP ESP 0x00000041 0x00000000 0x00000000 0x00000000 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 16
  17. 17. Enough theory  Noticed something juicy in the stack process?  If an attacker controls saved EIP, he controls the program flow  Buffer overflow = saved EIP control. That’s it.  Go play! © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 17
  18. 18. When I get to rest  Compile the following program: cisco@kali:~/src/seccon$ pygmentize -g ch2.c #include <stdio.h> int callee(int a, int b, int c) { char local_buf[0x20] = {0x01}; unsigned int local_int = 0xffffffff; return 0x12345678; } int main(int argc, char **argv) { int ret = callee(0x1, 0x2, 0x3); return 0; }  Disassemble it  Understand the objdump output  Draw out the stack movement on paper  Fire up gdb and set a breakpoint on callee entry and exit. Inspect the stack. Follow ebp, esp.  Make sure you understand the output from “info frame”. Get the output manually  Overwrite callee’s saved EIP. What happens when callee exits?  Add a function called by callee. Follow the stack cisco@kali:~/src/seccon$ objdump -d -j .text -M intel ch2 | grep 'callee>:' -A 40 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 18
  • ssuser45dedd

    Apr. 19, 2017
  • AaronJin2

    Nov. 18, 2015

* Brief description of the x86 ASI and cdecl ABI * Data and code segregation * Into cdecl * The stack frame

Views

Total views

892

On Slideshare

0

From embeds

0

Number of embeds

26

Actions

Downloads

0

Shares

0

Comments

0

Likes

2

×