This project deals with …..
Filed under: Project Information | Leave a comment »
This project deals with …..
Filed under: Project Information | Leave a comment »
You may encounter, during your debugging sessions, the `stack corruption’ problem. Usually you will find it out after seeing your program run into a segmentation fault. Otherwise, it must mean that some very malicious and subtle code has been injected into your program, usually through a buffer overrun. What is a buffer overrun? Let’s examine the following short C code:
#include <stdio.h>
void bar(char* str) {
char buf[4];
strcpy( buf, str );
}
void foo() {
printf("Hello from foo!");
}
int main(void) {
bar("This string definitely is too long, sorry!");
foo();
return 0;
}
There’s clearly something wrong with it: as you can see, we are copying `str’ to `buf’ without first checking the size of `str’. First of all there is a security issue, because if `str’ didn’t just come from a fixed string like in this case, but got inputted from somewhere (maybe on a website), then there could be a string long enough to overwrite the code of `foo’, and run malicious code on its behalf. What we have here, anyhow, is just a segmentation fault. Let’s debug the program.
(gdb) file stack
Reading symbols from /home/siovene/stack...done.
(gdb) run
Starting program: /home/siovene/stack
Program received signal SIGSEGV, Segmentation fault.
0x6f6c206f in ?? ()
(gdb) backtrace
#0 0x6f6c206f in ?? ()
#1 0x202c676e in ?? ()
#2 0x72726f73 in ?? ()
#3 0xbf002179 in ?? ()
#4 0xb7df9970 in __libc_start_main ()
from /lib/tls/i686/cmov/libc.so.6
Previous frame inner to this frame (corrupt stack?)
Obviously something must have gone wrong.
In order to better understand what is going on, let’s make a step back, and let’s examine
a working example instead:#include <stdio.h> void bar(char* str) { char buf[4]; strcpy( buf, str ); } void foo() { printf("Hello from foo!"); } int main(void) { bar("abc"); foo(); return 0; }
This is the same code, but it’s been stripped off of the long string that caused the
segmentation fault, and in its place we find a harmless 3 character string: `abc’.
Let’s name the program stack.c anc compile it with debug informaion:
$> gcc -g -o stack stack.c
Now let’s debug it:
(gdb) file stack Reading symbols from /home/siovene/stack...done. (gdb) break bar Breakpoint 1 at 0x80483ca: file stack.c, line 5. (gdb) run Starting program: /home/siovene/stack Breakpoint 1, bar (str=0x8048545 "abc") at stack.c:5 5 strcpy( buf, str );
We have entered the bar() function, let’s examine the backtrace:
(gdb) backtrace #0 bar (str=0x8048545 "abc") at stack.c:5 #1 0x0804840e in main () at stack.c:13
What is the address of the bar() function?
(gdb) print bar $1 = {void (char *)} 0x80483c4
Let’s now be paranoid and check this out producing a dump of our executable:
$> objdump -tD stack > stack.dis
Open the file with your favorite editor and look for `80483c4′, the address of bar():
080483c4 <bar>: 80483c4: 55 push %ebp 80483c5: 89 e5 mov %esp,%ebp 80483c7: 83 ec 28 sub $0x28,%esp 80483ca: 8b 45 08 mov 0x8(%ebp),%eax 80483cd: 89 44 24 04 mov %eax,0x4(%esp) 80483d1: 8d 45 e8 lea 0xffffffe8(%ebp),%eax 80483d4: 89 04 24 mov %eax,(%esp) 80483d7: e8 0c ff ff ff call 80482e8 80483dc: c9 leave 80483dd: c3 ret
Perfect, that’s our function. But now let’s get curious.
Where’s the stack pointer in the CPU registers?
(gdb) info registers eax 0x0 0 ecx 0xb7ed11b4 -1209200204 edx 0xbff04f60 -1074770080 ebx 0xb7ecfe9c -1209205092 esp 0xbff04f10 0xbff04f10 ebp 0xbff04f38 0xbff04f38 esi 0xbff04fd4 -1074769964 edi 0xbff04fdc -1074769956 eip 0x80483ca 0x80483ca eflags 0x282 642 cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51
The `esp’ register, on the architecture this article is written on, is the stack pointer.
Its address is 0xbff04f10. Let’s examine the memory at that point:
(gdb) x/20xw 0xbff04f10 0xbff04f10: 0x00000000 0x08049638 0xbff04f28 0x080482b5 0xbff04f20: 0xb7ecfe90 0xbff04f34 0xbff04f48 0x0804843b 0xbff04f30: 0xbff04fdc 0xb7ecfe9c 0xbff04f48 0x0804840e 0xbff04f40: 0x08048545 0x08048480 0xbff04fa8 0xb7db3970 0xbff04f50: 0x00000001 0xbff04fd4 0xbff04fdc 0x00000000
With this command we have told GDB to examine 20 words in exadecimal format
at the address 0xbff04f10. That’s because the value of the stack pointer is the
address of the back-chain pointer to the previous stack frame. So address 0×00000000 is the
address of the previous stack frame. But 0×00000000 is put in the stack frame in concurrence of
the program entry point, i.e. the main() function. This agrees with the fact that we know bar()
was called by main()!
Everything looks ok and in place, since the program works perfectly we weren’t expecting anything
different. Let’s now do the same with the faulty program. At the moment of the segmentation fault,
the backtrace looked like this:
(gdb) backtrace #0 0x6f6c206f in ?? () #1 0x202c676e in ?? () #2 0x72726f73 in ?? () #3 0xbf002179 in ?? () #4 0xb7df9970 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 Previous frame inner to this frame (corrupt stack?)
To see exactly what goes on, it would be better to debug it more carefully:
(gdb) file stack Reading symbols from /home/siovene/stack...done. (gdb) break bar Breakpoint 1 at 0x80483ca: file stack.c, line 5. (gdb) run Starting program: /home/siovene/stack Breakpoint 1, bar (str=0x8048580 "This string definitely is too long, sorry!") at stack.c:5 5 strcpy( buf, str ); (gdb) next 6 } (gdb) next 0x6f6c206f in ?? () (gdb) next Cannot find bounds of current function
Let’s then try to follow back the stacktrace, as we did previously:(gdb) backtrace #0 0x6f6c206f in ?? () #1 0x202c676e in ?? () #2 0x72726f73 in ?? () #3 0xbf002179 in ?? () #4 0xb7e9b970 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 Previous frame inner to this frame (corrupt stack?) (gdb) info registers eax 0xbfeed1e0 -1074867744 ecx 0xb7ea4c5f -1209381793 edx 0x80485ab 134514091 ebx 0xb7fb7e9c -1208254820 esp 0xbfeed200 0xbfeed200 ebp 0x6f742073 0x6f742073 esi 0xbfeed294 -1074867564 edi 0xbfeed29c -1074867556 eip 0x6f6c206f 0x6f6c206f eflags 0x246 582 cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb) x/20xw 0xbfeed200 0xbfeed200: 0x202c676e 0x72726f73 0xbf002179 0xb7e9b970 0xbfeed210: 0x00000001 0xbfeed294 0xbfeed29c 0x00000000 0xbfeed220: 0xb7fb7e9c 0xb7fee540 0x08048480 0xbfeed268 0xbfeed230: 0xbfeed210 0xb7e9b932 0x00000000 0x00000000 0xbfeed240: 0x00000000 0xb7feeca0 0x00000001 0x08048300 (gdb) x/20xw 0x202c676e 0x202c676e: Cannot access memory at address 0x202c676e
There’s only one explanation to that: the stack memory has been overwritten and now contains
gibberish. We have been very unlucky with our example, but this gave us the tools to imagine
another case. Let’s assume the stack got actually corrupted not because it was overwritten
accidentally, but because GDB was failing to build it. In this case you are still able to
navigate it backwards. All you need to do it keep following the value of the stack frames,
starting from the `esp’ register, until you reach 0×000000. Write all the addresses down, and
then use `objdump’ to obtain the disassembly and symbols information from the binary. All is left,
now, is to check the names of the symbols matching the pinned up addresses.
If you can actually do that, than you have successfully reconstructed your stacktrace.
It wasn’t really corrupted by a bug in your program, but simply GDB missed to keep it up with it.
Filed under: Debugging | 1 Comment »
/* Binary search Tree */
#include <stdio.h>
#include <stdlib.h>
#define SUCCESS 0
#define FAILURE 1
int bst_insert(int);
void bst_print_inorder(void);
struct bstn {
int data;
struct bstn *left;
struct bstn *prev;
struct bstn *right;
};
#define BSTN_SIZE sizeof(struct bstn)
struct bstn *root = NULL;
int input[] = {25,5,36,4,2,85,42,65,7,22,51};
main()
{
int i, ret;
int ipsz = sizeof(input)/sizeof(int);
printf(“Size of array is %d\n”, ipsz);
/* Create a BST */
for(i=0; i<ipsz; i++) {
ret = bst_insert(input[i]);
if (ret != SUCCESS) {
printf(“Failed to create a binary search tree\n”);
return FAILURE;
}
}
/* Print values by accessing the BST inorder */
bst_print_inorder();
}
/* Insertion */
int bst_insert(int value)
{
struct bstn *ptr, *place_holder;
int left_right = 0;
if (root == NULL) {
root = malloc(BSTN_SIZE);
if (root == NULL) {
printf(“Resource unavailable”);
return FAILURE;
}
root->data = value;
root->left = NULL;
root->right = NULL;
root->prev = NULL;
} else {
ptr = root;
place_holder = root;
while(ptr != NULL) {
if(ptr->data >= value) {
place_holder = ptr;
left_right = 1;
ptr = ptr->left;
} else {
place_holder = ptr;
left_right = 2;
ptr = ptr->right;
}
}
if(left_right == 1) {
place_holder->left = malloc(BSTN_SIZE);
if (place_holder->left == NULL) {
printf(“Resource unavailable”);
return FAILURE;
}
place_holder->left->data = value;
place_holder->left->prev = place_holder;
place_holder->left->left = NULL;
place_holder->left->right = NULL;
} else if(left_right == 2 ) {
place_holder->right = malloc(BSTN_SIZE);
if (place_holder->right == NULL) {
printf(“Resource unavailable”);
return FAILURE;
}
place_holder->right->data = value;
place_holder->right->prev = place_holder;
place_holder->right->left = NULL;
place_holder->right->right = NULL;
} else {
printf(“Insertion error in the BST\n”);
return FAILURE;
}
}
return SUCCESS;
}
/* Deletion */
/* Search */
/* Depth of a tree */
/* Printing inorder */
void bst_print_inorder(struct bstn *ptr, int left_middle_right)
{
struct bstn *ptr = root, *place_holder = root;
if(root == NULL) {
printf(“BST not created\n”);
return;
}
if(left_middle_right == 1) {
/* Go to the left most node */
while(ptr != NULL) {
place_holder = ptr;
ptr = ptr->left;
}
printf(“%d\t”, place_holder->data);
while(place_holder->prev != NULL) {
printf(“%d\t”, place_holder->prev->data);
printf(“%d\t”, place_holder->prev->right->data);
}
bst_print_inorder(place_holder->prev, 2);
} else if(left_middle_right == 2) {
} else if(left_middle_right == 3) {
} else {
printf(“Incorrect Usage \n”);
return;
}
}
Filed under: Algorithms and Data structure | Leave a comment »
Stability
Stable sorting algorithms maintain the relative order of records with equal keys (i.e., sort key values). That is, a sorting algorithm is stable if whenever there are two records R and S with the same key and with R appearing before S in the original list, R will appear before S in the sorted list.
When equal elements are indistinguishable, such as with integers, or more generally, any data where the entire element is the key, stability is not an issue. However, assume that the following pairs of numbers are to be sorted by their first component:
(4, 2) (3, 7) (3, 1) (5, 6)
In this case, two different results are possible, one which maintains the relative order of records with equal keys, and one which does not:
(3, 7) (3, 1) (4, 2) (5, 6) (order maintained) (3, 1) (3, 7) (4, 2) (5, 6) (order changed)
Unstable sorting algorithms may change the relative order of records with equal keys, but stable sorting algorithms never do so. Unstable sorting algorithms can be specially implemented to be stable. One way of doing this is to artificially extend the key comparison, so that comparisons between two objects with otherwise equal keys are decided using the order of the entries in the original data order as a tie-breaker. Remembering this order, however, often involves an additional space cost.
Sorting based on a primary, secondary, tertiary, etc. sort key can be done by any sorting method, taking all sort keys into account in comparisons (in other words, using a single composite sort key). If a sorting method is stable, it is also possible to sort multiple times, each time with one sort key. In that case the keys need to be applied in order of increasing priority.
Example: sorting pairs of numbers as above by first, then second component:
(4, 2) (3, 7) (3, 1) (4, 6) (original) (3, 1) (4, 2) (4, 6) (3, 7) (after sorting by second component) (3, 1) (3, 7) (4, 2) (4, 6) (after sorting by first component)
On the other hand:
(3, 7) (3, 1) (4, 2) (4, 6) (after sorting by first component) (3, 1) (4, 2) (4, 6) (3, 7) (after sorting by second component, order by first component is disrupted)
Filed under: Insertion sort, Sorting Techniques | Leave a comment »
Complexity: O(n^2) { O of n square)
Space Complexity: О(n) total, O(1) auxiliary
Key Properties:
Psuedocode:
for i ← 0 to n-2 do
min ← i
for j ← (i + 1) to n-1 do
if A[j] < A[min]
min ← j
swap A[i] and A[min]
Analysis:
Selecting the lowest element requires scanning all n elements (this takes n – 1 comparisons) and then swapping it into the first position. Finding the next lowest element requires scanning the remaining n – 1 elements and so on, for (n – 1) + (n – 2) + … + 2 + 1 = n * (n – 1) / 2 ∈ Θ(n2) comparisons (by Arithmetic progression). Each of these scans requires one swap for n – 1 elements (the final element is already in place).
Filed under: Selection sort | Leave a comment »
int v; // we want to find the sign of v
int sign; // the result goes here
// CHAR_BIT is the number of bits per byte (normally 8).
The obvious way is to use
sign = -(v < 0);// but this would involve CPU to branch using the EFLAGS register.
The portable way
sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT – 1));
A non portable way
sign = v >> (sizeof(int) * CHAR_BIT – 1);
Filed under: Bit OPs | Leave a comment »
Some intresting Bit twiddling Hacks
http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive
Filed under: Bit OPs | Leave a comment »
The following in NOT a generic solution. You have to construct the masks for each case.
—————————————————————————————
#include
/* In the following example bits 0, 2, 6
* are toggled. The MASK has to be calculated
* seperately for differenct cases.
*/
#define MASK_NON_TOGGLED_BITS 0xFFFFFFBA
#define MASK_TOGGLED_BITS 0x45
main()
{
int num=0xEB, result, tmp, tmp1;
tmp = num & MASK_NON_TOGGLED_BITS;
tmp1 = num & MASK_TOGGLED_BITS;
result = tmp + (~tmp1 & MASK_TOGGLED_BITS);
printf(“toggled result: %x :num %x\n”,result, num);
}
————————————————————————————–
Filed under: Bit OPs | Leave a comment »
This program also has a definition to determine if a given number is “power of two”
#include <stdio.h>
unsigned int countones(unsigned int, unsigned char);
#define new_power_of_two(x) \
(((x)&(x-1)) == 0)
main()
{
unsigned int result, num = 0xFFF0F0F0;
result = countones(num, 1);
printf(“M1::Number of ones in integer is %d\n”, result);
result = countones(num, 2);
printf(“M2::Number of ones in integer is %d\n”, result);
result = countones(num, 3);
printf(“M3::Number of ones in integer is %d\n”, result);
printf(“Is power of two %d\n”, new_power_of_two(1512));
}
unsigned int countones(unsigned int num, unsigned char method)
{
if (method == 1) {
int count = sizeof(unsigned int) * 8;
int result = 0;
while(count) {
result += (num & 1);
num = num>>1;
count–;
}
return result;
} else if (method == 2) {
//Prefered Method
unsigned int x = num;
const unsigned int m1 = 0x55555555;
const unsigned int m2 = 0x33333333;
const unsigned int m4 = 0x0f0f0f0f;
const unsigned int m8 = 0x00ff00ff;
const unsigned int m16 = 0x0000ffff;
x = (x & m1 ) + ((x >> 1 ) & m1 );
x = (x & m2 ) + ((x >> 2 ) & m2 );
x = (x & m4 ) + ((x >> 4 ) & m4 );
x = (x & m8 ) + ((x >> 8 ) & m8 );
x = (x & m16) + ((x >> 16) & m16);
return x;
// Brain Kerninghan’s method, This logic woks in O(number of bits set)….
} else if (method == 3) {
unsigned int v = num; // count the number of bits set in v
unsigned int c = 0; // c accumulates the total bits set in v
for (c = 0; v; c++) {
printf(“num is %x::::num&(num-1) is %x\n”, v, v&(v-1));
v &= v – 1; // clear the least significant bit set
}
return c;
}
}
Filed under: Bit OPs | Leave a comment »
http://www.cs.virginia.edu/woda2004/slides/maebe.ppt
Memory Leaks
•What
–Allocating memory without releasing later
•Why bad
–Reduce performance
–May cause crashes
•How to solve
–Find out where exactly memory is leaked
Physical Leaks
•What
–Last pointer to a block of memory is destroyed
•Causes
–Pointer overwrite
–Free block containing pointer
–Stack shrinks
•Important information:
–Allocation site of block
–Location where last pointer is lost
–Assignment location of last pointer
Logical Leaks
•What
–Reachable pointer available, but block never freed
•Important information
–Allocation site of block
–Where are these pointers?
Filed under: Debugging | Leave a comment »