Skip to content

Examples | Searching through the Database, but Quickly

Ali Rizvi-Santiago edited this page Apr 28, 2023 · 2 revisions

Searching all branch instructions for a specific offset

This gets you all direct calls to a specific virtual method, but ignores cases where the operand is loaded and then executed.

# what array index are we looking for?
index = 52
# index = db.address(db.a.prevlabel(), db.a.nextlabel()).index(h())

# first we need some range to search
bounds = seg.bounds('.text')

# now we can grab all the bytes that contain the index "\x34"
Fstep = functools.partial(db.a.nextbyte, index)
candidates = db.address(bounds, Fstep)

# then we can filter them for only addresses representing instructions
filtered_candidates = [ea for ea in candidates if db.type.code(ea)]

# now we can just search the readable operands of all of these instructions
results = []
for ea in filtered_candidates:
    for ref in ins.ops_read(ea):
        # check if the readable (r) operand is being executed (x)
        if 'x' in ref and ins.op(ref).offset == index:
            results.append(ea)
            break
        continue
    continue

# of course this can be done with a list comprehension
results = [ea for ea in filtered_candidates if any(ins.op(ref).offset == index for ref in ins.ops_read(ea) if 'x' in ref)]

# show your work
for ea in results:
    print(db.disasm(ea))

Searching all instructions for a store to some specific offset

This is essentially the same as the previous topic, except we filter it a little bit differently.

# first we need a value and some range to search, but let's do it backwards.
left, right = db.top(), db.bottom()
value = 0x5c

# now we can grab all the addresses using this value, but backwards.
Fstep = functools.partial(db.a.prevbyte, value)
candidates = db.address(bottom, top, Fstep)

# then we can filter them for only addresses representing instructions
filtered_candidates = [ea for ea in candidates if db.type.code(ea)]

# and then use a list-comprehension to find all writes (w) to an operand
writes = [ea for ea in filtered_candidates if any('w' in ref for ref in ins.ops_write(ea) if isinstance(ins.op(ref), tuple))]

# and finish by checking the operand for a specific value
results = [ea for ea in writes if any(ins.op(ref).offset in {value} for ref in ins.ops_write(ea))]

# show your moves
for ea in results:
    print(db.disasm(results))