cpup entry point id

This commit is contained in:
Elliot Nunn 2018-03-06 17:25:35 +08:00
parent 09de7433ab
commit 6081cb1e2c
3 changed files with 232 additions and 0 deletions

View File

@ -0,0 +1,72 @@
#!/usr/bin/env python3
from pefbinary import PEF
from zcpcore import read_rsrc_path
# FIGURE OUT THE ENTRY POINTS IN A CPU PLUGIN!
# Paste in what the NanoKernel extruded under the influence of HackLogFirstSIGPs.
NK_OUTPUT = """
0 7c0802a6 90010008 9421ffc0 5463043e 480086d9 80410014 39820360 806c0748 38210040
1 7c0802a6 bf41ffe8 90010008 9421ffb0 3bc20360 549f043e 57e7083c 7d07f214 547d043e
2 7c0802a6 bfa1fff4 90010008 9421ffb0 3bc20360 549f043e 57e5083c 7cc5f214 5463043e
3 7c0802a6 bf81fff0 90010008 9421ffb0 3b820360 549f043e 57e5083c 7cc5e214 547e043e
4 7c0802a6 bf41ffe8 90010008 9421ffb0 3bc20360 549f043e 3b600001 57e5083c 3b400000
5 7c0802a6 bfc1fff8 90010008 9421ffc0 3bc20360 549f043e 5463043e 480084bd 80410014
6 7c0802a6 bfc1fff8 90010008 9421ffc0 83e2ffc4 549e043e 5463043e 48008239 80410014
7 7c0802a6 bfc1fff8 90010008 9421ffc0 83e2ffc4 549e043e 5463043e 4800810d 80410014
8 7c0802a6 bf41ffe8 90010008 9421ffb0 3bc20360 547c043e 837e074c 7f83e378 8bbe0f82
9 7c0802a6 bf21ffe4 90010008 9421ffa0 3bc20360 547d043e 839e0b80 57bf083c 3b400000
10 7c0802a6 bfc1fff8 90010008 9421ffc0 3bc20360 549f043e 5463043e 48007de1 80410014
11 7c0802a6 90010008 9421ffc0 5463043e 48007d81 80410014 38210040 80010008 7c0803a6
12 7c0802a6 bee1ffdc 90010008 9421ffa0 90a10080 90c10084 90e10088 9101008c 91210090
13 7c0802a6 be61ffcc 90010008 9421ff90 83e2ffc4 547a043e 839f0b7c 3b000001 833f0b80
14 456e7472 79000000 00000000 00000000 4e56ffe2 48e70718 266e0008 7005fe04 28484aae
15 456e7472 79000000 00000000 00000000 4e56ffe2 48e70718 266e0008 7005fe04 28484aae
16 7c0802a6 bf21ffe4 90010008 9421ffa0 90c10084 90e10088 9101008c 91210090 91410094
17 7c0802a6 90010008 9421ffc0 5463043e 48006fd5 80410014 8062ffc4 38800007 48003409
"""
# And this should be the PEF to search.
CPUP_PATH = '/Users/elliotnunn/Nosy/Victims/Extensions/Multiprocessing/Apple CPU Plugins//cpup/4/Core99Plugin/locked'
KNOWN_SELECTORS = {
1: 'StartProcessor',
3: 'StopProcessor',
4: 'ResetProcessor',
8: 'SynchClock',
}
whole_binary = read_rsrc_path(CPUP_PATH)
code_section = PEF(whole_binary).code
patchpef_args = []
for l in NK_OUTPUT.split('\n'):
l = l.rstrip()
if not l: continue
n, _, hx = l.partition(' ')
n = int(n)
hx = bytes.fromhex(hx.replace(' ', ''))
name = KNOWN_SELECTORS.get(n, 'UnknownSelector')
name = '%s_%d' % (name, n)
print('Selector %d:' % n, end='')
loc = code_section.find(hx)
if loc == -1:
print(' not found')
continue
while loc != -1:
patchpef_args.extend(['0x%X' % loc, ':'+name])
print(' 0x%X' % loc, end='')
loc = code_section.find(hx, loc+1)
print()
if patchpef_args:
print()
print('Suggested patchpef arguments:')
print(*patchpef_args)

88
pefbinary.py Executable file
View File

