1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
|
/*
* Architecture-dependent application data.
*
* The code assumes that ulong is big enough to hold
* an address on any system of interest as well as any
* register. Debugging 64-bit code on 32-bit machines
* will be interesting.
*
* Supported architectures:
*
* MIPS R3000
* Motorola 68020
* Intel 386
* SPARC
* PowerPC (limited)
* ARM (limited)
* Intel 960 (limited)
* AT&T 3210 DSP (limited)
* MIPS2 (R4000)
*/
typedef struct Fhdr Fhdr;
typedef struct Loc Loc;
typedef struct Mach Mach;
typedef struct Map Map;
typedef struct Regdesc Regdesc;
typedef struct Regs Regs;
typedef struct Seg Seg;
typedef struct Symbol Symbol;
typedef struct Symtype Symtype;
typedef int (*Tracer)(Map*, Regs*, ulong, ulong, Symbol*, int);
extern Mach *mach;
extern Mach *machcpu;
/*
* Byte-order data layout manipulation.
* swap.c ieee.c
*/
u16int beswap2(u16int u);
u32int beswap4(u32int u);
u64int beswap8(u64int u);
int beieeeftoa32(char*, uint, void*);
int beieeeftoa64(char*, uint, void*);
int beieeeftoa80(char*, uint, void*);
u16int leswap2(u16int u);
u32int leswap4(u32int u);
u64int leswap8(u64int u);
int leieeeftoa32(char *a, uint n, void *v);
int leieeeftoa64(char *a, uint n, void *v);
int leieeeftoa80(char *a, uint n, void *v);
u16int beload2(uchar*);
u32int beload4(uchar*);
u64int beload8(uchar*);
u16int leload2(uchar*);
u32int leload4(uchar*);
u64int leload8(uchar*);
int ieeeftoa32(char *a, uint n, u32int u);
int ieeeftoa64(char *a, uint n, u32int h, u32int u);
/*
* Machine-independent access to an executable image.
* map.c
*/
struct Seg
{
char *name;
char *file;
uchar *p;
int fd;
int pid;
ulong base;
ulong size;
ulong offset;
int (*rw)(Map*, Seg*, ulong, void*, uint, int);
};
struct Map
{
int nseg;
Seg *seg;
};
struct Regs
{
int (*rw)(Regs*, char*, ulong*, int);
};
typedef struct UregRegs UregRegs;
struct UregRegs
{
Regs r;
uchar *ureg;
};
int _uregrw(Regs*, char*, ulong*, int);
typedef struct PidRegs PidRegs;
struct PidRegs
{
Regs r;
int pid;
};
Map* allocmap(void);
int addseg(Map *map, Seg seg);
int findseg(Map *map, char *name, char *file);
int addrtoseg(Map *map, ulong addr, Seg *seg);
int addrtosegafter(Map *map, ulong addr, Seg *seg);
void removeseg(Map *map, int i);
void freemap(Map*);
int get1(Map *map, ulong addr, uchar *a, uint n);
int get2(Map *map, ulong addr, u16int *u);
int get4(Map *map, ulong addr, u32int *u);
int get8(Map *map, ulong addr, u64int *u);
int put1(Map *map, ulong addr, uchar *a, uint n);
int put2(Map *map, ulong addr, u16int u);
int put4(Map *map, ulong addr, u32int u);
int put8(Map *map, ulong addr, u64int u);
int rget(Regs*, char*, ulong*);
int rput(Regs*, char*, ulong);
/*
* A location is either a memory address or a register.
* It is useful to be able to specify constant values that
* originate from outside the register set and memory,
* hence LCONST. If the register values are known, then
* we can dispense with LOFFSET, but it's useful to be able
* to look up local symbols (via findlsym) with locations
* like 8(BP).
*
* loc.c
*/
enum
{
/* location type */
LNONE,
LREG, /* register */
LADDR, /* absolute address */
LCONST, /* constant (an anonymous readonly location) */
LOFFSET, /* dereference offset + register ptr */
};
struct Loc
{
uint type; /* LNONE, ... */
char *reg; /* LREG */
ulong addr; /* LADDR, CONST */
long offset; /* LOFFSET */
};
int lget1(Map *map, Regs *regs, Loc loc, uchar *a, uint n);
int lget2(Map *map, Regs *regs, Loc loc, u16int *v);
int lget4(Map *map, Regs *regs, Loc loc, u32int *v);
int lget8(Map *map, Regs *regs, Loc loc, u64int *v);
int lput1(Map *map, Regs *regs, Loc loc, uchar *a, uint n);
int lput2(Map *map, Regs *regs, Loc loc, u16int v);
int lput4(Map *map, Regs *regs, Loc loc, u32int v);
int lput8(Map *map, Regs *regs, Loc loc, u64int v);
Loc locnone(void);
Loc locaddr(ulong addr);
Loc locconst(ulong con);
Loc locreg(char*);
Loc locindir(char*, long);
/*
* Executable file parsing.
*
* An Fhdr represents an open file image.
* The contents are a grab bag of constants used for the
* various file types. Not all elements are used by all
* file types.
*
* crackadotplan9.c crackadotunix.c
* crackelf.c crackdwarf.c
*/
enum
{
/* file types */
FNONE,
FEXEC, /* executable image */
FLIB, /* library */
FOBJ, /* object file */
FRELOC, /* relocatable executable */
FSHLIB, /* shared library */
FSHOBJ, /* shared object */
FCORE, /* core dump */
FBOOT, /* bootable image */
FKERNEL, /* kernel image */
NFTYPE,
/* abi types */
ANONE = 0,
APLAN9,
ALINUX,
AFREEBSD,
AMACH,
NATYPE
};
/* I wish this could be kept in stabs.h */
struct Stab
{
uchar *stabbase;
uint stabsize;
char *strbase;
uint strsize;
u16int (*e2)(uchar*);
u32int (*e4)(uchar*);
};
struct Fhdr
{
int fd; /* file descriptor */
char *filename; /* file name */
Mach *mach; /* machine */
char *mname; /* 386, power, ... */
uint mtype; /* machine type M386, ... */
char *fname; /* core, executable, boot image, ... */
uint ftype; /* file type FCORE, ... */
char *aname; /* abi name */
uint atype; /* abi type ALINUX, ... */
ulong magic; /* magic number */
ulong txtaddr; /* text address */
ulong entry; /* entry point */
ulong txtsz; /* text size */
ulong txtoff; /* text offset in file */
ulong dataddr; /* data address */
ulong datsz; /* data size */
ulong datoff; /* data offset in file */
ulong bsssz; /* bss size */
ulong symsz; /* symbol table size */
ulong symoff; /* symbol table offset in file */
ulong sppcsz; /* size of sp-pc table */
ulong sppcoff; /* offset of sp-pc table in file */
ulong lnpcsz; /* size of line number-pc table */
ulong lnpcoff; /* size of line number-pc table */
void *elf; /* handle to elf image */
void *dwarf; /* handle to dwarf image */
void *macho; /* handle to mach-o image */
struct Stab stabs;
/* private */
Symbol *sym; /* cached list of symbols */
Symbol **byname;
uint nsym;
Symbol *esym; /* elf symbols */
Symbol **ebyname;
uint nesym;
ulong base; /* base address for relocatables */
Fhdr *next; /* link to next fhdr (internal) */
/* file mapping */
int (*map)(Fhdr*, ulong, Map*, Regs**);
/* debugging symbol access; see below */
int (*syminit)(Fhdr*);
void (*symclose)(Fhdr*);
int (*pc2file)(Fhdr*, ulong, char*, uint, ulong*);
int (*file2pc)(Fhdr*, char*, ulong, ulong*);
int (*line2pc)(Fhdr*, ulong, ulong, ulong*);
int (*lookuplsym)(Fhdr*, Symbol*, char*, Symbol*);
int (*indexlsym)(Fhdr*, Symbol*, uint, Symbol*);
int (*findlsym)(Fhdr*, Symbol*, Loc, Symbol*);
int (*unwind)(Fhdr*, Map*, Regs*, ulong*);
};
Fhdr* crackhdr(char *file, int mode);
void uncrackhdr(Fhdr *hdr);
int crackelf(int fd, Fhdr *hdr);
int crackmacho(int fd, Fhdr *hdr);
int syminit(Fhdr*);
int symdwarf(Fhdr*);
int symelf(Fhdr*);
int symstabs(Fhdr*);
int symmacho(Fhdr*);
int mapfile(Fhdr *fp, ulong base, Map *map, Regs **regs);
void unmapfile(Fhdr *fp, Map *map);
/*
* Process manipulation.
*/
int mapproc(int pid, Map *map, Regs **regs);
void unmapproc(Map *map);
int detachproc(int pid);
int ctlproc(int pid, char *msg);
int procnotes(int pid, char ***notes);
char* proctextfile(int pid);
/*
* Machine descriptions.
*
* mach.c
* mach386.c dis386.c
* machsparc.c dissparc.c
* ...
*/
/*
* Register sets. The Regs are opaque, accessed by using
* the reglist (and really the accessor functions).
*/
enum
{
/* must be big enough for all machine register sets */
REGSIZE = 256,
RINT = 0<<0,
RFLT = 1<<0,
RRDONLY = 1<<1,
};
struct Regdesc
{
char *name; /* register name */
uint offset; /* offset in b */
uint flags; /* RINT/RFLT/RRDONLY */
uint format; /* print format: 'x', 'X', 'f', 'z', 'Z' */
};
Regdesc* regdesc(char*);
enum
{
/* machine types */
MNONE,
MMIPS, /* MIPS R3000 */
MSPARC, /* SUN SPARC */
M68000, /* Motorola 68000 */
M386, /* Intel 32-bit x86*/
M960, /* Intel 960 */
M3210, /* AT&T 3210 DSP */
MMIPS2, /* MIPS R4000 */
M29000, /* AMD 29000 */
MARM, /* ARM */
MPOWER, /* PowerPC */
MALPHA, /* DEC/Compaq Alpha */
NMTYPE
};
struct Mach
{
char *name; /* "386", ... */
uint type; /* M386, ... */
Regdesc *reglist; /* register set */
uint regsize; /* size of register set in bytes */
uint fpregsize; /* size of fp register set in bytes */
char *pc; /* name of program counter */
char *sp; /* name of stack pointer */
char *fp; /* name of frame pointer */
char *link; /* name of link register */
char *sbreg; /* name of static base */
ulong sb; /* value of static base */
uint pgsize; /* page size */
ulong kbase; /* kernel base address for Plan 9 */
ulong ktmask; /* ktzero = kbase & ~ktmask */
uint pcquant; /* pc quantum */
uint szaddr; /* size of pointer in bytes */
uint szreg; /* size of integer register */
uint szfloat; /* size of float */
uint szdouble; /* size of double */
char** windreg; /* unwinding registers */
uint nwindreg;
uchar bpinst[4]; /* break point instruction */
uint bpsize; /* size of bp instruction */
int (*foll)(Map*, Regs*, ulong, ulong*); /* follow set */
char* (*exc)(Map*, Regs*); /* last exception */
int (*unwind)(Map*, Regs*, ulong*);
/* cvt to local byte order */
u16int (*swap2)(u16int);
u32int (*swap4)(u32int);
u64int (*swap8)(u64int);
int (*ftoa32)(char*, uint, void*);
int (*ftoa64)(char*, uint, void*);
int (*ftoa80)(char*, uint, void*);
/* disassembly */
int (*das)(Map*, ulong, char, char*, int); /* symbolic */
int (*kendas)(Map*, ulong, char, char*, int); /* symbolic */
int (*codas)(Map*, ulong, char, char*, int);
int (*hexinst)(Map*, ulong, char*, int); /* hex */
int (*instsize)(Map*, ulong); /* instruction size */
};
Mach *machbyname(char*);
Mach *machbytype(uint);
extern Mach mach386;
extern Mach machsparc;
extern Mach machmips;
extern Mach machpower;
/*
* Debugging symbols and type information.
* (Not all objects include type information.)
*
* sym.c
*/
enum
{
/* symbol table classes */
CNONE,
CAUTO, /* stack variable */
CPARAM, /* function parameter */
CTEXT, /* text segment */
CDATA, /* data segment */
CANY,
};
struct Symbol
{
char *name; /* name of symbol */
/* Symtype *typedesc; /* type info, if any */
Loc loc; /* location of symbol */
Loc hiloc; /* location of end of symbol */
char class; /* CAUTO, ... */
char type; /* type letter from a.out.h */
Fhdr *fhdr; /* where did this come from? */
uint index; /* in by-address list */
/* private use by various symbol implementations */
union {
struct {
uint unit;
uint uoff;
} dwarf;
struct {
uint i;
uint locals;
char *dir;
char *file;
char frameptr;
uint framesize;
} stabs;
} u;
};
/* look through all currently cracked Fhdrs calling their fns */
int pc2file(ulong pc, char *file, uint nfile, ulong *line);
int file2pc(char *file, ulong line, ulong *addr);
int line2pc(ulong basepc, ulong line, ulong *pc);
int fnbound(ulong pc, ulong *bounds);
int fileline(ulong pc, char *a, uint n);
int pc2line(ulong pc, ulong *line);
int lookupsym(char *fn, char *var, Symbol *s);
int indexsym(uint ndx, Symbol *s);
int findsym(Loc loc, uint class, Symbol *s);
int findexsym(Fhdr*, uint, Symbol*);
int lookuplsym(Symbol *s1, char *name, Symbol *s2);
int indexlsym(Symbol *s1, uint ndx, Symbol *s2);
int findlsym(Symbol *s1, Loc loc, Symbol *s);
int symoff(char *a, uint n, ulong addr, uint class);
int unwindframe(Map *map, Regs *regs, ulong *next);
void _addhdr(Fhdr*);
void _delhdr(Fhdr*);
extern Fhdr* fhdrlist;
Symbol* flookupsym(Fhdr*, char*);
Symbol* ffindsym(Fhdr*, Loc, uint);
Symbol* addsym(Fhdr*, Symbol*);
/*
* Stack frame walking.
*
* frame.c
*/
int stacktrace(Map*, Regs*, Tracer);
int windindex(char*);
Loc* windreglocs(void);
/*
* Debugger help.
*/
int localaddr(Map *map, Regs *regs, char *fn, char *var, ulong *val);
int fpformat(Map *map, Regdesc *reg, char *a, uint n, uint code);
char* _hexify(char*, ulong, int);
int locfmt(Fmt*);
int loccmp(Loc*, Loc*);
int locsimplify(Map *map, Regs *regs, Loc loc, Loc *newloc);
extern int machdebug;
|