diff options
author | Juan Cespedes <cespedes@thehackers.org> | 1997-04-21 18:03:20 +0200 |
---|---|---|
committer | Juan Cespedes <cespedes@thehackers.org> | 1997-04-21 18:03:20 +0200 |
commit | c9dcf60e5ad9964fb930910f1b2a519bb7053d7c (patch) | |
tree | 0cd3b1bbf7c901fee906acd37b376716c25d631c | |
parent | 802aa0ac85d59f97db6621db12865058c9549ba0 (diff) | |
download | ltrace-c9dcf60e5ad9964fb930910f1b2a519bb7053d7c.tar.gz |
Version 0.0.1997.04.21
Use section 'ctors' to initialize libtrace.
There are no exported functions anymore.
-rw-r--r-- | README | 3 | ||||
-rw-r--r-- | include/hck/syscall.h | 2 | ||||
-rwxr-xr-x | lib/libtrace.so.1 | bin | 19367 -> 6767 bytes | |||
-rw-r--r-- | src/libtrace/Makefile | 2 | ||||
-rw-r--r-- | src/libtrace/TODO | 11 | ||||
-rw-r--r-- | src/libtrace/init_libtrace-old.c | 200 | ||||
-rw-r--r-- | src/libtrace/init_libtrace.c | 98 | ||||
-rw-r--r-- | src/libtrace/libtrace.c | 4 | ||||
-rw-r--r-- | src/libtrace/print_results-old.c | 353 | ||||
-rw-r--r-- | src/libtrace/printf.c | 28 | ||||
-rw-r--r-- | src/libtrace/vsprintf.c | 2 | ||||
-rw-r--r-- | src/ltrace/ltrace.c | 1 |
12 files changed, 666 insertions, 38 deletions
@@ -2,3 +2,6 @@ Funcionamiento: --------------- * Intercepts library function '__setfpucw' + +YA NO: Ahora usa seccion 'ctors' para inicializacion de la libreria; + ya no exporta ninguna funcion. diff --git a/include/hck/syscall.h b/include/hck/syscall.h index c1c9f44..5432fcd 100644 --- a/include/hck/syscall.h +++ b/include/hck/syscall.h @@ -77,6 +77,7 @@ #define __NR_wait4 114 #define __NR_swapoff 115 #define __NR_uname 122 +#define __NR_mprotect 125 #define __NR_llseek 140 #define __NR_select 142 @@ -229,6 +230,7 @@ _syscall2(int,fstat,int,filedes,struct stat *,buff) _syscall4(pid_t,wait4,pid_t,pid,int *,status,int,options,struct rusage *,rusage) _syscall1(int,swapoff,const char *,path) _syscall1(int,uname,struct utsname *,buf) +_syscall3(int,mprotect,caddr_t,addr,size_t,len,int,prot) _syscall5(int,llseek,int,fd,unsigned long,hi,unsigned long,lo,loff_t *,result,unsigned int,whence) _syscall5(int,select,int,n,fd_set *,readfds,fd_set *,writefds,fd_set *,exceptfds,struct timeval *,timeout) diff --git a/lib/libtrace.so.1 b/lib/libtrace.so.1 Binary files differindex d3e190f..1275cbb 100755 --- a/lib/libtrace.so.1 +++ b/lib/libtrace.so.1 diff --git a/src/libtrace/Makefile b/src/libtrace/Makefile index 54c9661..c4c197a 100644 --- a/src/libtrace/Makefile +++ b/src/libtrace/Makefile @@ -7,7 +7,7 @@ OBJS = libtrace.o all: libtrace.so.1 -libtrace.o: libtrace.c init_libtrace.c strlen.c strncmp.c getenv.c atoi.c bcopy.c print_results.c sprintf.c vsprintf.c strcmp.c strnlen.c strcat.c unsetenv.c +libtrace.o: libtrace.c init_libtrace.c strlen.c strncmp.c getenv.c atoi.c bcopy.c sprintf.c vsprintf.c strcmp.c strnlen.c strcat.c unsetenv.c print_results.c printf.c libtrace.so.1: $(OBJS) $(LD) -shared -m elf_i386 -soname $@ -o $@ $(OBJS) diff --git a/src/libtrace/TODO b/src/libtrace/TODO index b412049..a7462e7 100644 --- a/src/libtrace/TODO +++ b/src/libtrace/TODO @@ -15,10 +15,15 @@ WARNING: Si se quiere loggear todo, hay que tener presente que pueden tener un 'where_to_return'; hay que tener muchos (tal vez se podria hacer con un struct similar a 'ax_jmp_t')... -* Utilizar prefijos para cada simbolo dentro de un mismo ejecutable - (ejemplo: init_a, init_b, print_a, print_b ...) +SOLUCION 2: Para evitar que se nos pase alguna funcion (por ejemplo, + dos funciones noreturn que se llaman una detras de otra), + se podria modificar el ".plt" en lugar del ".got", y + saltar siempre luego a la direccion del ".got" que + corresponda. -* Usar 'errno' para loggear errores de function calls +* Usar 'errno' para loggear errores de library calls * Usar 'msync' (o algo parecido; 'access'?) para ver si las direcciones dereferenciadas son validas, para evitar SIGSEGV + +* Deberia usar 'pusha' e incluso 'pushf' diff --git a/src/libtrace/init_libtrace-old.c b/src/libtrace/init_libtrace-old.c new file mode 100644 index 0000000..c79ea37 --- /dev/null +++ b/src/libtrace/init_libtrace-old.c @@ -0,0 +1,200 @@ +#include <fcntl.h> +#include <sys/types.h> +#include <linux/elf.h> +#include <hck/syscall.h> +#include <sys/mman.h> + +static int fd = 2; + +static char ax_jmp[] = { + 0xb8, 1, 2, 3, 4, /* movl $0x04030201, %eax */ + 0xa3, 5, 6, 7, 8, /* movl %eax, 0x08070605 */ + 0xff, 0x25, 1, 2, 3, 4, /* jmp *0x04030201 */ + 0, 0, 0, 0, /* real_func */ + 0, 0, 0, 0, /* name */ + 0, 0, 0, 0 /* got */ +}; + +static char where_to_ret[] = { +}; + +struct ax_jmp_t { + char tmp1; + void * src __attribute__ ((packed)); + char tmp2; + void * dst __attribute__ ((packed)); + char tmp3,tmp4; + void * new_func __attribute__ ((packed)); + void * real_func __attribute__ ((packed)); + char * name __attribute__ ((packed)); + u_long * got __attribute__ ((packed)); +}; + +static struct ax_jmp_t * pointer_tmp; +static struct ax_jmp_t * pointer; + +static void new_func(void); +static void * new_func_ptr = NULL; + +static int current_pid; + +static void init_libtrace(void) +{ + int i,j; + void * k; + struct elf32_sym * symtab = NULL; + size_t symtab_len = 0; + char * strtab = NULL; + char * tmp; + int nsymbols = 0; + long buffer[6]; + struct ax_jmp_t * table; + + if (new_func_ptr) { + return; + } + new_func_ptr = new_func; + + current_pid = _sys_getpid(); + + tmp = getenv("LTRACE_FILENAME"); + if (tmp) { + int fd_old; + + fd_old = _sys_open(tmp, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (fd_old<0) { + _sys_write(2, "Can't open LTRACE_FILENAME\n", 27); + return; + } + fd = _sys_dup2(fd_old, 234); + _sys_close(fd_old); + if (fd<0) { + _sys_write(2, "Not enough fd's?\n", 17); + return; + } + } + + tmp = getenv("LTRACE_SYMTAB"); + if (!tmp) { + _sys_write(fd, "No LTRACE_SYMTAB...\n", 20); + return; + } + symtab = (struct elf32_sym *)atoi(tmp); + + tmp = getenv("LTRACE_SYMTAB_LEN"); + if (!tmp) { + _sys_write(fd, "No LTRACE_SYMTAB_LEN...\n", 24); + return; + } + symtab_len = atoi(tmp); + + tmp = getenv("LTRACE_STRTAB"); + if (!tmp) { + _sys_write(fd, "No LTRACE_STRTAB...\n", 20); + return; + } + strtab = (char *)atoi(tmp); + + unsetenv("LD_PRELOAD"); + unsetenv("LTRACE_SYMTAB"); + unsetenv("LTRACE_SYMTAB_LEN"); + unsetenv("LTRACE_STRTAB"); + + for(i=0; i<symtab_len/sizeof(struct elf32_sym); i++) { + if (!((symtab+i)->st_shndx) && (symtab+i)->st_value) { + nsymbols++; +#if 0 + _sys_write(fd, "New symbol: ", 12); + _sys_write(fd,strtab+(symtab+i)->st_name,strlen(strtab+(symtab+i)->st_name)); + _sys_write(fd, "\n", 1); +#endif + } + } + + buffer[0] = 0; + buffer[1] = nsymbols * sizeof(struct ax_jmp_t); + buffer[2] = PROT_READ | PROT_WRITE | PROT_EXEC; + buffer[3] = MAP_PRIVATE | MAP_ANON; + buffer[4] = 0; + buffer[5] = 0; + table = (struct ax_jmp_t *)_sys_mmap(buffer); + if (!table) { + _sys_write(fd,"Cannot mmap?\n",13); + return; + } + + j=0; + for(i=0; i<symtab_len/sizeof(struct elf32_sym); i++) { + if (!((symtab+i)->st_shndx) && (symtab+i)->st_value) { + bcopy(ax_jmp, (char *)&table[j], sizeof(struct ax_jmp_t)); + table[j].src = (char *)&table[j]; + table[j].dst = &pointer_tmp; + table[j].new_func = &new_func_ptr; + table[j].name = strtab+(symtab+i)->st_name; + table[j].got = (u_long *)*(long *)(((int)((symtab+i)->st_value))+2); + table[j].real_func = (void *)*(table[j].got); + k = &table[j]; + bcopy((char*)&k, (char *)table[j].got, 4); + j++; + } + } + + _sys_write(fd,"ltrace starting...\n",19); +} + +static u_long where_to_return; +static u_long returned_value; +static u_long where_to_jump; + +static int reentrant=0; + +static void print_results(u_long arg); + +static void kk(void) +{ + char buf[1024]; + sprintf(buf, "\n%s(", pointer_tmp->name); + _sys_write(fd,buf,strlen(buf)); +} + +static void new_func(void) +{ +#if 1 + kk(); +#endif + if (reentrant) { +#if 0 +_sys_write(fd,"reentrant\n",10); +#endif + __asm__ __volatile__( + "movl %%ebp, %%esp\n\t" + "popl %%ebp\n\t" + "jmp *%%eax\n" + : : "a" (pointer_tmp->real_func) + ); + } + reentrant=1; + pointer = pointer_tmp; + where_to_jump = (u_long)pointer->real_func; + + /* This is only to avoid a GCC warning; shouldn't be here: + */ + where_to_return = (long)print_results; + + /* HCK: Is all these stuff about 'ebp' buggy? */ + __asm__ __volatile__( + "movl %ebp, %esp\n\t" + "popl %ebp\n\t" + "popl %eax\n\t" + "movl %eax, where_to_return\n\t" + "movl where_to_jump, %eax\n\t" + "call *%eax\n\t" + "movl %eax, returned_value\n\t" + "call print_results\n\t" + "movl where_to_return, %eax\n\t" + "pushl %eax\n\t" + "movl returned_value, %eax\n\t" + "movl $0, reentrant\n\t" + "ret\n" + ); +} diff --git a/src/libtrace/init_libtrace.c b/src/libtrace/init_libtrace.c index 131c31f..37f2ce5 100644 --- a/src/libtrace/init_libtrace.c +++ b/src/libtrace/init_libtrace.c @@ -4,29 +4,25 @@ #include <hck/syscall.h> #include <sys/mman.h> -static int fd = 2; - -static char ax_jmp[] = { - 0xb8, 1, 2, 3, 4, /* movl $0x04030201, %eax */ - 0xa3, 5, 6, 7, 8, /* movl %eax, 0x08070605 */ - 0xff, 0x25, 1, 2, 3, 4, /* jmp *0x04030201 */ - 0, 0, 0, 0, /* real_func */ - 0, 0, 0, 0, /* name */ - 0, 0, 0, 0 /* got */ +static int fd; + +static char trampoline[] = { + 1, 2, 3, 4, /* pointer to trampoline+4 */ + 0x68, 1, 2, 3, 4, /* pushl $0x04030201 (symbol index) */ + 0xff, 0x25, 1, 2, 3, 4 /* jmp *0x04030201 */ }; -struct ax_jmp_t { +struct trampoline_t { + void * aqui __attribute__ ((packed)); char tmp1; - void * src __attribute__ ((packed)); - char tmp2; - void * dst __attribute__ ((packed)); - char tmp3,tmp4; - void * new_func __attribute__ ((packed)); - void * real_func __attribute__ ((packed)); - char * name __attribute__ ((packed)); - u_long * got __attribute__ ((packed)); + long function_no __attribute__ ((packed)); + char tmp2, tmp3; + void (*new_func)() __attribute__ ((packed)); }; +void ** GOT; /* Array indexed by 'symbol index' (value pushed) */ +char ** name; + static struct ax_jmp_t * pointer_tmp; static struct ax_jmp_t * pointer; @@ -38,14 +34,14 @@ static int current_pid; static void init_libtrace(void) { int i,j; - void * k; struct elf32_sym * symtab = NULL; size_t symtab_len = 0; - char * strtab = NULL; char * tmp; - int nsymbols = 0; long buffer[6]; - struct ax_jmp_t * table; + void * table; + unsigned long plt_min=-1, plt_max=0; + char * strtab = NULL; + size_t nsymbols; if (new_func_ptr) { return; @@ -65,10 +61,12 @@ static void init_libtrace(void) } fd = _sys_dup2(fd_old, 234); _sys_close(fd_old); - if (fd<0) { - _sys_write(2, "Not enough fd's?\n", 17); - return; - } + } else { + fd = _sys_dup2(2, 234); + } + if (fd<0) { + _sys_write(2, "Not enough fd's?\n", 17); + return; } tmp = getenv("LTRACE_SYMTAB"); @@ -97,32 +95,63 @@ static void init_libtrace(void) unsetenv("LTRACE_SYMTAB_LEN"); unsetenv("LTRACE_STRTAB"); + nsymbols = 0; for(i=0; i<symtab_len/sizeof(struct elf32_sym); i++) { if (!((symtab+i)->st_shndx) && (symtab+i)->st_value) { + unsigned got_tmp; nsymbols++; -#if 0 - _sys_write(fd, "New symbol: ", 12); - _sys_write(fd,strtab+(symtab+i)->st_name,strlen(strtab+(symtab+i)->st_name)); - _sys_write(fd, "\n", 1); + if ((symtab+i)->st_value < plt_min) { + plt_min = (symtab+i)->st_value; + } + if ((symtab+i)->st_value > plt_max) { + plt_max = (symtab+i)->st_value; + } + +#if 1 + got_tmp = (long)*(long *)(((int)((symtab+i)->st_value))+2); + + printf("New symbol: %-16s, JMP: 0x%08x, GOT: 0x%08x\n", + (strtab+(symtab+i)->st_name), + (unsigned)((symtab+i)->st_value), got_tmp); + printf("tpnt = 0x%08x\n", + *(long *)(2+((symtab+i)->st_value)+16+(long)*(long *)(((int)((symtab+i)->st_value))+12)) + ); + #endif } } + printf("Total: %d symbols; plt_min=0x%08x, plt_max=0x%08x\n", nsymbols, plt_min, plt_max); buffer[0] = 0; - buffer[1] = nsymbols * sizeof(struct ax_jmp_t); + buffer[1] = nsymbols * sizeof(struct trampoline_t); buffer[2] = PROT_READ | PROT_WRITE | PROT_EXEC; buffer[3] = MAP_PRIVATE | MAP_ANON; buffer[4] = 0; buffer[5] = 0; - table = (struct ax_jmp_t *)_sys_mmap(buffer); + table = (void *)_sys_mmap(buffer); if (!table) { - _sys_write(fd,"Cannot mmap?\n",13); + printf("ltrace: Cannot mmap?\n"); + return; + } + plt_min = plt_min & ~(4096-1); + printf("plt_min=0x%08x\n", plt_min); + i = _sys_mprotect((void*)plt_min, plt_max-plt_min+6, PROT_READ | PROT_WRITE | PROT_EXEC); + if (i<0) { + printf("ltrace: Cannot mprotect?\n"); return; } +#if 1 + return; +} +static void new_func(void) +{ +} +#else j=0; for(i=0; i<symtab_len/sizeof(struct elf32_sym); i++) { if (!((symtab+i)->st_shndx) && (symtab+i)->st_value) { +#if 0 bcopy(ax_jmp, (char *)&table[j], sizeof(struct ax_jmp_t)); table[j].src = (char *)&table[j]; table[j].dst = &pointer_tmp; @@ -133,6 +162,7 @@ static void init_libtrace(void) k = &table[j]; bcopy((char*)&k, (char *)table[j].got, 4); j++; +#endif } } @@ -195,3 +225,5 @@ _sys_write(fd,"reentrant\n",10); "ret\n" ); } + +#endif diff --git a/src/libtrace/libtrace.c b/src/libtrace/libtrace.c index 9ff94e1..26a57bc 100644 --- a/src/libtrace/libtrace.c +++ b/src/libtrace/libtrace.c @@ -13,6 +13,7 @@ static char * getenv(const char *); static unsigned long atoi(const char *); static char * bcopy(const char *, char *, int); static int sprintf(char * buf, const char *fmt, ...); +static int printf(const char *fmt, ...); static int strcmp(const char * cs,const char * ct); static size_t strnlen(const char * s, size_t count); static int vsprintf(char *buf, const char *fmt, va_list args); @@ -25,13 +26,16 @@ static void unsetenv(const char *); #include "getenv.c" #include "atoi.c" #include "bcopy.c" +#if 0 #include "print_results.c" +#endif #include "sprintf.c" #include "vsprintf.c" #include "strcmp.c" #include "strnlen.c" #include "strcat.c" #include "unsetenv.c" +#include "printf.c" __asm__(".section .init"); void _init(void) diff --git a/src/libtrace/print_results-old.c b/src/libtrace/print_results-old.c new file mode 100644 index 0000000..2c41916 --- /dev/null +++ b/src/libtrace/print_results-old.c @@ -0,0 +1,353 @@ +static u_long * function_args; + +struct debug_functions { + const char * function_name; + int return_type; + int no_params; + int params_type[10]; +}; + +/* + * Lista de types: + */ + +#define _TYPE_UNKNOWN -1 +#define _TYPE_VOID 0 +#define _TYPE_INT 1 +#define _TYPE_UINT 2 +#define _TYPE_OCTAL 3 +#define _TYPE_CHAR 4 +#define _TYPE_STRING 5 +#define _TYPE_ADDR 6 +#define _TYPE_FILE 7 +#define _TYPE_HEX 8 + +#define MAX_STRING 30 + +static struct debug_functions * function_actual; + +static struct debug_functions functions_info[] = { + {"__libc_init", _TYPE_VOID, 0, {0}}, + {"__setjmp", _TYPE_INT, 1, {_TYPE_ADDR}}, + {"__overflow", _TYPE_CHAR, 2, {_TYPE_FILE, _TYPE_CHAR}}, + {"__random", _TYPE_INT, 0, {0}}, + {"__setfpucw", _TYPE_VOID, 1, {_TYPE_UINT}}, + {"__srandom", _TYPE_VOID, 1, {_TYPE_UINT}}, + {"__uflow", _TYPE_INT, 1, {_TYPE_FILE}}, + {"_fxstat", _TYPE_INT, 3, {_TYPE_INT, _TYPE_INT, _TYPE_ADDR}}, + {"_lxstat", _TYPE_INT, 3, {_TYPE_INT, _TYPE_STRING, _TYPE_ADDR}}, + {"_xmknod", _TYPE_INT, 4, {_TYPE_INT, _TYPE_STRING, _TYPE_OCTAL, _TYPE_ADDR}}, + {"_xstat", _TYPE_INT, 3, {_TYPE_INT, _TYPE_STRING, _TYPE_ADDR}}, + {"XSupportsLocale",_TYPE_INT, 0, {}}, + {"access", _TYPE_INT, 2, {_TYPE_STRING, _TYPE_INT}}, + {"alarm", _TYPE_INT, 1, {_TYPE_INT}}, + {"atexit", _TYPE_INT, 1, {_TYPE_ADDR}}, + {"atoi", _TYPE_INT, 1, {_TYPE_STRING}}, + {"basename", _TYPE_STRING,1, {_TYPE_STRING}}, + {"bcmp", _TYPE_INT, 3, {_TYPE_ADDR, _TYPE_ADDR, _TYPE_UINT}}, + {"bind", _TYPE_INT, 3, {_TYPE_INT, _TYPE_ADDR, _TYPE_INT}}, + {"bindresvport",_TYPE_INT, 2, {_TYPE_INT, _TYPE_ADDR}}, + {"brk", _TYPE_INT, 1, {_TYPE_ADDR}}, + {"bzero", _TYPE_VOID, 2, {_TYPE_ADDR, _TYPE_UINT}}, + {"calloc", _TYPE_ADDR, 2, {_TYPE_UINT, _TYPE_UINT}}, + {"cfgetospeed", _TYPE_UINT, 1, {_TYPE_ADDR}}, + {"creat", _TYPE_INT, 2, {_TYPE_STRING, _TYPE_OCTAL}}, + {"dup", _TYPE_INT, 1, {_TYPE_UINT}}, + {"dup2", _TYPE_INT, 2, {_TYPE_UINT, _TYPE_UINT}}, + {"chdir", _TYPE_INT, 1, {_TYPE_STRING}}, + {"chmod", _TYPE_INT, 2, {_TYPE_STRING, _TYPE_OCTAL}}, + {"chown", _TYPE_INT, 3, {_TYPE_STRING, _TYPE_UINT, _TYPE_UINT}}, + {"close", _TYPE_INT, 1, {_TYPE_INT}}, + {"closedir", _TYPE_INT, 1, {_TYPE_ADDR}}, + {"ctime", _TYPE_STRING,1, {_TYPE_ADDR}}, + {"endmntent", _TYPE_INT, 1, {_TYPE_ADDR}}, + {"fchmod", _TYPE_INT, 2, {_TYPE_INT, _TYPE_OCTAL}}, + {"fchown", _TYPE_INT, 3, {_TYPE_INT, _TYPE_UINT, _TYPE_UINT}}, + {"fclose", _TYPE_INT, 1, {_TYPE_FILE}}, + {"fdopen", _TYPE_FILE, 2, {_TYPE_INT, _TYPE_STRING}}, + {"feof", _TYPE_INT, 1, {_TYPE_FILE}}, + {"ferror", _TYPE_INT, 1, {_TYPE_FILE}}, + {"fflush", _TYPE_INT, 1, {_TYPE_FILE}}, + {"fgetc", _TYPE_CHAR, 1, {_TYPE_FILE}}, + {"fgets", _TYPE_ADDR, 3, {_TYPE_ADDR, _TYPE_UINT, _TYPE_ADDR}}, + {"fileno", _TYPE_INT, 1, {_TYPE_ADDR}}, + {"fopen", _TYPE_ADDR, 2, {_TYPE_STRING, _TYPE_STRING}}, + {"fork", _TYPE_INT, 0, {0}}, + {"fprintf", _TYPE_INT, 2, {_TYPE_FILE, _TYPE_STRING}}, + {"fputc", _TYPE_INT, 2, {_TYPE_CHAR, _TYPE_FILE}}, + {"fputs", _TYPE_INT, 2, {_TYPE_STRING, _TYPE_FILE}}, + {"fread", _TYPE_UINT, 4, {_TYPE_FILE, _TYPE_UINT, _TYPE_UINT, _TYPE_ADDR}}, + {"free", _TYPE_VOID, 1, {_TYPE_ADDR}}, + {"freopen", _TYPE_ADDR, 3, {_TYPE_STRING, _TYPE_STRING, _TYPE_ADDR}}, + {"fseek", _TYPE_INT, 3, {_TYPE_FILE, _TYPE_UINT, _TYPE_INT}}, + {"ftell", _TYPE_UINT, 1, {_TYPE_FILE}}, + {"fwrite", _TYPE_UINT, 4, {_TYPE_FILE, _TYPE_UINT, _TYPE_UINT, _TYPE_ADDR}}, + {"getdtablesize",_TYPE_INT, 0, {0}}, + {"getenv", _TYPE_STRING,1, {_TYPE_STRING}}, + {"getgid", _TYPE_INT, 0, {0}}, + {"getgrgid", _TYPE_ADDR, 1, {_TYPE_UINT}}, + {"getgrnam", _TYPE_ADDR, 1, {_TYPE_STRING}}, + {"gethostbyname",_TYPE_ADDR, 1, {_TYPE_STRING, 0, 0, 0, 0}}, + {"gethostname", _TYPE_INT, 2, {_TYPE_STRING, _TYPE_UINT, 0, 0, 0}}, + {"getmntent", _TYPE_ADDR, 1, {_TYPE_ADDR}}, + {"getopt", _TYPE_CHAR, 3, {_TYPE_INT, _TYPE_ADDR, _TYPE_STRING}}, + {"getopt_long", _TYPE_CHAR, 5, {_TYPE_INT, _TYPE_ADDR,_TYPE_STRING,_TYPE_ADDR,_TYPE_ADDR}}, + {"getpagesize", _TYPE_UINT, 0, {0}}, + {"getpgrp", _TYPE_INT, 0, {0}}, + {"getpid", _TYPE_UINT, 0, {0}}, + {"getpwnam", _TYPE_ADDR, 1, {_TYPE_STRING, 0, 0, 0, 0}}, + {"getpwuid", _TYPE_ADDR, 1, {_TYPE_UINT, 0, 0, 0, 0}}, + {"getservbyname",_TYPE_ADDR, 2, {_TYPE_STRING, _TYPE_STRING, 0, 0, 0}}, + {"gettimeofday",_TYPE_INT, 2, {_TYPE_ADDR, _TYPE_ADDR, 0, 0, 0}}, + {"htonl", _TYPE_UINT, 1, {_TYPE_UINT, 0, 0, 0, 0}}, + {"inet_addr", _TYPE_ADDR, 1, {_TYPE_STRING, 0, 0, 0, 0}}, + {"inet_ntoa", _TYPE_STRING,1, {_TYPE_ADDR, 0, 0, 0, 0}}, + {"ioctl", _TYPE_INT, 2, {_TYPE_INT, _TYPE_HEX}}, + {"isalnum", _TYPE_INT, 1, {_TYPE_CHAR, 0, 0, 0, 0}}, + {"isalpha", _TYPE_INT, 1, {_TYPE_CHAR, 0, 0, 0, 0}}, + {"isascii", _TYPE_INT, 1, {_TYPE_CHAR, 0, 0, 0, 0}}, + {"isatty", _TYPE_INT, 1, {_TYPE_INT, 0, 0, 0, 0}}, + {"iscntrl", _TYPE_INT, 1, {_TYPE_CHAR, 0, 0, 0, 0}}, + {"isdigit", _TYPE_INT, 1, {_TYPE_CHAR, 0, 0, 0, 0}}, + {"isgraph", _TYPE_INT, 1, {_TYPE_CHAR, 0, 0, 0, 0}}, + {"islower", _TYPE_INT, 1, {_TYPE_CHAR, 0, 0, 0, 0}}, + {"isprint", _TYPE_INT, 1, {_TYPE_CHAR, 0, 0, 0, 0}}, + {"ispunct", _TYPE_INT, 1, {_TYPE_CHAR, 0, 0, 0, 0}}, + {"isspace", _TYPE_INT, 1, {_TYPE_CHAR, 0, 0, 0, 0}}, + {"isupper", _TYPE_INT, 1, {_TYPE_CHAR, 0, 0, 0, 0}}, + {"isxdigit", _TYPE_INT, 1, {_TYPE_CHAR, 0, 0, 0, 0}}, + {"malloc", _TYPE_ADDR, 1, {_TYPE_UINT, 0, 0, 0, 0}}, + {"memmove", _TYPE_ADDR, 3, {_TYPE_ADDR, _TYPE_ADDR, _TYPE_INT, 0, 0}}, + {"memset", _TYPE_ADDR, 3, {_TYPE_ADDR, _TYPE_HEX, _TYPE_UINT}}, + {"mmap", _TYPE_ADDR, 5, {_TYPE_UINT, _TYPE_UINT, _TYPE_UINT, _TYPE_INT,_TYPE_UINT}}, + {"mprotect", _TYPE_INT, 3, {_TYPE_ADDR, _TYPE_ADDR, _TYPE_HEX}}, + {"ntohl", _TYPE_UINT, 1, {_TYPE_UINT, 0, 0, 0, 0}}, + {"ntohs", _TYPE_UINT, 1, {_TYPE_UINT, 0, 0, 0, 0}}, + {"open", _TYPE_INT, 3, {_TYPE_STRING, _TYPE_INT, _TYPE_OCTAL, 0, 0}}, + {"opendir", _TYPE_ADDR, 1, {_TYPE_STRING, 0, 0, 0, 0}}, + {"perror", _TYPE_VOID, 1, {_TYPE_STRING, 0, 0, 0, 0}}, + {"pipe", _TYPE_INT, 1, {_TYPE_ADDR}}, + {"printf", _TYPE_INT, 1, {_TYPE_STRING, 0, 0, 0, 0}}, + {"putenv", _TYPE_INT, 1, {_TYPE_STRING, 0, 0, 0, 0}}, + {"puts", _TYPE_INT, 1, {_TYPE_STRING, 0, 0, 0, 0}}, + {"qsort", _TYPE_VOID, 4, {_TYPE_ADDR, _TYPE_UINT, _TYPE_UINT, _TYPE_ADDR, 0}}, + {"read", _TYPE_INT, 3, {_TYPE_INT, _TYPE_ADDR, _TYPE_UINT, 0, 0}}, + {"readdir", _TYPE_ADDR, 1, {_TYPE_ADDR, 0, 0, 0, 0}}, + {"readline", _TYPE_STRING,0, {0, 0, 0, 0, 0}}, + {"readlink", _TYPE_INT, 3, {_TYPE_STRING, _TYPE_ADDR, _TYPE_UINT, 0, 0}}, + {"realloc", _TYPE_ADDR, 2, {_TYPE_ADDR, _TYPE_UINT, 0, 0, 0}}, + {"rewind", _TYPE_VOID, 1, {_TYPE_FILE, 0, 0, 0, 0}}, + {"rewinddir", _TYPE_VOID, 1, {_TYPE_FILE, 0, 0, 0, 0}}, + {"rindex", _TYPE_STRING,2, {_TYPE_STRING, _TYPE_INT, 0, 0, 0}}, + {"sbrk", _TYPE_ADDR, 1, {_TYPE_UINT, 0, 0, 0, 0}}, + {"select", _TYPE_INT, 5, {_TYPE_INT, _TYPE_ADDR, _TYPE_ADDR, _TYPE_ADDR,_TYPE_ADDR}}, + {"setbuf", _TYPE_VOID, 2, {_TYPE_ADDR, _TYPE_ADDR, 0, 0, 0}}, + {"setgid", _TYPE_INT, 1, {_TYPE_UINT}}, + {"setlinebuf", _TYPE_VOID, 1, {_TYPE_FILE, 0, 0, 0, 0}}, + {"setlocale", _TYPE_STRING,2, {_TYPE_INT, _TYPE_STRING, 0, 0, 0}}, + {"setmntent", _TYPE_ADDR, 2, {_TYPE_STRING, _TYPE_STRING, 0, 0, 0}}, + {"setuid", _TYPE_INT, 1, {_TYPE_INT, 0, 0, 0, 0}}, + {"setvbuf", _TYPE_INT, 4, {_TYPE_ADDR, _TYPE_ADDR, _TYPE_INT, _TYPE_UINT, 0}}, + {"sigaction", _TYPE_INT, 3, {_TYPE_INT, _TYPE_ADDR, _TYPE_ADDR, 0, 0}}, + {"sleep", _TYPE_UINT, 1, {_TYPE_UINT, 0, 0, 0, 0}}, + {"sprintf", _TYPE_INT, 2, {_TYPE_STRING, _TYPE_STRING}}, + {"sscanf", _TYPE_INT, 2, {_TYPE_STRING, _TYPE_STRING}}, + {"strcasecmp", _TYPE_INT, 2, {_TYPE_STRING, _TYPE_STRING}}, + {"stpcpy", _TYPE_STRING,2, {_TYPE_STRING, _TYPE_STRING}}, + {"strcmp", _TYPE_INT, 2, {_TYPE_STRING, _TYPE_STRING}}, + {"strcpy", _TYPE_STRING,2, {_TYPE_STRING, _TYPE_STRING}}, + {"strcoll", _TYPE_INT, 2, {_TYPE_STRING, _TYPE_STRING}}, + {"strcspn", _TYPE_INT, 2, {_TYPE_STRING, _TYPE_STRING}}, + {"strdup", _TYPE_STRING,1, {_TYPE_STRING}}, + {"strerror", _TYPE_STRING,1, {_TYPE_INT}}, + {"strncmp", _TYPE_INT, 3, {_TYPE_STRING, _TYPE_STRING, _TYPE_INT}}, + {"strpbrk", _TYPE_STRING,2, {_TYPE_STRING, _TYPE_STRING, 0, 0, 0}}, + {"strrchr", _TYPE_STRING,2, {_TYPE_STRING, _TYPE_CHAR, 0, 0, 0}}, + {"strspn", _TYPE_UINT, 2, {_TYPE_STRING, _TYPE_STRING, 0, 0, 0}}, + {"strtok", _TYPE_STRING,2, {_TYPE_STRING, _TYPE_STRING, 0, 0, 0}}, + {"strtol", _TYPE_INT, 3, {_TYPE_STRING, _TYPE_ADDR, _TYPE_UINT, 0, 0}}, + {"strtoul", _TYPE_INT, 3, {_TYPE_STRING, _TYPE_ADDR, _TYPE_UINT, 0, 0}}, + {"tcgetattr", _TYPE_INT, 2, {_TYPE_INT, _TYPE_ADDR, 0, 0, 0}}, + {"tcsetattr", _TYPE_INT, 2, {_TYPE_INT, _TYPE_ADDR, 0, 0, 0}}, + {"time", _TYPE_UINT, 1, {_TYPE_ADDR}}, + {"toascii", _TYPE_CHAR, 1, {_TYPE_CHAR, 0, 0, 0, 0}}, + {"tolower", _TYPE_CHAR, 1, {_TYPE_CHAR, 0, 0, 0, 0}}, + {"toupper", _TYPE_CHAR, 1, {_TYPE_CHAR, 0, 0, 0, 0}}, + {"unlink", _TYPE_INT, 1, {_TYPE_STRING, 0, 0, 0, 0}}, + {"uname", _TYPE_INT, 1, {_TYPE_ADDR, 0, 0, 0, 0}}, + {"ungetc", _TYPE_CHAR, 2, {_TYPE_INT, _TYPE_ADDR, 0, 0, 0}}, + {"utime", _TYPE_INT, 2, {_TYPE_STRING, _TYPE_ADDR, 0, 0, 0}}, + {"vfprintf", _TYPE_INT, 2, {_TYPE_ADDR, _TYPE_STRING, 0, 0, 0}}, + {"wait", _TYPE_UINT, 1, {_TYPE_ADDR, 0, 0, 0, 0}}, + {"wait3", _TYPE_UINT, 3, {_TYPE_ADDR, _TYPE_INT, _TYPE_ADDR, 0, 0}}, + {"waitpid", _TYPE_UINT, 3, {_TYPE_UINT, _TYPE_ADDR, _TYPE_ADDR, 0, 0}}, + {"write", _TYPE_INT, 3, {_TYPE_INT, _TYPE_ADDR, _TYPE_UINT, 0, 0}}, + {NULL, _TYPE_UNKNOWN, 1, {_TYPE_UNKNOWN, 0, 0, 0, 0}} +}; + +static char * print_char(unsigned long value) +{ + static char result[5]; + + result[0]='\\'; + switch(value) { + case '\r': result[1]='r'; result[2]='\0'; break; + case '\n': result[1]='n'; result[2]='\0'; break; + case '\t': result[1]='t'; result[2]='\0'; break; + case '\\': result[1]='\\'; result[2]='\0'; break; + default: + if ((value<32) || ((value>126) && (value<256))) { + sprintf(result+1, "%lo", value); + } else { + result[0]=value; result[1]='\0'; break; + } + } + return result; +} + +static char * print_param(int type, unsigned long value) +{ + static char result[1024]; + + switch(type) { + case _TYPE_INT: + sprintf(result, "%d", (int)value); + break; + case _TYPE_UINT: + sprintf(result, "%u", (unsigned int)value); + break; + case _TYPE_ADDR: + if (!value) { + sprintf(result, "NULL"); + } else { + sprintf(result, "0x%08x", (unsigned int)value); + } + break; + case _TYPE_FILE: +#if 0 + if (value==(unsigned long)stdin) { + sprintf(result, "stdin"); + } else if (value==(unsigned long)stdout) { + sprintf(result, "stdout"); + } else if (value==(unsigned long)stderr) { + sprintf(result, "stderr"); + } else { +#endif + return print_param(_TYPE_ADDR, value); +#if 0 + } +#endif + break; + case _TYPE_OCTAL: + sprintf(result, "0%o", (unsigned int)value); + break; + case _TYPE_CHAR: + if (value==-1) { + sprintf(result, "EOF"); + } else { + sprintf(result, "'%s'", print_char(value)); + } + break; + case _TYPE_STRING: + if (value==0) { + sprintf(result, "<NULL>"); + } else { + int i; + sprintf(result, "\""); + for(i=0; *((char*)value+i) && i<MAX_STRING; i++) { + strcat(result, print_char(*((char*)value+i))); + } + strcat(result, "\""); + if (i==MAX_STRING) { + strcat(result, "..."); + } + } + break; + case _TYPE_HEX: + sprintf(result, "0x%lx", value); + break; + case _TYPE_VOID: + sprintf(result, "<void>"); + break; + case _TYPE_UNKNOWN: + sprintf(result, "???"); + break; + default: + sprintf(result, "???"); + } + return result; +} + +static void print_results(u_long arg) +{ + char message[1024]; + int i; + +#if 0 + if (!current_pid) { + return; + } +#endif + + if (pointer != (void *)*(pointer->got)) { + pointer->real_func = (void *)*(pointer->got); + bcopy((char *)&pointer, (char *)pointer->got, 4); + } + +#if 0 +_sys_write(fd, pointer->name, strlen(pointer->name)); +_sys_write(fd, ":\n", 2); +#endif + + function_actual = functions_info; + while(function_actual->function_name) { + if (!strcmp(pointer->name, function_actual->function_name)) { + break; + } + function_actual++; + } + + function_args = &arg; + +#if 0 + if (!strcmp(pointer->name, "fork")) { + if (_sys_getpid() != current_pid) { + _sys_close(fd); + current_pid=0; + return; + } + } +#endif + +#if 0 +sprintf(message,"call to = 0x%08x\n" + "got = 0x%08x\n" + "return = 0x%08x\n" + "args[0] = 0x%08x\n" + "args[1] = 0x%08x\n" + "args[2] = 0x%08x\n" + "args[3] = 0x%08x\n" + "args[4] = 0x%08x\n" + "args[5] = 0x%08x\n", + pointer, pointer->got, where_to_return, + function_args[0], function_args[1], function_args[2], + function_args[3], function_args[4], function_args[5]); +_sys_write(fd, message, strlen(message)); +#endif + + message[0] = '\0'; +#if 0 + sprintf(message, "%s%s(", message, pointer->name); +#endif + if (function_actual->no_params > 0) { + sprintf(message, "%s%s", message, + print_param(function_actual->params_type[0], function_args[0])); + } + for(i=1; i<function_actual->no_params; i++) { + sprintf(message, "%s,%s", message, + print_param(function_actual->params_type[i], function_args[i])); + } + sprintf(message, "%s) = %s\n", message, + print_param(function_actual->return_type, returned_value)); + _sys_write(fd, message, strlen(message)); +} diff --git a/src/libtrace/printf.c b/src/libtrace/printf.c new file mode 100644 index 0000000..85b254d --- /dev/null +++ b/src/libtrace/printf.c @@ -0,0 +1,28 @@ +/* + * linux/lib/vsprintf.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Wirzenius wrote this portably, Torvalds fucked it up :-) + */ + +#include <stdarg.h> + +static int printf(const char *fmt, ...) +{ + va_list args; + int i; + char buf[1024]; + + va_start(args, fmt); + i=vsprintf(buf,fmt,args); + va_end(args); + + _sys_write(fd, buf, strlen(buf)); + + return i; +} + diff --git a/src/libtrace/vsprintf.c b/src/libtrace/vsprintf.c index e5603c9..9805115 100644 --- a/src/libtrace/vsprintf.c +++ b/src/libtrace/vsprintf.c @@ -15,7 +15,7 @@ /* we use this so that we can do without the ctype library */ #define is_digit(c) ((c) >= '0' && (c) <= '9') -static int skip_atoi(const char **s) +static __inline__ int skip_atoi(const char **s) { int i=0; diff --git a/src/ltrace/ltrace.c b/src/ltrace/ltrace.c index 7a105d0..abb7b8b 100644 --- a/src/ltrace/ltrace.c +++ b/src/ltrace/ltrace.c @@ -76,6 +76,7 @@ int main(int argc, char **argv) * Tengo que decirle a libtrace: * - Comienzo y tamanno de '.dynsym' LTRACE_SYMTAB_ADDR, LTRACE_SYMTAB_SIZE * - Comienzo de '.dynstr' LTRACE_STRTAB_ADDR + * - Comienzo y tamanno de '.got' LTRACE_GOT_ADDR, LTRACE_GOT_SIZE * * Todo ello especificado en decimal (por elegir algo) */ |