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:~$ 

関数の戻り値の型はあわせる必要がある。
というより、あわせないと記述できない