mirror of
https://gitlab.com/Theopse/fbi-i18n-zh.git
synced 2025-04-06 03:58:02 +08:00
Clean up kernel exploit code.
This commit is contained in:
parent
3a4187ad39
commit
e1b2a7e4c7
@ -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) {
|
||||
|
@ -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
106
source/hax/khax.c
Normal 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
3
source/hax/khax.h
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
bool khax_execute();
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
@ -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
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user