Assignment 1, solutions

Part of the homework for 22C:169, Spring 2007
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

Always, on every assignment, please write your name legibly as it appears on your University ID and on the class list! All assignments will be due at the start of class on the day indicated (usually a Friday), and unless there is what insurance companies call "an act of God" - something outside your control; the only exceptions to this rule will be by advance arrangement.

  1. What is your E-mail address?

    No answer provided.

    Real Homework!

  2. Name that compiler and identify the computer system on which it works. (1 point)

    You had to specify the compiler's name e.g. "gcc" or "cc" for the CS department machines. You also had to specify the name of the operating system that the machine,on which you compiled the programs, uses, for instance Linux or Unix or Windows etc.

  3. Compile and run the C Hello World program from lecture 2. Change the program so that it contains a comment giving your name and so that it outputs your name instead of the string Hello World. Turn in a legible printed copy of this modified program. (1 point)

    Ans 3: The following is the changed "Hello World" program that would be sufficient for the purpose of this answer.

    /* Hello.c */
    
    /********************************************
     * How to write a Hello World program in C  *
     * Author:  Prof. Douglas Jones             *
     * Revised by:  Alankar Kampoowale          *
     * The comments have been added to indicate *
     * how to enable better readability.        *
     *******************************************/
    #include <stdio.h>
    
    int main()                           // the "main" function
    { 
        printf("Alankar Kampoowale\n");  // this line prints my name
        return 0; /* indicates success */
    }
    

  4. Modify the program so that it outputs, in hexadecimal, the bytes of your string instead of outputting them as characters. To output the character ch in hex using C, use printf("%2x",ch). Add a blank space between each successive character for legibility. Again, turn in a legible printed copy. (1 point)
    /* Hex.c */
    
    /********************************************
     * How to print a string's characters in hex*
     * Author: Alankar Kampoowale               *
     * The comments have been added to indicate *
     * how to enable better readability.        *
     *******************************************/
    #include <stdio.h>
    
    int main()
    {
        /* the string, the characters of which, will be printed in hex */
        char myname[] = "Alankar Kampoowale\n";
        int i = 0;                      /* the counter used for the while loop */
        while(myname[i] != '\0') {
            /* print out one byte of my name, in hex, per itereation */
            printf("%2x ",myname[i]);
            i++; 
        }                                 
        return 0; /* indicates success */
    }
    

  5. Figure out how to modify the object file! This is certainly possible with object files on the CS department's Linux systems (I tested it), so that your name is corrupted by replacing it with a string of exactly the same length. In the extreme case, it can always be done by writing a little program that reads in the object file, modifies it, and writes it out, but the UNIX sed utility can be made to do this for you. Report on your methodology, giving details of how you did it. (1 point)
    The following simple commands replace the string "Hello" in object file "Hello.out" with the string "H...o" and make the contents of "Hello.out" with the changes get stored in "CHello.out". The file "Hello.out" itself remains unchanged. After the changing of the mode of the file "CHello.out" to enable it to be executed, the string "Hello" doesn't appear in the output. It is globally replaced by "H...o".
    $ sed 's/Hello/H...o/g' < Hello.out > CHello.out 
    $ chmod +x CHello.out
    $ ./CHello.out
    H...o World! 
    

    To get full credit for this problem you had to provide the actual command(s) (if it was a Unix utility) being used e.g.sed, with the parameters passed to it (as shown in the first command in the above series of commands). If after running the command with the parameters the expected outcome was not obtained, some points were taken off. Also, according to the question, the object files had to be modified and NOT the C program files. Some points were deducted if this was your solution.

    If you were using some other methodology such as a self written program, you had to submit it too, to provide a definitive indicator to the extent upto which you were successful in solving the problem. If you did not submit the program, a major portion of points was deducted.

  6. Write a C or C++ function that prints out the return address of its caller, in hex. You'll have to write the function so it prints out a range of addresses, then call it several times to see what address is the return address, then narrow the range so it prints only the return address. Print out and turn in your finished function. Make sure you document what version of C or C++ it is tuned to work with. (1 point)
    #include <stdio.h>
    #include <stdlib.h>
    
    void wrongplace() {
            printf("We got to the wrong place\n");
            exit(0);
    }
    
    /* offset into stack to probe */
    int offset;
    void probe() {
            char * p;    /* The pointer that acts as an array */
            int ret_add; /* stores the values stored at specific locations? */
            p = (char *)&p; 
            printf("p:%x\n ",p);  /* The address pointed to by p */
            printf("The return address is:%x\n",*(int *)(&p[offset]));
    
            /* We've printed what we hope is the return address.
               This will be the return address if the offset is correct.
               Many people printed out the address of the location p[offset], 
               but did not go one step further to print the value stored there.
               Unless the return address was printed, full points were not given.
            */
                                             
            *(void **)(&p[offset]) = (void *)wrongplace;
            /* Changing the value at p[offset]. This will result in the 
               wrong return from probe when the offset is correct. */
    }
    
    int main(int args, char * argv[]) {
            offset = 8;
            /* The above line assigns a hardcoded value that was adjusted by
               experiment until the program returned to the wrong place.
               The value of correct offset will differ depending on the compiler
               and operating system.
            */
            /* offset = atoi(argv[1]); */
            /* the above alternative line could be used to simplify experiments */
            printf("offset: %d\n",offset);
            probe();
            puts("No damage\n");
    }