forked from 0vercl0k/windbg-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcodecov.js
144 lines (121 loc) · 3.89 KB
/
codecov.js
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
// Axel '0vercl0k' Souchet - 2 Feb 2018
//
// Example:
// 0:000> !codecov "kernel"
// Looking for *kernel*..
// Found 2 hits
// Found 7815 unique addresses in C:\WINDOWS\System32\KERNELBASE.dll
// Found 1260 unique addresses in C:\WINDOWS\System32\KERNEL32.DLL
// Writing C:\work\codes\tmp\js01.run.kernel.text...
// Done!
// @$codecov("kernel")
// 0:000> !codecov "kernel"
// Looking for *kernel*..
// The output file C:\work\codes\tmp\js01.run.kernel.text already exists, exiting.
// @$codecov("kernel")
//
'use strict';
const log = host.diagnostics.debugLog;
const logln = p => host.diagnostics.debugLog(p + '\n');
const hex = p => p.toString(16);
function ExtractModuleName(ModulePath) {
return ModulePath.slice(
ModulePath.lastIndexOf('\\') + 1
);
}
function CodeCoverageModule(Module) {
const CurrentSession = host.currentSession;
const BaseAddress = Module.BaseAddress;
const Size = Module.Size;
const CoverageLines = CurrentSession.TTD.Memory(
BaseAddress,
BaseAddress.add(Size),
'EC'
);
const Offsets = Array.from(CoverageLines).map(
p => hex(
p.Address.subtract(BaseAddress)
)
);
return {
'Path' : Module.Name.toLowerCase(),
'Base' : BaseAddress,
'Size' : Size,
'Offsets' : Offsets
};
}
function CodeCov(ModulePattern) {
const CurrentSession = host.currentSession;
const CurrentProcess = host.currentProcess;
const Utility = host.namespace.Debugger.Utility;
if(!CurrentSession.Attributes.Target.IsTTDTarget) {
logln('!codecov expects a TTD trace');
return;
}
if(ModulePattern == undefined) {
logln('!codecov "pattern"');
return;
}
ModulePattern = ModulePattern.toLowerCase();
logln('Looking for *' + ModulePattern + '*..');
const Modules = CurrentProcess.Modules.Where(
p => p.Name.toLowerCase().indexOf(ModulePattern) != -1
);
if(Modules.Count() == 0) {
logln('Could not find any matching module, exiting');
return;
}
const TracePath = CurrentSession.Attributes.Target.Details.DumpFileName;
const TraceDir = TracePath.slice(
0,
TracePath.lastIndexOf('\\')
);
const TraceName = TracePath.slice(
TracePath.lastIndexOf('\\') + 1
);
const FilePath = TraceDir + '\\' + TraceName + '.' + ModulePattern + '.txt';
if(Utility.FileSystem.FileExists(FilePath)) {
logln('The output file ' + FilePath + ' already exists, exiting.');
return;
}
const Metadata = {
'TracePath' : TracePath
};
const CoverageModules = [];
logln('Found ' + Modules.Count() + ' hits');
for(const Module of Modules) {
const ModuleCoverage = CodeCoverageModule(Module);
logln('Found ' + ModuleCoverage.Offsets.length + ' unique addresses in ' + Module.Name);
CoverageModules.push(ModuleCoverage);
}
logln('Writing ' + FilePath + '...');
const FileHandle = Utility.FileSystem.CreateFile(FilePath, 'CreateAlways');
const Writer = Utility.FileSystem.CreateTextWriter(FileHandle);
for(const [Name, Value] of Object.entries(Metadata)) {
Writer.WriteLine('; ' + Name + ': ' + Value);
}
for(const Module of CoverageModules) {
//
// First write the metadata that is module specific.
//
Writer.WriteLine('; ' + Module.Path + ', ' + hex(Module.Base) + ', ' + hex(Module.Size));
//
// Write down the offsets.
//
const ModuleName = ExtractModuleName(Module.Path);
for(const Offset of Module.Offsets) {
Writer.WriteLine(ModuleName + '+' + hex(Offset));
}
}
FileHandle.Close();
logln('Done!');
}
function initializeScript() {
return [
new host.apiVersionSupport(1, 2),
new host.functionAlias(
CodeCov,
'codecov'
)
];
}