From befa8903a84acd30d041e41ce600bb75d7a7fcec Mon Sep 17 00:00:00 2001 From: roblabla Date: Sat, 2 Dec 2017 17:17:39 +0100 Subject: [PATCH] Change the parameters of start On the switch, `start` takes two parameters : an exception pointer, and a handle to the main thread. For libtransistor, we'll also add a third one: a context handle. This should allow ace_loader to start apps expecting the usual switch treatment, while still providing the context to libtransistor binaries. --- main.c | 18 +++++++++++------- nro.c | 10 +++++----- server.c | 4 ++-- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/main.c b/main.c index 5da21ca..1e57f4e 100644 --- a/main.c +++ b/main.c @@ -35,7 +35,7 @@ typedef struct uint64_t unk3; } thread_context_t; -struct sockaddr_in stdout_server_addr = +static struct sockaddr_in stdout_server_addr = { .sin_family = AF_INET, .sin_port = htons(STDOUT_PORT), @@ -102,7 +102,7 @@ static int stdout_debug(struct _reent *reent, void *v, const char *ptr, int len) return len; } -void locate_threads(void *base, uint64_t size, int simple) +void locate_threads(void *base, uint64_t size, int simple, uint32_t *main_handle) { memory_info_t minfo; uint32_t pinfo; @@ -118,6 +118,9 @@ void locate_threads(void *base, uint64_t size, int simple) printf("- found thread context 0x%016lX at 0x%016lX\n handle: 0x%08X\n SP base: 0x%016lX\n SP mirror: 0x%016lX\n SP size: 0x%016lX\n ptrs 0x%016lX 0x%016lX 0x%016lX\n name: '%.32s'\n", (uint64_t)tc, (uint64_t)base, tc->handle, (uint64_t)tc->sp_base, (uint64_t)tc->sp_mirror, tc->sp_size, (uint64_t)tc->ptr_1c8, (uint64_t)tc->ptr_10_a, (uint64_t)tc->ptr_10_b, tc->name); if(strcmp(tc->name, "MainThread")) { + // Back up the handle, before we destroy it later on. + if (main_handle != NULL) + *main_handle = tc->handle; uint64_t *ptr = tc->sp_mirror; uint64_t sizE = tc->sp_size; uint64_t *bend = wkBase + WK_SIZE; @@ -158,7 +161,7 @@ void locate_threads(void *base, uint64_t size, int simple) } } -int thread_scan(int simple) +int thread_scan(int simple, uint32_t *main_handle) { void *addr = NULL; memory_info_t minfo; @@ -174,7 +177,7 @@ int thread_scan(int simple) if(minfo.permission == 3 && minfo.memory_type == 12) { printf("- found TLS block\n"); - locate_threads(minfo.base_addr, minfo.size, simple); + locate_threads(minfo.base_addr, minfo.size, simple, main_handle); } addr = minfo.base_addr + minfo.size; @@ -252,9 +255,10 @@ void hook_func(uint64_t arg0) map_base = (void*)0xffffffffffffffff; // kill all threads - thread_scan(0); + uint32_t main_handle = 0; + thread_scan(0, &main_handle); svcSleepThread(1000*1000*1000); - thread_scan(1); + thread_scan(1, NULL); svcSleepThread(1000*1000*1000); // close some handles @@ -311,7 +315,7 @@ void hook_func(uint64_t arg0) // start 'push' server if(!server_init()) - server_loop(); + server_loop(main_handle); crash: exit_loader(); diff --git a/nro.c b/nro.c index 2475392..2bfbfad 100644 --- a/nro.c +++ b/nro.c @@ -24,9 +24,9 @@ static char nro_args[NRO_MAX_ARG_BUF]; static int nro_argc; static char *nro_argoffs; -uint64_t nro_start() +uint64_t nro_start(uint32_t main_handle) { - uint64_t (*entry)(libtransistor_context_t*) = nro_base + 0x80; + uint64_t (*entry)(void*, uint32_t, libtransistor_context_t*) = nro_base + 0x80; uint64_t ret; // generate memory block @@ -69,7 +69,7 @@ uint64_t nro_start() *(void**)(get_tls() + 0x1f8) = NULL; // run NRO - ret = entry(&loader_context); + ret = entry(NULL, main_handle, &loader_context); // Restore TLS *tls_userspace_pointer = tls_backup; @@ -194,7 +194,7 @@ result_t nro_unload() return r; } -uint64_t nro_execute(void *load_base, int in_size) +uint64_t nro_execute(void *load_base, int in_size, uint32_t main_handle) { uint64_t ret; result_t r; @@ -203,7 +203,7 @@ uint64_t nro_execute(void *load_base, int in_size) if(r) return r; - ret = nro_start(); + ret = nro_start(main_handle); nro_unload(); // unload can fail; for now not a critical error diff --git a/server.c b/server.c index 1b1f368..3319715 100644 --- a/server.c +++ b/server.c @@ -95,7 +95,7 @@ int server_init() return 0; } -void server_loop() +void server_loop(uint32_t main_handle) { struct sockaddr_in client_addr; int ret; @@ -141,7 +141,7 @@ void server_loop() if(size != heap_size && size != 0xFFFFFFFF) { nro_arg_name("NRO"); - size = nro_execute(heap_base, (int)(ptr - heap_base)); + size = nro_execute(heap_base, (int)(ptr - heap_base), main_handle); printf("- NRO returned 0x%016lX\n", size); } continue;