Skip to content

Instantly share code, notes, and snippets.

@marysaka
Created August 21, 2021 11:34
Show Gist options
  • Save marysaka/0321b823ac692c016e171b16fc6cf902 to your computer and use it in GitHub Desktop.
Save marysaka/0321b823ac692c016e171b16fc6cf902 to your computer and use it in GitHub Desktop.
IDA 7.4+ helper script for Wii's IOS syscalls
# Based on https://wiibrew.org/wiki/IOS/Syscall_IDAPython
from idc import *
from idautils import *
from ida_bytes import *
from ida_idaapi import BADADDR
from ida_xref import add_cref
# NOTE: most names here are custom because even official names are confusing.
syscall_names = {
0x00: 'CreateThread',
0x01: 'JoinThread',
0x02: 'CancelThread',
0x03: 'GetThreadId',
0x04: 'GetProcessId',
0x05: 'StartThread',
0x06: 'SuspendThread',
0x07: 'YieldThread',
0x08: 'GetThreadPriority',
0x09: 'SetThreadPriority',
0x0A: 'CreateMessageQueue',
0x0B: 'DestroyMessageQueue',
# IOS_SendMessage
0x0C: 'SendMessageToQueue',
# IOS_JamMessage
0x0D: 'JamMessageToQueue',
# IOS_ReceiveMessage
0x0E: 'ReceiveMessageFromQueue',
0x0F: 'RegisterEventHandler',
0x10: 'UnregisterEventHandler',
0x11: 'CreateTimer',
0x12: 'RestartTimer',
0x13: 'StopTimer',
0x14: 'DestroyTimer',
# time_now
0x15: 'GetCurrentTimer',
0x16: 'CreateHeap',
0x17: 'DestroyHeap',
# Alloc
0x18: 'AllocFromHeap',
# AllocAligned
0x19: 'AlignedAllocFromHeap',
# Free
0x1A: 'FreeFromHeap',
0x1B: 'RegisterResourceManager',
0x1C: 'Open',
0x1D: 'Close',
0x1E: 'Read',
0x1F: 'Write',
0x20: 'Seek',
0x21: 'Ioctl',
# IOS_Ioctlv
0x22: 'IoctlFromVector',
0x23: 'OpenAsync',
0x24: 'CloseAsync',
0x25: 'ReadAsync',
0x26: 'WriteAsync',
0x27: 'SeekAsync',
0x28: 'IoctlAsync',
# IOS_IoctlvAsync
0x29: 'IoctlFromVectorAsync',
0x2A: 'ResourceReply',
# SetUid
0x2B: 'SetProcessUid',
# GetUid
0x2C: 'GetCurrentProcessUid',
# SetGid
0x2D: 'SetProcessGid',
# GetGid
0x2E: 'GetProcessGid',
# ahbMemFlush
0x2F: 'FlushFromAhbDeviceMemory',
# syscall_ahbMemFlush_wrapper
0x30: 'FlushToAhbDeviceMemory',
# ClearAndEnableIPCIOPIntr
0x31: 'EnableIPCInterruptEvent',
# ClearAndEnableDIIntr
0x32: 'EnableDriveInterfaceInterruptEvent',
# ClearAndEnableSDIntr
# NOTE: SDHC and Wireless are both controllable here and on the SDIO bus.
0x33: 'EnableSDIOInterruptEvent',
# ClearAndEnableEvent
0x34: 'EnableInterruptEvent',
# 0x35: stubbed (AccessIobPool)
# alloc_iobuf
0x36: 'CreateIoBuffer',
# free_iobuf
0x37: 'DestroyIoBuffer',
# 0x38: stubbed (iobuf_log_header_info)
# 0x39: stubbed (iobuf_log_buffer_info)
# extend_iobuf
0x3A: 'ExendIoBuffer',
# IOS_PushIob
0x3B: 'PushIoBuffer',
# IOS_PullIob
0x3C: 'PullIoBuffer',
# verify_iobuf
0x3D: 'VerifyIoBuffer',
# 0x3E: unknown (IOBuffer related)
# IOS_InvalidateDCache
0x3F: 'InvalidateDataCache',
# IOS_FlushDCache
0x40: 'FlushDataCache',
# ppc_boot
0x41: 'ExecutePPCImage',
# ios_boot
0x42: 'BootNewIOS',
# boot_new_ios_kernel
0x43: 'ExecuteNewIOS',
# assert_di_reset
0x44: 'DisableDriveInterface',
# deassert_di_reset
0x45: 'EnableDriveInterface',
# check_di_reset
0x46: 'CheckDriveInterfaceStatus',
# get_kernel_flavor
0x47: 'GetKernelConfiguration',
# 0x48: unknown (kernel config related, maybe release mode)
# 0x49: unknown (get_boot_vector, seems to be related to BOOT0/BOOT1)
# GetHollywoodId
0x4A: 'GetHollywoodHardwareRevision',
# kernel_debug_print
0x4B: 'OutputKernelUsageStatistics',
# SetLoMemOSVersion
0x4C: 'SetIOSVersion',
# GetLoMemOSVersion
0x4D: 'GetIOSVersion',
# SetDiSpinup
0x4E: 'FlipDriveInterfaceSpinup',
0x4F: 'VirtualToPhysical',
0x50: 'SetDvdReadDisable',
0x51: 'GetDvdReadDisable',
# SetEnableAHBPI2DI
0x52: 'EnableAIPPROTForDriveInterface',
# GetEnableAHBPI2DI
0x52: 'GetAIPPROTForDriveInterfaceState',
# SetPPCACRPerms
0x54: 'GiveFullAhbDeviceAccessToPPC',
0x55: 'GetBusSpeed',
0x56: 'ACRRegWrite',
0x57: 'DDRRegWrite',
0x58: 'OutputDebugPort',
0x59: 'SetIpcAccessRights',
# LaunchRM
0x5A: 'LoadModule',
# IOSC_CreateObject
0x5B: 'CreateCryptoObject',
# IOSC_DeleteObject
0x5C: 'DestroyCryptoObject',
# IOSC_ImportSecretKey
0x5D: 'ImportSecretKey',
# IOSC_ExportSecretKey
0x5E: 'ExportSecretKey',
# IOSC_ImportPublicKey
0x5F: 'ImportPublicKey',
# IOSC_ExportPublicKey
0x60: 'ExportPublicKey',
# IOSC_ComputeSharedKey
0x61: 'ComputeSharedKey',
# IOSC_SetData
0x62: 'SetCryptoObjectData',
# IOSC_GetData
0x63: 'GetCryptoObjectData',
# IOSC_GetKeySize
0x64: 'GetCryptoObjectKeySize',
# IOSC_GetSignatureSize
0x65: 'GetCryptoObjectSignatureSize',
# IOSC_GenerateHashAsync
0x66: 'GenerateHashAsync',
# IOSC_GenerateHash
0x67: 'GenerateHash',
# IOSC_EncryptAsync
0x68: 'EncryptDataAsync',
# IOSC_Encrypt
0x69: 'EncryptData',
# IOSC_DecryptAsync
0x6A: 'DecryptDataAsync',
# IOSC_Decrypt
0x6B: 'DecryptData',
# IOSC_VerifyPublicKeySign
0x6C: 'VerifyPublicKeySignature',
# IOSC_GenerateBlockMAC
0x6D: 'GenerateBlockMAC',
# IOSC_GenerateBlockMACAsync
0x6E: 'GenerateBlockMACAsync',
# IOSC_ImportCertificate
0x6F: 'ImportCertificate',
# IOSC_GetDeviceCertificate
0x70: 'GetDeviceCertificate',
# IOSC_SetOwnership
0x71: 'SetCryptoObjectOwnership',
# IOSC_GetOwnership
0x72: 'GetCryptoObjectOwnership',
# IOSC_GenerateRand
0x73: 'GenerateRandomBytes',
# IOSC_GenerateKey
0x74: 'GenerateRandomKey',
# IOSC_GeneratePublicKeySign
0x75: 'GeneratePublicKeySignature',
# IOSC_GenerateCertificate
0x76: 'GenerateCertificate',
# IOSC_CheckDiHashes
0x77: 'CheckDriveInterfaceHashes',
# 0x78: unknown
# 0x79: unknown
}
undef_address = 0
base = get_name_ea_simple("syscall_base")
syscall_undef_found_cache = {}
while 1:
undef_address = find_binary(undef_address, SEARCH_DOWN, "E6 ? ? ? E1 2F FF 1E")
if undef_address == BADADDR:
break
undef_inst = get_dword(undef_address)
syscall_undef_suffix = ''
if undef_inst not in syscall_undef_found_cache:
syscall_undef_found_cache[undef_inst] = 1
else:
syscall_undef_suffix = str(syscall_undef_found_cache[undef_inst])
syscall_undef_found_cache[undef_inst] += 1
syscall_nr = (undef_inst & 0x00FFFFE0) >> 5
syscall_addr = (base + syscall_nr * 4) &~1
create_data(undef_address, FF_DWORD, 4, BADADDR)
create_insn(undef_address + 4)
if syscall_nr in syscall_names:
base_name = syscall_names[syscall_nr]
name = "svc" + base_name
else:
base_name = "svcHandler%02x" % syscall_nr
name = "svc%02x" % syscall_nr
set_name(undef_address, "j_%s%s" % (name, syscall_undef_suffix), 0)
set_cmt(undef_address, name, 1)
# If the base isn't present that mean we don't have the kernel loaded with us.
if base != BADADDR:
set_name(get_dword(syscall_addr) - 1, base_name, SN_CHECK)
add_cref(undef_address, syscall_addr, XREF_USER)
undef_address += 4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment