Skip to content

Instantly share code, notes, and snippets.

@SciresM
Last active September 4, 2020 05:23
Show Gist options
  • Save SciresM/1c675b885d7277de51013b56b89917bb to your computer and use it in GitHub Desktop.
Save SciresM/1c675b885d7277de51013b56b89917bb to your computer and use it in GitHub Desktop.
Script for automatically identifying + labeling the Nintendo Switch SVC tables.
from idautils import *
from idaapi import *
from idc import *
from ida_hexrays import *
from ida_bytes import *
from ida_funcs import *
SVC_MAPPINGS = {
0x01 : ("SetHeapSize", "Result %s(uintptr_t *out_address, size_t size);"),
0x02 : ("SetMemoryPermission", "Result %s(uintptr_t address, size_t size, MemoryPermission perm);"),
0x03 : ("SetMemoryAttribute", "Result %s(uintptr_t address, size_t size, uint32_t mask, uint32_t attr);"),
0x04 : ("MapMemory", "Result %s(uintptr_t dst_address, uintptr_t src_address, size_t size);"),
0x05 : ("UnmapMemory", "Result %s(uintptr_t dst_address, uintptr_t src_address, size_t size);"),
0x06 : ("QueryMemory", "Result %s(MemoryInfo *out_memory_info, PageInfo *out_page_info, uintptr_t address);"),
0x07 : ("ExitProcess", "void %s();"),
0x08 : ("CreateThread", "Result %s(Handle *out_handle, ThreadFunc func, uintptr_t arg, uintptr_t stack_bottom, int32_t priority, int32_t core_id);"),
0x09 : ("StartThread", "Result %s(Handle thread_handle);"),
0x0A : ("ExitThread", "void %s();"),
0x0B : ("SleepThread", "void %s(int64_t ns);"),
0x0C : ("GetThreadPriority", "Result %s(int32_t *out_priority, Handle thread_handle);"),
0x0D : ("SetThreadPriority", "Result %s(Handle thread_handle, int32_t priority);"),
0x0E : ("GetThreadCoreMask", "Result %s(int32_t *out_core_id, uint64_t *out_affinity_mask, Handle thread_handle);"),
0x0F : ("SetThreadCoreMask", "Result %s(Handle thread_handle, int32_t core_id, uint64_t affinity_mask);"),
0x10 : ("GetCurrentProcessorNumber", "int32_t %s();"),
0x11 : ("SignalEvent", "Result %s(Handle event_handle);"),
0x12 : ("ClearEvent", "Result %s(Handle event_handle);"),
0x13 : ("MapSharedMemory", "Result %s(Handle shmem_handle, uintptr_t address, size_t size, MemoryPermission map_perm);"),
0x14 : ("UnmapSharedMemory", "Result %s(Handle shmem_handle, uintptr_t address, size_t size);"),
0x15 : ("CreateTransferMemory", "Result %s(Handle *out_handle, uintptr_t address, size_t size, MemoryPermission map_perm);"),
0x16 : ("CloseHandle", "Result %s(Handle handle);"),
0x17 : ("ResetSignal", "Result %s(Handle handle);"),
0x18 : ("WaitSynchronization", "Result %s(int32_t *out_index, const Handle *handles, int32_t numHandles, int64_t timeout_ns);"),
0x19 : ("CancelSynchronization", "Result %s(Handle handle);"),
0x1A : ("ArbitrateLock", "Result %s(Handle thread_handle, uintptr_t address, uint32_t tag);"),
0x1B : ("ArbitrateUnlock", "Result %s(uintptr_t address);"),
0x1C : ("WaitProcessWideKeyAtomic", "Result %s(uintptr_t address, uintptr_t cv_key, uint32_t tag, int64_t timeout_ns);"),
0x1D : ("SignalProcessWideKey", "void %s(uintptr_t cv_key, int32_t count);"),
0x1E : ("GetSystemTick", "int64_t %s();"),
0x1F : ("ConnectToNamedPort", "Result %s(Handle *out_handle, const char *name);"),
0x20 : ("SendSyncRequestLight", "Result %s(Handle session_handle);"),
0x21 : ("SendSyncRequest", "Result %s(Handle session_handle);"),
0x22 : ("SendSyncRequestWithUserBuffer", "Result %s(uintptr_t message_buffer, size_t message_buffer_size, Handle session_handle);"),
0x23 : ("SendAsyncRequestWithUserBuffer", "Result %s(Handle *out_event_handle, uintptr_t message_buffer, size_t message_buffer_size, Handle session_handle);"),
0x24 : ("GetProcessId", "Result %s(uint64_t *out_process_id, Handle process_handle);"),
0x25 : ("GetThreadId", "Result %s(uint64_t *out_thread_id, Handle thread_handle);"),
0x26 : ("Break", "void %s(BreakReason break_reason, uintptr_t arg, size_t size);"),
0x27 : ("OutputDebugString", "Result %s(const char *debug_str, size_t len);"),
0x28 : ("ReturnFromException", "void %s(Result result);"),
0x29 : ("GetInfo", "Result %s(uint64_t *out, InfoType info_type, Handle handle, uint64_t info_subtype);"),
0x2A : ("FlushEntireDataCache", "void %s();"),
0x2B : ("FlushDataCache", "Result %s(uintptr_t address, size_t size);"),
0x2C : ("MapPhysicalMemory", "Result %s(uintptr_t address, size_t size);"),
0x2D : ("UnmapPhysicalMemory", "Result %s(uintptr_t address, size_t size);"),
0x2E : ("GetDebugFutureThreadInfo", "Result %s(SvcLastThreadContext|| *out_context, uint64_t *thread_id, Handle debug_handle, int64_t ns);"),
0x2F : ("GetLastThreadInfo", "Result %s(SvcLastThreadContext|| *out_context, uintptr_t *out_tls_address, uint32_t *out_flags);"),
0x30 : ("GetResourceLimitLimitValue", "Result %s(int64_t *out_limit_value, Handle resource_limit_handle, LimitableResource which);"),
0x31 : ("GetResourceLimitCurrentValue", "Result %s(int64_t *out_current_value, Handle resource_limit_handle, LimitableResource which);"),
0x32 : ("SetThreadActivity", "Result %s(Handle thread_handle, ThreadActivity thread_activity);"),
0x33 : ("GetThreadContext3", "Result %s(ThreadContext *out_context, Handle thread_handle);"),
0x34 : ("WaitForAddress", "Result %s(uintptr_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns);"),
0x35 : ("SignalToAddress", "Result %s(uintptr_t address, SignalType signal_type, int32_t value, int32_t count);"),
0x36 : ("SynchronizePreemptionState", "void %s();"),
0x3C : ("KernelDebug", "void %s(KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2);"),
0x3D : ("ChangeKernelTraceState", "void %s(KernelTraceState kern_trace_state);"),
0x40 : ("CreateSession", "Result %s(Handle *out_server_session_handle, Handle *out_client_session_handle, bool is_light, uintptr_t name);"),
0x41 : ("AcceptSession", "Result %s(Handle *out_handle, Handle port);"),
0x42 : ("ReplyAndReceiveLight", "Result %s(Handle handle);"),
0x43 : ("ReplyAndReceive", "Result %s(int32_t *out_index, const Handle *handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);"),
0x44 : ("ReplyAndReceiveWithUserBuffer", "Result %s(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 : ("CreateEvent", "Result %s(Handle *out_write_handle, Handle *out_read_handle);"),
0x48 : ("MapPhysicalMemoryUnsafe", "Result %s(uintptr_t address, size_t size);"),
0x49 : ("UnmapPhysicalMemoryUnsafe", "Result %s(uintptr_t address, size_t size);"),
0x4A : ("SetUnsafeLimit", "Result %s(size_t limit);"),
0x4B : ("CreateCodeMemory", "Result %s(Handle *out_handle, uintptr_t address, size_t size);"),
0x4C : ("ControlCodeMemory", "Result %s(Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm);"),
0x4D : ("SleepSystem", "void %s();"),
0x4E : ("ReadWriteRegister", "Result %s(uint32_t *out_value, PhysicalAddress address, uint32_t mask, uint32_t value);"),
0x4F : ("SetProcessActivity", "Result %s(Handle process_handle, ProcessActivity process_activity);"),
0x50 : ("CreateSharedMemory", "Result %s(Handle *out_handle, size_t size, MemoryPermission owner_perm, MemoryPermission remote_perm);"),
0x51 : ("MapTransferMemory", "Result %s(Handle trmem_handle, uintptr_t address, size_t size, MemoryPermission owner_perm);"),
0x52 : ("UnmapTransferMemory", "Result %s(Handle trmem_handle, uintptr_t address, size_t size);"),
0x53 : ("CreateInterruptEvent", "Result %s(Handle *out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);"),
0x54 : ("QueryPhysicalAddress", "Result %s(SvcPhysicalMemoryInfo|| *out_info, uintptr_t address);"),
0x55 : ("QueryIoMapping", "Result %s(uintptr_t *out_address, size_t *out_size, PhysicalAddress physical_address, size_t size);"),
0x56 : ("CreateDeviceAddressSpace", "Result %s(Handle *out_handle, uint64_t das_address, uint64_t das_size);"),
0x57 : ("AttachDeviceAddressSpace", "Result %s(DeviceName device_name, Handle das_handle);"),
0x58 : ("DetachDeviceAddressSpace", "Result %s(DeviceName device_name, Handle das_handle);"),
0x59 : ("MapDeviceAddressSpaceByForce", "Result %s(Handle das_handle, Handle process_handle, uint64_t process_address, size_t size, uint64_t device_address, MemoryPermission device_perm);"),
0x5A : ("MapDeviceAddressSpaceAligned", "Result %s(Handle das_handle, Handle process_handle, uint64_t process_address, size_t size, uint64_t device_address, MemoryPermission device_perm);"),
0x5B : ("MapDeviceAddressSpace", "Result %s(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 : ("UnmapDeviceAddressSpace", "Result %s(Handle das_handle, Handle process_handle, uint64_t process_address, size_t size, uint64_t device_address);"),
0x5D : ("InvalidateProcessDataCache", "Result %s(Handle process_handle, uint64_t address, uint64_t size);"),
0x5E : ("StoreProcessDataCache", "Result %s(Handle process_handle, uint64_t address, uint64_t size);"),
0x5F : ("FlushProcessDataCache", "Result %s(Handle process_handle, uint64_t address, uint64_t size);"),
0x60 : ("DebugActiveProcess", "Result %s(Handle *out_handle, uint64_t process_id);"),
0x61 : ("BreakDebugProcess", "Result %s(Handle debug_handle);"),
0x62 : ("TerminateDebugProcess", "Result %s(Handle debug_handle);"),
0x63 : ("GetDebugEvent", "Result %s(DebugEventInfo|| *out_info, Handle debug_handle);"),
0x64 : ("ContinueDebugEvent", "Result %s(Handle debug_handle, uint32_t flags, const uint64_t *thread_ids, int32_t num_thread_ids);"),
0x65 : ("GetProcessList", "Result %s(int32_t *out_num_processes, uint64_t *out_process_ids, int32_t max_out_count);"),
0x66 : ("GetThreadList", "Result %s(int32_t *out_num_threads, uint64_t *out_thread_ids, int32_t max_out_count, Handle debug_handle);"),
0x67 : ("GetDebugThreadContext", "Result %s(ThreadContext *out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags);"),
0x68 : ("SetDebugThreadContext", "Result %s(Handle debug_handle, uint64_t thread_id, const ThreadContext *context, uint32_t context_flags);"),
0x69 : ("QueryDebugProcessMemory", "Result %s(MemoryInfo *out_memory_info, PageInfo *out_page_info, Handle process_handle, uintptr_t address);"),
0x6A : ("ReadDebugProcessMemory", "Result %s(uintptr_t buffer, Handle debug_handle, uintptr_t address, size_t size);"),
0x6B : ("WriteDebugProcessMemory", "Result %s(Handle debug_handle, uintptr_t buffer, uintptr_t address, size_t size);"),
0x6C : ("SetHardwareBreakPoint", "Result %s(HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value);"),
0x6D : ("GetDebugThreadParam", "Result %s(uint64_t *out_64, uint32_t *out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param);"),
0x6F : ("GetSystemInfo", "Result %s(uint64_t *out, SystemInfoType info_type, Handle handle, uint64_t info_subtype);"),
0x70 : ("CreatePort", "Result %s(Handle *out_server_handle, Handle *out_client_handle, int32_t max_sessions, bool is_light, uintptr_t name);"),
0x71 : ("ManageNamedPort", "Result %s(Handle *out_server_handle, const char *name, int32_t max_sessions);"),
0x72 : ("ConnectToPort", "Result %s(Handle *out_handle, Handle port);"),
0x73 : ("SetProcessMemoryPermission", "Result %s(Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm);"),
0x74 : ("MapProcessMemory", "Result %s(uintptr_t dst_address, Handle process_handle, uint64_t src_address, size_t size);"),
0x75 : ("UnmapProcessMemory", "Result %s(uintptr_t dst_address, Handle process_handle, uint64_t src_address, size_t size);"),
0x76 : ("QueryProcessMemory", "Result %s(MemoryInfo *out_memory_info, PageInfo *out_page_info, Handle process_handle, uint64_t address);"),
0x77 : ("MapProcessCodeMemory", "Result %s(Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);"),
0x78 : ("UnmapProcessCodeMemory", "Result %s(Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);"),
0x79 : ("CreateProcess", "Result %s(Handle *out_handle, const CreateProcessParameter *parameters, const uint32_t *caps, int32_t num_caps);"),
0x7A : ("StartProcess", "Result %s(Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size);"),
0x7B : ("TerminateProcess", "Result %s(Handle process_handle);"),
0x7C : ("GetProcessInfo", "Result %s(int64_t *out_info, Handle process_handle, ProcessInfoType info_type);"),
0x7D : ("CreateResourceLimit", "Result %s(Handle *out_handle);"),
0x7E : ("SetResourceLimitLimitValue", "Result %s(Handle resource_limit_handle, LimitableResource which, int64_t limit_value);"),
0x7F : ("CallSecureMonitor", "void %s(SecureMonitorArguments *args);"),
}
seg_mapping = {idc.get_segm_name(x): (idc.get_segm_start(x), idc.get_segm_end(x)) for x in Segments()}
text_start, text_end = seg_mapping['.text']
def IsInText(ea):
return text_start <= ea and ea < text_end
def Test(ea):
unknowns = []
for svc_id in xrange(0x80):
ea_svc32 = ea + 8 * svc_id
ea_svc64 = ea_svc32 + 0x80 * 8
val32 = ida_bytes.get_64bit(ea_svc32)
val64 = ida_bytes.get_64bit(ea_svc64)
if svc_id in SVC_MAPPINGS.keys():
if not IsInText(val32):
return False
if not IsInText(val64):
return False
else:
if val32 == 0 and val64 == 0:
continue
elif val32 == 0 or val64 == 0:
return False
else:
unknowns.append(svc_id)
for unknown in unknowns:
print '[!] Possible unknown SVC 0x%02x' % unknown
return True
rodata_mappings = {x: seg_mapping[x] for x in seg_mapping.keys() if x.startswith('.rodata')}
candidates = []
for (seg_name, (seg_start, seg_end)) in rodata_mappings.items():
print 'Looking at %s (%08x-%08x)...' % (seg_name, seg_start, seg_end)
ea = seg_start & ~7
while ea < seg_end:
if Test(ea):
candidates.append(ea)
ea += 8
assert(len(candidates) == 1)
svc_table32 = candidates[0]
svc_table64 = svc_table32 + 0x80 * 8
print 'Found Svc Tables: %08x %08x' % (svc_table32, svc_table64)
BLS_32 = {}
BLS_64 = {}
BLS_BOTH = {}
def GetBl(func_ea):
bls = []
for (startea, endea) in Chunks(func_ea):
for head in Heads(startea, endea):
disasm = GetDisasm(head).lstrip().rstrip().replace(',',' ')
if ';' in disasm:
disasm = disasm[:disasm.index(';')]
disasm = disasm.split()
if len(disasm) != 2:
continue
if disasm[0].lower() == 'bl':
bls.append(disasm[1])
assert(len(bls) in [0, 1])
if len(bls) == 1:
target_func = get_name_ea_simple(bls[0])
assert(IsInText(target_func))
return target_func
else:
return None
def GetMutualBl(func_ea):
bls = []
disasms = []
for (startea, endea) in Chunks(func_ea):
for head in Heads(startea, endea):
disasm = GetDisasm(head).lstrip().rstrip().replace(',',' ')
if ';' in disasm:
disasm = disasm[:disasm.index(';')]
disasm = disasm.split()
disasms.append(disasm)
if len(disasm) != 2:
continue
if disasm[0].lower() == 'bl':
bls.append(disasm[1])
if len(bls) == 1:
target_func = get_name_ea_simple(bls[0])
if not IsInText(target_func):
target_func = get_name_ea_simple(bls[0].replace('__', '::'))
assert(IsInText(target_func))
if len(disasms) >= 3:
if disasms[0][0].lower() != 'stp':
return None
if disasms[-1][0].lower() != 'ret':
if disasms[-1][0].lower() == 'bl':
return target_func
return None
if disasms[-2][0].lower() != 'ldp':
return None
return target_func
elif len(disasms) >= 2:
if disasms[0][0].lower() != 'stp':
return None
if disasms[-1][0].lower() != 'bl':
return target_func
return target_func
else:
return None
else:
return None
def IsTrampoline(func_ea):
disasm = GetDisasm(func_ea).lstrip().rstrip().replace(', ',' ').split()
return disasm[0].lower() == 'b'
def GetBranch(func_ea):
disasm = GetDisasm(func_ea).lstrip().rstrip().replace(', ',' ').split()
assert disasm[0].lower() == 'b'
target_func = get_name_ea_simple(disasm[1])
if not IsInText(target_func):
target_func = get_name_ea_simple(disasm[1].replace('__', '::'))
assert IsInText(target_func)
return target_func
# Process Tables
for svc_id in SVC_MAPPINGS.keys():
ea_func32 = ida_bytes.get_64bit(svc_table32 + 8 * svc_id)
ea_func64 = ida_bytes.get_64bit(svc_table64 + 8 * svc_id)
assert(get_func_name(ea_func32))
assert(get_func_name(ea_func64))
bl32 = GetBl(ea_func32)
bl64 = GetBl(ea_func64)
if bl32 == bl64 and bl32:
BLS_BOTH[svc_id] = bl32
else:
if bl32:
BLS_32[svc_id] = bl32
if bl64:
BLS_64[svc_id] = bl64
for (svc_id, (svc_name, svc_type)) in SVC_MAPPINGS.items():
ea_func32 = ida_bytes.get_64bit(svc_table32 + 8 * svc_id)
ea_func64 = ida_bytes.get_64bit(svc_table64 + 8 * svc_id)
svc_name32 = '%s64From32' % svc_name
svc_name64 = '%s64' % svc_name
idc.set_name(ea_func32, 'Svc%s' % svc_name32, SN_CHECK)
idc.SetType(ea_func32, 'void %s();' % svc_name)
idc.set_name(ea_func64, 'Svc%s' % svc_name64, SN_CHECK)
idc.SetType(ea_func64, 'void %s();' % svc_name)
if svc_id in BLS_BOTH:
assert('||' not in svc_type)
idc.set_name(BLS_BOTH[svc_id], '%s' % svc_name, SN_CHECK)
idc.SetType(BLS_BOTH[svc_id], svc_type % svc_name)
else:
if svc_id in BLS_32:
idc.set_name(BLS_32[svc_id], svc_name32, SN_CHECK)
idc.SetType(BLS_32[svc_id], svc_type.replace('||', '32') % svc_name32)
if svc_id in BLS_64:
idc.set_name(BLS_64[svc_id], svc_name64, SN_CHECK)
idc.SetType(BLS_64[svc_id], svc_type.replace('||', '64') % svc_name64)
if svc_id in BLS_32 and svc_id in BLS_64:
subbl32 = GetMutualBl(BLS_32[svc_id])
subbl64 = GetMutualBl(BLS_64[svc_id])
if subbl32 is not None and subbl64 is not None:
if subbl32 == subbl64:
assert('||' not in svc_type)
idc.set_name(subbl64, svc_name, SN_CHECK)
idc.SetType(subbl64, svc_type % svc_name)
elif IsTrampoline(BLS_32[svc_id]) and IsTrampoline(BLS_64[svc_id]):
b32 = GetBranch(BLS_32[svc_id])
b64 = GetBranch(BLS_64[svc_id])
if b32 == b64:
assert('||' not in svc_type)
ida_funcs.del_func(BLS_32[svc_id])
ida_funcs.del_func(BLS_64[svc_id])
ida_funcs.del_func(b32)
ida_funcs.add_func(b32)
ida_funcs.add_func(BLS_32[svc_id])
ida_funcs.add_func(BLS_64[svc_id])
idc.set_name(b64, svc_name, SN_CHECK)
idc.SetType(b64, svc_type % svc_name)
#define __int8 char
#define __int16 short
#define __int32 int
#define __int64 long long
union __attribute__((aligned(8))) __n64
{
unsigned __int64 n64_u64[1];
unsigned __int32 n64_u32[2];
unsigned __int16 n64_u16[4];
unsigned __int8 n64_u8[8];
__int64 n64_i64[1];
__int32 n64_i32[2];
__int16 n64_i16[4];
__int8 n64_i8[8];
float n64_f32[2];
double n64_f64[1];
};
union __attribute__((aligned(8))) __n128
{
unsigned __int64 n128_u64[2];
unsigned __int32 n128_u32[4];
unsigned __int16 n128_u16[8];
unsigned __int8 n128_u8[16];
__int64 n128_i64[2];
__int32 n128_i32[4];
__int16 n128_i16[8];
__int8 n128_i8[16];
float n128_f32[4];
double n128_f64[2];
};
typedef __n64 int8x8_t;
typedef __n64 uint8x8_t;
typedef __n64 int16x4_t;
typedef __n64 int32x2_t;
typedef __n64 uint16x4_t;
typedef __n64 uint32x2_t;
typedef __n128 int8x16_t;
typedef __n128 int16x8_t;
typedef __n128 int32x4_t;
typedef __n128 int64x2_t;
typedef __n128 uint8x16_t;
typedef __n128 uint16x8_t;
typedef __n128 uint32x4_t;
typedef __n128 uint64x2_t;
typedef __n64 poly8x8_t;
typedef __n64 poly16x4_t;
typedef __n128 poly16x8_t;
typedef __n128 poly8x16_t;
typedef __n64 float32x2_t;
typedef __n128 float32x4_t;
typedef __n128 float64x2_t;
typedef __n128 poly128_t;
struct __va_list_tag
{
void *__stack;
void *__gr_top;
void *__vr_top;
int __gr_offs;
int __vr_offs;
};
typedef __va_list_tag gcc_va_list[1];
typedef uintptr_t ThreadFunc;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
enum Result
{
ResultSuccess = 0x0,
ResultSvcOutOfSessions = 0xE01,
ResultSvcInvalidArgument = 0x1C01,
ResultSvcNotImplemented = 0x4201,
ResultSvcThreadTerminating = 0x7601,
ResultSvcNoEvent = 0x8C01,
ResultSvcInvalidSize = 0xCA01,
ResultSvcInvalidAddress = 0xCC01,
ResultSvcOutOfResource = 0xCE01,
ResultSvcOutOfMemory = 0xD001,
ResultSvcOutOfHandles = 0xD201,
ResultSvcInvalidCurrentMemoryState = 0xD401,
ResultSvcInvalidNewMemoryPermissions = 0xD801,
ResultSvcInvalidMemoryRegion = 0xDC01,
ResultSvcInvalidPriority = 0xE001,
ResultSvcInvalidCoreId = 0xE201,
ResultSvcInvalidHandle = 0xE401,
ResultSvcInvalidPointer = 0xE601,
ResultSvcInvalidCombination = 0xE801,
ResultSvcTimedOut = 0xEA01,
ResultSvcCancelled = 0xEC01,
ResultSvcOutOfRange = 0xEE01,
ResultSvcInvalidEnumValue = 0xF001,
ResultSvcNotFound = 0xF201,
ResultSvcBusy = 0xF401,
ResultSvcSessionClosed = 0xF601,
ResultSvcNotHandled = 0xF801,
ResultSvcInvalidState = 0xFA01,
ResultSvcReservedValue = 0xFC01,
ResultSvcNotSupported = 0xFE01,
ResultSvcDebug = 0x10001,
ResultSvcThreadNotOwned = 0x10201,
ResultSvcPortClosed = 0x10601,
ResultSvcLimitReached = 0x10801,
ResultSvcReceiveListBroken = 0x20401,
ResultSvcOutOfAddressSpace = 0x20601,
ResultSvcMessageTooLarge = 0x20801,
ResultSvcProcessTerminated = 0x41001,
};
typedef unsigned int Handle;
enum LimitableResource : unsigned __int32
{
LimitableResource_PhysicalMemoryMax = 0x0,
LimitableResource_ThreadCountMax = 0x1,
LimitableResource_EventCountMax = 0x2,
LimitableResource_TransferMemoryCountMax = 0x3,
LimitableResource_SessionCountMax = 0x4,
LimitableResource_Count = 0x5,
};
enum MemoryState : unsigned __int32
{
MemoryState_Free = 0x0,
MemoryState_Io = 0x1,
MemoryState_Static = 0x2,
MemoryState_Code = 0x3,
MemoryState_CodeData = 0x4,
MemoryState_Normal = 0x5,
MemoryState_Shared = 0x6,
MemoryState_Alias = 0x7,
MemoryState_AliasCode = 0x8,
MemoryState_AliasCodeData = 0x9,
MemoryState_Ipc = 0xA,
MemoryState_Stack = 0xB,
MemoryState_ThreadLocal = 0xC,
MemoryState_Transfered = 0xD,
MemoryState_SharedTransfered = 0xE,
MemoryState_SharedCode = 0xF,
MemoryState_Inaccessible = 0x10,
MemoryState_NonSecureIpc = 0x11,
MemoryState_NonDeviceIpc = 0x12,
MemoryState_Kernel = 0x13,
MemoryState_GeneratedCode = 0x14,
MemoryState_CodeOut = 0x15,
};
enum MemoryPermission : unsigned __int32
{
MemoryPermission_None = 0x0,
MemoryPermission_Read = 0x1,
MemoryPermission_Write = 0x2,
MemoryPermission_Execute = 0x4,
MemoryPermission_ReadWrite = 0x3,
MemoryPermission_ReadExecute = 0x5,
MemoryPermission_DontCare = 0x10000000,
};
enum MemoryAttribute : unsigned __int32
{
MemoryAttribute_Locked = 0x1,
MemoryAttribute_IpcLocked = 0x2,
MemoryAttribute_DeviceShared = 0x4,
MemoryAttribute_Uncached = 0x8,
};
struct PageInfo
{
u32 flags;
};
enum InfoType : unsigned __int32
{
InfoType_CoreMask = 0x0,
InfoType_PriorityMask = 0x1,
InfoType_AliasRegionAddress = 0x2,
InfoType_AliasRegionSize = 0x3,
InfoType_HeapRegionAddress = 0x4,
InfoType_HeapRegionSize = 0x5,
InfoType_TotalMemorySize = 0x6,
InfoType_UsedMemorySize = 0x7,
InfoType_DebuggerAttached = 0x8,
InfoType_ResourceLimit = 0x9,
InfoType_IdleTickCount = 0xA,
InfoType_RandomEntropy = 0xB,
InfoType_AslrRegionAddress = 0xC,
InfoType_AslrRegionSize = 0xD,
InfoType_StackRegionAddress = 0xE,
InfoType_StackRegionSize = 0xF,
InfoType_SystemResourceSizeTotal = 0x10,
InfoType_SystemResourceSizeUsed = 0x11,
InfoType_ProgramId = 0x12,
InfoType_InitialProcessIdRange = 0x13,
InfoType_UserExceptionContextAddress = 0x14,
InfoType_TotalNonSystemMemorySize = 0x15,
InfoType_UsedNonSystemMemorySize = 0x16,
InfoType_IsApplication = 0x17,
InfoType_ThreadTickCount = 0xF0000002,
};
enum SystemInfoType : unsigned __int32
{
SystemInfoType_TotalPhysicalMemorySize = 0x0,
SystemInfoType_UsedPhysicalMemorySize = 0x1,
SystemInfoType_InitialProcessIdRange = 0x2,
};
enum InitialProcessIdRangeInfo : unsigned __int64
{
InitialProcessIdRangeInfo_Minimum = 0x0,
InitialProcessIdRangeInfo_Maximum = 0x1,
};
enum PhysicalMemoryInfo : unsigned __int64
{
PhysicalMemoryInfo_Application = 0x0,
PhysicalMemoryInfo_Applet = 0x1,
PhysicalMemoryInfo_System = 0x2,
PhysicalMemoryInfo_SystemUnsafe = 0x3,
};
enum LastThreadInfoFlag : unsigned __int32
{
};
enum TickCountInfo : unsigned __int64
{
TickCountInfo_Core0 = 0x0,
TickCountInfo_Core1 = 0x1,
TickCountInfo_Core2 = 0x2,
TickCountInfo_Core3 = 0x3,
TickCountInfo_Total = 0xFFFFFFFFFFFFFFFF,
};
enum CodeMemoryOperation : unsigned __int32
{
CodeMemoryOperation_MapOwner = 0x0,
CodeMemoryOperation_MapSlave = 0x1,
CodeMemoryOperation_UnmapOwner = 0x2,
CodeMemoryOperation_UnmapSlave = 0x3,
};
enum SignalType : unsigned __int32
{
SignalType_Signal = 0x0,
SignalType_SignalAndIfEqual = 0x1,
SignalType_SignalAndModifyBasedOnWaitingThreadCountIfEqual = 0x2,
};
enum ArbitrationType : unsigned __int32
{
ArbitrationType_WaitIfLessThan = 0x0,
ArbitrationType_DecrementAndWaitIfLessThan = 0x1,
ArbitrationType_WaitIfEqual = 0x2,
};
enum InterruptType : unsigned __int32
{
InterruptType_Edge = 0x0,
InterruptType_Level = 0x1,
};
typedef int64_t s64;
enum YieldType : __int64
{
YieldType_WithoutCoreMigration = 0x0,
YieldType_WithCoreMigration = 0xFFFFFFFFFFFFFFFF,
YieldType_ToAnyThread = 0xFFFFFFFFFFFFFFFE,
};
struct ThreadContext
{
u64 r[29];
u64 fp;
u64 lr;
u64 sp;
u64 pc;
u32 pstate;
u32 padding;
unsigned __int128 v[32];
u32 fpcr;
u32 fpsr;
u64 tpidr;
};
enum ThreadSuspend : unsigned __int32
{
ThreadSuspend_Debug = 0x1,
ThreadSuspend_User = 0x2,
};
enum ThreadContextFlag : unsigned __int32
{
ThreadContextFlag_General = 0x1,
ThreadContextFlag_Control = 0x2,
ThreadContextFlag_Fpu = 0x4,
ThreadContextFlag_FpuControl = 0x8,
ThreadContextFlag_All = 0xF,
};
enum ThreadExitReason : unsigned __int32
{
ThreadExitReason_ExitThread = 0x0,
ThreadExitReason_TerminateThread = 0x1,
ThreadExitReason_ExitProcess = 0x2,
ThreadExitReason_TerminateProcess = 0x3,
};
enum ThreadActivity : unsigned __int32
{
ThreadActivity_Runnable = 0x0,
ThreadActivity_Paused = 0x1,
};
enum ProcessInfoType : unsigned __int32
{
ProcessInfoType_ProcessState = 0x0,
};
enum ProcessState : unsigned __int32
{
ProcessState_Created = 0x0,
ProcessState_CreatedAttached = 0x1,
ProcessState_Running = 0x2,
ProcessState_Crashed = 0x3,
ProcessState_RunningAttached = 0x4,
ProcessState_Exiting = 0x5,
ProcessState_Exited = 0x6,
ProcessState_DebugSuspended = 0x7,
};
enum ProcessExitReason : unsigned __int32
{
ProcessExitReason_ExitProcess = 0x0,
ProcessExitReason_TerminateProcess = 0x1,
ProcessExitReason_Exception = 0x2,
};
enum ProcessActivity : unsigned __int32
{
ProcessActivity_Runnable = 0x0,
ProcessActivity_Paused = 0x1,
};
enum CreateProcessFlag : unsigned __int32
{
CreateProcessFlag_Is64Bit = 0x1,
CreateProcessFlag_AddressSpaceShift = 0x1,
CreateProcessFlag_AddressSpaceMask = 0xE,
CreateProcessFlag_AddressSpace32Bit = 0x0,
CreateProcessFlag_AddressSpace64BitDeprecated = 0x2,
CreateProcessFlag_AddressSpace32BitWithoutAlias = 0x4,
CreateProcessFlag_AddressSpace64Bit = 0x6,
CreateProcessFlag_EnableDebug = 0x10,
CreateProcessFlag_EnableAslr = 0x20,
CreateProcessFlag_IsApplication = 0x40,
CreateProcessFlag_DeprecatedUseSecureMemory = 0x80,
CreateProcessFlag_PoolPartitionShift = 0x7,
CreateProcessFlag_PoolPartitionMask = 0x780,
CreateProcessFlag_PoolPartitionApplication = 0x0,
CreateProcessFlag_PoolPartitionApplet = 0x80,
CreateProcessFlag_PoolPartitionSystem = 0x100,
CreateProcessFlag_PoolPartitionSystemNonSecure = 0x180,
CreateProcessFlag_OptimizeMemoryAllocation = 0x800,
};
enum DebugEvent : unsigned __int32
{
DebugEvent_AttachProcess = 0x0,
DebugEvent_AttachThread = 0x1,
DebugEvent_ExitProcess = 0x2,
DebugEvent_ExitThread = 0x3,
DebugEvent_Exception = 0x4,
};
enum DebugThreadParam : unsigned __int32
{
DebugThreadParam_Priority = 0x0,
DebugThreadParam_State = 0x1,
DebugThreadParam_IdealCore = 0x2,
DebugThreadParam_CurrentCore = 0x3,
DebugThreadParam_AffinityMask = 0x4,
};
enum DebugException : unsigned __int32
{
DebugException_UndefinedInstruction = 0x0,
DebugException_InstructionAbort = 0x1,
DebugException_DataAbort = 0x2,
DebugException_AlignmentFault = 0x3,
DebugException_DebuggerAttached = 0x4,
DebugException_BreakPoint = 0x5,
DebugException_UserBreak = 0x6,
DebugException_DebuggerBreak = 0x7,
DebugException_UndefinedSystemCall = 0x8,
DebugException_MemorySystemError = 0x9,
};
enum ExceptionType : unsigned __int32
{
ExceptionType_Init = 0x0,
ExceptionType_InstructionAbort = 0x100,
ExceptionType_DataAbort = 0x101,
ExceptionType_UnalignedInstruction = 0x102,
ExceptionType_UnalignedData = 0x103,
ExceptionType_UndefinedInstruction = 0x104,
ExceptionType_ExceptionInstruction = 0x105,
ExceptionType_MemorySystemError = 0x106,
ExceptionType_FpuException = 0x200,
ExceptionType_InvalidSystemCall = 0x301,
ExceptionType_SystemCallBreak = 0x302,
ExceptionType_AtmosphereStdAbort = 0xFFE,
};
enum BreakReason : unsigned __int32
{
};
enum KernelDebugType : unsigned __int32
{
};
enum KernelTraceState : unsigned __int32
{
KernelTraceState_Disabled = 0x0,
KernelTraceState_Enabled = 0x1,
};
enum BreakPointType : unsigned __int32
{
BreakPointType_HardwareInstruction = 0x0,
BreakPointType_HardwareData = 0x1,
};
enum HardwareBreakPointRegisterName : unsigned __int32
{
HardwareBreakPointRegisterName_I0 = 0x0,
HardwareBreakPointRegisterName_I1 = 0x1,
HardwareBreakPointRegisterName_I2 = 0x2,
HardwareBreakPointRegisterName_I3 = 0x3,
HardwareBreakPointRegisterName_I4 = 0x4,
HardwareBreakPointRegisterName_I5 = 0x5,
HardwareBreakPointRegisterName_I6 = 0x6,
HardwareBreakPointRegisterName_I7 = 0x7,
HardwareBreakPointRegisterName_I8 = 0x8,
HardwareBreakPointRegisterName_I9 = 0x9,
HardwareBreakPointRegisterName_I10 = 0xA,
HardwareBreakPointRegisterName_I11 = 0xB,
HardwareBreakPointRegisterName_I12 = 0xC,
HardwareBreakPointRegisterName_I13 = 0xD,
HardwareBreakPointRegisterName_I14 = 0xE,
HardwareBreakPointRegisterName_I15 = 0xF,
HardwareBreakPointRegisterName_D0 = 0x10,
HardwareBreakPointRegisterName_D1 = 0x11,
HardwareBreakPointRegisterName_D2 = 0x12,
HardwareBreakPointRegisterName_D3 = 0x13,
HardwareBreakPointRegisterName_D4 = 0x14,
HardwareBreakPointRegisterName_D5 = 0x15,
HardwareBreakPointRegisterName_D6 = 0x16,
HardwareBreakPointRegisterName_D7 = 0x17,
HardwareBreakPointRegisterName_D8 = 0x18,
HardwareBreakPointRegisterName_D9 = 0x19,
HardwareBreakPointRegisterName_D10 = 0x1A,
HardwareBreakPointRegisterName_D11 = 0x1B,
HardwareBreakPointRegisterName_D12 = 0x1C,
HardwareBreakPointRegisterName_D13 = 0x1D,
HardwareBreakPointRegisterName_D14 = 0x1E,
HardwareBreakPointRegisterName_D15 = 0x1F,
};
struct SvcExceptionInfo64
{
u64 r[9];
u64 lr;
u64 sp;
u64 pc;
u32 pstate;
u32 afsr0;
u32 afsr1;
u32 esr;
u64 _far;
};
struct SvcProcessLocalRegion64
{
u64 data[41];
SvcExceptionInfo64 exception_info;
u64 dying_message_region_address;
u64 dying_message_region_size;
u64 padding[6];
};
struct SvcExceptionInfo32Status32
{
u32 cpsr;
u32 fsr;
u32 _far;
u32 fpexc;
u32 fpinst;
u32 fpinst2;
};
struct SvcExceptionInfo32Status64
{
u32 pstate;
u32 afsr0;
u32 esr;
u32 _far;
};
union SvcExceptionInfo32StatusUnion
{
SvcExceptionInfo32Status32 status_32;
SvcExceptionInfo32Status64 status_64;
};
struct SvcExceptionInfo32
{
u32 r[8];
u32 sp;
u32 lr;
u32 pc;
u32 flags;
SvcExceptionInfo32StatusUnion status_union;
};
struct SvcProcessLocalRegion32
{
u32 data[94];
SvcExceptionInfo32 exception_info;
u64 dying_message_region_address;
u64 dying_message_region_size;
u64 padding[6];
};
struct SecureMonitorArguments
{
u64 r[8];
};
typedef u64 PhysicalAddress;
struct SvcPhysicalMemoryInfo64
{
PhysicalAddress physical_address;
u64 virtual_address;
u64 size;
};
struct SvcPhysicalMemoryInfo32
{
PhysicalAddress physical_address;
u32 virtual_address;
u32 size;
};
enum DeviceName
{
DeviceName_Afi = 0x0,
DeviceName_Avpc = 0x1,
DeviceName_Dc = 0x2,
DeviceName_Dcb = 0x3,
DeviceName_Hc = 0x4,
DeviceName_Hda = 0x5,
DeviceName_Isp2 = 0x6,
DeviceName_MsencNvenc = 0x7,
DeviceName_Nv = 0x8,
DeviceName_Nv2 = 0x9,
DeviceName_Ppcs = 0xA,
DeviceName_Sata = 0xB,
DeviceName_Vi = 0xC,
DeviceName_Vic = 0xD,
DeviceName_XusbHost = 0xE,
DeviceName_XusbDev = 0xF,
DeviceName_Tsec = 0x10,
DeviceName_Ppcs1 = 0x11,
DeviceName_Dc1 = 0x12,
DeviceName_Sdmmc1a = 0x13,
DeviceName_Sdmmc2a = 0x14,
DeviceName_Sdmmc3a = 0x15,
DeviceName_Sdmmc4a = 0x16,
DeviceName_Isp2b = 0x17,
DeviceName_Gpu = 0x18,
DeviceName_Gpub = 0x19,
DeviceName_Ppcs2 = 0x1A,
DeviceName_Nvdec = 0x1B,
DeviceName_Ape = 0x1C,
DeviceName_Se = 0x1D,
DeviceName_Nvjpg = 0x1E,
DeviceName_Hc1 = 0x1F,
DeviceName_Se1 = 0x20,
DeviceName_Axiap = 0x21,
DeviceName_Etr = 0x22,
DeviceName_Tsecb = 0x23,
DeviceName_Tsec1 = 0x24,
DeviceName_Tsecb1 = 0x25,
DeviceName_Nvdec1 = 0x26,
DeviceName_Count = 0x27,
};
struct MemoryInfo
{
u64 addr;
u64 size;
MemoryState state;
MemoryAttribute attr;
MemoryPermission perm;
u32 ipc_refcount;
u32 device_refcount;
u32 padding;
};
struct SvcLastThreadContext64
{
u64 fp;
u64 sp;
u64 lr;
u64 pc;
};
struct SvcLastThreadContext32
{
u32 fp;
u32 sp;
u32 lr;
u32 pc;
};
struct CreateProcessParameter
{
char name[12];
u32 version;
u64 program_id;
u64 code_address;
u32 code_num_pages;
u32 flags;
Handle reslimit;
u32 system_resource_num_pages;
};
struct DebugInfoAttachProcess64
{
u64 program_id;
u64 process_id;
char name[12];
u32 flags;
u64 user_exception_context_address;
};
struct DebugInfoAttachThread64
{
u64 thread_id;
u64 tls_address;
u64 entrypoint;
};
struct DebugInfoExitProcess64
{
ProcessExitReason reason;
};
struct DebugInfoExitThread64
{
ThreadExitReason reason;
};
struct DebugInfoUndefinedInstructionException64
{
u32 insn;
};
struct DebugInfoDataAbortException64
{
u64 address;
};
struct DebugInfoAlignmentFaultException64
{
u64 address;
};
struct DebugInfoBreakPointException64
{
BreakPointType type;
u64 address;
};
struct DebugInfoUserBreakException64
{
BreakReason break_reason;
u64 address;
u64 size;
};
struct DebugInfoDebuggerBreakException64
{
u64 active_thread_ids[4];
};
struct DebugInfoUndefinedSystemCallException64
{
u32 id;
};
union DebugInfoSpecificException64
{
DebugInfoUndefinedInstructionException64 undefined_instruction;
DebugInfoDataAbortException64 data_abort;
DebugInfoAlignmentFaultException64 alignment_fault;
DebugInfoBreakPointException64 break_point;
DebugInfoUserBreakException64 user_break;
DebugInfoDebuggerBreakException64 debugger_break;
DebugInfoUndefinedSystemCallException64 undefined_system_call;
u64 raw;
};
struct DebugInfoException64
{
DebugException type;
u64 address;
DebugInfoSpecificException64 specific;
};
union DebugInfo64
{
DebugInfoAttachProcess64 attach_process;
DebugInfoAttachThread64 attach_thread;
DebugInfoExitProcess64 exit_process;
DebugInfoExitThread64 exit_thread;
DebugInfoException64 exception;
};
struct DebugEventInfo64
{
DebugEvent type;
u32 flags;
u64 thread_id;
DebugInfo64 info;
};
struct DebugInfoAttachProcess32
{
u64 program_id;
u64 process_id;
char name[12];
u32 flags;
u32 user_exception_context_address;
};
struct DebugInfoAttachThread32
{
u64 thread_id;
u32 tls_address;
u32 entrypoint;
};
struct DebugInfoExitProcess32
{
ProcessExitReason reason;
};
struct DebugInfoExitThread32
{
ThreadExitReason reason;
};
struct DebugInfoUndefinedInstructionException32
{
u32 insn;
};
struct DebugInfoDataAbortException32
{
u32 address;
};
struct DebugInfoAlignmentFaultException32
{
u32 address;
};
struct DebugInfoBreakPointException32
{
BreakPointType type;
u32 address;
};
struct DebugInfoUserBreakException32
{
BreakReason break_reason;
u32 address;
u32 size;
};
struct DebugInfoDebuggerBreakException32
{
u64 active_thread_ids[4];
};
struct DebugInfoUndefinedSystemCallException32
{
u32 id;
};
union DebugInfoSpecificException32
{
DebugInfoUndefinedInstructionException32 undefined_instruction;
DebugInfoDataAbortException32 data_abort;
DebugInfoAlignmentFaultException32 alignment_fault;
DebugInfoBreakPointException32 break_point;
DebugInfoUserBreakException32 user_break;
DebugInfoDebuggerBreakException32 debugger_break;
DebugInfoUndefinedSystemCallException32 undefined_system_call;
u64 raw;
};
struct DebugInfoException32
{
DebugException type;
u32 address;
DebugInfoSpecificException32 specific;
};
union DebugInfo32
{
DebugInfoAttachProcess32 attach_process;
DebugInfoAttachThread32 attach_thread;
DebugInfoExitProcess32 exit_process;
DebugInfoExitThread32 exit_thread;
DebugInfoException32 exception;
};
struct DebugEventInfo32
{
DebugEvent type;
u32 flags;
u64 thread_id;
DebugInfo32 info;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment