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