mirror of
https://github.com/Karmaz95/Snake_Apple.git
synced 2026-09-29 00:01:44 +02:00
Enhance IDA script for IOExternalMethodDispatch structures:
- Added support for struct_type argument in create_external_method_dispatch_struct and format_external_method_array functions. - Updated documentation for usage and structure formats. - Improved handling of specific fields for IOExternalMethodDispatch2022.
This commit is contained in:
1 parent
bcc9f34241
commit
0f8df62d82
1 file changed
+78
-26
@@ -1,45 +1,86 @@
|
|||||||
|
"""
|
||||||
|
IDA script to format and analyze IOExternalMethodDispatch structures in iOS kernelcache.
|
||||||
|
Supports both IOExternalMethodDispatch (0x18 bytes) and IOExternalMethodDispatch2022 (0x28 bytes) formats.
|
||||||
|
|
||||||
|
Usage in IDA Python console:
|
||||||
|
format_external_method_array(0xFFFFFE0007DCDBD8, 16, 1) # For old format
|
||||||
|
format_external_method_array(0xFFFFFE0007DCDBD8, 16) # For 2022 format
|
||||||
|
|
||||||
|
Structure formats:
|
||||||
|
IOExternalMethodDispatch (0x18):
|
||||||
|
0x00 - function (ptr)
|
||||||
|
0x08 - checkScalarInputCount
|
||||||
|
0x0C - checkStructureInputSize
|
||||||
|
0x10 - checkScalarOutputCount
|
||||||
|
0x14 - checkStructureOutputSize
|
||||||
|
|
||||||
|
IOExternalMethodDispatch2022 (0x28):
|
||||||
|
[all fields from IOExternalMethodDispatch]
|
||||||
|
0x18 - allowAsync
|
||||||
|
0x20 - checkEntitlement (ptr)
|
||||||
|
"""
|
||||||
|
|
||||||
from idaapi import *
|
from idaapi import *
|
||||||
import ida_bytes
|
import ida_bytes
|
||||||
import idc
|
import idc
|
||||||
import ida_name
|
import ida_name
|
||||||
|
|
||||||
def create_external_method_dispatch_struct():
|
def create_external_method_dispatch_struct(struct_type=0):
|
||||||
sid = idc.get_struc_id("IOExternalMethodDispatch2022")
|
"""
|
||||||
|
Creates IDA structure for IOExternalMethodDispatch.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
struct_type: 0 for IOExternalMethodDispatch2022 (0x28 bytes)
|
||||||
|
1 for IOExternalMethodDispatch (0x18 bytes)
|
||||||
|
Returns:
|
||||||
|
Structure ID or -1 on failure
|
||||||
|
"""
|
||||||
|
struct_name = f"IOExternalMethodDispatch{2022 if struct_type == 0 else ''}"
|
||||||
|
sid = idc.get_struc_id(struct_name)
|
||||||
if sid != -1:
|
if sid != -1:
|
||||||
# Structure already exists
|
|
||||||
return sid
|
return sid
|
||||||
|
|
||||||
sid = idc.add_struc(-1, "IOExternalMethodDispatch2022", 0)
|
sid = idc.add_struc(-1, struct_name, 0)
|
||||||
if sid == -1:
|
if sid == -1:
|
||||||
print("Failed to create structure")
|
print("Failed to create structure")
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
# Define structure members
|
# Common fields for both types
|
||||||
idc.add_struc_member(sid, "function", 0, ida_bytes.qword_flag(), -1, 8)
|
idc.add_struc_member(sid, "function", 0, ida_bytes.qword_flag(), -1, 8)
|
||||||
idc.add_struc_member(sid, "checkScalarInputCount", 8, ida_bytes.dword_flag(), -1, 4)
|
idc.add_struc_member(sid, "checkScalarInputCount", 8, ida_bytes.dword_flag(), -1, 4)
|
||||||
idc.add_struc_member(sid, "checkStructureInputSize", 0xC, ida_bytes.dword_flag(), -1, 4)
|
idc.add_struc_member(sid, "checkStructureInputSize", 0xC, ida_bytes.dword_flag(), -1, 4)
|
||||||
idc.add_struc_member(sid, "checkScalarOutputCount", 0x10, ida_bytes.dword_flag(), -1, 4)
|
idc.add_struc_member(sid, "checkScalarOutputCount", 0x10, ida_bytes.dword_flag(), -1, 4)
|
||||||
idc.add_struc_member(sid, "checkStructureOutputSize", 0x14, ida_bytes.dword_flag(), -1, 4)
|
idc.add_struc_member(sid, "checkStructureOutputSize", 0x14, ida_bytes.dword_flag(), -1, 4)
|
||||||
idc.add_struc_member(sid, "allowAsync", 0x18, ida_bytes.byte_flag(), -1, 1)
|
|
||||||
# Align to pointer size for checkEntitlement
|
if struct_type == 0:
|
||||||
idc.add_struc_member(sid, "checkEntitlement", 0x20, ida_bytes.qword_flag(), -1, 8)
|
# Type 0 (2022) specific fields
|
||||||
|
idc.add_struc_member(sid, "allowAsync", 0x18, ida_bytes.byte_flag(), -1, 1)
|
||||||
|
# Align to pointer size for checkEntitlement
|
||||||
|
idc.add_struc_member(sid, "checkEntitlement", 0x20, ida_bytes.qword_flag(), -1, 8)
|
||||||
|
|
||||||
return sid
|
return sid
|
||||||
|
|
||||||
def format_external_method_array(start_addr, count):
|
def format_external_method_array(start_addr, count, struct_type=0):
|
||||||
# Create structure if it doesn't exist
|
"""
|
||||||
sid = create_external_method_dispatch_struct()
|
Formats and analyzes an array of IOExternalMethodDispatch structures.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
start_addr: Start address of the methods array
|
||||||
|
count: Number of entries to process
|
||||||
|
struct_type: 0 for IOExternalMethodDispatch2022 (default)
|
||||||
|
1 for IOExternalMethodDispatch
|
||||||
|
"""
|
||||||
|
sid = create_external_method_dispatch_struct(struct_type)
|
||||||
if sid == -1:
|
if sid == -1:
|
||||||
return
|
return
|
||||||
|
|
||||||
struct_size = 0x28 # Size of IOExternalMethodDispatch2022
|
struct_size = 0x28 if struct_type == 0 else 0x18
|
||||||
|
|
||||||
# Create array
|
|
||||||
for i in range(count):
|
for i in range(count):
|
||||||
current_addr = start_addr + (i * struct_size)
|
current_addr = start_addr + (i * struct_size)
|
||||||
|
|
||||||
# Create structure instance
|
# Create structure instance
|
||||||
idc.create_struct(current_addr, struct_size, "IOExternalMethodDispatch2022")
|
idc.create_struct(current_addr, struct_size, f"IOExternalMethodDispatch{2022 if struct_type == 0 else ''}")
|
||||||
|
|
||||||
# Get function pointer and try to get its name
|
# Get function pointer and try to get its name
|
||||||
func_ptr = idc.get_qword(current_addr)
|
func_ptr = idc.get_qword(current_addr)
|
||||||
@@ -50,35 +91,46 @@ def format_external_method_array(start_addr, count):
|
|||||||
else:
|
else:
|
||||||
print(f"Entry {i}: Function = 0x{func_ptr:x}")
|
print(f"Entry {i}: Function = 0x{func_ptr:x}")
|
||||||
|
|
||||||
# Get other fields
|
# Get common fields
|
||||||
scalar_input = idc.get_wide_dword(current_addr + 8)
|
scalar_input = idc.get_wide_dword(current_addr + 8)
|
||||||
struct_input = idc.get_wide_dword(current_addr + 0xC)
|
struct_input = idc.get_wide_dword(current_addr + 0xC)
|
||||||
scalar_output = idc.get_wide_dword(current_addr + 0x10)
|
scalar_output = idc.get_wide_dword(current_addr + 0x10)
|
||||||
struct_output = idc.get_wide_dword(current_addr + 0x14)
|
struct_output = idc.get_wide_dword(current_addr + 0x14)
|
||||||
allow_async = idc.get_wide_byte(current_addr + 0x18)
|
|
||||||
entitlement = idc.get_qword(current_addr + 0x20)
|
|
||||||
|
|
||||||
print(f" ScalarInput: {scalar_input}")
|
print(f" ScalarInput: {scalar_input}")
|
||||||
print(f" StructInput: {struct_input}")
|
print(f" StructInput: {struct_input}")
|
||||||
print(f" ScalarOutput: {scalar_output}")
|
print(f" ScalarOutput: {scalar_output}")
|
||||||
print(f" StructOutput: {struct_output}")
|
print(f" StructOutput: {struct_output}")
|
||||||
print(f" AllowAsync: {allow_async}")
|
|
||||||
if entitlement != 0:
|
if struct_type == 0:
|
||||||
ent_str = idc.get_strlit_contents(entitlement, -1, STRTYPE_C)
|
# Type 0 (2022) specific fields
|
||||||
if ent_str:
|
allow_async = idc.get_wide_byte(current_addr + 0x18)
|
||||||
print(f" Entitlement: {ent_str.decode('utf-8')}")
|
entitlement = idc.get_qword(current_addr + 0x20)
|
||||||
|
|
||||||
|
print(f" AllowAsync: {allow_async}")
|
||||||
|
if entitlement != 0:
|
||||||
|
ent_str = idc.get_strlit_contents(entitlement, -1, STRTYPE_C)
|
||||||
|
if ent_str:
|
||||||
|
print(f" Entitlement: {ent_str.decode('utf-8')}")
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if len(idc.ARGV) != 3:
|
if len(idc.ARGV) < 3:
|
||||||
print("Usage: format_externalmethods.py <start_address> <count>")
|
print("Usage: format_externalmethods.py <start_address> <count> [type]")
|
||||||
print("Example: format_externalmethods.py 0xFFFFFE0007E1B118 10")
|
print("In IDA: format_external_method_array(0xFFFFFE0007DCDBD8, 16, 1)")
|
||||||
|
print("Type: 0 = IOExternalMethodDispatch2022 (0x28 bytes)")
|
||||||
|
print(" 1 = IOExternalMethodDispatch (0x18 bytes)")
|
||||||
return
|
return
|
||||||
|
|
||||||
start_addr = int(idc.ARGV[1], 16)
|
start_addr = int(idc.ARGV[1], 16)
|
||||||
count = int(idc.ARGV[2])
|
count = int(idc.ARGV[2])
|
||||||
|
struct_type = int(idc.ARGV[3]) if len(idc.ARGV) > 3 else 0
|
||||||
|
|
||||||
format_external_method_array(start_addr, count)
|
format_external_method_array(start_addr, count, struct_type)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|
||||||
|
# format_external_method_array(0xFFFFFE0007F647A0, 10)
|
||||||
|
# format_external_method_array(0xFFFFFE0007DCDBD8, 15, 1)
|
||||||
Reference in new issue
Block a user