You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
4.3 KiB
101 lines
4.3 KiB
import os
|
|
print("from import")
|
|
del os.environ["LD_PRELOAD"]
|
|
import ctypes, ctypes.util
|
|
from extra.dsp.run import install_hook, ioctl, libc, get_struct, qcom_dsp, format_struct, to_mv, hexdump
|
|
|
|
@ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_long)
|
|
def _mmap(addr, length, prot, flags, fd, offset):
|
|
mmap_type = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_long)
|
|
orig_mmap = mmap_type(ctypes.addressof(orig_mmap_mv))
|
|
ret = orig_mmap(addr, length, prot, flags, fd, offset)
|
|
# ll = os.readlink(f"/proc/self/fd/{fd}") if fd >= 0 else ""
|
|
print(f"mmap {addr=}, {length=}, {prot=}, {flags=}, {fd=}, {offset=} {ret=}")
|
|
return ret
|
|
|
|
#install_hook(libc.ioctl, ioctl)
|
|
#orig_mmap_mv = install_hook(libc.mmap, _mmap)
|
|
print("import done")
|
|
import mmap
|
|
|
|
alloc_sizes = {}
|
|
mmaped = {}
|
|
|
|
def handle_ioctl(fd, request, argp, ret):
|
|
fn = os.readlink(f"/proc/self/fd/{fd}")
|
|
idir, size, itype, nr = (request>>30), (request>>16)&0x3FFF, (request>>8)&0xFF, request&0xFF
|
|
|
|
if fn == "/dev/ion":
|
|
if nr == 0:
|
|
st = get_struct(argp, qcom_dsp.struct_ion_allocation_data)
|
|
print(ret, "ION_IOC_ALLOC", format_struct(st))
|
|
alloc_sizes[st.handle] = st.len
|
|
elif nr == 1:
|
|
st = get_struct(argp, qcom_dsp.struct_ion_handle_data)
|
|
print(ret, "ION_IOC_FREE", format_struct(st))
|
|
if st.handle in alloc_sizes: del alloc_sizes[st.handle]
|
|
if st.handle in mmaped: del mmaped[st.handle]
|
|
elif nr == 2:
|
|
st = get_struct(argp, qcom_dsp.struct_ion_fd_data)
|
|
print(ret, "ION_IOC_MAP", format_struct(st))
|
|
mmaped[st.handle] = mmap.mmap(st.fd, alloc_sizes[st.handle])
|
|
elif fn == "/dev/adsprpc-smd":
|
|
assert chr(itype) == 'R'
|
|
if nr == 8:
|
|
st = ctypes.c_uint32.from_address(argp)
|
|
print(ret, "FASTRPC_IOCTL_GETINFO", st.value)
|
|
elif nr == 2:
|
|
st = get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_mmap)
|
|
print(ret, "FASTRPC_IOCTL_MMAP", format_struct(st))
|
|
elif nr == 1:
|
|
# https://research.checkpoint.com/2021/pwn2own-qualcomm-dsp/
|
|
st = get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_invoke)
|
|
print(ret, "FASTRPC_IOCTL_INVOKE", format_struct(st))
|
|
# 0xFF000000 = Method index and attribute (the highest byte)
|
|
# 0x00FF0000 = Number of input arguments
|
|
# 0x0000FF00 = Number of output arguments
|
|
# 0x000000F0 = Number of input handles
|
|
# 0x0000000F = Number of output handles
|
|
|
|
method = (st.sc>>24) & 0xFF
|
|
in_args = (st.sc>>16) & 0xFF
|
|
out_args = (st.sc>>8) & 0xFF
|
|
in_h = (st.sc>>4) & 0xF
|
|
out_h = (st.sc>>0) & 0xF
|
|
print(f"\tm:{method} ia:{in_args} oa:{out_args} ih:{in_h} oh:{out_h}")
|
|
"""
|
|
if in_args or out_args:
|
|
for arg in range(in_args+out_args):
|
|
print(arg, format_struct(st.pra[arg]))
|
|
if st.pra[arg].buf.pv is not None:
|
|
ww = to_mv(st.pra[arg].buf.pv, st.pra[arg].buf.len)
|
|
hexdump(to_mv(st.pra[arg].buf.pv, st.pra[arg].buf.len)[:0x40])
|
|
"""
|
|
elif nr == 6:
|
|
print(ret, "FASTRPC_IOCTL_INIT", format_struct(ini:=get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_init)))
|
|
print(os.readlink(f"/proc/self/fd/{ini.filefd}"))
|
|
# print(bytearray(to_mv(ini.file, ini.filelen)))
|
|
elif nr == 7:
|
|
print(ret, "FASTRPC_IOCTL_INVOKE_ATTRS", format_struct(ini:=get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_invoke_attrs)))
|
|
elif nr == 12: print(ret, "FASTRPC_IOCTL_CONTROL", format_struct(get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_control)))
|
|
elif nr == 4:
|
|
st_fd = get_struct(argp, qcom_dsp.struct_fastrpc_ioctl_invoke_fd)
|
|
st = st_fd.inv
|
|
print(ret, "FASTRPC_IOCTL_INVOKE_FD", format_struct(st))
|
|
|
|
method = (st.sc>>24) & 0xFF
|
|
in_args = (st.sc>>16) & 0xFF
|
|
out_args = (st.sc>>8) & 0xFF
|
|
in_h = (st.sc>>4) & 0xF
|
|
out_h = (st.sc>>0) & 0xF
|
|
print(f"\tm:{method} ia:{in_args} oa:{out_args} ih:{in_h} oh:{out_h}")
|
|
|
|
if st.sc in [0x2030200, 0x3040300]:
|
|
for handle, mapped in mmaped.items():
|
|
print(f" buffer {handle} {alloc_sizes[handle]:X}")
|
|
with open(f"/tmp/buf_{st.sc:X}_{handle}_{alloc_sizes[handle]:X}", "wb") as f: f.write(mapped)
|
|
else:
|
|
print(f"{ret} UNPARSED {nr}")
|
|
else:
|
|
print("ioctl", f"{idir=} {size=} {itype=} {nr=} {fd=} {ret=}", fn)
|
|
|
|
|