-
Notifications
You must be signed in to change notification settings - Fork 5
/
debdump.d
101 lines (88 loc) · 2.2 KB
/
debdump.d
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
import std.conv;
import std.exception;
import std.path;
import std.process;
import std.stdio;
import std.string;
import x86dis;
import windebug;
void main(string[] args)
{
assert(args.length >= 2, "Usage: trace sym dest");
auto trace = args[1];
auto sym = args.length >= 3 ? args[2] : args[1].setExtension("sym");
auto dest = args.length >= 4 ? args[3] : args[1].setExtension("log");
dump(trace, sym, dest);
}
string[uint] getSyms(string fn)
{
string[uint] r;
foreach(l; File(fn, "r").byLine())
{
foreach(ref char c; l)
if (c >= 0x80)
c = '?';
auto x = split(l);
r[to!uint(x[0], 16)] = x[1].idup;
}
return r;
}
void dump(string src, string symf, string dest)
{
auto f0 = File(src, "rb");
auto l0 = f0.byLine();
uint lastbase;
bool u;
auto out0 = File(dest, "w");
auto count = 0;
auto syms = getSyms(symf);
while (!l0.empty && count < 1_000_000)
{
auto con0 = unpack(l0.front);
if (con0.addr > 0x400_000 && con0.addr < 0x500_000)
{
con0.expand(syms);
out0.writefln("%.8X: %s (%s+0x%X)", con0.addr, X86Disassemble(con0.inst.ptr), con0.sym, con0.off);
}
else if (con0.addr < 0x400_000 || con0.addr > 0x500_000 && u)
{
}
else if (lastbase != con0.addr - con0.off)
{
con0.expand(syms);
u = con0.sym == "__Unknown__";
out0.writefln("%.8X: %s (%s+0x%X)", con0.addr, X86Disassemble(con0.inst.ptr), con0.sym, con0.off);
lastbase = con0.addr - con0.off;
}
l0.popFront();
}
}
struct context
{
uint addr;
ubyte[16] inst;
uint off;
string sym;
void expand(string[uint] syms)
{
sym = "__Unknown__";
auto p = addr;
while (p >= 0x400000 && p <= 0x500000 && p !in syms)
p--;
if (p in syms)
sym = syms[p];
off = addr - p;
}
}
context unpack(char[] l)
{
auto v = split(l);
context c;
with (c)
{
scope(failure) writeln(v);
addr = to!uint(v[0], 16);
foreach(i, ref b; inst) b = to!ubyte(v[1][i*2..i*2+2], 16);
}
return c;
}