Enhance ioconnectcallmethod_hook to generate unique filenames for dumped inputStruct and print IOConnectCallMethod return code

This commit is contained in:
Karol Mazurek
2025-06-11 00:04:42 +02:00
parent 0fd3c811db
commit 06d77e7c09
+24 -6
View File
@@ -109,15 +109,20 @@ def ioconnectcallmethod_hook(frame, bp_loc, internal_dict):
if err.Success(): if err.Success():
service_name = sanitize_filename(info['service_name']) service_name = sanitize_filename(info['service_name'])
type_val = info['type'] type_val = info['type']
fname = ( # Find the next available n for the filename
f"corpus_{service_name}_{type_val}_{selector}_" n = 0
f"{inputCnt}_{inputStructCnt}_{outputCnt_str}_{outputStructCnt_str}_{corpus_counter}.bin" while True:
) fname = (
full_path = os.path.join(corpus_dir, fname) f"corpus_{service_name}_{type_val}_{selector}_"
f"{inputCnt}_{inputStructCnt}_{outputCnt_str}_{outputStructCnt_str}_{n}.bin"
)
full_path = os.path.join(corpus_dir, fname)
if not os.path.exists(full_path):
break
n += 1
with open(full_path, "wb") as f: with open(full_path, "wb") as f:
f.write(data) f.write(data)
print(f"[iokit_tracer] Dumped inputStruct ({inputStructCnt} bytes) to {full_path}") print(f"[iokit_tracer] Dumped inputStruct ({inputStructCnt} bytes) to {full_path}")
corpus_counter += 1
except Exception as e: except Exception as e:
print(f"[iokit_tracer] Error dumping inputStruct: {e}") print(f"[iokit_tracer] Error dumping inputStruct: {e}")
@@ -152,6 +157,19 @@ def ioconnectcallmethod_hook(frame, bp_loc, internal_dict):
lines.append(f"outputStructCnt: {outputStructCnt_str} (capacity pointer: {hex(outputStructCnt_ptr)})") lines.append(f"outputStructCnt: {outputStructCnt_str} (capacity pointer: {hex(outputStructCnt_ptr)})")
lines.append("----------------------------------------------------------------\n") lines.append("----------------------------------------------------------------\n")
print("\n".join(lines)) print("\n".join(lines))
# After printing all trace info, try to get the return value from the previous frame (caller)
result_code = None
caller_frame = thread.GetFrameAtIndex(1) if thread.GetNumFrames() > 1 else None
if caller_frame:
# On macOS/ARM64, return value is in x0; on x86_64, it's rax
reg = caller_frame.FindRegister("x0") if caller_frame.FindRegister("x0").IsValid() else caller_frame.FindRegister("rax")
if reg and reg.IsValid():
result_code = reg.GetValueAsUnsigned()
# Print result code if available
if result_code is not None:
print(f"[iokit_tracer] IOConnectCallMethod return code: 0x{result_code:x} ({result_code})")
else:
print("[iokit_tracer] IOConnectCallMethod return code: <unavailable>")
return False return False
def trace_iokit(debugger, command, result, internal_dict): def trace_iokit(debugger, command, result, internal_dict):