Video: Solving VM-based challenges using Cerbero

How to solve VM-based challenges with the help of Cerbero.

This is the template code:

from Pro.Core import *
from Pro.UI import *
from Pro.ccast import sbyte
import os, struct

REG_COUNT = 16

def regName(id):
    return "R" + str(id)

def disassemble(code, regs):
    return "instr"

STEP_VIEW_ID = 1
DISASM_VIEW_ID = 2
MEMORY_VIEW_ID = 3
REGISTERS_VIEW_ID = 4
STACK_VIEW_ID = 5

# the dump directory should have files with increasing number as name
# e.g.: 0, 1, 2, etc.
DBGDIR = r"path/to/state/dumps"
BPX = -1

# logic to extract the instruction pointer from the dumps
# we use that as text in the Trace table and to go to a break point
def loadStepDescr(ud, steps):
    stepsdescr = []
    bpx_pos = -1
    for step in steps:
        with open(os.path.join(DBGDIR, str(step)), "rb") as f:
            f.seek((REG_COUNT - 1) * 2)
            ip = struct.unpack_from(">H", f.read(2), 0)[0]
            if bpx_pos == -1 and ip == BPX:
                bpx_pos = len(stepsdescr)
            stepsdescr.append("%04X" % (ip,))
    ud["stepsdescr"] = stepsdescr
    if bpx_pos != -1:
        ud["bpxpos"] = bpx_pos

def loadStep(cv, step, ud):
    #with open(os.path.join(DBGDIR, str(step)), "rb") as f:
    #    dump = f.read()
    dump = b"\x00\x01" * REG_COUNT
    regs = struct.unpack_from("<" + ("H" * REG_COUNT), dump, 0)
    ud["regs"] = regs
    # set up regs table
    t = cv.getView(REGISTERS_VIEW_ID)
    labels = NTStringList()
    labels.append("Register")
    labels.append("Value")
    t.setColumnCount(2)
    t.setRowCount(REG_COUNT)
    t.setColumnLabels(labels)
    t.setColumnCWidth(0, 10)
    t.setColumnCWidth(1, 20)
    # set up memory
    h = cv.getView(MEMORY_VIEW_ID)
    curoffs = h.getCurrentOffset()
    cursoroffs = h.getCursorOffset()
    #mem = dump[REG_COUNT * 2:]
    mem = b"dummy memory"
    ud["mem"] = mem
    h.setBytes(mem)
    h.setCursorOffset(cursoroffs)
    h.setCurrentOffset(curoffs)
    # set up stack table
    stack = (0x1000, 0x2000, 0x3000)
    ud["cursp"] = 0x6000
    ud["stack"] = stack
    t = cv.getView(STACK_VIEW_ID)
    labels = NTStringList()
    labels.append("Stack address")
    labels.append("Value")
    t.setColumnCount(2)
    t.setRowCount(len(stack))
    t.setColumnLabels(labels)
    t.setColumnCWidth(0, 10)
    t.setColumnCWidth(1, 20)
    # set up disasm
    t = cv.getView(DISASM_VIEW_ID)
    disasm = disassemble(mem, regs)
    t.setText(disasm)

def tracerCallback(cv, ud, code, view, data):
    if code == pvnInit:
        # get steps
        steps = os.listdir(dbgdir)
        steps = [int(e) for e in steps]
        steps = sorted(steps)
        ud["steps"] = steps
        loadStepDescr(ud, steps)
        # set up steps
        t = cv.getView(STEP_VIEW_ID)
        labels = NTStringList()
        labels.append("Trace")
        t.setColumnCount(1)
        t.setRowCount(len(steps))
        t.setColumnLabels(labels)
        t.setColumnCWidth(0, 10)
        # go to bpx if any
        if "bpxpos" in ud:
            bpxpos = ud["bpxpos"]
            t.setSelectedRow(bpxpos)
        return 1
    elif code == pvnGetTableRow:
        vid = view.id()
        if vid == STEP_VIEW_ID:
            data.setText(0, str(ud["stepsdescr"][data.row]))
        elif vid == REGISTERS_VIEW_ID:
            data.setText(0, regName(data.row))
            v = ud["regs"][data.row]
            data.setText(1, "%d (0x%X)" % (v, v))
            if data.row >= 13:
                data.setBgColor(0, ProColor_Special)
                data.setBgColor(1, ProColor_Special)
        elif vid == STACK_VIEW_ID:
            spaddr = ud["cursp"] + (data.row * 2)
            data.setText(0, "0x%04X" % (spaddr,))
            v = ud["stack"][data.row]
            data.setText(1, "%d (0x%X)" % (v, v))
    elif code == pvnRowSelected:
        vid = view.id()
        if vid == STEP_VIEW_ID:
            loadStep(cv, ud["steps"][data.row], ud)
    return 0

def tracerDlg():
    ctx = proContext()
    v = ctx.createView(ProView.Type_Custom, "Tracer Demo")
    user_data = {}
    v.setup("<ui><hs><table id='1'/><vs><text id='2'/><hex id='3'/></vs><table id='4'/><table id='5'/></hs></ui>", tracerCallback, user_data)
    dlg = ctx.createDialog(v)
    dlg.show()
    
tracerDlg()

Leave a Reply

Your email address will not be published. Required fields are marked *