ChaptAddendum
以下はIPAのセキュアプログラミング講座からのパクリです。
肝はstack_dump()のところね
なにをやっているかといえば、hexdump -C と似たようなことをやってますね。
[hirasawa@ubunt1004-32-2 ~]$ cat stack_dump.c #include <stdio.h> #include <stdlib.h> #include <string.h> #define FILEPATH "msg_file.txt" int main(void); void vuln(const char* line); void stack_dump(void* ptr, int counts); void hello(); int main() { char linebuf[1024]; FILE *fp; long mark1 = 0x11111111; memset(linebuf, 0, sizeof(linebuf)); fp = fopen(FILEPATH, "r"); fgets(linebuf, sizeof(linebuf)-1, fp); fclose(fp); vuln(linebuf); printf("------------- end of main() -------------\n"); } void vuln(const char* line) { char msg[20]; long mark2 = 0x22222222; memset(msg, 0, sizeof(msg)); strcpy(msg, line); stack_dump(&mark2, 13); printf("INPUT[%s]\n", msg); } void stack_dump(void* ptr, int counts) { int i; unsigned long *ulong_ptr = (unsigned long *)ptr; unsigned char uchar_buf[4]; printf("-----------------------------------------\n"); printf(" address | long var | +0 +1 +2 +3 | 0123\n"); printf("-----------------------------------------\n"); for(i=0; i<counts; i++) { printf(" %08x| %08x", &ulong_ptr[i], ulong_ptr[i]); memcpy(uchar_buf, &ulong_ptr[i], sizeof(uchar_buf)); printf(" | %02x %02x %02x %02x", uchar_buf[0], uchar_buf[1], uchar_buf[2], uchar_buf[3]); if(uchar_buf[0]<32 || uchar_buf[0]>126) uchar_buf[0] = '.'; if(uchar_buf[1]<32 || uchar_buf[1]>126) uchar_buf[1] = '.'; if(uchar_buf[2]<32 || uchar_buf[2]>126) uchar_buf[2] = '.'; if(uchar_buf[3]<32 || uchar_buf[3]>126) uchar_buf[3] = '.'; printf(" | %c%c%c%c\n", uchar_buf[0], uchar_buf[1], uchar_buf[2], uchar_buf[3]); } printf("-----------------------------------------\n"); }
もう一個
関数へのポインターの備忘録
hirasawa@aspire-white:~$ cat func1.c #include <stdio.h> #include <stdlib.h> int func(const char * str) { printf("%s\n",str); return 0; } int main(void) { printf("func main addr is %p \n",main); printf("func func addr is %p \n",func); return 0; } hirasawa@aspire-white:~$ ./func1 func main addr is 0x804840c func func addr is 0x80483f4
hirasawa@aspire-white:~$ cat func2.c #include <stdio.h> #include <stdlib.h> int func(const char * str) { printf("%s\n",str); return 0; } int main(void) { int (*funcp)() ; printf("func main addr is %p \n",main); printf("func func addr is %p \n",func); funcp = func; printf("func func addr is %p \n",funcp); return 0; } hirasawa@aspire-white:~$ ./func2 func main addr is 0x804840c func func addr is 0x80483f4 func func addr is 0x80483f4
hirasawa@aspire-white:~$ cat func3.c #include <stdio.h> #include <stdlib.h> int func(const char * str) { printf("%s\n",str); return 0; } int main(void) { char char_str[] = "abc"; int (*funcp)() ; printf("func main addr is %p \n",main); printf("func func addr is %p \n",func); funcp = func; printf("func func addr is %p \n",funcp); (*funcp)(char_str) ; return 0; } hirasawa@aspire-white:~$ ./func3 func main addr is 0x804845c func func addr is 0x8048444 func func addr is 0x8048444 abc
hirasawa@aspire-white:~$ cat func4.c #include <stdio.h> #include <stdlib.h> int plus(int a, int b) { return (a + b) ; } int minus(int a, int b) { return (a - b) ; } int main(void) { int (*funcp[2])() = {plus, minus} ; printf("func main addr is %p \n",main); printf("func func addr is %p \n",plus); printf("func func addr is %p \n",minus); printf("func func addr is %p \n",funcp[0]); printf("func func addr is %p \n",funcp[1]); printf("exec using ptr (plus) %d \n",(*funcp[0])(3,5)); printf("exec using ptr (minus) %d \n",(*funcp[1])(3,5)); return 0; } hirasawa@aspire-white:~$ ./func4 func main addr is 0x80483e3 func func addr is 0x80483c4 func func addr is 0x80483d2 func func addr is 0x80483c4 func func addr is 0x80483d2 exec using ptr (plus) 8 exec using ptr (minus) -2 hirasawa@aspire-white:~$
関数の戻り値の型はあわせる必要がある。
というより、あわせないと記述できない