Skip to content

Commit ad279da

Browse files
author
Your Name
committed
Changes to renumber modules in coverage file header
1 parent c784efe commit ad279da

File tree

1 file changed

+36
-23
lines changed

1 file changed

+36
-23
lines changed

src/traces/coverage/coverage.ts

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -348,19 +348,37 @@ export class Coverage implements CoverageSession {
348348
});
349349
Stalker.flush();
350350
const eventList = Array.from(this.events.entries());
351-
const convertedEvents = eventList.map(([start, end]) =>
352-
this.convertEvent(start, end),
351+
const convertedEvents = eventList
352+
.map(([start, end]) => this.convertEvent(start, end))
353+
.filter(e => e !== undefined) as ICoverageEvent[];
354+
355+
const referencedModuleIds = [
356+
...new Set(convertedEvents.map(e => e.moduleId)),
357+
].sort();
358+
359+
const referencedModules = this.modules.filter((_mapping, idx) =>
360+
referencedModuleIds.includes(idx),
353361
);
354-
const nonNullEvents = convertedEvents.filter(
355-
e => e !== undefined,
356-
) as ICoverageEvent[];
357-
358-
this.emitHeader(nonNullEvents);
359-
for (const convertedEvent of nonNullEvents) {
360-
if (convertedEvent !== undefined) {
361-
this.emitEvent(convertedEvent);
362-
}
363-
}
362+
363+
const mapping: { [moduleId: number]: number } = referencedModuleIds.reduce(
364+
(dict: { [moduleId: number]: number }, item: number, index: number) => {
365+
dict[item] = index;
366+
return dict;
367+
},
368+
{} as { [moduleId: number]: number },
369+
);
370+
371+
const remapped: ICoverageEvent[] = convertedEvents.map(
372+
e =>
373+
({
374+
length: e.length,
375+
moduleId: mapping[e.moduleId],
376+
offset: e.offset,
377+
}) as ICoverageEvent,
378+
);
379+
380+
this.emitHeader(referencedModules, convertedEvents);
381+
remapped.forEach(e => this.emitEvent(e));
364382
}
365383

366384
/**
@@ -436,20 +454,17 @@ export class Coverage implements CoverageSession {
436454

437455
/**
438456
* Function to emit the header information at the start of the DRCOV coverage information format. Note that the
439-
* format includes a number of events in the header. This is obviously not ideally suited to streaming data, so we
440-
* instead write the value of -1. This does not impair the operation of dragondance (which ignores the field), but
441-
* changes may be required for IDA lighthouse to accept this modification.
457+
* format includes a number of events in the header.
458+
* @param modules The modules referenced by the events
442459
* @param events The coverage events to be emitted in the file
443460
*/
444-
private emitHeader(events: ICoverageEvent[]): void {
461+
private emitHeader(modules: Module[], events: ICoverageEvent[]): void {
445462
this.emit(Coverage.convertString('DRCOV VERSION: 2\n'), true);
446463
this.emit(Coverage.convertString('DRCOV FLAVOR: frida\n'), true);
447464

448-
const referencedModules = [...new Set(events.map(e => e.moduleId))];
449-
450465
this.emit(
451466
Coverage.convertString(
452-
`Module Table: version 2, count ${referencedModules.length}\n`,
467+
`Module Table: version 2, count ${modules.length}\n`,
453468
),
454469
true,
455470
);
@@ -461,10 +476,8 @@ export class Coverage implements CoverageSession {
461476
true,
462477
);
463478

464-
465-
referencedModules.sort().forEach(id => {
466-
const module = this.modules[id] as Module;
467-
this.emitModule(id, module);
479+
modules.forEach((module, idx) => {
480+
this.emitModule(idx, module);
468481
});
469482

470483
this.emit(Coverage.convertString(`BB Table: ${events.length} bbs\n`), true);

0 commit comments

Comments
 (0)