From ad7836215eecdc6700b2207f2c6b8294936bbe39 Mon Sep 17 00:00:00 2001 From: Juan Cespedes Date: Tue, 10 Jun 1997 17:11:33 +0200 Subject: Version 0.0.1997.06.10 --- Makefile | 5 +-- Makefile2 | 17 ------- README | 4 +- ltrace | Bin 0 -> 7212 bytes ltrace.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 5 files changed, 133 insertions(+), 44 deletions(-) delete mode 100644 Makefile2 create mode 100755 ltrace diff --git a/Makefile b/Makefile index ec4d8a5..1037283 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,10 @@ CC = gcc -CFLAGS = -Wall -Werror -O2 +CFLAGS = -Wall -O2 all: ltrace clean: rm -f ltrace ltrace.o -dist: - make clean +dist: #clean ( cd .. ; tar zcvf ltrace2-`date +%y%m%d`.tgz ltrace2 ) diff --git a/Makefile2 b/Makefile2 deleted file mode 100644 index 0278488..0000000 --- a/Makefile2 +++ /dev/null @@ -1,17 +0,0 @@ -CC = gcc -CFLAGS = -Wall -O2 -Iinclude -LD = ld - -all: - @echo 'Type "make dist" to make a distribution .tgz' - @echo - -clean: - make -C src/libtrace clean - make -C src/ltrace clean - make -C src/test clean - rm -f *.o - -dist: - make clean - ( cd .. ; tar zcvf ltrace-`date +%y%m%d`.tgz ltrace ) diff --git a/README b/README index 23b6e80..27ac67c 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ Funcionamiento: --------------- -* Puts soft breakpoints (INT 3, CC) in process using ptrace, just like - gdb/strace +* 2nd approach: using soft breakpoints (INT 3, CC) in process using + ptrace, just like gdb/strace diff --git a/ltrace b/ltrace new file mode 100755 index 0000000..6aeb155 Binary files /dev/null and b/ltrace differ diff --git a/ltrace.c b/ltrace.c index 207913a..af5773f 100644 --- a/ltrace.c +++ b/ltrace.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -11,9 +12,16 @@ #include #include -u_long strtab; -u_long symtab; -u_long symtab_len; +static int debug = 0; + +struct library_symbol { + char * name; + unsigned long addr; + unsigned char value; + struct library_symbol * next; +}; + +struct library_symbol * library_symbols = NULL; int read_elf(char *filename) { @@ -22,9 +30,10 @@ int read_elf(char *filename) void * addr; struct elf32_hdr * hdr; Elf32_Shdr * shdr; + struct elf32_sym * symtab = NULL; int i; - - strtab = symtab = symtab_len = 0; + char * strtab = NULL; + u_long symtab_len = 0; fd = open(filename, O_RDONLY); if (fd==-1) { @@ -53,20 +62,52 @@ int read_elf(char *filename) shdr = addr + hdr->e_shoff + i*hdr->e_shentsize; if (shdr->sh_type == SHT_DYNSYM) { if (!symtab) { - symtab = shdr->sh_addr; +#if 0 + symtab = (struct elf32_sym *)shdr->sh_addr; +#else + symtab = (struct elf32_sym *)(addr + shdr->sh_offset); +#endif symtab_len = shdr->sh_size; } } if (shdr->sh_type == SHT_STRTAB) { if (!strtab) { - strtab = shdr->sh_addr; +#if 0 + strtab = (char *)(addr + shdr->sh_offset); +#else + strtab = (char *)(addr + shdr->sh_offset); +#endif } } } - fprintf(stderr, "symtab: 0x%08lx\n", symtab); - fprintf(stderr, "symtab_len: %lu\n", symtab_len); - fprintf(stderr, "strtab: 0x%08lx\n", strtab); - return 0; + if (debug>0) { + fprintf(stderr, "symtab: 0x%08x\n", (unsigned)symtab); + fprintf(stderr, "symtab_len: %lu\n", symtab_len); + fprintf(stderr, "strtab: 0x%08x\n", (unsigned)strtab); + } + if (!symtab) { + return 0; + } + for(i=0; ist_shndx) && (symtab+i)->st_value) { + struct library_symbol * tmp = library_symbols; + + library_symbols = malloc(sizeof(struct library_symbol)); + if (!library_symbols) { + perror("malloc"); + exit(1); + } + library_symbols->addr = ((symtab+i)->st_value); + library_symbols->name = strtab+(symtab+i)->st_name; + library_symbols->next = tmp; + if (debug>0) { + fprintf(stderr, "addr: 0x%08x, symbol: \"%s\"\n", + (unsigned)((symtab+i)->st_value), + (strtab+(symtab+i)->st_name)); + } + } + } + return 1; } int main(int argc, char **argv) @@ -74,13 +115,23 @@ int main(int argc, char **argv) int pid; int status; struct rusage ru; + struct library_symbol * tmp = NULL; + + while ((argc>1) && (argv[1][0] == '-') && (argv[1][2] == '\0')) { + switch(argv[1][1]) { + case 'd': debug++; + break; + default: fprintf(stderr, "Unknown option '%c'\n", argv[1][1]); + exit(1); + } + argc--; argv++; + } if (argc<2) { - fprintf(stderr, "Usage: %s []\n", argv[0]); + fprintf(stderr, "Usage: %s [] []\n", argv[0]); exit(1); } - read_elf(argv[1]); - if (!symtab) { + if (!read_elf(argv[1])) { fprintf(stderr, "%s: Not dynamically linked\n", argv[0]); exit(1); } @@ -98,7 +149,30 @@ int main(int argc, char **argv) exit(1); } fprintf(stderr, "pid %u attached\n", pid); + + /* Enable breakpoints: */ + pid = wait4(-1, &status, 0, &ru); + if (pid==-1) { + perror("wait4"); + exit(1); + } + fprintf(stderr, "Enabling breakpoints...\n"); + tmp = library_symbols; + while(tmp) { + int a; + a = ptrace(PTRACE_PEEKTEXT, pid, tmp->addr, 0); + tmp->value = a & 0xFF; + a &= 0xFFFFFF00; + a |= 0xCC; + ptrace(PTRACE_POKETEXT, pid, tmp->addr, a); + tmp = tmp->next; + } + ptrace(PTRACE_CONT, pid, 1, 0); + while(1) { + int eip; + int function_seen; + pid = wait4(-1, &status, 0, &ru); if (pid==-1) { if (errno == ECHILD) { @@ -112,17 +186,50 @@ int main(int argc, char **argv) fprintf(stderr, "pid %u exited\n", pid); continue; } - fprintf(stderr,"EIP = 0x%08x\n", ptrace(PTRACE_PEEKUSR, pid, 4*EIP, 0)); + if (!WIFSTOPPED(status)) { + fprintf(stderr, "pid %u ???\n", pid); + continue; + } + /* pid is stopped... */ + eip = ptrace(PTRACE_PEEKUSR, pid, 4*EIP, 0); +/* + fprintf(stderr,"EIP = 0x%08x\n", eip); fprintf(stderr,"EBP = 0x%08x\n", ptrace(PTRACE_PEEKUSR, pid, 4*EBP, 0)); -#if 0 - ptrace(PTRACE_SINGLESTEP, pid, 0, 0); - continue; -#endif - if (WIFSTOPPED(status)) { +*/ + tmp = library_symbols; + function_seen = 0; + while(tmp) { + if (eip == tmp->addr+1) { + int a; + function_seen = 1; + fprintf(stderr, "Function: %s\n", tmp->name); + a = ptrace(PTRACE_PEEKTEXT, pid, tmp->addr, 0); + a &= 0xFFFFFF00; + a |= tmp->value; + ptrace(PTRACE_POKETEXT, pid, tmp->addr, a); + ptrace(PTRACE_POKEUSR, pid, 4*EIP, eip-1); + ptrace(PTRACE_SINGLESTEP, pid, 0, 0); + pid = wait4(-1, &status, 0, &ru); + if (pid==-1) { + if (errno == ECHILD) { + fprintf(stderr, "No more children\n"); + exit(0); + } + perror("wait4"); + exit(1); + } + a = ptrace(PTRACE_PEEKTEXT, pid, tmp->addr, 0); + a &= 0xFFFFFF00; + a |= 0xCC; + ptrace(PTRACE_POKETEXT, pid, tmp->addr, a); + ptrace(PTRACE_CONT, pid, 1, 0); + break; + } + tmp = tmp->next; + } + if (!function_seen) { fprintf(stderr, "pid %u stopped; continuing it...\n", pid); ptrace(PTRACE_CONT, pid, 1, 0); - } else { - fprintf(stderr, "pid %u ???\n", pid); } } exit(0); -- cgit v1.2.3