Skip to content
This repository was archived by the owner on Dec 13, 2017. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down
10 changes: 5 additions & 5 deletions nro.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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

Expand Down
4 changes: 2 additions & 2 deletions server.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down