Skip to content

Instantly share code, notes, and snippets.

@v-p-b
Last active October 14, 2020 08:23
Show Gist options
  • Save v-p-b/238d2e3bfa6671904f7e416e8a8ca562 to your computer and use it in GitHub Desktop.
Save v-p-b/238d2e3bfa6671904f7e416e8a8ca562 to your computer and use it in GitHub Desktop.
From debugger to Lighthouse
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