Clean up kernel exploit code.

This commit is contained in:
Steveice10 2016-12-19 16:37:45 -08:00
parent 3a4187ad39
commit e1b2a7e4c7
11 changed files with 148 additions and 75 deletions

View File

@ -131,6 +131,10 @@ void util_panic(const char* s, ...) {
gfxFlushBuffers();
gspWaitForVBlank();
util_panic_quiet();
}
void util_panic_quiet() {
while(aptMainLoop()) {
hidScanInput();
if(hidKeysDown() & ~KEY_TOUCH) {

View File

@ -40,6 +40,7 @@ typedef struct {
void util_store_console_std();
void util_panic(const char* s, ...);
void util_panic_quiet();
FS_Path* util_make_path_utf8(const char* path);
void util_free_path_utf8(FS_Path* path);

106
source/hax/khax.c Normal file
View File

@ -0,0 +1,106 @@
#include <3ds.h>
#include <stdio.h>
#include "khax.h"
#include "svchax/svchax.h"
#include "waithax/waithax.h"
#define CURRENT_KPROCESS 0xFFFF9004
static void (*khax_backdoor)(void (*func)());
static volatile u32 khax_read32_kernel_addr;
static volatile u32 khax_read32_kernel_result;
static volatile u32 khax_write32_kernel_addr;
static volatile u32 khax_write32_kernel_value;
static void khax_read32_kernel_priv() {
khax_read32_kernel_result = *(u32*) khax_read32_kernel_addr;
}
static u32 khax_read32_kernel(u32 addr) {
khax_read32_kernel_addr = addr;
khax_backdoor(khax_read32_kernel_priv);
return khax_read32_kernel_result;
}
static void khax_write32_kernel_priv() {
*(u32*) khax_write32_kernel_addr = khax_write32_kernel_value;
}
static void khax_write32_kernel(u32 addr, u32 value) {
khax_write32_kernel_addr = addr;
khax_write32_kernel_value = value;
khax_backdoor(khax_write32_kernel_priv);
}
bool khax_execute() {
printf("khax: Retrieving system information...\n");
u32 kver = osGetKernelVersion();
bool n3ds = false;
APT_CheckNew3DS(&n3ds);
void (*khax_cleanup)() = NULL;
if(envIsHomebrew()) {
printf("khax: Choosing exploit to execute...\n");
if(kver > SYSTEM_VERSION(2, 51, 2)) {
printf("khax: Unsupported firmware version.\n");
return false;
} else if(kver > SYSTEM_VERSION(2, 50, 11)) {
printf("khax: Executing waithax...\n");
if(!waithax_run()) {
printf("khax: waithax failed.\n");
return false;
}
khax_backdoor = waithax_backdoor;
khax_cleanup = NULL;
} else {
printf("khax: Executing svchax...\n");
svchax_init(false);
if(!__ctr_svchax) {
printf("khax: svchax failed.\n");
return false;
}
khax_backdoor = (void (*)(void (*func)())) svcBackdoor;
khax_cleanup = waithax_cleanup;
}
printf("khax: Kernel exploit executed successfully.\n");
} else {
printf("khax: Not running as a 3DSX; assuming CIA/3DS with svcBackdoor access.\n");
khax_backdoor = (void (*)(void (*func)())) svcBackdoor;
khax_cleanup = NULL;
}
printf("khax: Retrieving PID kernel address...\n");
u32 pidAddr = khax_read32_kernel(CURRENT_KPROCESS) + (n3ds ? 0xBC : (kver > SYSTEM_VERSION(2, 40, 0)) ? 0xB4 : 0xAC);
printf("khax: Backing up PID and patching to 0...\n");
u32 oldPid = khax_read32_kernel(pidAddr);
khax_write32_kernel(pidAddr, 0);
printf("khax: Reinitializing srv...\n");
srvExit();
srvInit();
printf("khax: Restoring PID...\n");
khax_write32_kernel(pidAddr, oldPid);
printf("khax: Cleaning up...\n");
if(khax_cleanup != NULL) {
khax_cleanup();
}
printf("khax: Success.\n");
return true;
}

3
source/hax/khax.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
bool khax_execute();

View File

@ -3,7 +3,6 @@
#include <string.h>
#include <malloc.h>
#include "svchax.h"
#include "waithax.h"
#define CURRENT_KTHREAD 0xFFFF9000
#define CURRENT_KPROCESS 0xFFFF9004
@ -46,12 +45,10 @@ static u32 svc_7b(backdoor_fn entry_fn, ...) // can pass up to two arguments to
return 0;
}
static bool g_is_new3ds;
static void k_enable_all_svcs()
static void k_enable_all_svcs(u32 isNew3DS)
{
u32* thread_ACL = *(*(u32***)CURRENT_KTHREAD + 0x22) - 0x6;
u32* process_ACL = *(u32**)CURRENT_KPROCESS + (g_is_new3ds ? 0x24 : 0x22);
u32* process_ACL = *(u32**)CURRENT_KPROCESS + (isNew3DS ? 0x24 : 0x22);
memset(thread_ACL, 0xFF, 0x10);
memset(process_ACL, 0xFF, 0x10);
@ -230,7 +227,7 @@ static void do_memchunkhax2(void)
if (!mch2.threads[i].keep)
svcCloseHandle(mch2.threads[i].handle);
svcCreateEvent(&mch2.dummy_threads_lock, RESET_STICKY);
svcCreateEvent(&mch2.dummy_threads_lock, 1);
svcClearEvent(mch2.dummy_threads_lock);
for (i = 0; i < mch2.threads_limit; i++)
@ -247,7 +244,7 @@ static void do_memchunkhax2(void)
svcCloseHandle(mch2.threads[i].handle);
mch2.threads[i].handle = 0;
}
svcSleepThread(40000000LL);
svcCloseHandle(mch2.dummy_threads_lock);
@ -315,8 +312,8 @@ static void do_memchunkhax2(void)
volatile u32* thread_ACL = &mapped_page[THREAD_PAGE_ACL_OFFSET >> 2];
svcCreateEvent(&mch2.main_thread_lock, RESET_ONESHOT);
svcCreateEvent(&mch2.target_threads_lock, RESET_STICKY);
svcCreateEvent(&mch2.main_thread_lock, 0);
svcCreateEvent(&mch2.target_threads_lock, 1);
svcClearEvent(mch2.target_threads_lock);
for (i = 0; i < mch2.threads_limit; i++)
@ -380,13 +377,16 @@ static void do_memchunkhax2(void)
static void gspwn(u32 dst, u32 src, u32 size, u8* flush_buffer)
{
extern Handle gspEvents[GSPGPU_EVENT_MAX];
memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000);
GSPGPU_InvalidateDataCache((void*)dst, size);
GSPGPU_FlushDataCache((void*)src, size);
memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000);
svcClearEvent(gspEvents[GSPGPU_EVENT_PPF]);
GX_TextureCopy((void*)src, 0, (void*)dst, 0, size, 8);
gspWaitForPPF();
svcWaitSynchronization(gspEvents[GSPGPU_EVENT_PPF], U64_MAX);
memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000);
}
@ -463,66 +463,37 @@ static void do_memchunkhax1(void)
Result svchax_init(bool patch_srv)
{
APT_CheckNew3DS(&g_is_new3ds);
bool isNew3DS;
APT_CheckNew3DS(&isNew3DS);
u32 kver = osGetKernelVersion();
if(!__ctr_svchax) {
if(__service_ptr) {
if(kver > SYSTEM_VERSION(2, 51, 2)) {
printf("Unsupported firmware version.\n");
if (!__ctr_svchax)
{
if (__service_ptr)
{
if (kver > SYSTEM_VERSION(2, 50, 11))
return -1;
} else if(kver > SYSTEM_VERSION(2, 50, 11)) {
printf("Executing waithax...");
if(waithax_run()) {
printf("Executing k_enable_all_svcs...\n");
waithax_backdoor(k_enable_all_svcs);
printf("Cleaning up waithax...\n");
waithax_cleanup();
printf("waithax complete.\n");
__ctr_svchax = 1;
}
} else {
if(kver > SYSTEM_VERSION(2, 46, 0)) {
printf("Executing memchunkhax2...\n");
do_memchunkhax2();
} else {
printf("Executing memchunkhax1...\n");
do_memchunkhax1();
}
printf("Executing k_enable_all_svcs...\n");
svc_7b((backdoor_fn) k_enable_all_svcs);
printf("memchunkhax complete.\n");
__ctr_svchax = 1;
}
} else {
printf("Executing k_enable_all_svcs...\n");
svc_7b((backdoor_fn) k_enable_all_svcs);
printf("SVC access patch complete.\n");
__ctr_svchax = 1;
else if (kver > SYSTEM_VERSION(2, 46, 0))
do_memchunkhax2();
else
do_memchunkhax1();
}
svc_7b((backdoor_fn)k_enable_all_svcs, isNew3DS);
__ctr_svchax = 1;
}
if (patch_srv && __ctr_svchax && !__ctr_svchax_srv)
if (patch_srv && !__ctr_svchax_srv)
{
printf("Patching PID to 0...\n");
u32 PID_kaddr = read_kaddr(CURRENT_KPROCESS) + (g_is_new3ds ? 0xBC : (kver > SYSTEM_VERSION(2, 40, 0)) ? 0xB4 : 0xAC);
u32 PID_kaddr = read_kaddr(CURRENT_KPROCESS) + (isNew3DS ? 0xBC : (kver > SYSTEM_VERSION(2, 40, 0)) ? 0xB4 : 0xAC);
u32 old_PID = read_kaddr(PID_kaddr);
write_kaddr(PID_kaddr, 0);
printf("Reinitializing srv...\n");
srvExit();
srvInit();
printf("Restoring PID...\n");
write_kaddr(PID_kaddr, old_PID);
printf("Service access patch complete.\n");
__ctr_svchax_srv = 1;
}

View File

@ -7,4 +7,3 @@ typedef u32(*backdoor_fn)(u32 arg0, u32 arg1);
u32 svc_7b(void* entry_fn, ...); // can pass up to two arguments to entry_fn(...)
Result svcCreateSemaphoreKAddr(Handle *semaphore, s32 initialCount, s32 maxCount, u32 **kaddr);
Result svcGetHandleInfo(s64* out, Handle handle, u32 type);

View File

@ -18,16 +18,6 @@ svcCreateSemaphoreKAddr:
str r1, [r3]
bx lr
.global svcGetHandleInfo
.type svcGetHandleInfo, %function
svcGetHandleInfo:
str r0, [sp, #-0x4]!
svc 0x29
ldr r3, [sp], #4
str r1, [r3]
str r2, [r3, #4]
bx lr
@ Here for debug/dev purposes
.global svc_7b

View File

@ -7,7 +7,7 @@
#include "core/clipboard.h"
#include "core/screen.h"
#include "core/util.h"
#include "hax/svchax.h"
#include "hax/khax.h"
#include "ui/error.h"
#include "ui/mainmenu.h"
#include "ui/ui.h"
@ -94,8 +94,12 @@ void init() {
consoleInit(GFX_TOP, NULL);
util_store_console_std();
printf("Attempting to acquire kernel access...");
svchax_init(true);
if(!khax_execute()) {
printf("Press any key to exit.\n");
util_panic_quiet();
return;
}
devoptab_list[STD_OUT] = oldStdOut;
devoptab_list[STD_ERR] = oldStdErr;
@ -103,11 +107,6 @@ void init() {
gfxSetScreenFormat(GFX_TOP, GSP_BGR8_OES);
gfxSetDoubleBuffering(GFX_TOP, true);
if(!__ctr_svchax || !__ctr_svchax_srv) {
util_panic("Failed to acquire kernel access.");
return;
}
Result initRes = init_services();
if(R_FAILED(initRes)) {
util_panic("Failed to initialize services: %08lX", initRes);