The goal is to call the function foo in the following program:
struct object {
unsigned char buf[36];
void (*fp)();
};
void baz(struct object * obj, unsigned int num) {
for (int i = 0; i < num; i++) {
unsigned int x;
scanf("%d", &x);
if (x == 0) break;
obj->buf[i] = x & 0x000000ff;
}
}
void foo() { // target
}
void bar() {
}
int main() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
struct object * obj = malloc(sizeof(struct object));
memset(obj->buf, 0, 36);
obj->fp = &bar;
int num;
scanf("%d", &num);
if (num > 36) {
num = 0;
} else {
baz(obj, num);
}
for (int i = 0; i < num; i++) {
printf("%d. \t", i + 1);
for (int j = 0; j < obj->buf[i]; j++) {
printf("*");
}
puts("");
}
obj->fp();
free(obj);
}
My thoughts were to modify fp in obj (which is called at the end) such that it points to foo instead of bar. By entering a negative number for num such that it becomes a large positive number when casted to unsigned int in baz, this should allow the modification of fp by overflowing buf in obj. However, this would require the address of foo which changes every time the program is run.
I would appreciate any ideas or hints to solve this problem.
EDIT: This is a homework question.
scanf. – wayne Apr 01 '20 at 12:13foo()andbar()are placed relatively to each other? – Apr 01 '20 at 12:34&foo + 0x37 = &baron every run (although the addresses themselves change). – wayne Apr 01 '20 at 13:14