@ -0,0 +1,88 @@
import struct
class PEF:
MAGIC = b'Joy!'
CONT_HEAD_FMT = '>4s4s4s5I2HI'
CONT_HEAD_LEN = struct.calcsize(CONT_HEAD_FMT)
SEC_HEAD_FMT = '>i5I4B'
SEC_HED_LEN = struct.calcsize(SEC_HEAD_FMT)
@classmethod
def read_from(cls, path):
with open(path, 'rb') as f:
return cls(f.read())
def __init__(self, data):
(magic, fourcc, arch, ver,
timestamp, old_def_ver, old_imp_ver, cur_ver,
sec_count, inst_sec_count, reserv) = struct.unpack_from(self.CONT_HEAD_FMT, data)
sec_earliest = len(data)
sec_latest = 0
self.sections = []
self.sectypes = []
self.headeroffsets = []
self.code = None
for i in range(sec_count):
sh_offset = self.CONT_HEAD_LEN + self.SEC_HED_LEN*i
(sectionName, sectionAddress, execSize,
initSize, rawSize, containerOffset,
regionKind, shareKind, alignment, reserved) = struct.unpack_from(self.SEC_HEAD_FMT, data, sh_offset)
the_sec = data[containerOffset : containerOffset + rawSize]
if regionKind == 0 and execSize == initSize == rawSize:
the_sec = bytearray(the_sec)
self.code = the_sec
self.sections.append(the_sec)
self.sectypes.append(regionKind)
self.headeroffsets.append(sh_offset)
sec_earliest = min(sec_earliest, containerOffset)
sec_latest = max(sec_latest, containerOffset + rawSize)
if any(data[sec_latest:]):
print('nonzero trailing data from', hex(sec_latest), 'to', hex(len(data)), ' ... will cause incorrect output')
self.padmult = 1
while len(data) % (self.padmult * 2) == 0:
self.padmult *= 2
self.header = data[:sec_earliest]
def __bytes__(self):
accum = bytearray(self.header)
for i in range(len(self.sections)):
the_sec = self.sections[i]
hoff = self.headeroffsets[i]
while len(accum) % 16:
accum.append(0)
new_off = len(accum)
new_len = len(the_sec)
accum.extend(the_sec)
struct.pack_into('>I', accum, hoff + 20, new_off)
if the_sec is self.code:
for i in range(8, 20, 4):
struct.pack_into('>I', accum, hoff + i, new_len)
while len(accum) % self.padmult != 0:
accum.extend(b'\x00')
return bytes(accum)
def write_to(self, path):
with open(path, 'wb') as f:
f.write(bytes(self))

72
zcpcore.py Normal file
View File

@ -0,0 +1,72 @@
#!/usr/bin/env python3
from subprocess import run, PIPE
from sys import argv
import tempfile
def read_rsrc_path(path):
BADCHARS = b'\t$" '
if '//' not in path:
with open(path, 'rb') as f:
return f.read()
else:
path, _, rest = path.partition('//')
rtype, rid, *_ = rest.split('/')
try:
int(rid)
except ValueError:
rid = '"%s"' % rid
type_expr = '\'%s\' (%s)' % (rtype, rid)
rez_code = run(['DeRez', '-only', type_expr, path], stdout=PIPE, check=True).stdout
if len(rez_code) < 2:
raise FileNotFoundError
accum = bytearray()
for l in rez_code.split(b'\n'):
if len(l) >= 6 and l[1:2] == b'$':
hx = l[:43].lstrip(BADCHARS).rstrip(BADCHARS)
accum.extend(bytes.fromhex(hx.decode('ascii')))
return bytes(accum)
def write_rsrc_path(path, data):
STEP = 32
if '//' not in path:
with open(path, 'wb') as f:
f.write(data)
else:
path, _, rest = path.partition('//')
rtype, rid, *args = rest.split('/')
if args:
rname = ', "%s"' % args[0]
args = args[1:]
else:
rname = ""
rid = int(rid)
args = ''.join(', %s' % x for x in args)
with tempfile.NamedTemporaryFile(mode='w') as f:
print('data \'%s\' (%d%s%s) {\n' % (rtype, rid, rname, args), file=f)
for o in range(0, len(data), STEP):
chunk = data[o:o+STEP].hex()
print('\t$"%s"' % chunk, file=f)
print('};', file=f)
f.flush()
run(['Rez', '-a', '-o', path, f.name], check=True)