aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Cespedes <cespedes@thehackers.org>1997-04-21 18:03:20 +0200
committerJuan Cespedes <cespedes@thehackers.org>1997-04-21 18:03:20 +0200
commitc9dcf60e5ad9964fb930910f1b2a519bb7053d7c (patch)
tree0cd3b1bbf7c901fee906acd37b376716c25d631c
parent802aa0ac85d59f97db6621db12865058c9549ba0 (diff)
downloadltrace-c9dcf60e5ad9964fb930910f1b2a519bb7053d7c.tar.gz
Version 0.0.1997.04.21
Use section 'ctors' to initialize libtrace. There are no exported functions anymore.
-rw-r--r--README3
-rw-r--r--include/hck/syscall.h2
-rwxr-xr-xlib/libtrace.so.1bin19367 -> 6767 bytes
-rw-r--r--src/libtrace/Makefile2
-rw-r--r--src/libtrace/TODO11
-rw-r--r--src/libtrace/init_libtrace-old.c200
-rw-r--r--src/libtrace/init_libtrace.c98
-rw-r--r--src/libtrace/libtrace.c4
-rw-r--r--src/libtrace/print_results-old.c353
-rw-r--r--src/libtrace/printf.c28
-rw-r--r--src/libtrace/vsprintf.c2
-rw-r--r--src/ltrace/ltrace.c1
12 files changed, 666 insertions, 38 deletions
diff --git a/README b/README
index 7aae4f0..83ba6d3 100644
--- a/README
+++ b/README
@@ -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
index d3e190f..1275cbb 100755
--- a/lib/libtrace.so.1
+++ b/lib/libtrace.so.1
Binary files differ
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)
*/