aboutsummaryrefslogtreecommitdiffstats
path: root/psp_out/svcscan.py
blob: fb7b758a0956b1b9339eb0fe8f2845d89c97ecf3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
"""Enumerate the SVC numbers each TA actually issues (function-accurate disassembly),
then map them to the sOS handler side. TA-reachable SVCs are the host->TA->kernel
privilege boundary."""
import struct, json, sys
from capstone import *

BASE = '/Users/user/dev/amd-psp-re/psp_out/handover/'

def load(mod):
    raw = open(BASE + 'elf/%s2.elf' % mod, 'rb').read()
    ph = struct.unpack('<I', raw[28:32])[0]
    o, v, pa, f = struct.unpack('<IIII', raw[ph+4:ph+20])
    d = json.load(open(BASE + 'symbols/%s.json' % mod))
    return raw[o:o+f], v, {int(k, 16): val for k, val in d['functions'].items()}

def svcs_of(mod):
    body, vaddr, funcs = load(mod)
    md = Cs(CS_ARCH_ARM, CS_MODE_THUMB)
    out = {}
    for ea, f in funcs.items():
        end = f.get('end', ea + 0x40)
        if end <= ea or end - ea > 0x4000: end = ea + 0x40
        off = ea - vaddr
        if off < 0 or off >= len(body): continue
        for i in md.disasm(body[off:off + (end - ea)], ea):
            if i.mnemonic.startswith('svc'):
                try: n = int(i.op_str.replace('#', ''), 0)
                except Exception: continue
                out.setdefault(n, []).append(f['name'])
    return out

if __name__ == '__main__':
    allsvc = {}
    for mod in ('hdcp', 'asd', 'dtm', 'ras'):
        s = svcs_of(mod)
        print("%-5s : %s" % (mod, sorted(hex(k) for k in s)))
        for k, v in s.items(): allsvc.setdefault(k, set()).update([mod])
    print("\n=== union of TA-reachable SVC numbers ===")
    for k in sorted(allsvc):
        print("  %#04x  used by %s" % (k, sorted(allsvc[k])))