diff --git a/ctrtool/ctrtool.vcxproj b/ctrtool/ctrtool.vcxproj index e0d01b5..71596d6 100644 --- a/ctrtool/ctrtool.vcxproj +++ b/ctrtool/ctrtool.vcxproj @@ -99,6 +99,7 @@ + @@ -131,6 +132,7 @@ + diff --git a/ctrtool/ctrtool.vcxproj.filters b/ctrtool/ctrtool.vcxproj.filters index 075c29d..f7862f2 100644 --- a/ctrtool/ctrtool.vcxproj.filters +++ b/ctrtool/ctrtool.vcxproj.filters @@ -117,6 +117,9 @@ Source Files + + Source Files + @@ -209,5 +212,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/ctrtool/exheader.c b/ctrtool/exheader.c index 9715616..e9a6af1 100644 --- a/ctrtool/exheader.c +++ b/ctrtool/exheader.c @@ -1,3 +1,4 @@ +#include #include #include @@ -5,6 +6,7 @@ #include "exheader.h" #include "utils.h" #include "ncch.h" +#include "syscalls.h" #include void exheader_init(exheader_context* ctx) @@ -193,7 +195,7 @@ int exheader_process(exheader_context* ctx, u32 actions) exheader_verify(ctx); if (actions & InfoFlag) - exheader_print(ctx); + exheader_print(ctx, actions); return 1; } @@ -231,7 +233,7 @@ void exheader_print_arm9accesscontrol(exheader_context* ctx) } } -void exheader_print_arm11kernelcapabilities(exheader_context* ctx) +void exheader_print_arm11kernelcapabilities(exheader_context* ctx, u32 actions) { unsigned int i, j; unsigned int systemcallmask[8]; @@ -294,42 +296,66 @@ void exheader_print_arm11kernelcapabilities(exheader_context* ctx) } fprintf(stdout, "Allowed systemcalls: "); - for(i=0; i<8; i++) + if(!(actions & ShowSyscallsFlag)) { - for(j=0; j<24; j++) + for(i=0; i<8; i++) { - svcmask = systemcallmask[i]; - - if (svcmask & (1< 0x%02X %s\n", svcid, svcname); } } } } - if (svccount & 7) - fprintf(stdout, "\n"); - if (svccount == 0) - fprintf(stdout, "none\n"); - fprintf(stdout, "Allowed interrupts: "); for(i=0; i<0x7F; i++) @@ -618,7 +644,7 @@ const char* exheader_getsystemmodeextstring(u8 systemmodeext, u8 systemmode) } -void exheader_print(exheader_context* ctx) +void exheader_print(exheader_context* ctx, u32 actions) { u32 i; u64 savedatasize = getle64(ctx->header.systeminfo.savedatasize); @@ -679,7 +705,7 @@ void exheader_print(exheader_context* ctx) fprintf(stdout, "Main thread priority: %d %s\n", ctx->system_local_caps.priority, exheader_getvalidstring(ctx->validpriority)); // print resource limit descriptor too? currently mostly zeroes... exheader_print_arm11storageinfo(ctx); - exheader_print_arm11kernelcapabilities(ctx); + exheader_print_arm11kernelcapabilities(ctx, actions); exheader_print_arm9accesscontrol(ctx); fprintf(stdout, "Service access: %s\n", exheader_getvalidstring(ctx->validservicecontrol)); diff --git a/ctrtool/exheader.h b/ctrtool/exheader.h index 9691e0f..9ac656f 100644 --- a/ctrtool/exheader.h +++ b/ctrtool/exheader.h @@ -194,7 +194,7 @@ int exheader_get_compressedflag(exheader_context* ctx); void exheader_read(exheader_context* ctx, u32 actions); int exheader_process(exheader_context* ctx, u32 actions); const char* exheader_getvalidstring(int valid); -void exheader_print(exheader_context* ctx); +void exheader_print(exheader_context* ctx, u32 actions); void exheader_verify(exheader_context* ctx); int exheader_hash_valid(exheader_context* ctx); int exheader_programid_valid(exheader_context* ctx); diff --git a/ctrtool/main.c b/ctrtool/main.c index 76f9ad6..8282c9b 100644 --- a/ctrtool/main.c +++ b/ctrtool/main.c @@ -58,6 +58,7 @@ static void usage(const char *argv0) " --ncchkey=key Set ncch key.\n" " --ncchsyskey=key Set ncch fixed system key.\n" " --showkeys Show the keys being used.\n" + " --showsyscalls Show system call names instead of numbers.\n" " -t, --intype=type Specify input file type [ncsd, ncch, exheader, cia, tmd, lzss,\n" " firm, cwav, exefs, romfs]\n" "LZSS options:\n" @@ -150,6 +151,7 @@ int main(int argc, char* argv[]) {"decompresscode", 0, NULL, 21}, {"titlekey", 1, NULL, 22}, {"plainrgn", 1, NULL, 23}, + {"showsyscalls", 0, NULL, 24}, {NULL}, }; @@ -239,6 +241,7 @@ int main(int argc, char* argv[]) case 21: ctx.actions |= DecompressCodeFlag; break; case 22: keyset_parse_titlekey(&tmpkeys, optarg, strlen(optarg)); break; case 23: settings_set_plainrgn_path(&ctx.usersettings, optarg); break; + case 24: ctx.actions |= ShowSyscallsFlag; break; default: usage(argv[0]); diff --git a/ctrtool/syscalls.c b/ctrtool/syscalls.c new file mode 100644 index 0000000..edf8e8c --- /dev/null +++ b/ctrtool/syscalls.c @@ -0,0 +1,165 @@ +#include +#include +#include +#include "syscalls.h" + +// List of 3DS system calls. NULL indicates unknown. +static const char *const syscall_list[NUM_SYSCALLS] = +{ + NULL, // 00 + "ControlMemory", // 01 + "QueryMemory", // 02 + "ExitProcess", // 03 + "GetProcessAffinityMask", // 04 + "SetProcessAffinityMask", // 05 + "GetProcessIdealProcessor", // 06 + "SetProcessIdealProcessor", // 07 + "CreateThread", // 08 + "ExitThread", // 09 + "SleepThread", // 0A + "GetThreadPriority", // 0B + "SetThreadPriority", // 0C + "GetThreadAffinityMask", // 0D + "SetThreadAffinityMask", // 0E + "GetThreadIdealProcessor", // 0F + "SetThreadIdealProcessor", // 10 + "GetCurrentProcessorNumber", // 11 + "Run", // 12 + "CreateMutex", // 13 + "ReleaseMutex", // 14 + "CreateSemaphore", // 15 + "ReleaseSemaphore", // 16 + "CreateEvent", // 17 + "SignalEvent", // 18 + "ClearEvent", // 19 + "CreateTimer", // 1A + "SetTimer", // 1B + "CancelTimer", // 1C + "ClearTimer", // 1D + "CreateMemoryBlock", // 1E + "MapMemoryBlock", // 1F + "UnmapMemoryBlock", // 20 + "CreateAddressArbiter", // 21 + "ArbitrateAddress", // 22 + "CloseHandle", // 23 + "WaitSynchronization1", // 24 + "WaitSynchronizationN", // 25 + "SignalAndWait", // 26 + "DuplicateHandle", // 27 + "GetSystemTick", // 28 + "GetHandleInfo", // 29 + "GetSystemInfo", // 2A + "GetProcessInfo", // 2B + "GetThreadInfo", // 2C + "ConnectToPort", // 2D + "SendSyncRequest1", // 2E + "SendSyncRequest2", // 2F + "SendSyncRequest3", // 30 + "SendSyncRequest4", // 31 + "SendSyncRequest", // 32 + "OpenProcess", // 33 + "OpenThread", // 34 + "GetProcessId", // 35 + "GetProcessIdOfThread", // 36 + "GetThreadId", // 37 + "GetResourceLimit", // 38 + "GetResourceLimitLimitValues", // 39 + "GetResourceLimitCurrentValues", // 3A + "GetThreadContext", // 3B + "Break", // 3C + "OutputDebugString", // 3D + "ControlPerformanceCounter", // 3E + NULL, // 3F + NULL, // 40 + NULL, // 41 + NULL, // 42 + NULL, // 43 + NULL, // 44 + NULL, // 45 + NULL, // 46 + "CreatePort", // 47 + "CreateSessionToPort", // 48 + "CreateSession", // 49 + "AcceptSession", // 4A + "ReplyAndReceive1", // 4B + "ReplyAndReceive2", // 4C + "ReplyAndReceive3", // 4D + "ReplyAndReceive4", // 4E + "ReplyAndReceive", // 4F + "BindInterrupt", // 50 + "UnbindInterrupt", // 51 + "InvalidateProcessDataCache", // 52 + "StoreProcessDataCache", // 53 + "FlushProcessDataCache", // 54 + "StartInterProcessDma", // 55 + "StopDma", // 56 + "GetDmaState", // 57 + "RestartDma", // 58 + NULL, // 59 + NULL, // 5A + NULL, // 5B + NULL, // 5C + NULL, // 5D + NULL, // 5E + NULL, // 5F + "DebugActiveProcess", // 60 + "BreakDebugProcess", // 61 + "TerminateDebugProcess", // 62 + "GetProcessDebugEvent", // 63 + "ContinueDebugEvent", // 64 + "GetProcessList", // 65 + "GetThreadList", // 66 + "GetDebugThreadContext", // 67 + "SetDebugThreadContext", // 68 + "QueryDebugProcessMemory", // 69 + "ReadProcessMemory", // 6A + "WriteProcessMemory", // 6B + "SetHardwareBreakPoint", // 6C + "GetDebugThreadParam", // 6D + NULL, // 6E + NULL, // 6F + "ControlProcessMemory", // 70 + "MapProcessMemory", // 71 + "UnmapProcessMemory", // 72 + "CreateCodeSet", // 73 + NULL, // 74 + "CreateProcess", // 75 + "TerminateProcess", // 76 + "SetProcessResourceLimits", // 77 + "CreateResourceLimit", // 78 + "SetResourceLimitValues", // 79 + "AddCodeSegment", // 7A + "Backdoor", // 7B + "KernelSetState", // 7C + "QueryProcessMemory", // 7D + NULL, // 7E + NULL, // 7F +}; + + +void syscall_get_name(char *output, size_t size, unsigned int call_num) +{ + typedef char StaticAssert[sizeof(syscall_list) / sizeof(syscall_list[0]) == NUM_SYSCALLS ? 1 : -1]; + + if (size == 0) + { + return; + } + + const char *name = NULL; + if (call_num < (unsigned int) NUM_SYSCALLS) + { + name = syscall_list[call_num]; + } + + char name_buf[] = "UnknownXX"; + sprintf(&name_buf[sizeof(name_buf) - 3], "%02X", call_num & 0xFFu); + + name = name ? name : name_buf; + + size_t length = strlen(name); + length = (length > (size - 1)) ? (size - 1) : length; + + memcpy(output, name, length); + output[length] = '\0'; +} diff --git a/ctrtool/syscalls.h b/ctrtool/syscalls.h new file mode 100644 index 0000000..5afca89 --- /dev/null +++ b/ctrtool/syscalls.h @@ -0,0 +1,19 @@ +#ifndef _SYSCALLS_H_ +#define _SYSCALLS_H_ + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +enum { NUM_SYSCALLS = 0x80 }; + +void syscall_get_name(char *output, size_t size, unsigned int call_num); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/ctrtool/types.h b/ctrtool/types.h index 9234fe1..5904a08 100644 --- a/ctrtool/types.h +++ b/ctrtool/types.h @@ -23,7 +23,8 @@ enum flags VerifyFlag = (1<<4), RawFlag = (1<<5), ShowKeysFlag = (1<<6), - DecompressCodeFlag = (1<<7) + DecompressCodeFlag = (1<<7), + ShowSyscallsFlag = (1<<8), }; enum validstate