Professional Documents
Culture Documents
A L
TI
E N
I D By
NF Madheswaran D
C O
R O
P
WI Version: <1.3>
Date: < 23/10/2006>
Introduction
§ Pre-requisites
• Basic C knowledge (Not covered here)
• Familiarity with Unix environment (basic unix commands, user
knowledge on Vi or Emacs editors). (Not covered here)
• Alignment & Padding issues.
• Good understanding about pointers.
• Good understanding about bitwise operators
A L
TI
§ Advanced Topics N
• E
Handy Expressions involving bitDwise operations
• Stack frames à What happens F Iduring function calls
• Variable arguments à How O Nis it implemented?
• C
Dynamic memory allocation à A sample design of malloc/free
• R O
P
Executable File content
I
W
Wipro confidential 2
Alignment & Padding
§ For today’s session, assume following sizes and study the following program
• Char: 1 byte
• Int: 4 bytes
• Short: 2 bytes
typedef struct
{
char name[30];
int empno;
int salary;
} EmpRec, * EmpRecPtr;
A L
main()
{
T I
int x = 1;
E N
char y = 2;
I D
int z = 3;
EmpRec abc; N F
EmpRecPtr empr = &abc;
C O
R O
printf(“Sizes: int=%d, char=%d, EmpRec=%d, EmpRecPtr=%d\n”, sizeof(x), sizeof(y),
sizeof(abc), sizeof(empr));
P
WI
printf(“Address: &x=%p, &y=%p, &z=%p, &abc=%p, &empr=%p\n”, &x, &y, &z, &abc,
&empr);
printf("Address: &abc.name=%p, &abc.empno=%p, &abc.salary=%p\n", &abc.name,
&abc.empno, &abc.salary); }
Wipro confidential 3
Alignment & Padding
§ For today’s session, assume following sizes and study the following program
• Char: 1 byte
• Int: 4 bytes
• Short: 2 bytes Sizes: int=4, char=1, EmpRec=40, EmpRecPtr=4
typedef struct Address: &x=0xbffffb3c, &y=0xbffffb3b, &z=0xbffffb34,
{ &abc=0xbffffb00, &empr=0xbffffafc
char name[30];
int empno;
Address: &abc.name=0xbffffb00,
int salary; &abc.empno=0xbffffb20, &abc.salary=0xbffffb24
} EmpRec, * EmpRecPtr;
main() A L
{
T I
int x = 1;
E N
char y = 2;
int z = 3; I D
EmpRec abc;
N F
EmpRecPtr empr = &abc;
C O
O
printf(“Sizes: int=%d, char=%d, EmpRec=%d, EmpRecPtr=%d\n”, sizeof(x), sizeof(y),
R
sizeof(abc), sizeof(empr));
P
WI
printf(“Address: &x=%p, &y=%p, &z=%p, &abc=%p, &empr=%p\n”, &x, &y, &z, &abc,
&empr);
printf("Address: &abc.name=%p, &abc.empno=%p, &abc.salary=%p\n", &abc.name,
&abc.empno, &abc.salary);}
Wipro confidential 4
Memory view
&(abc.name)
&(abc.salary) &(abc.empno)
Stack grows | | |
main()
{ | | |
int x = 1; this way
| | p | p b1f
char y = 2;
int z = 3; L
b20
Ab24
| | |
TI
EmpRec abc; | | | b27
EmpRecPtr empr = &abc; p | p | p | p
E N
Higher
b28
p | p | p | p
printf("Sizes: int=%d, char=%d, EmpRec=%d,
DMemory
FI
EmpRecPtr=%d\n", sizeof(x), sizeof(y), p | p | p | p
sizeof(abc), sizeof(empr)); 3 | 0 | 0 | 0 b37
printf("Address: &x=%p, &y=%p, &z=%p,
&abc=%p, &empr=%p\n", &x, &y, &z, &abc,
O N b34
b38 p | p | p | 2 b3b
&empr);
C b3c 1 | 0 | 0 | 0 b3f
O
printf("Address: &abc.name=%p,
P R
&abc.empno=%p, &abc.salary=%p\n",
&abc.name, &abc.empno, &abc.salary);
WI
}
&z &x &y
Wipro confidential 5
Alignment & Padding
main()
{
char x = 10;
char y = 20;
int *p = &y;
printf(“&y=%p &p=%p\n”, &y, &p);
printf(“%d\n”, (*p) & 0xff); /* SIGBUS or unaligned split access */
} L
A
T I
E N
ID
N F
CO
R O
P
WI
Wipro confidential 7
Alignment & Padding
Register sequence:
Two 32 bit Registers(CNTL1, CNTL2, in that order)
Three 8 bit Registers(STAT1, STAT2, STAT3, in that order)
One 32 bit register CNTL3
One 8 bit register ERR
Bad structure that can cause trouble:
typedef struct hw_device {
unsigned int cntl1;
unsigned int cntl2;
unsigned char stat1; A L
unsigned char stat2; T I
unsigned char stat3; E N
unsigned int cntl3; I D
unsigned char err; N F
} MYDEVICE, *MYDEVICE_PTR;CO
R O
P
WI
Wipro confidential 9
Pointers – Basics
const int *p = x;
L
*p = 10; /* illegal statement */
§ Arrays and Pointers
char a[10]=“Hello”;
I A
char *str = a;
printf(“%s %s\n”, a, str);
N T
printf(“%c %c %c %c\n”, a[1], str[1], 1[str], 1[a]);
DE
I
printf(“%p %p %p %p\n”, a, str, &a[1], str+1);
F
Output:
Hello Hello
eeee
O N
0x22ccd0 0x22ccd0 0x22ccd1 0x22ccd1 C
§
• Yes and No.
R O
Then pointers and arrays be interchangeably used?
P
WI
Wipro confidential 10
Pointers – Basics
WI
Wipro confidential 11
Pointers – Basics
• &(*(*(0x22cca4) + 1))).
Output:
50 4 20 4 R O This is equal to
P
WI
0x22cca0 0x22cca0 0x22ccaa 0x22cca4 0x22ccab 0x1 &(*(0 + 1)) and is equal
0x22cc60 0x22cc60 0x22cc64 0x22cc64 0x403005 0x403005 to 1 and str[1][1] will be
a junk value
Wipro confidential 12
Pointer Basics
&str1[0][0] b
&str[0][0]
0 1 2 3 4 5 6 7 8 9
a[0] O n e \0 b[0] One\0
a[1] T w o \0 b[1]L Two\0
a[2] T h r e e \0 I A Three\0
N T b[2]
a[3] F o u r \0
D E b[3] Four\0
FI b[4] Five\0
a[4] F i v e \0
O N
C
&str[1][1] translates to
&(*(*(str+4byte) + 1)), i.e
R O
P
WI
&(*(*(0x22cca4) + 1))).
This is equal to &(*(0 + str1[1][0]=
1)) and is equal to 1. So str1[1]=*(st str1[1][1]
str[1][1] will be a junk r1 + 4byte) *(*(str1+4bytes
value )+0) = T
Wipro confidential 13
Pointer Basics
a b
Junk\0
0 1 2 3 4 5 6 7 8 9
a[0] O n e \0 b[0] One\0
NF b[4] Five\0
a[4] F i v e \0
CO
char *temp = “junk”; R
O
IP
char *temp= “junk”;
a[0]=temp;
W b[2] = temp;
Wipro confidential 14
Pointers – Arithmetic & Casting
typedef struct
{
int day;
ef be ad de ee ff c0 00 ‘a’ ‘b’ ‘c’ ‘d’ ‘e’ 0 0 0 1f ca af de de ca 0 0 1 0 0 0
int month;
int year;
} Date;
all
cp+1 sp+1 ip+1cp+5 sp+3 ip+2 dp+1 dp+2
ip + 3 ip + 6
int abc=0xdeadbeef; sp + 8 sp + 16
int def=0xc0ffee;
char ghi[6]=“abcde”; cp + 12 cp + 24
int jkl = 0xdeafca1f;
short mno = 0xcade;
A L
I
• When a pointer is incremented by 1, depending upon
ofTbytes moved will defer.
Date pqr = { 1, 1, 2006 };
the type, number N
main()
{ D E
int *ip = &abc;
• When casting I from one type to another
Fcare alignment issues (SIGBUS)
short *sp = (short *)&abc;
char *cp = (char *) &abc; O
• TakeN
Date *dp = (Date *) &abc; C
……..
O • Keep in mind that number of bytes that will move
PR for every increment/decrement will change.
}
}
R O
Alternate 2: MyAlloc = *(TempMyAlloc + user_choice) */
P
WI
Wipro confidential 16
Volatile pointers
Wipro confidential 17
Think about this – Volatile & Constant together
A L
TI
E N
I D
NF
C O
R O
P
WI
Wipro confidential 18
Bit Manipulations
main()
{
int x = -10;
printf(“%d\n”, ~x+1);
}
main()
{
unsigned int x = 5; A L
while(--x >= 0) TI
{ E N
I D
printf(“Hello World\n”);
NF
}
C O
}
R O
P
WI
Wipro confidential 19
Bit Manipulations
main()
Output: 10
{
~x represents one’s compliment of x.
int x = -10;
~x+1 represents two’s compliment of x. (i.e
printf(“%d\n”, ~x+1); negative of x)
}
main()
{ HelloWorld is printed infinitely.
unsigned int x = 5; X becomes MAXINT A Lwhen it is decremented
while(--x >= 0) while it is havingT I a value of 0.
{ E N
I D
printf(“Hello World\n”);
N F
}
C O
}
R O
P
WI
Wipro confidential 20
Arithmetic and Logical Shifts
main()
Output: 0xC0000000
{ Signed number, “sign extension” happens
int x = 0x80000000; for right shift. (Arithmetic shift)
printf(“%x\n”, x >> 1);
}
main()
A L
{
T I
unsigned int x = 0x80000000; E N
printf(“%x\n”, x >> 1); I D
F 0x40000000
Output:
N
} O
Unsigned
C number, “sign extension”
doesn’t happen for right shift. (Logical shift)
R O
P
WI
Wipro confidential 21
Advanced Topics
A L
TI
E N
I D
NF
C O
R O
P
WI
Wipro confidential 22
Handy Bitwise Expressions
3 X >> 1 Divide by 2
I D
F
8 Mask = (X-Y) >> 31 Min(X, Y) without using Mask contains all zeros if Y is less than or
Result = (Mask & X) | (~Mask & Y)
O N
comparisions equal to X and all ones if X is less than Y.
RO
Result = (Mask & Y) | (~Mask & X)
than X.
I P
W
Wipro confidential 23
Exercise 1: Power of 2.
Sample program:
/* assuming EBP as a integer pointer */ ESP
int f2(int x1, int y1) /* x1 is *(EBP+2), y1 *(EBP + 3) */
{ Saved regs in f2
int l5 = 110; /* l5 is *(EBP – 1), l6 is *(EBP -2) */ l6
int l6 = 120; l5
Lower EBP
Memory Prev Frame Ptr
return (0)
Ret addr in f1
} x1
y1
AL
{ l4
int l3 = 50; this way
int l4 = 60;
T I l3
Prev Frame Ptr
return f2(l3 + x, l4 + y);
/* right most argument pushed to stack first */
E N Ret addr in main
I D x
NF
} Higher y
main()
CO
Memory Saved regs in main
{
int l1 = 10; l3
int l2 = 20;
int l3 = f1(l1 + 20, l2 + 20);
R O l2
P l1
WI
}
Prev Frame Ptr
Wipro confidential 25
Scope – Check your understanding now
printf(“%x\n”, abc);
A L
TI
{
E N
int abc = 0xc0ffee;
I D
int x = 0x100;
NF
printf(“%x\, %xn”, abc, x);
C O
}
} R O
P
WI
(Clue: Local variables can get into stack or register)
Wipro confidential 26
Function Arguments – Check your understanding
now
if (argc != 2)
{
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(1);
}
….
flag = check_permission();
........
A L
strcpy(filename, argv[1]); /* Depending upon argv[1], the return address could get corrupted */
if (flag == 0xdeadbeef)
T I
{
E N
/* execute the as root or deposit million dollars in a bank account */
}
I D
else
{
NF
} C O
/* execute the program as normal user, deduct $10 from an account */.
}
R O
P
WI
/* clever hacker will manage the argv[1] such that return address is changed to a desired location. Or he can change the value of flag
*/
/* typically entire binary program of “undesired program” is also passed as an argument, along with return address change */
Wipro confidential 29
Variable arguments in C
Main()
Heap Start {
ptr1
MCB 1: 0, 108 char *ptr1 = malloc(100);
Allocation 1 char *ptr2 = malloc(200);
MCB 2: 0, 208 ptr2 Control
Last allocation Allocation 2
…….
Free Memory free(ptr1);
….
ptr1 = malloc(300);
A L ….
Heap End
T I
E N free(ptr1)
ID
….
Note:
N
When 100 bytes are requested, actually 100 bytes
F
+
ptr1 = malloc(50);
CO
sizeof(MCB) has been utilized. MCB is the overhead. ….
R O
I P free(ptr1);
W free(ptr2);
}
Wipro confidential 33
Dynamic Memory Allocation
Main()
Heap Start {
MCB 1: 1, 108 char *ptr1 = malloc(100);
Allocation 1 char *ptr2 = malloc(200);
MCB 2: 0, 208 ptr2
Allocation 2
…….
MCB 3: 0, 308 free(ptr1);
ptr1
Last allocation Allocation 3
….
Free Memory
ptr1 = malloc(300);
A
Control L ….
Heap End
T I
E N free(ptr1)
ID
….
Note:
NF
ptr1 = malloc(50);
free doesn’t take size as the the argument. It is
calculated by accessing *(ptr1 – sizeof(MCB) +
sizeof(int))
CO ….
R O
P
MCB1 & allocation 1 remains intact even though it is free(ptr1);
WI
not allotted.
free(ptr2);
}
Wipro confidential 34
Dynamic Memory Allocation
Main()
Heap Start {
ptr1
MCB 1: 0, 108 char *ptr1 = malloc(100);
Allocation 1 char *ptr2 = malloc(200);
MCB 2: 0, 208 ptr2
Allocation 2
…….
MCB 3: 1, 308 free(ptr1);
Last allocation
Allocation 3
….
Free Memory
ptr1 = malloc(300);
A L ….
Heap End
T I
E N free(ptr1)
ID
….
Note:
N
First allocation is re-utilised. That is 100 bytes are
F ptr1 = malloc(50);
R O
I P free(ptr1);
W free(ptr2);
}
Wipro confidential 35
Dynamic Memory Allocation
Main()
Heap Start {
MCB 1: 1, 108 char *ptr1 = malloc(100);
Allocation 1 char *ptr2 = malloc(200);
MCB 2: 1, 208
Allocation 2
…….
Last allocation MCB 3: 1, 308 free(ptr1);
Allocation 3
….
Free Memory
ptr1 = malloc(300);
A L ….
Heap End
T I
E N free(ptr1)
ID
….
NF
ptr1 = malloc(50);
CO ….
R O
P free(ptr1);
WI Control free(ptr2);
}
Wipro confidential 36
Pros & cons of MCB approach
1. Lost memory
ptr1=malloc(100);
ptr1=malloc(200);
2. Double free
ptr1=malloc(100);
free(ptr1);
free(ptr1);
3. Accessing memory after free
A L
ptr1=malloc(10); TI
free(ptr1) E N
*(ptr1+9) = ‘\0’’; I D
NF
4. Out of range access
C O
ptr1=malloc(10);
*(ptr1+10) = ‘\0’;
P RO
W I
Wipro confidential 38
Exercise 4: Implement myalloc & myfree functions
§ Requirements:
• You should not use any of the existing C or C++ library calls for
memory alloc (malloc, calloc, realloc, new, etc…)
• Implement void *myalloc(int elem_size) and void free(void *p);
• You also have to implement void InitMem(char *ptr, int
size_in_bytes)
• Through this interface, one big chunk of memory will be provided to
you.
L
• Use the part of these memory in further calls of myalloc & myfree
A
functions.
T I
• N
You also have to implement int MemEfficiency()
E
that returns
D
number of MCBs (chunks) present.
• FI following aspects
If you are adventurous, address
N
•
C O
Minimize the fragmentation by joining adjacent free blocks
•
O
Put a time limit towards myalloc and myfree functions.
R
•
P
Make it thread safe. J
• WI
Allocated memory should align with the size requested. Example:
myalloc(10) means the pointer returned must be divisible by 10.
Wipro confidential 39
Security issue – buffer overflow on heap
char *filename_p;
if (argc != 2)
{
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(1); A L
}
T I
filename_p = malloc(1024);
E N
I D
N F
get corrupted */ C O
strcpy(filename, argv[1]); /* Depending upon argv[1], MCBs or even other areas can
R O
P
WI
....
}
Wipro confidential 40
Security issues – Be aware
N F
C O
O
Note: Nowadays, linking typically refers to static linking. Loader is
R Relocation, etc.
P
taking care of dynamic linking,
I
W
Wipro confidential 42
Where the data goes?
T I
printf("%s %d\n", my_str_p, my_static); N
{
E local_f1();
my_uninit_data[99] = 0xdeadbeef;
I D}
f2();
N F
}
C O
main()
R O
{
I P
static int my_static = 3;
W
printf("%d %s %d\n", my_global, my_string, my_static);
local_f1(); }
Wipro confidential 44
Output of elfdump or readelf
WI
Wipro confidential 45
Exercise 5: Disassemble the code
A L
TI
E N
I D
NF
C O
R O
P
WI
Wipro confidential 46
Thank you.
A L
T I
E N
I D
N F
C O
R O
P
WI
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.
Wipro confidential 47