| CompOrg Spring 2004 Lab |
|   CompOrg Home   |   p1   |   p2   |   p3 |
The files p1.s, p2.s, etc. are also
available on monte.cs.rpi.edu in ~hollingd/public/lab7:
> mkdir lab7 > cp ~hollingd/public/lab7/* lab7 > cd lab7
The progam shown below defines a C struct named "list". A list
structure includes and array of 10 integers and a count. The count
(the field n) represents the number of items in the
array, 10 is just the maximum.
You jobs is to write a function named listsum that
computes the sum of a list (the sum of the first n n
integers in the array vals) in assembly language. The C
code below can be converted to assembly with "gcc -S", then edit the
function named listsum (with the C prototype shown).
Want something harder (not really harder, but a little different)?
Try writing the function lsum that does the same thing as
listsum, but has a parameter that is a structure, not a
pointer to a structure (the entire structure is passed on the stack).
| p1.c |
/* C Structure Lab */
#include <stdio.h>
/* A list structure holds an array of up to 10 integers,
n is the number of integers in the list.
*/
typedef struct list {
int vals[10];
int n;
} list;
/* listsum returns the sum of a list
you need to write this! (in assembly).
*/
int listsum(list *l) {
/* your code goes here */
return(0);
}
/* Harder version (optional) - the parameter is an actual
struct (not a pointer to a struct). Use gcc to
see what is passed and how!
int lsum(list l) {
return(0);
}
*/
int main(){
int i;
list x;
for (i=0;i<5;i++)
x.vals[i]=i;
x.n=5;
printf("Sum of list is %d\n",
listsum(&x));
/* call to optional function
printf("Sum of list is %d\n",
lsum(x));
*/
}
|
The is the code we worked on in class yesterday, the idea here is just to repeat what we did in class - use GDB to replace the return address used by the function blah, so that it jumps to the function named wizard().
| p2.c |
/* Use GDB to get this program to print "You are a wizard"
(we did this in class yesterday!).
Notes:
1. set a breakpoint in blah
2. run (until the above breakpoint)
3. determine the address of the function wizard()
4. find out where the return address is located in memory.
The return address will be the address of the
"return(1)" statement in main.
5. replace the return address with the address of wizard().
6. continue the program in gdb ("continue"), and verify that
it prints out "You are a wizard".
*/
#include <stdio.h>
void wizard() {
printf("You are a wizard\n");
}
void blah() {
int x,y;
x = y + 3;
}
int main(){
blah();
return(1);
}
|
Below is a program similar to the one above, the main difference is
that blah() has a potential buffer overflow, and
main() reads a string from standard input that is passed
to blah(). Your job is (once again) to make this program
print "You are a wizard", but here you run the program and feed it a
string that causes this behavior (overflows the buffer in
blah and replaces the return address with a new one).
| p3.c |
/* Similar to p2.c, but now blah has a potential
overflow you must exploit. You need to create
a string which when read (via stdin by main),
will cause this progam to print "You are a wizard".
Notes:
The string that overflows the buffer must have the
new return address in the right place (so it overwrites
the real return address). The actual values placed in the
buffer are irrelevant (only the new return address is important).
Use gdb to find the number of bytes of padding you need to
put in your string.
*/
#include <stdio.h>
void wizard() {
printf("You are a wizard\n");
}
void blah(char *s) {
char buff[12];
strcpy(buff,s);
}
/* main calls read to get a string from stdin,
then passes the address of this string to blah.
You want to create a string that will cause blah
to "return to wizard()".
*/
int main(void) {
char x[10000];
read(0,x,2000);
blah(x);
printf("Done\n");
}
|
Important Note: You need some way to construct a string that can
be fed as input to this program. Write a program that generates the
string ! If your program is named genstring, you can test
it with: ./genstring | ./p3 Here is some code to get you
started, it prints all the byte values 1-255 to stdout:
/* writes the byte values 1-255 to stdout */
int main() {
int i;
unsigned char s[300];
for (i=1;i<=255;i++) {
s[i-1]=i;
}
/* write all 255 bytes to stdout */
write(1,s,255);
}
You may find the Unix program od (octal dump) useful,
it can display binary files in hex, decimal or octal. "man
od" for more info (or ask Dave).