I’m trying to see how format string bug works and tried to explore it by myself.
This is a simple program:
#include"stdio.h"
#include"string.h"
struct mystruct{
char buf[32];
int num;
};
typedef struct mystruct *mys;
void myfunction2(){
struct mystruct struct1;
mys p1 = &struct1;
p1->num = 43981;
strcpy(p1->buf,"caaaaaaaaaaaaaaaaaaaaaaaaaaaaac"); // there are 31 characters in order to fit the
printf("%x %x %x %x %x %x %x %x %x %x %x %x");
}
int main(int argc, char *argv[]){
myfunction2();
return 0;
}
Output:
61616161 61616163 61616161 ff78bf10 ff7b6040 61616163 61616161 61616161 61616161 abcd fffedfb0 fffee000
What is “ff78bf10 ff7b6040” doing in there? And why isn’t “61616163” (“caaa” in hex) at the start and end of the string but is at random places?
I expected to see 61616163
at the start and end of the string.
I also expected a 63616161
to appear since it starts with a c and ends with a c.
I didn’t expect to see random stuff in the middle of my string bytes.
4
printf("%x %x %x %x %x %x %x %x %x %x %x %x");
asks printf
to print 12 unsigned int
values but does not pass it those values. In a typical situation, in the absence of interference from optimization and other factors, printf
will nonetheless retrieve values from where the arguments should have been passed.
Probably, in your C implementation, the first several of those arguments would be passed in CPU registers, and the remaining arguments would be passed on the stack. So printf
gets values from those places. They hold data leftover from earlier actions in your program. printf
is printing this data, and it is not particularly informative.