Files

66 lines
2.2 KiB
Python

"""
RE (reverse engineering) skeleton — copy & fill. (p4-team style)
Common p4 patterns:
* Extract bytes from a .rodata / data dump (IDA "db 30h" lines) -> often just
RSA key material. See 'reversing_is_amazing': parse the bytes, RSA.importKey,
then decrypt the given ciphertext.
* Symbolic execution / path constraint solving with angr.
* Binary parsing / patching with lief; emulation with unicorn.
"""
import re
# ---- pattern A: RSA key from an IDA/Ghidra byte dump ----
def bytes_from_rodata(dump_text):
"""Parse lines like: .rodata:0000 db 30h, 82h, 2, 5Ch ; comment"""
out = []
for line in dump_text.splitlines():
m = re.search(r"\bdb\b\s+(.*)", line)
if not m:
continue
body = m.group(1).split(";")[0]
for tok in re.findall(r"([0-9a-fA-F]+)h?|(\d+)", body):
val = tok[0] or tok[1]
try:
out.append(int(val, 16) if (tok[0] and val.endswith("h")) or
(tok[0] and not val.isdigit()) else int(val))
except ValueError:
pass
return bytes(out)
def solve_rsa_from_dump(dump_text, ciphertext_int):
from Crypto.PublicKey import RSA
from Crypto.Util.number import long_to_bytes
data = bytes_from_rodata(dump_text)
key = RSA.importKey(bytearray(data))
return long_to_bytes(pow(ciphertext_int, key.e, key.n))
# ---- pattern B: angr symbolic execution (uncomment & adapt) ----
"""
import angr, claripy
def solve_with_angr(binary, find_addr, avoid_addr, input_len=20):
proj = angr.Project(binary, auto_load_libs=False)
sim = proj.factory.entry_state()
flag = sim.solver.BVS('flag', input_len*8)
for i in range(input_len):
sim.memory.store(sim.regs.rsp + i, flag.get_byte(i))
sim = proj.factory.simgr(sim)
sim.explore(find=find_addr, avoid=avoid_addr)
if sim.found:
return sim.found[0].solver.eval(flag, cast_to=bytes)
"""
# ---- pattern C: lief parse / patch ----
"""
import lief
def parse(binary):
f = lief.parse(binary)
for sym in f.symbols: print(sym.name, hex(sym.value))
"""
if __name__ == "__main__":
raise NotImplementedError("pick a pattern above and fill it in")