Wipro Confidential: Stack Tracing and Variable Arguments in C - Workshop

Download as pdf or txt
Download as pdf or txt
You are on page 1of 15

Stack Tracing and Variable Arguments in C - Workshop

WI

RO P

ON C

ID F

NT E

AL I
By FCG Team

Version: <0.2> Date: < 10/11/2006>

X86 Stack view during function calls in C

Consider the function f1(int x, int y) Consider call to this function f1(1, 2) The function arguments are passed using the stack. Therefore this results in values 2 and 1 being pushed on to the stack in that order.

AL Assembly directive Call typically translates to: TI PUSH 2 and then PUSH 1) Push arguments to the stack (RightN left, to IAL T E Push contents of Program Counter to stack N ID FIDE JUMP to the function. NF CON CO RO O WIP PR WI
Wipro confidential 2

X86 Stack view during function calls in C

int f1(int x, int y) { int local; if (x % 2) local = x+y; else local = x; return local; } main() { int a; a = f1(1,2); printf(%d\n, a); }

Stack during execution of f1 local Return address

Push local

IAL NT ID FIDE NF CON Stack when f1 CO RO is called O WIPPush 2 Return address Push 1 PR 1 Store PC WI JUMP f1 2
Wipro confidential 3

NT E

AL I

1 2

X86 Stack view during function calls in C The stack keeps growing during runtime. It contains

Arguments passed The return address of the calling function Local variables

There is a need to keep track of the current top of the stack through some means. This is achieved typically through a register Stack AL Pointer (SP). L TI

TIA EN However, the stack pointer value may NFID FI O change during the execution of the current function. In particular, it can change when: ON O C C Parameters are passedO another function to IPR R W Local variables are created on stack P

EN D

WI

Wipro confidential

X86 Stack view during function calls in C Functions are set up with a "stack frame

A call stack is composed of stack frames (sometimes called activation records). Each stack frame corresponds to a call to a function which has not yet terminated with a return. Stack frame contains both function parameters, and automatic function variables. The idea behind a stack frame is that each subroutine can act independently of its location on the stack, and each subroutine can act L as if it is the top of the stack.
local Return address

TIA Stack Frame EN 1 I FID NF2 CON local (local variable) can be accessed as contents at [sp + 0] CO RO Parameters passed, ie. x and Wcan be accessed as [sp + 8] and [sp + 12] O y IP

EN D

A IStack Pointer L T

respectively. However, as the stack keeps growing, the Stack Pointer keeps IPoffsets also would differ at different places in the moving. Therefore these W program.
Wipro confidential 5

X86 Stack view during function calls in C The base pointer ebp

As the value of the stack pointer changes, the offsets used to access a local variable may be different in different places of a function. To avoid this, access to local variables is done using negative offsets from another register known as the ebp. Through use of ebp, we can assume that the same offset is always used to access the same variable (or parameter). The ebp register is called the frame pointer, or FP.

Stack with EBP local EBP Value of old ebp Return address

push ebp mov ebp, sub esp,

1 2

PR I

IAL NT ID FIDE NF CON ebp [ebp - 1](local) value) esp O O Prev [ebp + 0](old ebp <sizeofC locals> [ebp + 1](return address) O WIPR [ebp + 2](arg1)
[ebp + 3](arg2)

Stack NT... E

AL I

ebp

Wipro confidential

X86 Stack view during function calls in C


Sample program: /* assuming EBP as a integer pointer */ int f2(int x1, int y1) /* x1 is *(EBP+2), y1 *(EBP + 3) */ { int l5 = 110; /* l5 is *(EBP 1), l6 is *(EBP -2) */ int l6 = 120; return (0) }

ESP Saved regs in f2 l6 l5 Prev Frame Ptr Ret addr in f1 x1 y1

Lower Memory

EBP

int f1(int x, int y) { int l3 = 50; int l4 = 60; return f2(l3 + x, l4 + y); /* right most argument pushed to stack first */ } main() { int l1 = 10; int l2 = 20; int l3 = f1(l1 + 20, l2 + 20); }

Stack grows this way

Saved regs in f1

IAL E NT IDHigher FIDE NF Memory ON CO RO C O WIP PR Prev Frame Ptr WI

TI N

AL

l4 l3 Prev Frame Ptr Ret addr in main x y Saved regs in main l3 l2 l1

Wipro confidential

X86 Stack view during function calls in C


The return sequence would need to perform the following tasks:

Remove space for local variables, by reverting esp to its old value. Restore the old value of ebp. Return to the calling function with a ret command. The ret command adjusts ESP to offset the parameters passed and restores the PC

Lower Memory

Saved regs in f2 l6 l5 Prev Frame Ptr Ret addr in f1 x1 y1

ESP

EBP

Stack grows this way

Saved regs in f1

ESP

IAL mov esp, ebp NT pop ebp IDHigher FIDE ret NF Memory ON CO RO C O WIP Note that the gray-ed out portion refers

EN

TI

AL

l4 l3 Prev Frame Ptr Ret addr in main x y Saved regs in main l3 l2

EBP

PR EBP. old contents of the stack, ESP and WI

Prev Frame Ptr

Wipro confidential

Scope Where are all variables stored

S.No 1 2 3 4 5 6 7

Type of Data Local variables (automatic variable) Dynamically allocated memroy Code (functions) Global variables Initialized

Sections Stack, not part of executable file Heap, not part of executable file Code Segment (.text) Data Segment (.data)

AL Read Only Data Global variables Initialized and const TI Segment (.rodata) IAL N E NT Const Strings (example: %d used in ERead Only Data ID FID Segment (.rodata) format string of printf) NF CON Global variable Not initialized Unitialized Data CO RO Segment (.bss, only O WIP size info kept in PR executable file) WI

Wipro confidential

Scope Check your understanding now

Is scope of global and static variables clear? Following code is sequence is perfectly legal. How is it handled?
f1(int x, int y) { int abc = 0xdeadbeef; printf(%x\n, abc); {

} (Clue: Local variables can get into stack or register)

IAL NT int abc = 0xc0ffee; ID FIDE int x = 0x100; NF CON printf(%x, %xn, abc, x); O C RO } O WIP

NT E

AL I

PR I

Wipro confidential

10

Function Arguments Check your understanding now A new function named File1Func1 is implemented in file1 Prototype of the function is as follows

Int File1Func1();

In file1, the function is implemented as follows:


Int File1Func1(int x, int y) { .. }

IAL T In file2, this function is called as follows. EN ID FID File1Func1(10,20,30); NF CON O O File1Func1 is called with 3Carguments, while the implementation takes only two arguments. What will happen O WIPR
now?

NT E

AL I

PR I

Wipro confidential

11

Security issue Buffer Overflow on stack


main(int argc, char *argv[]) { int flag; char filename[16]; if (argc != 2) { fprintf(stderr, "Usage: %s filename\n", argv[0]); exit(1); } . flag = check_permission(); strcpy(filename, argv[1]); /* Depending upon argv[1], the return address could get corrupted */ ........ if (flag == 0) { /* execute the as root or deposit million dollars in a bank account */ } else { /* execute the program as normal user, deduct $10 from an account */. }

IAL NT ID FIDE NF CON CO RO O WIP } /* clear hacker will manage the argv[1] such that return address is changed to a desired location. Or he can change the value of flag PR */ /* typically entire binary program of undesired program is also passed as an argument, along with return address change */ WI
Wipro confidential 12

NT E

AL I

Variable arguments in C va_start(ap, num_args) Typically implemented as macro, just initializes ap such that it points to first un-named argument. (It will use frame pointer + offset of second argument from fp to iniatialize ap) va_arg(ap, type) Returns an argument with type specified in the type parameter and suitably updates ap. va_end(ap) Implementation specific cleanups. Number of arguments should be known AL directly or indirectly
main: argc is the first argument that will tell number of arguments TI IAL number of % N printf: number of arguments are indirectly found from E NT in format argument ID IDE

NF CON F CO be Type of the arguments shouldRO known I main: Strings (char *argv[]) P RO W printf: character following % tells the argument type IP W
F

Wipro confidential

13

Variable arguments - Example

Declaration of va_list

#include <stdio.h> #include <stdarg.h> void foo(char *fmt, ...) { va_list ap; int d; char c, *p, *s; va_start(ap, fmt); while (*fmt) switch(*fmt++) { case s: /* string */ s = va_arg(ap, char *); case d: /* int */ d = va_arg(ap, int); } va_end(ap); }
Initializes the list ap. fmt is the last parameter of which the calling function knows the type.

IAL NT ID FIDE NF CON CO RO O WIP PR WI

NT E

AL I

Parses the argument list to retrieve a string if the format string contains s.

Wipro confidential

14

Thank you.

Information contained and transmitted by this presentation is proprietary to Wipro Limited and is intended for use only by the individual or entity to which it is addressed, and contains information that is privileged, confidential or exempt from disclosure under applicable law.

IAL NT ID FIDE NF CON CO RO O WIP PR WI

NT E

AL I

Wipro confidential

15

You might also like