Skip to content

Instantly share code, notes, and snippets.

@exelix11
Last active April 11, 2026 14:57
Show Gist options
  • Select an option

  • Save exelix11/5b05bcdf47bbc7ca2aa7ed12d52bef43 to your computer and use it in GitHub Desktop.

Select an option

Save exelix11/5b05bcdf47bbc7ca2aa7ed12d52bef43 to your computer and use it in GitHub Desktop.
Finds and types the svc calls in switch sysmodule binaries. Not precise but ok enough.
import idaapi
import idautils
import idc
import re
from ida_typeinf import tinfo_t, apply_type, parse_decl
no_return = [
"ExitProcess", "Break"
]
# Define the SVC table
svc_table = [
(0x01, "Result", "SetHeapSize", "uintptr_t *out_address, size_t size"),
(0x02, "Result", "SetMemoryPermission", "uintptr_t address, size_t size, MemoryPermission perm"),
(0x03, "Result", "SetMemoryAttribute", "uintptr_t address, size_t size, uint32_t mask, uint32_t attr"),
(0x04, "Result", "MapMemory", "uintptr_t dst_address, uintptr_t src_address, size_t size"),
(0x05, "Result", "UnmapMemory", "uintptr_t dst_address, uintptr_t src_address, size_t size"),
(0x06, "Result", "QueryMemory", "arch_MemoryInfo *out_memory_info, PageInfo *out_page_info, uintptr_t address"),
(0x07, "void", "ExitProcess", ""),
(0x08, "Result", "CreateThread", "Handle *out_handle, ThreadFunc func, uintptr_t arg, uintptr_t stack_bottom, int32_t priority, int32_t core_id"),
(0x09, "Result", "StartThread", "Handle thread_handle"),
(0x0A, "void", "ExitThread", ""),
(0x0B, "void", "SleepThread", "int64_t ns"),
(0x0C, "Result", "GetThreadPriority", "int32_t *out_priority, Handle thread_handle"),
(0x0D, "Result", "SetThreadPriority", "Handle thread_handle, int32_t priority"),
(0x0E, "Result", "GetThreadCoreMask", "int32_t *out_core_id, uint64_t *out_affinity_mask, Handle thread_handle"),
(0x0F, "Result", "SetThreadCoreMask", "Handle thread_handle, int32_t core_id, uint64_t affinity_mask"),
(0x10, "int32_t", "GetCurrentProcessorNumber", ""),
(0x11, "Result", "SignalEvent", "Handle event_handle"),
(0x12, "Result", "ClearEvent", "Handle event_handle"),
(0x13, "Result", "MapSharedMemory", "Handle shmem_handle, uintptr_t address, size_t size, MemoryPermission map_perm"),
(0x14, "Result", "UnmapSharedMemory", "Handle shmem_handle, uintptr_t address, size_t size"),
(0x15, "Result", "CreateTransferMemory", "Handle *out_handle, uintptr_t address, size_t size, MemoryPermission map_perm"),
(0x16, "Result", "CloseHandle", "Handle handle"),
(0x17, "Result", "ResetSignal", "Handle handle"),
(0x18, "Result", "WaitSynchronization", "int32_t *out_index, const Handle *handles, int32_t numHandles, int64_t timeout_ns"),
(0x19, "Result", "CancelSynchronization", "Handle handle"),
(0x1A, "Result", "ArbitrateLock", "Handle thread_handle, uintptr_t address, uint32_t tag"),
(0x1B, "Result", "ArbitrateUnlock", "uintptr_t address"),
(0x1C, "Result", "WaitProcessWideKeyAtomic", "uintptr_t address, uintptr_t cv_key, uint32_t tag, int64_t timeout_ns"),
(0x1D, "void", "SignalProcessWideKey", "uintptr_t cv_key, int32_t count"),
(0x1E, "int64_t", "GetSystemTick", ""),
(0x1F, "Result", "ConnectToNamedPort", "Handle *out_handle, const char *name"),
(0x20, "Result", "SendSyncRequestLight", "Handle session_handle"),
(0x21, "Result", "SendSyncRequest", "Handle session_handle"),
(0x22, "Result", "SendSyncRequestWithUserBuffer", "uintptr_t message_buffer, size_t message_buffer_size, Handle session_handle"),
(0x23, "Result", "SendAsyncRequestWithUserBuffer", "Handle *out_event_handle, uintptr_t message_buffer, size_t message_buffer_size, Handle session_handle"),
(0x24, "Result", "GetProcessId", "uint64_t *out_process_id, Handle process_handle"),
(0x25, "Result", "GetThreadId", "uint64_t *out_thread_id, Handle thread_handle"),
(0x26, "void", "Break", "BreakReason break_reason, uintptr_t arg, size_t size"),
(0x27, "Result", "OutputDebugString", "const char *debug_str, size_t len"),
(0x28, "void", "ReturnFromException", "Result result"),
(0x29, "Result", "GetInfo", "uint64_t *out, InfoType info_type, Handle handle, uint64_t info_subtype"),
(0x2A, "void", "FlushEntireDataCache", ""),
(0x2B, "Result", "FlushDataCache", "uintptr_t address, size_t size"),
# [3.0.0+]
(0x2C, "Result", "MapPhysicalMemory", "uintptr_t address, size_t size"),
# [3.0.0+]
(0x2D, "Result", "UnmapPhysicalMemory", "uintptr_t address, size_t size"),
# [5.0.0-5.1.0]
# (0x2E, "Result", "GetFutureThreadInfo", "arch_LastThreadContext *out_context, uintptr_t *out_tls_address, uint32_t *out_flags, int64_t ns"),
# [6.0.0+]
(0x2E, "Result", "GetDebugFutureThreadInfo", "arch_LastThreadContext *out_context, uint64_t *thread_id, Handle debug_handle, int64_t ns"),
(0x2F, "Result", "GetLastThreadInfo", "arch_LastThreadContext *out_context, uintptr_t *out_tls_address, uint32_t *out_flags"),
(0x30, "Result", "GetResourceLimitLimitValue", "int64_t *out_limit_value, Handle resource_limit_handle, LimitableResource which"),
(0x31, "Result", "GetResourceLimitCurrentValue", "int64_t *out_current_value, Handle resource_limit_handle, LimitableResource which"),
(0x32, "Result", "SetThreadActivity", "Handle thread_handle, ThreadActivity thread_activity"),
(0x33, "Result", "GetThreadContext3", "ThreadContext *out_context, Handle thread_handle"),
# [4.0.0+]
(0x34, "Result", "WaitForAddress", "uintptr_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns"),
# [4.0.0+]
(0x35, "Result", "SignalToAddress", "uintptr_t address, SignalType signal_type, int32_t value, int32_t count"),
# [8.0.0+]
(0x36, "void", "SynchronizePreemptionState", ""),
# [11.0.0+]
(0x37, "Result", "GetResourceLimitPeakValue", "int64_t *out_peak_value, Handle resource_limit_handle, LimitableResource which"),
# [13.0.0+]
(0x39, "Result", "CreateIoPool", "Handle *out_handle, IoPoolType which_pool"),
# [13.0.0+]
(0x3A, "Result", "CreateIoRegion", "Handle *out_handle, Handle io_pool, PhysicalAddress physical_address, size_t size, MemoryMapping mapping, MemoryPermission perm"),
# [1.0.0-3.0.2]
# (0x3C, "void", "DumpInfo", "DumpInfoType dump_info_type, uint64_t arg"),
# [4.0.0+]
(0x3C, "void", "KernelDebug", "KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2"),
# [4.0.0+]
(0x3D, "void", "ChangeKernelTraceState", "KernelTraceState kern_trace_state"),
(0x40, "Result", "CreateSession", "Handle *out_server_session_handle, Handle *out_client_session_handle, bool is_light, uintptr_t name"),
(0x41, "Result", "AcceptSession", "Handle *out_handle, Handle port"),
(0x42, "Result", "ReplyAndReceiveLight", "Handle handle"),
(0x43, "Result", "ReplyAndReceive", "int32_t *out_index, const Handle *handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns"),
(0x44, "Result", "ReplyAndReceiveWithUserBuffer", "int32_t *out_index, uintptr_t message_buffer, size_t message_buffer_size, const Handle *handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns"),
(0x45, "Result", "CreateEvent", "Handle *out_write_handle, Handle *out_read_handle"),
# [13.0.0+]
( 0x46, "Result", "MapIoRegion", "Handle io_region, uintptr_t address, size_t size, MemoryPermission perm"),
# [13.0.0+]
(0x47, "Result", "UnmapIoRegion", "Handle io_region, uintptr_t address, size_t size"),
# [5.0.0+]
(0x48, "Result", "MapPhysicalMemoryUnsafe", "uintptr_t address, size_t size"),
# [5.0.0+]
(0x49, "Result", "UnmapPhysicalMemoryUnsafe", "uintptr_t address, size_t size"),
# [5.0.0+]
(0x4A, "Result", "SetUnsafeLimit", "size_t limit"),
# [4.0.0+]
(0x4B, "Result", "CreateCodeMemory", "Handle *out_handle, uintptr_t address, size_t size"),
# [4.0.0+]
(0x4C, "Result", "ControlCodeMemory", "Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm"),
(0x4D, "void", "SleepSystem", ""),
(0x4E, "Result", "ReadWriteRegister", "uint32_t *out_value, PhysicalAddress address, uint32_t mask, uint32_t value"),
(0x4F, "Result", "SetProcessActivity", "Handle process_handle, ProcessActivity process_activity"),
(0x50, "Result", "CreateSharedMemory", "Handle *out_handle, size_t size, MemoryPermission owner_perm, MemoryPermission remote_perm"),
(0x51, "Result", "MapTransferMemory", "Handle trmem_handle, uintptr_t address, size_t size, MemoryPermission owner_perm"),
(0x52, "Result", "UnmapTransferMemory", "Handle trmem_handle, uintptr_t address, size_t size"),
(0x53, "Result", "CreateInterruptEvent", "Handle *out_read_handle, int32_t interrupt_id, InterruptType interrupt_type"),
(0x54, "Result", "QueryPhysicalAddress", "arch_PhysicalMemoryInfo *out_info, uintptr_t address"),
# [1.0.0-9.2.0]
# (0x55, "Result", "QueryIoMapping", "uintptr_t *out_address, PhysicalAddress physical_address, size_t size"),
# [10.0.0+]
(0x55, "Result", "QueryMemoryMapping", "uintptr_t *out_address, size_t *out_size, PhysicalAddress physical_address, size_t size"),
(0x56, "Result", "CreateDeviceAddressSpace", "Handle *out_handle, uint64_t das_address, uint64_t das_size"),
(0x57, "Result", "AttachDeviceAddressSpace", "DeviceName device_name, Handle das_handle"),
(0x58, "Result", "DetachDeviceAddressSpace", "DeviceName device_name, Handle das_handle"),
(0x59, "Result", "MapDeviceAddressSpaceByForce", "Handle das_handle, Handle process_handle, uint64_t process_address, size_t size, uint64_t, device_address, uint32_t option"),
(0x5A, "Result", "MapDeviceAddressSpaceAligned", "Handle das_handle, Handle process_handle, uint64_t process_address, size_t size, uint64_t, device_address, uint32_t option"),
# [1.0.0-12.1.0]
# (0x5B, "Result", "MapDeviceAddressSpace", "size_t *out_mapped_size, Handle das_handle, Handle process_handle, uint64_t process_address, size_t size, uint64_t device_address, MemoryPermission device_perm"),
(0x5C, "Result", "UnmapDeviceAddressSpace", "Handle das_handle, Handle process_handle, uint64_t process_address, size_t size, uint64_t device_address"),
(0x5D, "Result", "InvalidateProcessDataCache", "Handle process_handle, uint64_t address, uint64_t size"),
(0x5E, "Result", "StoreProcessDataCache", "Handle process_handle, uint64_t address, uint64_t size"),
(0x5F, "Result", "FlushProcessDataCache", "Handle process_handle, uint64_t address, uint64_t size"),
(0x60, "Result", "DebugActiveProcess", "Handle *out_handle, uint64_t process_id"),
(0x61, "Result", "BreakDebugProcess", "Handle debug_handle"),
(0x62, "Result", "TerminateDebugProcess", "Handle debug_handle"),
(0x63, "Result", "GetDebugEvent", "arch_DebugEventInfo *out_info, Handle debug_handle"),
(0x64, "Result", "ContinueDebugEvent", "Handle debug_handle, uint32_t flags, const uint64_t *thread_ids, int32_t num_thread_ids"),
(0x65, "Result", "GetProcessList", "int32_t *out_num_processes, uint64_t *out_process_ids, int32_t max_out_count"),
(0x66, "Result", "GetThreadList", "int32_t *out_num_threads, uint64_t *out_thread_ids, int32_t max_out_count, Handle debug_handle"),
(0x67, "Result", "GetDebugThreadContext", "ThreadContext *out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags"),
(0x68, "Result", "SetDebugThreadContext", "Handle debug_handle, uint64_t thread_id, const ThreadContext *context, uint32_t context_flags"),
(0x69, "Result", "QueryDebugProcessMemory", "arch_MemoryInfo *out_memory_info, PageInfo *out_page_info, Handle process_handle, uintptr_t address"),
(0x6A, "Result", "ReadDebugProcessMemory", "uintptr_t buffer, Handle debug_handle, uintptr_t address, size_t size"),
(0x6B, "Result", "WriteDebugProcessMemory", "Handle debug_handle, uintptr_t buffer, uintptr_t address, size_t size"),
(0x6C, "Result", "SetHardwareBreakPoint", "HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value"),
(0x6D, "Result", "GetDebugThreadParam", "uint64_t *out_64, uint32_t *out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param"),
# [5.0.0+]
(0x6F, "Result", "GetSystemInfo", "uint64_t *out, SystemInfoType info_type, Handle handle, uint64_t info_subtype"),
(0x70, "Result", "CreatePort", "Handle *out_server_handle, Handle *out_client_handle, int32_t max_sessions, bool is_light, uintptr_t name"),
(0x71, "Result", "ManageNamedPort", "Handle *out_server_handle, const char *name, int32_t max_sessions"),
(0x72, "Result", "ConnectToPort", "Handle *out_handle, Handle port"),
(0x73, "Result", "SetProcessMemoryPermission", "Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm"),
(0x74, "Result", "MapProcessMemory", "uintptr_t dst_address, Handle process_handle, uint64_t src_address, size_t size"),
(0x75, "Result", "UnmapProcessMemory", "uintptr_t dst_address, Handle process_handle, uint64_t src_address, size_t size"),
(0x76, "Result", "QueryProcessMemory", "arch_MemoryInfo *out_memory_info, PageInfo *out_page_info, Handle process_handle, uint64_t address"),
(0x77, "Result", "MapProcessCodeMemory", "Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size"),
(0x78, "Result", "UnmapProcessCodeMemory", "Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size"),
(0x79, "Result", "CreateProcess", "Handle *out_handle, const arch_CreateProcessParameter *parameters, const uint32_t *caps, int32_t num_caps"),
(0x7A, "Result", "StartProcess", "Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size"),
(0x7B, "Result", "TerminateProcess", "Handle process_handle"),
(0x7C, "Result", "GetProcessInfo", "int64_t *out_info, Handle process_handle, ProcessInfoType info_type"),
(0x7D, "Result", "CreateResourceLimit", "Handle *out_handle"),
(0x7E, "Result", "SetResourceLimitLimitValue", "Handle resource_limit_handle, LimitableResource which, int64_t limit_value"),
(0x7F, "void", "CallSecureMonitor", "SecureMonitorArguments *args"),
#[15.0.0+]
(0x90, "Result", "MapInsecurePhysicalMemory", "uintptr_t address, size_t size"),
#[15.0.0+]
(0x91, "Result", "UnmapInsecurePhysicalMemory", "uintptr_t address, size_t size")
]
def set_type(ea, type_str):
tif = tinfo_t()
if parse_decl(tif, None, type_str, 0):
apply_type(ea, tif, 0)
# Find functions with SVC instructions and label/set types
def process_svc_functions():
for func_ea in idautils.Functions():
func = idaapi.get_func(func_ea)
if not func:
continue
# Filter by instruction count
insn_count = (func.end_ea - func.start_ea) / 4
if insn_count >= 20:
continue
# Check for SVC instruction
has_svc = False
svc_num = None
for head in idautils.Heads(func.start_ea, func.end_ea):
mnem = idaapi.print_insn_mnem(head)
if mnem == "SVC":
has_svc = True
svc_num = idc.get_operand_value(head, 0)
break
if has_svc:
# Find matching SVC entry
for entry in svc_table:
if entry[0] == svc_num:
# Set function name and type
func_name = entry[2]
ret_type = entry[1]
args = entry[3]
full_prototype = f"{ret_type} svc{func_name}({args});"
if func_name in no_return:
func.flags |= ida_funcs.FUNC_NORET
idaapi.set_name(func_ea, "svc" + func_name, idaapi.SN_FORCE)
set_type(func_ea, full_prototype)
print(f"{hex(func_ea)} SVC 0x{svc_num:X}: {full_prototype}")
break
if __name__ == "__main__":
process_svc_functions()
print("Processing complete.")
// Basic types
typedef unsigned __int64 uintptr_t;
typedef unsigned __int64 size_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
// Custom types
typedef unsigned __int32 Handle;
typedef unsigned __int32 Result;
typedef unsigned __int32 MemoryPermission;
typedef __int32 BreakReason;
typedef __int32 InfoType;
typedef __int32 LimitableResource;
typedef __int32 ThreadActivity;
typedef __int32 ArbitrationType;
typedef __int32 SignalType;
typedef __int32 IoPoolType;
typedef __int32 InterruptType;
typedef unsigned __int64 PhysicalAddress;
typedef void (*ThreadFunc)(void);
typedef void* DeviceName;
// Pointer types
typedef unsigned __int64* uintptr_t_ptr;
typedef unsigned __int32* uint32_t_ptr;
typedef unsigned __int64* uint64_t_ptr;
typedef __int32* int32_t_ptr;
typedef __int64* int64_t_ptr;
typedef unsigned __int64* size_t_ptr;
typedef Handle* Handle_ptr;
struct arch_MemoryInfo;
struct arch_PhysicalMemoryInfo;
struct arch_DebugEventInfo;
struct arch_CreateProcessParameter;
struct PageInfo;
struct ThreadContext;
// Random libnx structs
typedef enum {
ProcessActivity_Runnable = 0, ///< Process can run.
ProcessActivity_Paused = 1, ///< Process is paused.
} ProcessActivity;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment