1 /* 2 Declaration for Linux kernel compatibility 3 */ 4 5 #include <assert.h> 6 #include <stdarg.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <sys/types.h> 10 #include <sys/ptrace.h> 11 12 #include "extra.h" 13 14 pid_t victim_pid= -1; 15 char *victim_exe= NULL; 16 17 #define TRAP_BIT (0x80000000) 18 19 static struct nlist *exe_nlist; 20 static int exe_nlist_n; 21 22 /* unsigned long __get_free_page(int type) { assert(0); } */ 23 /* void *kmalloc(size_t size, int type) { assert(0); } */ 24 void free_page(unsigned long page) { assert(0); } 25 /* void kfree(void *mem) { assert(0); } */ 26 void vfree(void *mem) { assert(0); } 27 28 size_t strncpy_from_user(char *addr, const char *user_name, size_t size) 29 { assert(0); return 0; } 30 31 /* void lock_kernel(void) { assert(0); } */ 32 /* void unlock_kernel(void) { assert(0); } */ 33 /* void __asm__(char *str) { assert(0); } */ 34 35 extern void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot) 36 { assert(0); return NULL; } 37 38 #if 0 39 void kallsyms_sections(void *infop, 40 int (*fp)(void *token, const char *modname, const char *secname, 41 ElfW(Addr) secstart, ElfW(Addr) secend, ElfW(Word) secflags)) 42 { assert(0); } 43 #endif 44 45 unsigned long __generic_copy_to_user(void *x, const void *y, unsigned long z) 46 { assert(0); return -1; } 47 unsigned long __generic_copy_from_user(void *x, const void *y, unsigned long z) 48 { assert(0); return -1; } 49 50 /* void read_lock(struct lock *lock) { assert(0); } */ 51 /* void read_unlock(struct lock *lock) { assert(0); } */ 52 void udelay(unsigned long usecs) { assert(0); } 53 int copy_to_user(void * result_record, void *res, size_t size) 54 { 55 memcpy(result_record, res, size); 56 return 0; 57 } 58 59 void panic(char *str) { assert(0); } 60 61 void printk(char *fmt, ...) 62 { 63 va_list ap; 64 65 va_start(ap, fmt); 66 vfprintf(stderr, fmt, ap); 67 va_end(ap); 68 } 69 70 int kallsyms_address_to_symbol(db_expr_t off, 71 const char * *mod_name, unsigned long *mod_start, unsigned long *mod_end, 72 const char * *sec_name, unsigned long *sec_start, unsigned long *sec_end, 73 const char * *sym_name, unsigned long *sym_start, unsigned long *sym_end) 74 { 75 static char name[64]; 76 77 int i; 78 unsigned long btext, etext; 79 struct nlist *below, *above; 80 81 off &= ~TRAP_BIT; 82 load_nlist(victim_exe, &btext, &etext); 83 below= above= NULL; 84 for (i= 0; i<exe_nlist_n; i++) 85 { 86 if (exe_nlist[i].n_type != N_TEXT) 87 continue; 88 if (exe_nlist[i].n_value <= off) 89 { 90 if (!below || exe_nlist[i].n_value > below->n_value) 91 below= &exe_nlist[i]; 92 } 93 if (exe_nlist[i].n_value > off) 94 { 95 if (!above || exe_nlist[i].n_value < above->n_value) 96 above= &exe_nlist[i]; 97 } 98 } 99 #if 0 100 if (below) 101 { 102 printf("found '%s' at 0x%x\n", below->n_name, below->n_value); 103 } 104 if (above) 105 { 106 printf("found '%s' at 0x%x\n", above->n_name, above->n_value); 107 } 108 #endif 109 110 btext |= TRAP_BIT; 111 etext |= TRAP_BIT; 112 113 *mod_name = victim_exe; 114 *mod_start = btext; 115 *mod_end = etext; 116 *sec_name = ".text"; 117 *sec_start = btext; 118 *sec_end = etext; 119 120 assert(below && above); 121 122 strncpy(name, below->n_name, sizeof(name)-1); 123 name[sizeof(name)-1]= '\0'; 124 *sym_name= name; 125 126 *sym_start= below->n_value | TRAP_BIT; 127 *sym_end= above->n_value | TRAP_BIT; 128 129 return 1; 130 } 131 132 struct module *module_list; 133 struct task_struct *task_list; 134 struct lock tasklist_lock; 135 136 unsigned long text_read_ul(void *addr) 137 { 138 int i; 139 unsigned long value; 140 141 for (i= 0; i<sizeof(value); i++) 142 { 143 ((unsigned char *)&value)[i]= text_read_ub((char *)addr+i); 144 } 145 return value; 146 } 147 148 unsigned char text_read_ub(void *addr) 149 { 150 int v; 151 unsigned long vaddr; 152 153 vaddr= (unsigned long)addr; 154 vaddr &= ~TRAP_BIT; 155 v= ptrace(T_READB_INS, victim_pid, vaddr, 0); 156 if (v < 0) 157 { 158 fprintf(stderr, 159 "text_read_ub: trace T_READB_INS failed on pid %d, addr 0x%lx: %s\n", 160 victim_pid, vaddr, strerror(errno)); 161 exit(1); 162 } 163 return v; 164 } 165 166 void text_write_ul(void *addr, unsigned long value) 167 { 168 int i; 169 170 for (i= 0; i<sizeof(value); i++) 171 { 172 text_write_ub((char *)addr+i, ((unsigned char *)&value)[i]); 173 } 174 } 175 176 void text_write_ub(void *addr, unsigned char value) 177 { 178 int v; 179 unsigned long vaddr; 180 181 vaddr= (unsigned long)addr; 182 vaddr &= ~TRAP_BIT; 183 v= ptrace(T_WRITEB_INS, victim_pid, vaddr, value); 184 if (v < 0) 185 { 186 fprintf(stderr, 187 "text_read_ub: trace T_WRITEB_INS failed on pid %d, addr 0x%lx: %s\n", 188 victim_pid, vaddr, strerror(errno)); 189 exit(1); 190 } 191 } 192 193 void load_nlist(exe_name, btextp, etextp) 194 char *exe_name; 195 unsigned long *btextp; 196 unsigned long *etextp; 197 { 198 int i; 199 unsigned long btext, etext; 200 201 if (!exe_nlist) 202 { 203 exe_nlist_n= read_nlist(exe_name, &exe_nlist); 204 if (exe_nlist_n <= 0) 205 { 206 if (exe_nlist_n == -1) 207 { 208 fprintf(stderr, 209 "error reading name list from '%s': %s\n", 210 exe_name, strerror(errno)); 211 } 212 else 213 fprintf(stderr, "no name list in '%s'\n", 214 exe_name); 215 exit(1); 216 } 217 } 218 219 if (!btextp && !etextp) 220 return; 221 222 etext= 0; 223 btext= (unsigned long)-1; 224 for (i= 0; i<exe_nlist_n; i++) 225 { 226 if (exe_nlist[i].n_type != N_TEXT) 227 continue; 228 if (exe_nlist[i].n_value < btext) 229 btext= exe_nlist[i].n_value; 230 if (exe_nlist[i].n_value > etext) 231 etext= exe_nlist[i].n_value; 232 } 233 234 if (btext >= etext) 235 { 236 fprintf(stderr, "Bad btext (0x%lx) or etext (0x%lx) in %s\n", 237 btext, etext, exe_name); 238 exit(1); 239 } 240 241 btext |= TRAP_BIT; 242 etext |= TRAP_BIT; 243 244 if (btextp) 245 *btextp= btext; 246 if (etextp) 247 *etextp= etext; 248 } 249