00001
00002
00003
00004
00005 #include <assert.h>
00006 #include <stdarg.h>
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <sys/types.h>
00010 #include <sys/ptrace.h>
00011
00012 #include "extra.h"
00013
00014 pid_t victim_pid= -1;
00015 char *victim_exe= NULL;
00016
00017 #define TRAP_BIT (0x80000000)
00018
00019 static struct nlist *exe_nlist;
00020 static int exe_nlist_n;
00021
00022
00023
00024 void free_page(unsigned long page) { assert(0); }
00025
00026 void vfree(void *mem) { assert(0); }
00027
00028 size_t strncpy_from_user(char *addr, const char *user_name, size_t size)
00029 { assert(0); }
00030
00031
00032
00033 void __asm__(char *str) { assert(0); }
00034
00035 extern void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot)
00036 { assert(0); }
00037
00038 #if 0
00039 void kallsyms_sections(void *infop,
00040 int (*fp)(void *token, const char *modname, const char *secname,
00041 ElfW(Addr) secstart, ElfW(Addr) secend, ElfW(Word) secflags))
00042 { assert(0); }
00043 #endif
00044
00045 unsigned long __generic_copy_to_user(void *x, const void *y, unsigned long z)
00046 { assert(0); }
00047 unsigned long __generic_copy_from_user(void *x, const void *y, unsigned long z)
00048 { assert(0); }
00049
00050
00051
00052 void udelay(unsigned long usecs) { assert(0); }
00053 int copy_to_user(void * result_record, void *res, size_t size)
00054 {
00055 memcpy(result_record, res, size);
00056 return 0;
00057 }
00058
00059 void panic(char *str) { assert(0); }
00060
00061 void printk(char *fmt, ...)
00062 {
00063 va_list ap;
00064
00065 va_start(ap, fmt);
00066 vfprintf(stderr, fmt, ap);
00067 va_end(ap);
00068 }
00069
00070 int kallsyms_address_to_symbol(db_expr_t off,
00071 const char * *mod_name, unsigned long *mod_start, unsigned long *mod_end,
00072 const char * *sec_name, unsigned long *sec_start, unsigned long *sec_end,
00073 const char * *sym_name, unsigned long *sym_start, unsigned long *sym_end)
00074 {
00075 static char name[sizeof(((struct nlist *)0)->n_name)+1];
00076
00077 int i;
00078 unsigned long btext, etext;
00079 struct nlist *below, *above;
00080
00081 off &= ~TRAP_BIT;
00082 load_nlist(victim_exe, &btext, &etext);
00083 below= above= NULL;
00084 for (i= 0; i<exe_nlist_n; i++)
00085 {
00086 if ((exe_nlist[i].n_sclass & N_SECT) != N_TEXT)
00087 continue;
00088 if (exe_nlist[i].n_value <= off)
00089 {
00090 if (!below || exe_nlist[i].n_value > below->n_value)
00091 below= &exe_nlist[i];
00092 }
00093 if (exe_nlist[i].n_value > off)
00094 {
00095 if (!above || exe_nlist[i].n_value < above->n_value)
00096 above= &exe_nlist[i];
00097 }
00098 }
00099 #if 0
00100 if (below)
00101 {
00102 printf("found '%.*s' at 0x%x\n", sizeof(below->n_name),
00103 below->n_name, below->n_value);
00104 }
00105 if (above)
00106 {
00107 printf("found '%.*s' at 0x%x\n", sizeof(above->n_name),
00108 above->n_name, above->n_value);
00109 }
00110 #endif
00111
00112 btext |= TRAP_BIT;
00113 etext |= TRAP_BIT;
00114
00115 *mod_name = victim_exe;
00116 *mod_start = btext;
00117 *mod_end = etext;
00118 *sec_name = ".text";
00119 *sec_start = btext;
00120 *sec_end = etext;
00121
00122 assert(below && above);
00123
00124 memcpy(name, below->n_name, sizeof(below->n_name));
00125 name[sizeof(below->n_name)]= '\0';
00126 *sym_name= name;
00127
00128 *sym_start= below->n_value | TRAP_BIT;
00129 *sym_end= above->n_value | TRAP_BIT;
00130
00131 return 1;
00132 }
00133
00134 struct module *module_list;
00135 struct task_struct *task_list;
00136 struct lock tasklist_lock;
00137
00138 unsigned long text_read_ul(void *addr)
00139 {
00140 int i;
00141 unsigned long value;
00142
00143 for (i= 0; i<sizeof(value); i++)
00144 {
00145 ((unsigned char *)&value)[i]= text_read_ub((char *)addr+i);
00146 }
00147 return value;
00148 }
00149
00150 unsigned char text_read_ub(void *addr)
00151 {
00152 int v;
00153 unsigned long vaddr;
00154
00155 vaddr= (unsigned long)addr;
00156 vaddr &= ~TRAP_BIT;
00157 v= ptrace(T_READB_INS, victim_pid, vaddr, 0);
00158 if (v < 0)
00159 {
00160 fprintf(stderr,
00161 "text_read_ub: trace T_READB_INS failed on pid %d, addr 0x%x: %s\n",
00162 victim_pid, vaddr, strerror(errno));
00163 exit(1);
00164 }
00165 return v;
00166 }
00167
00168 void text_write_ul(void *addr, unsigned long value)
00169 {
00170 int i;
00171
00172 for (i= 0; i<sizeof(value); i++)
00173 {
00174 text_write_ub((char *)addr+i, ((unsigned char *)&value)[i]);
00175 }
00176 }
00177
00178 void text_write_ub(void *addr, unsigned char value)
00179 {
00180 int v;
00181 unsigned long vaddr;
00182
00183 vaddr= (unsigned long)addr;
00184 vaddr &= ~TRAP_BIT;
00185 v= ptrace(T_WRITEB_INS, victim_pid, vaddr, value);
00186 if (v < 0)
00187 {
00188 fprintf(stderr,
00189 "text_read_ub: trace T_WRITEB_INS failed on pid %d, addr 0x%x: %s\n",
00190 victim_pid, vaddr, strerror(errno));
00191 exit(1);
00192 }
00193 }
00194
00195 void load_nlist(exe_name, btextp, etextp)
00196 char *exe_name;
00197 unsigned long *btextp;
00198 unsigned long *etextp;
00199 {
00200 int i;
00201 unsigned long btext, etext;
00202
00203 if (!exe_nlist)
00204 {
00205 exe_nlist_n= read_nlist(exe_name, &exe_nlist);
00206 if (exe_nlist_n <= 0)
00207 {
00208 if (exe_nlist_n == -1)
00209 {
00210 fprintf(stderr,
00211 "error reading name list from '%s': %s\n",
00212 exe_name, strerror(errno));
00213 }
00214 else
00215 fprintf(stderr, "no name list in '%s'\n",
00216 exe_name);
00217 exit(1);
00218 }
00219 }
00220
00221 if (!btextp && !etextp)
00222 return;
00223
00224 etext= 0;
00225 btext= (unsigned long)-1;
00226 for (i= 0; i<exe_nlist_n; i++)
00227 {
00228 if ((exe_nlist[i].n_sclass & N_SECT) != N_TEXT)
00229 continue;
00230 if (exe_nlist[i].n_value < btext)
00231 btext= exe_nlist[i].n_value;
00232 if (exe_nlist[i].n_value > etext)
00233 etext= exe_nlist[i].n_value;
00234 }
00235
00236 if (btext >= etext)
00237 {
00238 fprintf(stderr, "Bad btext (0x%x) or etext (0x%x) in %d\n",
00239 btext, etext, exe_name);
00240 exit(1);
00241 }
00242
00243 btext |= TRAP_BIT;
00244 etext |= TRAP_BIT;
00245
00246 if (btextp)
00247 *btextp= btext;
00248 if (etextp)
00249 *etextp= etext;
00250 }