Setting Up An Exploit.

Exploits Are Created.

Exploits are created by humans, through consequences of errors, unintended functionality, or by construction.  In our case the we are constructing exploits so that we can explore how they work.  Well Jon Erickson constructed the exploits and we are playing around with the ones he constructed.  These exploits have been included in simple programs that have illustrated the concept of a buffer overflow nicely.  Now we are going to gradually increase the complexity of the programs (not by much but still a little more is going on).  We are going to set the stage for an introduction to using shell code and exploiting the heap.

First Program.

We are going to take a look at the notetaker.c and notesearch.c programs from HTAE.  Lets look at the notetaker.c program first:

//A program that writes data to a file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include "hacking.h"

//function to display an error message and exit program if no args
void usage(char *prog_name, char *filename) {
    printf("Usage: %s \n", prog_name, filename);
    exit(0);
}

void fatal(char *);
void *ec_malloc(unsigned in);

int main(int argc, char *argv[]) {
    int userid, fd;
    char *buffer, *datafile;

    buffer = (char *) ec_malloc(100);
    datafile = (char *) ec_malloc(20);
    strcpy(datafile, "/var/notes");

    if(argc < 2)                        //If no args invoke usage fctn.
        usage(argv[0], datafile);

    strcpy(buffer, argv[1]);            //copy cmd arg to buffer

    printf("[DEBUG] buffer      @ %p: \'%s\'\n", buffer, buffer);
    printf("[DEBUG] datafile    @ %p: \'%s\'\n", datafile, datafile);

    //Open the file write only, create if doesn't exist, append to file.
    fd = open(datafile, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
    if(fd == -1)                                    //Check if file opened.
        fatal("in main() while opening file");      //if not call error fct.
    printf("[DEBUG] file descriptor is %d\n", fd);

    userid = getuid();                              //Get the real UID.

    //Writing Data
    if(write(fd, buffer, strlen(buffer)) == -1)     //Write user ID before note data
        fatal("in main() while writing userid to file");
    write(fd, "\n", 1);                             //terminate the line

    //Close the file
    if(close(fd) == -1)
        fatal("in main() while closing file");

    printf("Note has been saved.\n");
    free(buffer);
    free(datafile);
}

I like this program as an introduction to some operations in the C programming language.  The first thing we are doing is including a custom header file that provides some error functionality and error checking for the malloc function.  To get the program to work on a modern Linux distro we have to include unistd.h to get the getuid() function.  If you haven’t included the proper header file you will get an error on compilation.

The functionality of the program is pretty straightforward.   We pass a command line argument that is written into a data file on our system at “/var/notes”.  The flags we pass to the open() function specifies that we are opening the file as write only, create it if it doesn’t exist, and append the new information to the end of the file.  The second set of flags are file permissions.  Most of the program is actually checking that the operations on the file are successful, and if not present the user with an error message.

The one thing that we haven’t seen in the blog here is malloc.  The malloc function is used to allocate memory in the heap.

The Heap.

The heap is another section of memory for a program in execution.  Like the stack it holds memory for variables.  Unlike the stack the heap is programmer controlled and grows upwards towards the stack instead of downward.  Like the stack the heap is vulnerable to exploits.  We will explore one of those exploits later when we have things all set up.

In our program we see two calls to ec_malloc.  This is the error checking malloc function in “hacking.h”.  This function determines if the malloc function succeeded by using a generic pointer to check that the memory address returned by malloc is not NULL.  If it is it notifies the user that the allocation failed.  We see that at the end of our program we release the memory as well.  If we fail to release the memory we end up getting a memory leak.

In addition to this program we will use a second program that interacts with it.

Second Program.

//A program to search a file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include "hacking.h"

#define FILENAME "/var/notes"

int print_notes(int, int, char*);                //Note Printing Function
int find_user_note(int, int);                   //Seek a user note
int search_note(char *, char *);                //Search for keyword
void fatal(char *);                             //Fatal error from hacking.

int main(int argc, char *argv[]) {
    int userid, printing=1, fd;
    char searchstring[100];

    if(argc > 1)                                //check for cmd arg.
        strcpy(searchstring, argv[1]);          //cmd arg is searchstring
    else 
        searchstring[0] = 0;                    //else no searchstring

    userid = getuid();                          //Get the user id.
    fd = open(FILENAME, O_RDONLY);              //Open /var/notes read only
    if(fd == -1)                                //if opening fails.
        fatal("in main() while opening file");

    while(printing)
        printing = print_notes(fd, userid, searchstring);
    printf("-------[ end of note data ]-------\n");
    close(fd);
}

/*A function to print the notes for a given uid that match
  an optional search string;
  returns 0 at end of file, 1 if there are still more notes*/
int print_notes(int fd, int uid, char *searchstring) {
    int note_length;
    char byte=0, note_buffer[100];              

    note_length = find_user_note(fd, uid);
    if(note_length == -1)                       //if the end of file return 0.
        return 0;

    read(fd, note_buffer, note_length);         //Read note data
    note_buffer[note_length] = 0;  

    if(search_note(note_buffer, searchstring))
        printf(note_buffer);                    //print buffer if search matches
    
    return 1;
}

/*A function to find the next note for a given uid.
  returns -1 if the EOF is reached.  Otherwise returns length of note.*/
int find_user_note(int fd, int user_id) {
    int note_uid = -1;
    unsigned char byte;
    int length;

    while(note_uid != user_id) {
        if(read(fd, &note_uid, 4) != 4)         //Read the uid data
            return -1;                          //if 4 bytes not read return EOF
        if(read(fd, &byte, 1) != 1)             //Read the newline separater.
            return -1;                          
        
        byte = length = 0;
        while(byte != '\n') {                   //Determin bytes to EOL.
            if(read(fd, &byte, 1) != 1)         //read a single byte.
                return -1;                      //If not read return EOF
            length++;
        }
    }
    lseek(fd, length * -1, SEEK_CUR);           //rewind file reading by byte lngt

    printf("[DEBUG] found a %d byte note fo user id %d\n", length, note_uid);
    return length;
}

/*A function to search a note for a given keyword;
  returns 1 if match found, 0 if there isno match */
int search_note(char *note, char *keyword) {
    int i, keyword_length, match=0;

    keyword_length = strlen(keyword);
    if(keyword_length == 0)                     //If no search always match
        return 1;

    for(i=0; i < strlen(note); i++) {           //iterate over note bytes
        if(note[i] == keyword[match])           //if bytes match keyword
            match++;                            //get ready to check next byte
        else {                                  
            if(note[i] == keyword[0])           //if that byte matches first kw
                match = 1;                      //start match at 1
            else
                match = 0;                      //set match to 0 otherwise
        }
        if(match == keyword_length)             //if there is a full match
            return 1;                           //return matched.
    }
    return 0;
}

The comments of the code explain what is happening at each stage of the program.  The program is pretty straightforward.  However we should be able to see some vulnerabilities in the program on first examination.  There right at the beginning is strcpy which will copy unverified command line arguments into the searchstring buffer.

Getting Things Running.

If we just try to run the  notetaker.c program without taking some additional steps we end up getting an error.  As we can see from the output:

./notetaker "This is a test"
[DEBUG] buffer      @ 0x804a008: 'This is a test'
[DEBUG] datafile    @ 0x804a070: '/var/notes'
[!!] Fatal Error in main() while opening file: Permission denied

So what went wrong here? In this program we are accessing a file, and if the file doesn’t exist we are trying to create it. We don’t necessarily have the permission to do those operations on the system. To fix this problem we need to change the ownership and permissions of the file. To do that we use the chown and chmod commands.  After running those commands changing the owner to root and permissions to u+s we are able to run the program as it should be run.

$ ./notetaker "this is a test of multiuser notes"
[DEBUG] buffer      @ 0x804a008: 'this is a test of multiuser notes'
[DEBUG] datafile    @ 0x804a070: '/var/notes'
[DEBUG] file descriptor is 3
Note has been saved.

What we have done is taken the executable and made it run as root every time it is invoked. Which is not necessarily a good thing in general.

Assembly

We can now take a look at the assembly dump of the notetaker program. We have added some new functionality we didn’t see before so our assembly dump should be a bit more complicated.

Dump of assembler code for function main:
   0x080486ea <+0>:     lea    ecx,[esp+0x4]
   0x080486ee <+4>:     and    esp,0xfffffff0
   0x080486f1 <+7>:     push   DWORD PTR [ecx-0x4]
   0x080486f4 <+10>:    push   ebp
   0x080486f5 <+11>:    mov    ebp,esp
   0x080486f7 <+13>:    push   ebx
   0x080486f8 <+14>:    push   ecx
   0x080486f9 <+15>:    sub    esp,0x10
   0x080486fc <+18>:    mov    ebx,ecx
   0x080486fe <+20>:    sub    esp,0xc
   0x08048701 <+23>:    push   0x64
   0x08048703 <+25>:    call   0x8048692 
   0x08048708 <+30>:    add    esp,0x10
   0x0804870b <+33>:    mov    DWORD PTR [ebp-0xc],eax
   0x0804870e <+36>:    sub    esp,0xc
   0x08048711 <+39>:    push   0x14
   0x08048713 <+41>:    call   0x8048692 
   0x08048718 <+46>:    add    esp,0x10
   0x0804871b <+49>:    mov    DWORD PTR [ebp-0x10],eax
   0x0804871e <+52>:    mov    eax,DWORD PTR [ebp-0x10]
   0x08048721 <+55>:    mov    DWORD PTR [eax],0x7261762f
   0x08048727 <+61>:    mov    DWORD PTR [eax+0x4],0x746f6e2f
   0x0804872e <+68>:    mov    WORD PTR [eax+0x8],0x7365
   0x08048734 <+74>:    mov    BYTE PTR [eax+0xa],0x0
   0x08048738 <+78>:    cmp    DWORD PTR [ebx],0x1
   0x0804873b <+81>:    jg     0x8048751 <main+103>
   0x0804873d <+83>:    mov    eax,DWORD PTR [ebx+0x4]
   0x08048740 <+86>:    mov    eax,DWORD PTR [eax]
   0x08048742 <+88>:    sub    esp,0x8
   0x08048745 <+91>:    push   DWORD PTR [ebp-0x10]
   0x08048748 <+94>:    push   eax
   0x08048749 <+95>:    call   0x80486c4 
   0x0804874e <+100>:   add    esp,0x10
   0x08048751 <+103>:   mov    eax,DWORD PTR [ebx+0x4]
   0x08048754 <+106>:   add    eax,0x4
   0x08048757 <+109>:   mov    eax,DWORD PTR [eax]
   0x08048759 <+111>:   sub    esp,0x8
   0x0804875c <+114>:   push   eax
   0x0804875d <+115>:   push   DWORD PTR [ebp-0xc]
   0x08048760 <+118>:   call   0x8048490 <strcpy@plt>
   0x08048765 <+123>:   add    esp,0x10
   0x08048768 <+126>:   sub    esp,0x4
   0x0804876b <+129>:   push   DWORD PTR [ebp-0xc]
   0x0804876e <+132>:   push   DWORD PTR [ebp-0xc]
   0x08048771 <+135>:   push   0x8048960
---Type  to continue, or q  to quit---
   0x08048776 <+140>:   call   0x8048450 <printf@plt>
   0x0804877b <+145>:   add    esp,0x10
   0x0804877e <+148>:   sub    esp,0x4
   0x08048781 <+151>:   push   DWORD PTR [ebp-0x10]
   0x08048784 <+154>:   push   DWORD PTR [ebp-0x10]
   0x08048787 <+157>:   push   0x8048980
   0x0804878c <+162>:   call   0x8048450 <printf@plt>
   0x08048791 <+167>:   add    esp,0x10
   0x08048794 <+170>:   sub    esp,0x4
   0x08048797 <+173>:   push   0x180
   0x0804879c <+178>:   push   0x441
   0x080487a1 <+183>:   push   DWORD PTR [ebp-0x10]
   0x080487a4 <+186>:   call   0x80484e0 <open@plt>
   0x080487a9 <+191>:   add    esp,0x10
   0x080487ac <+194>:   mov    DWORD PTR [ebp-0x14],eax
   0x080487af <+197>:   cmp    DWORD PTR [ebp-0x14],0xffffffff
   0x080487b3 <+201>:   jne    0x80487c5 <main+219>
   0x080487b5 <+203>:   sub    esp,0xc
   0x080487b8 <+206>:   push   0x80489a0
   0x080487bd <+211>:   call   0x804863b 
   0x080487c2 <+216>:   add    esp,0x10
   0x080487c5 <+219>:   sub    esp,0x8
   0x080487c8 <+222>:   push   DWORD PTR [ebp-0x14]
   0x080487cb <+225>:   push   0x80489c0
   0x080487d0 <+230>:   call   0x8048450 <printf@plt>
   0x080487d5 <+235>:   add    esp,0x10
   0x080487d8 <+238>:   call   0x8048470 <getuid@plt>
   0x080487dd <+243>:   mov    DWORD PTR [ebp-0x18],eax
   0x080487e0 <+246>:   sub    esp,0xc
   0x080487e3 <+249>:   push   DWORD PTR [ebp-0xc]
   0x080487e6 <+252>:   call   0x80484f0 <strlen@plt>
   0x080487eb <+257>:   add    esp,0x10
   0x080487ee <+260>:   sub    esp,0x4
   0x080487f1 <+263>:   push   eax
   0x080487f2 <+264>:   push   DWORD PTR [ebp-0xc]
   0x080487f5 <+267>:   push   DWORD PTR [ebp-0x14]
   0x080487f8 <+270>:   call   0x8048510 <write@plt>
   0x080487fd <+275>:   add    esp,0x10
   0x08048800 <+278>:   cmp    eax,0xffffffff
   0x08048803 <+281>:   jne    0x8048815 <main+299>
   0x08048805 <+283>:   sub    esp,0xc
   0x08048808 <+286>:   push   0x80489e0
   0x0804880d <+291>:   call   0x804863b 
   0x08048812 <+296>:   add    esp,0x10
   0x08048815 <+299>:   sub    esp,0x4
   0x08048818 <+302>:   push   0x1
---Type  to continue, or q  to quit---
   0x0804881a <+304>:   push   0x8048a07
   0x0804881f <+309>:   push   DWORD PTR [ebp-0x14]
   0x08048822 <+312>:   call   0x8048510 <write@plt>
   0x08048827 <+317>:   add    esp,0x10
   0x0804882a <+320>:   sub    esp,0xc
   0x0804882d <+323>:   push   DWORD PTR [ebp-0x14]
   0x08048830 <+326>:   call   0x8048520 <close@plt>
   0x08048835 <+331>:   add    esp,0x10
   0x08048838 <+334>:   cmp    eax,0xffffffff
   0x0804883b <+337>:   jne    0x804884d <main+355>
   0x0804883d <+339>:   sub    esp,0xc
   0x08048840 <+342>:   push   0x8048a09
   0x08048845 <+347>:   call   0x804863b 
   0x0804884a <+352>:   add    esp,0x10
   0x0804884d <+355>:   sub    esp,0xc
   0x08048850 <+358>:   push   0x8048a26
   0x08048855 <+363>:   call   0x80484b0 <puts@plt>
   0x0804885a <+368>:   add    esp,0x10
   0x0804885d <+371>:   sub    esp,0xc
   0x08048860 <+374>:   push   DWORD PTR [ebp-0xc]
   0x08048863 <+377>:   call   0x8048460 <free@plt>
   0x08048868 <+382>:   add    esp,0x10
   0x0804886b <+385>:   sub    esp,0xc
   0x0804886e <+388>:   push   DWORD PTR [ebp-0x10]
   0x08048871 <+391>:   call   0x8048460 <free@plt>
   0x08048876 <+396>:   add    esp,0x10
   0x08048879 <+399>:   lea    esp,[ebp-0x8]
   0x0804887c <+402>:   pop    ecx
   0x0804887d <+403>:   pop    ebx
   0x0804887e <+404>:   pop    ebp
   0x0804887f <+405>:   lea    esp,[ecx-0x4]
   0x08048882 <+408>:   ret    
End of assembler dump.

As expected there’s a lot more there.  When I first saw this I started working at trying to figure out what structures in the assembly dump corresponded to the C program code.  Fortunately for us gdb has a nice feature that will mix the C code with the assembly dump.  Using the /m flag on disass main and we get a nice readable output that takes the guesswork out of identifying what assembly code goes with what C code.

(gdb) disass /m main
Dump of assembler code for function main:
19      int main(int argc, char *argv[]) {
   0x080486ea <+0>:     lea    ecx,[esp+0x4]
   0x080486ee <+4>:     and    esp,0xfffffff0
   0x080486f1 <+7>:     push   DWORD PTR [ecx-0x4]
   0x080486f4 <+10>:    push   ebp
   0x080486f5 <+11>:    mov    ebp,esp
   0x080486f7 <+13>:    push   ebx
   0x080486f8 <+14>:    push   ecx
   0x080486f9 <+15>:    sub    esp,0x10
   0x080486fc <+18>:    mov    ebx,ecx

20          int userid, fd;
21          char *buffer, *datafile;
22
23          buffer = (char *) ec_malloc(100);
   0x080486fe <+20>:    sub    esp,0xc
   0x08048701 <+23>:    push   0x64
   0x08048703 <+25>:    call   0x8048692 
   0x08048708 <+30>:    add    esp,0x10
   0x0804870b <+33>:    mov    DWORD PTR [ebp-0xc],eax

24          datafile = (char *) ec_malloc(20);
   0x0804870e <+36>:    sub    esp,0xc
   0x08048711 <+39>:    push   0x14
   0x08048713 <+41>:    call   0x8048692 
   0x08048718 <+46>:    add    esp,0x10
   0x0804871b <+49>:    mov    DWORD PTR [ebp-0x10],eax

25          strcpy(datafile, "/var/notes");
   0x0804871e <+52>:    mov    eax,DWORD PTR [ebp-0x10]
   0x08048721 <+55>:    mov    DWORD PTR [eax],0x7261762f
   0x08048727 <+61>:    mov    DWORD PTR [eax+0x4],0x746f6e2f
   0x0804872e <+68>:    mov    WORD PTR [eax+0x8],0x7365
   0x08048734 <+74>:    mov    BYTE PTR [eax+0xa],0x0

26                                                                                                                                                                 
27          if(argc < 2)                        //If no args invoke usage fctn.                                                                                    
   0x08048738 <+78>:    cmp    DWORD PTR [ebx],0x1                                                                                                                 
   0x0804873b <+81>:    jg     0x8048751 <main+103>                                                                                                                
                                                                                                                                                
28              usage(argv[0], datafile);                                                                                                       
   0x0804873d <+83>:    mov    eax,DWORD PTR [ebx+0x4]                                                                                          
   0x08048740 <+86>:    mov    eax,DWORD PTR [eax]
   0x08048742 <+88>:    sub    esp,0x8
   0x08048745 <+91>:    push   DWORD PTR [ebp-0x10]
---Type  to continue, or q  to quit---
   0x08048748 <+94>:    push   eax
   0x08048749 <+95>:    call   0x80486c4 
   0x0804874e <+100>:   add    esp,0x10

29
30          strcpy(buffer, argv[1]);            //copy cmd arg to buffer
   0x08048751 <+103>:   mov    eax,DWORD PTR [ebx+0x4]
   0x08048754 <+106>:   add    eax,0x4
   0x08048757 <+109>:   mov    eax,DWORD PTR [eax]
   0x08048759 <+111>:   sub    esp,0x8
   0x0804875c <+114>:   push   eax
   0x0804875d <+115>:   push   DWORD PTR [ebp-0xc]
   0x08048760 <+118>:   call   0x8048490 <strcpy@plt>
   0x08048765 <+123>:   add    esp,0x10

31
32          printf("[DEBUG] buffer      @ %p: \'%s\'\n", buffer, buffer);
   0x08048768 <+126>:   sub    esp,0x4
   0x0804876b <+129>:   push   DWORD PTR [ebp-0xc]
   0x0804876e <+132>:   push   DWORD PTR [ebp-0xc]
   0x08048771 <+135>:   push   0x8048960
   0x08048776 <+140>:   call   0x8048450 <printf@plt>
   0x0804877b <+145>:   add    esp,0x10

33          printf("[DEBUG] datafile    @ %p: \'%s\'\n", datafile, datafile);
   0x0804877e <+148>:   sub    esp,0x4
   0x08048781 <+151>:   push   DWORD PTR [ebp-0x10]
   0x08048784 <+154>:   push   DWORD PTR [ebp-0x10]
   0x08048787 <+157>:   push   0x8048980
   0x0804878c <+162>:   call   0x8048450 <printf@plt>
   0x08048791 <+167>:   add    esp,0x10

34
35          //Open the file write only, create if doesn't exist, append to file.
36          fd = open(datafile, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
   0x08048794 <+170>:   sub    esp,0x4
   0x08048797 <+173>:   push   0x180
   0x0804879c <+178>:   push   0x441
   0x080487a1 <+183>:   push   DWORD PTR [ebp-0x10]
   0x080487a4 <+186>:   call   0x80484e0 <open@plt>
   0x080487a9 <+191>:   add    esp,0x10
   0x080487ac <+194>:   mov    DWORD PTR [ebp-0x14],eax

37          if(fd == -1)              //Check if file open---Type  to continue, or q  to quit---
   0x080487af <+197>:   cmp    DWORD PTR [ebp-0x14],0xffffffff
   0x080487b3 <+201>:   jne    0x80487c5 <main+219>

38              fatal("in main() while opening file");      //if not call error fct.
   0x080487b5 <+203>:   sub    esp,0xc
   0x080487b8 <+206>:   push   0x80489a0
   0x080487bd <+211>:   call   0x804863b 
   0x080487c2 <+216>:   add    esp,0x10

39          printf("[DEBUG] file descriptor is %d\n", fd);
   0x080487c5 <+219>:   sub    esp,0x8
   0x080487c8 <+222>:   push   DWORD PTR [ebp-0x14]
   0x080487cb <+225>:   push   0x80489c0
   0x080487d0 <+230>:   call   0x8048450 <printf@plt>
   0x080487d5 <+235>:   add    esp,0x10

40
41          userid = getuid();                              //Get the real UID.
   0x080487d8 <+238>:   call   0x8048470 <getuid@plt>
   0x080487dd <+243>:   mov    DWORD PTR [ebp-0x18],eax

42
43          //Writing Data
44          if(write(fd, buffer, strlen(buffer)) == -1)     //Write user ID before note data
   0x080487e0 <+246>:   sub    esp,0xc
   0x080487e3 <+249>:   push   DWORD PTR [ebp-0xc]
   0x080487e6 <+252>:   call   0x80484f0 <strlen@plt>
   0x080487eb <+257>:   add    esp,0x10
   0x080487ee <+260>:   sub    esp,0x4
   0x080487f1 <+263>:   push   eax
   0x080487f2 <+264>:   push   DWORD PTR [ebp-0xc]
   0x080487f5 <+267>:   push   DWORD PTR [ebp-0x14]
   0x080487f8 <+270>:   call   0x8048510 <write@plt>
   0x080487fd <+275>:   add    esp,0x10
   0x08048800 <+278>:   cmp    eax,0xffffffff
   0x08048803 <+281>:   jne    0x8048815 <main+299>

45              fatal("in main() while writing userid to file");
   0x08048805 <+283>:   sub    esp,0xc
   0x08048808 <+286>:   push   0x80489e0
   0x0804880d <+291>:   call   0x804863b 
   0x08048812 <+296>:   add    esp,0x10

---Type  to continue, or q  to quit---
46          write(fd, "\n", 1);                             //terminate the line
   0x08048815 <+299>:   sub    esp,0x4
   0x08048818 <+302>:   push   0x1
   0x0804881a <+304>:   push   0x8048a07
   0x0804881f <+309>:   push   DWORD PTR [ebp-0x14]
   0x08048822 <+312>:   call   0x8048510 <write@plt>
   0x08048827 <+317>:   add    esp,0x10

47
48          //Close the file
49          if(close(fd) == -1)
   0x0804882a <+320>:   sub    esp,0xc
   0x0804882d <+323>:   push   DWORD PTR [ebp-0x14]
   0x08048830 <+326>:   call   0x8048520 <close@plt>
   0x08048835 <+331>:   add    esp,0x10
   0x08048838 <+334>:   cmp    eax,0xffffffff
   0x0804883b <+337>:   jne    0x804884d <main+355>

50              fatal("in main() while closing file");
   0x0804883d <+339>:   sub    esp,0xc
   0x08048840 <+342>:   push   0x8048a09
   0x08048845 <+347>:   call   0x804863b 
   0x0804884a <+352>:   add    esp,0x10

51
52          printf("Note has been saved.\n");
   0x0804884d <+355>:   sub    esp,0xc
   0x08048850 <+358>:   push   0x8048a26
   0x08048855 <+363>:   call   0x80484b0 <puts@plt>
   0x0804885a <+368>:   add    esp,0x10

53          free(buffer);
   0x0804885d <+371>:   sub    esp,0xc
   0x08048860 <+374>:   push   DWORD PTR [ebp-0xc]
   0x08048863 <+377>:   call   0x8048460 <free@plt>
   0x08048868 <+382>:   add    esp,0x10

54          free(datafile);
   0x0804886b <+385>:   sub    esp,0xc
   0x0804886e <+388>:   push   DWORD PTR [ebp-0x10]
   0x08048871 <+391>:   call   0x8048460 <free@plt>
   0x08048876 <+396>:   add    esp,0x10

55      }
   0x08048879 <+399>:   lea    esp,[ebp-0x8]
---Type  to continue, or q  to quit---
   0x0804887c <+402>:   pop    ecx
   0x0804887d <+403>:   pop    ebx
   0x0804887e <+404>:   pop    ebp
   0x0804887f <+405>:   lea    esp,[ecx-0x4]
   0x08048882 <+408>:   ret    

End of assembler dump.

This is a much nicer output for matching assembly code to program code.  I especially like how we can directly look at where malloc() allocates the memory in the heap.

Next Time.

Next time we will continue discussing this set of programs.  We will get an introduction to shellcode and look at what hexdump is.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s