Last active
October 14, 2020 08:23
-
-
Save v-p-b/238d2e3bfa6671904f7e416e8a8ca562 to your computer and use it in GitHub Desktop.
From debugger to Lighthouse
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import struct | |
""" | |
From debugger trace to Lighthouse | |
================================= | |
Converting debugger trace logs to binary drcov format that is good enough for Lighthouse. | |
Quick and dirty, some hacking is probably required. | |
x64dbg Trace Log command: | |
{p:eip}, {dis.isbranch(eip)} | |
... if you Trace Into stuff (you should constrain log rules to a single module for this to work): | |
{p:eip}, {dis.isbranch(eip)||dis.isret(eip)} | |
Known issues: | |
* Tested with 32-bit only | |
* Branches aren't colored (but you get the BBs, so...) | |
* Threads... | |
""" | |
# === From https://github.com/gaasedelen/lighthouse/blob/master/coverage/frida/frida-drcov.py === | |
# take the module dict and format it as a drcov logfile header | |
def create_header(mods): | |
header = '' | |
header += 'DRCOV VERSION: 2\n' | |
header += 'DRCOV FLAVOR: drcov\n' | |
header += 'Module Table: version 2, count %d\n' % len(mods) | |
header += 'Columns: id, base, end, entry, checksum, timestamp, path\n' | |
entries = [] | |
for m in mods: | |
# drcov: id, base, end, entry, checksum, timestamp, path | |
# frida doesnt give us entry, checksum, or timestamp | |
# luckily, I don't think we need them. | |
entry = '%3d, %#016x, %#016x, %#016x, %#08x, %#08x, %s' % ( | |
m['id'], m['base'], m['end'], 0, 0, 0, m['path']) | |
entries.append(entry) | |
header_modules = '\n'.join(entries) | |
return header + header_modules + '\n' | |
def create_coverage(data): | |
bb_header = 'BB Table: %d bbs\n' % len(data) | |
return bb_header + ''.join(data) | |
# === | |
if len(sys.argv)<4: | |
print("Usage: drcov.py <TRACE FILE> <MODULE NAME> <MODULE BASE>") | |
print("Example: drcov.py trace.out dummy.dll dead0000") | |
exit() | |
mod_name=sys.argv[2] | |
base=int(sys.argv[3],16) | |
mods=[{"id":0,"base":base,"end":0x70900000,"path":"c:\\dummypath\\%s" % (mod_name)}] | |
bbs=[] | |
with open(sys.argv[1],"r") as trace: | |
lines=trace.readlines() | |
bb_start=None | |
for l in lines: | |
addr=int(l.split(",")[0].strip(),16)-base | |
isbranch=int(l.split(",")[1].strip())!=0 | |
if bb_start is None: | |
bb_start=addr | |
if isbranch: | |
print("%08x, %x" % (bb_start,addr-bb_start)) | |
if addr-bb_start<0: | |
print(hex(bb_start), hex(addr)) | |
""" | |
From lighthouse/parsers/drcov.py: | |
Based off the C structure as used by drcov - | |
/* Data structure for the coverage info itself */ | |
typedef struct _bb_entry_t { | |
uint start; /* offset of bb start from the image base */ | |
ushort size; | |
ushort mod_id; | |
} bb_entry_t; | |
""" | |
bbs.append(struct.pack("<IHH",bb_start,addr-bb_start,0)) | |
bb_start=None | |
with open("drcov.out","wb") as drcov: | |
drcov.write(create_header(mods)) | |
drcov.write(create_coverage(bbs)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment