Skip to content

Instantly share code, notes, and snippets.

@SonoSooS
Created August 2, 2017 15:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save SonoSooS/c22f748f9318725020f5d9f7dd4f77eb to your computer and use it in GitHub Desktop.
Save SonoSooS/c22f748f9318725020f5d9f7dd4f77eb to your computer and use it in GitHub Desktop.
Unrestrict - parental control remover for Nintendo 3DS
#include <3ds.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void __system_allocateHeaps(void)
{
extern char* fake_heap_start;
extern char* fake_heap_end;
extern u32 __ctru_heap;
extern u32 __ctru_heap_size;
extern u32 __ctru_linear_heap;
extern u32 __ctru_linear_heap_size;
u32 tmp = 0;
// Distribute available memory into halves, aligning to page size.
//u32 size = (osGetMemRegionFree(MEMREGION_SYSTEM) / 2) & 0xFFFFF000;
__ctru_heap_size = 0x130000;
__ctru_linear_heap_size = 0x780000;
//*(u32*)0x00100998 = size;
// Allocate the application heap
__ctru_heap = 0x08000000;
svcControlMemory(&tmp, __ctru_heap, 0x0, __ctru_heap_size, (MemOp)MEMOP_ALLOC, (MemPerm)(MEMPERM_READ | MEMPERM_WRITE));
// Allocate the linear heap
//__ctru_linear_heap = 0x14000000;
//svcControlMemory(&tmp, 0x1C000000 - __ctru_linear_heap_size, 0x0, __ctru_linear_heap_size, (MemOp)MEMOP_FREE, (MemPerm)(0));
Result res = svcControlMemory(&__ctru_linear_heap, 0x0, 0x0, __ctru_linear_heap_size, (MemOp)MEMOP_ALLOC_LINEAR, (MemPerm)(MEMPERM_READ | MEMPERM_WRITE));
if(res < 0) *(u32*)0x00100070 = res;
if(__ctru_linear_heap < 0x10000000) *(u32*)0x00100071 = __ctru_linear_heap;
// Set up newlib heap
fake_heap_start = (char*)__ctru_heap;
fake_heap_end = fake_heap_start + __ctru_heap_size;
}
Handle mcuHandle = 0;
Result mcuInit()
{
return srvGetServiceHandle(&mcuHandle, "mcu::HWC");
}
Result mcuExit()
{
return svcCloseHandle(mcuHandle);
}
Result mcuReadRegister(u8 reg, u8* data, u32 size)
{
u32* ipc = getThreadCommandBuffer();
ipc[0] = 0x10082;
ipc[1] = reg;
ipc[2] = size;
ipc[3] = size << 4 | 0xC;
ipc[4] = data;
Result ret = svcSendSyncRequest(mcuHandle);
if(ret < 0) return ret;
return ipc[1];
}
Result mcuWriteRegister(u8 reg, u8* data, u32 size)
{
u32* ipc = getThreadCommandBuffer();
ipc[0] = 0x20082;
ipc[1] = reg;
ipc[2] = size;
ipc[3] = size << 4 | 0xA;
ipc[4] = data;
Result ret = svcSendSyncRequest(mcuHandle);
if(ret < 0) return ret;
return ipc[1];
}
int main()
{
gfxInit(GSP_RGB565_OES, GSP_RGB565_OES, false);
PrintConsole console;
consoleInit(GFX_BOTTOM, &console);
puts("Unrestrict by Sono (C) 2017");
Result res = 0;
do
{
Handle h = 0;
res = srvGetServiceHandle(&h, "cfg:s");
if(res < 0) res = srvGetServiceHandle(&h, "cfg:i");
if(res < 0)
{
printf("GetServiceHandle: %08X\n", res);
break;
}
u32* ipc = getThreadCommandBuffer();
ipc[0] = 0x40F0000;
res = svcSendSyncRequest(h);
if(res < 0)
{
printf("SendSyncRequest1: %08X\n", res);
svcCloseHandle(h);
break;
}
res = ipc[1];
if(res < 0)
{
printf("IPC1: %08X\n", res);
svcCloseHandle(h);
break;
}
ipc[0] = 0x4030000;
res = svcSendSyncRequest(h);
if(res < 0)
{
printf("SendSyncRequest2: %08X\n", res);
svcCloseHandle(h);
break;
}
res = ipc[1];
if(res < 0)
{
printf("IPC2: %08X\n", res);
svcCloseHandle(h);
break;
}
svcCloseHandle(h);
res = 0;
/*res = -1;//mcuInit();
if(res >= 0)
{
u8 val = 2;
mcuWriteRegister(0x20, &val, 1);
mcuExit();
}
else printf("Failed to reboot: %08X\n", res);*/
}
while(0);
if(res >= 0) goto ded;
puts("An error occurred, press SELECT to exit");
while(aptMainLoop())
{
hidScanInput();
if(hidKeysHeld() & KEY_SELECT) break;
gfxFlushBuffers();
gspWaitForVBlank();
}
ded:
gfxExit();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment