Lab 4: Operating the Machine

In this lab you'll explore how your code gets executed on the machine and how a computer looks at data. Do this lab in PAIRS.

Goals:

  1. Compile some code on the Pi
  2. Deconstruct machine code
  3. Examine how the machine stores arrays

The lab is divided into two parts. The first part is intended to help you develop the skills needed to solve the problem in the second. The lab should be done in pairs on the Raspberry Pi in Linux. Only one lab writeup should be submitted in hardcopy. Ensure that both names are included on all submissions (electronic and hardcopy).

Before we Start:

We will walk through the first part of the lab together, as a class. Be sure you have your Pi connected and turned on.

Part 1:

We will walk through this together as a class.

  1. Examining a program

    • Look at part1.c using cat, less, vi, emacs (if you installed it) or nano.
    • Rescue keys (to escape from editors):
      • Emacs: <ctrl>-x <ctrl>-c
      • Vi: <Esc> <Esc> :q! and push return
      • Nano: <ctrl>-x
      • Less: q
  2. Compiling a program

    • gcc -S part1.c
    • Look at part1.s. What have we made?
  3. Assembling a program

    • gcc -c part1.s -o part1.o
    • The objdump -d <object to dump> might be helpful for inspecting programs. Look at part1.o using objdump. What have we made?
    • Look at part1.o using gdb:
     pi@my-pi$ gdb part1.o
     (gdb) disassemble main
     (gdb) q
    
    • But we can't run part1.o! Why not?
  4. Linking

    • Linux doesn't know how to run your code. Need to use some pre-compiled libraries to "start" it. Can use a linker. Or we can just have gcc do it for us.
  5. All in one step

    • gcc part1.c -o part1.o
    • Lets get a little more complicated: we'll tell GCC to add "debugger hints" to make gdb more useful.
    gcc -g part1.c -o part1.o
    
  6. Use make to do the work: Makefiles describe how to create things.

    • Look at Makefile. part1 is created using part1.c. The procedure is listed below the rule.
    • Running make part1 from the command line will run the Makefile in the local directory and build part1. Try this out.
  7. Looking at data in gdb

    • tui mode (gdb -tui part1)
    • disassemble (disassemble main)
    • list
    • breakpoints (b main or b file.c:line)
    • stepping through C (next, step)
    • running between breakpoints (continue)
    • examining the array using print: p array

Part 2:

In this part, you'll examine some C code, then try and break a program. After you've broken the program, you'll modify the C code so it is no longer fragile.

Before beginning, print out the Lab Question Sheet to answer the questions as you do this part of the lab.

  1. Examine part2.c What does it do? Lets find out: add a rule to your Makefile and compile part2.c into part2.

    • (Q2.1.1) What was code for the rule you added to the Makefile?
  2. Run part2 with one short argument AAA. You can do this by running ./part2 AAA. Now try with 100 A chars.

    • (Q2.2.1) What happens with AAA? What about with 100 A's?
  3. Try running the program with fewer A's until the program works. Your goal is to figure out the smallest number of A's that make the program mad. Write a script if you want to automate this, though writing a script is not required. (If you write a script, be sure to add it to SVN.)

    • (Q2.3.1) How many As were required to change the behavior? Does this surprise you?
  4. Modify part2.c to have a bigger buffer.

    • (Q2.4.1) Before you run the modified program, write down the size of your new buffer and how many A's you predict will be needed to break it.
    • Compile part2 again.
    • (Q2.4.2) How many A's did you need to break it? Does the result surprise you?
  5. Run the program one additional time, but this time use the alternate argument printed out by the program. This "alternate" value is constructed by the program by adding some stuff to the argument you gave it, and putting it in a single-quoted escape string.

    • (Q2.5.1) What happens now? Explain what you think the program did.

    (A single-quoted escape string looks like $'foo'. Your command line interprets back-slashes in that string and will change $'\x12' into the character with raw hexidecimal value 12. This means you can specify raw values instead of character values in the argument.)

    • (Q2.5.2) What was the name of the function that, while never explicitly called, gets executed?
  6. Run your program with the debugger: gdbtui ./part2. Set a breakpoint in copyIntoBuffer and run the program with run ARG, replacing ARG with your alternate value. Then step through lines of code until the program ends up in a function it never called.

    • (Q2.6.1) What happened right before the unexpected function started executing? (You can figure this out stepping through with gdb)

    • (Q2.6.2) What do you think caused the jump into the unexpected function?

    To figure out why this happened, try stepping through part2 in gdb with using various arguments: some that break the program, some that don't.

    • (Q2.6.3) Explain how you used GDB to make an educated guess about what happened.
  7. Open part2.c. Change copyIntoBuffer so it never copies more than the size of the buffer.

    • (Q2.7.1) What did you change to prevent "over-copying"?
    • compile part2
    • (Q2.7.2) Try to break it again. Can you make the program crash?

Finishing the lab

  1. Commit your code (including any changes to code provided to you) to SVN.
    • Make sure both of your names are in any code files you created or modified.
    • Add and commit your files to svn
    • Only one of you is required to commit the code into SVN, but you both may commit copies.
  2. Submit the Lab Question Sheet in hard copy to your instructor.