Beispiel #1
0
void getEmuRW(void *pos, u32 size, u32 *readOff, u32 *writeOff){
    //Look for read/write code
    unsigned char pattern[] = {0x04, 0x00, 0x0D, 0x00, 0x17, 0x00, 0x1E, 0x00, 0xC8, 0x05};

    *writeOff = memsearch(pos, pattern, size, 10);
    *readOff = memsearch((void *)(*writeOff - 0x1000), pattern, 0x1000, 10);
}
Beispiel #2
0
void getEmuCode(void *pos, u32 *off, u32 size){
    void *proc9 = memsearch(pos, "Process9", size, 8);
    unsigned char pattern[] = {0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF};
 
    //Looking for the last spot before Process9
    *off = memsearch(pos, pattern, size - (size - (u32)(proc9 - pos)), 6) + 0xF;
}
Beispiel #3
0
void patchFirm(void){
    //Part1: Add emunand parsing code
    u32 offset = 0;
    u32 header = 0;
    if(getEmunand(&offset, &header) == 1){
        fileRead((u8*)emuCode, "/rei/emunand/emunand.bin", 0);
        u32 *pos_offset = memsearch((u8*)emuCode, "NAND", 0x218, 4);
        u32 *pos_header = memsearch((u8*)emuCode, "NCSD", 0x218, 4);
        memcpy((void *)pos_offset, (void *)offset, 4);
        memcpy((void *)pos_header, (void *)header, 4);
    }
    //Part2: Add emunand hooks
    memcpy((u8*)emuHook1, eh1, sizeof(eh1));
    memcpy((u8*)emuHook2, eh2, sizeof(eh2));
    memcpy((u8*)emuHook3, eh3, sizeof(eh3));
    memcpy((u8*)emuHook4, eh4, sizeof(eh4));
    
    //Part3: Disable signature checks
    memcpy((u8*)patch1, p1, sizeof(p1));
    memcpy((u8*)patch2, p2, sizeof(p2));
    
    //Part4: Create arm9 thread
    fileRead((u8*)threadCode, "/rei/thread/arm9.bin", 0);
    memcpy((u8*)threadHook1, th1, sizeof(th1));
    memcpy((u8*)threadHook2, th2, sizeof(th2));
}
Beispiel #4
0
void getFIRMWrite(void *pos, u32 size, u32 *off){
    //Look for FIRM writing code
    void *firmwrite = memsearch(pos, "exe:", size, 4);
    unsigned char pattern[] = {0x00, 0x28, 0x01, 0xDA};

    *off = (u32)memsearch(firmwrite - 0x100, pattern, 0x100, 4);
}
Beispiel #5
0
/*
** This patch will fix the error 022-2812
** Adapted from the post of PF2M
** https://gbatemp.net/threads/release-miiverse-custom-image-tool.415505/page-69#post-6787736
*/
static inline void antibanPatch(u8 *code, u32 size)
{
    static const char *deviceID = "X-Nintendo-Device-ID";
    static const char *fpdVersion = "X-Nintendo-FPD-Version";
    static const char *apiVersion = "X-Nintendo-API-Version";
    static const char *deviceIDPatched = "X-Nintendo-ZZZZZZ-ID";
    static const char *apiVersionPatched = "1234";

    char    *position;
    u32     patternSize;

    patternSize = strnlen(deviceID, 30);
    position = (char *)memsearch(code, deviceID, size, patternSize);
    if (position == NULL) goto error;
    strcpy(position, deviceIDPatched);
    patternSize = strnlen(fpdVersion, 30);
    position = (char *)memsearch(code, fpdVersion, size, patternSize);
    if (position == NULL) goto error;
    strcpy(position, deviceID);
    patternSize = strnlen(apiVersion, 30);
    position = (char *)memsearch(code, apiVersion, size, patternSize);
    if (position == NULL) goto error;
    position += patternSize;
    position += 2;
    strcpy(position, apiVersionPatched);
error:
    return;
}
Beispiel #6
0
void getEmuRW(void *pos, u32 size, u32 *readOff, u32 *writeOff){
    //Look for read/write code
    const u8 pattern[] = {0x1E, 0x00, 0xC8, 0x05};

    *writeOff = (u32)memsearch(pos, pattern, size, 4) - 6;
    *readOff = (u32)memsearch((void *)(*writeOff - 0x1000), pattern, 0x1000, 4) - 6;
}
Beispiel #7
0
u16 *getFirmWrite(u8 *pos, u32 size){
    //Look for FIRM writing code
    u8 *const off = memsearch(pos, "exe:", size, 4);
    const u8 pattern[] = {0x00, 0x28, 0x01, 0xDA};

    return (u16 *)memsearch(off - 0x100, pattern, 0x100, 4);
}
Beispiel #8
0
int memsearch(int array[][MAX], int mem[][MAX], int r, int c, int a, int b){
    if (mem[a][b]!=0)
        return mem[a][b];
    int max=1;
    if (a-1>=0&&a-1<r&&b>=0&&b<c&&array[a-1][b]<array[a][b]){
        int temp=memsearch(array,mem,r,c,a-1,b);
        if (1+temp>max)
            max=1+temp;
    }
    if (a+1>=0&&a+1<r&&b>=0&&b<c&&array[a+1][b]<array[a][b]){
        int temp=memsearch(array,mem,r,c,a+1,b);
        if (1+temp>max)
            max=1+temp;
    }
    if (a>=0&&a<r&&b+1>=0&&b+1<c&&array[a][b+1]<array[a][b]){
        int temp=memsearch(array,mem,r,c,a,b+1);
        if (1+temp>max)
            max=1+temp;
    }
    if (a>=0&&a<r&&b-1>=0&&b-1<c&&array[a][b-1]<array[a][b]){
        int temp=memsearch(array,mem,r,c,a,b-1);
        if (1+temp>max)
            max=1+temp;
    }
    mem[a][b]=max;
    return max;
}
Beispiel #9
0
//Nand redirection
void loadEmu(void){ 
    //Dont boot emu if AGB game was just played, or if START was held.
    if((HID & 0xFFF) == (1 << 3) || CFG_BOOTENV == 0x7) return;
    
    //Read emunand code from SD
    fopen("/rei/emunand/emunand.bin");
    Size emuSize = fsize();
    getEmuCode(firmLocation, firmSize, &emuCodeOffset);
    fread(emuCodeOffset, 1, emuSize);
    fclose();
    
    //Setup Emunand code
    uPtr *pos_sdmmc = memsearch(emuCodeOffset, "SDMC", emuSize, 4);
    uPtr *pos_offset = memsearch(emuCodeOffset, "NAND", emuSize, 4);
    uPtr *pos_header = memsearch(emuCodeOffset, "NCSD", emuSize, 4);
	getSDMMC(firmLocation, firmSize, &sdmmcOffset);
    getEmuRW(firmLocation, firmSize, &emuRead, &emuWrite);
    *pos_sdmmc = sdmmcOffset;
    *pos_offset = emuOffset;
    *pos_header = emuHeader;
    
    //Add Emunand hooks
    memcpy((u8*)emuRead, nandRedir, sizeof(nandRedir));
    memcpy((u8*)emuWrite, nandRedir, sizeof(nandRedir));

    //Set MPU for emu code region
    getMPU(firmLocation, firmSize, &mpuOffset);
    memcpy((u8*)mpuOffset, mpu, sizeof(mpu));
}
Beispiel #10
0
//Offsets to redirect to thread code
void getSigChecks(void *pos, u32 size, u32 *off, u32 *off2){
    const u8 pattern[] = {0xC0, 0x1C, 0x76, 0xE7};
    const u8 pattern2[] = {0xB5, 0x22, 0x4D, 0x0C};

    *off = (u32)memsearch(pos, (void*)pattern, size, 4);
    *off2 = (u32)memsearch(pos, (void*)pattern2, size, 4) - 1;
}
Beispiel #11
0
void getEmuRW(u8 *pos, u32 size, u16 **readOffset, u16 **writeOffset)
{
    //Look for read/write code
    const u8 pattern[] = {0x1E, 0x00, 0xC8, 0x05};

    *readOffset = (u16 *)memsearch(pos, pattern, size, 4) - 3;
    *writeOffset = (u16 *)memsearch((u8 *)(*readOffset + 5), pattern, 0x100, 4) - 3;
}
Beispiel #12
0
void getSigChecks(u8 *pos, u32 size, u32 *off, u32 *off2){
    //Look for signature checks
    const u8 pattern[] = {0xC0, 0x1C, 0x76, 0xE7},
             pattern2[] = {0xB5, 0x22, 0x4D, 0x0C};

    *off = (u32)memsearch(pos, pattern, size, 4);
    *off2 = (u32)memsearch(pos, pattern2, size, 4) - 1;
}
Beispiel #13
0
void getSignatures(void *pos, u32 size, u32 *off, u32 *off2){
    //Look for signature checks
    unsigned char pattern[] = {0xC0, 0x1C, 0x76, 0xE7};
    unsigned char pattern2[] = {0xB5, 0x22, 0x4D, 0x0C};

    *off = (u32)memsearch(pos, pattern, size, 4);
    *off2 = (u32)memsearch(pos, pattern2, size, 4) - 1;
}
Beispiel #14
0
int patch_options(void *address, uint32_t size, uint8_t options, enum types type)
{
    if (options & patch_option_keyx) {
        print("Patch option: Adding keyX");

        if (read_file(fcram_temp, PATH_SLOT0X25KEYX, AES_BLOCK_SIZE) != 0) {
            print("Failed to load keyX");
            draw_message("Failed to load keyX", "Make sure the keyX is\n  located at /slot0x25keyX.bin");
            return 1;
        }

        void *pos = memsearch(address, "slot0x25keyXhere", size, AES_BLOCK_SIZE);
        if (pos) {
            memcpy32(pos, fcram_temp, AES_BLOCK_SIZE);
        } else {
            print("I don't know where to add keyX.\n  Ignoring...");
        }
    }
    if (options & patch_option_emunand) {
        print("Patch option: Setting emuNAND offsets");

        uint32_t offset = 0;
        uint32_t header = 0;

        if (get_emunand_offsets(config->emunand_location, &offset, &header)) {
            print("Failed to get the emuNAND offsets");
            draw_message("Failed to get the emuNAND offsets",
                    "There's 3 possible causes for this error:\n"
                    " - You don't even have an emuNAND installed\n"
                    " - Your SD card can't be read\n"
                    " - You're using an unsupported emuNAND format");
            return 1;
        }

        uint32_t *pos_offset = memsearch(address, "NAND", size, 4);
        uint32_t *pos_header = memsearch(address, "NCSD", size, 4);
        if (pos_offset && pos_header) {
            *pos_offset = offset;
            *pos_header = header;
        } else {
            print("I don't know where to set the offsets.\n"
                  "  Ignoring...");
        }
    }
    if (options & patch_option_save && type == NATIVE_FIRM) {
        print("Patch option: Save firm");

        save_firm = 1;

        // This absolutely requires the -fshort-wchar option to be enabled.
        char *offset = address + size;
        memcpy(offset, L"sdmc:", 10);
        memcpy(offset + 10, L"" PATH_PATCHED_FIRMWARE, sizeof(PATH_PATCHED_FIRMWARE) * 2);
    }

    return 0;
}
Beispiel #15
0
void getfOpen(void *pos, u32 size, u32 *off){
    //Calculate fOpen
    u32 p9addr = *(u32*)(memsearch(pos, "ess9", size, 4) + 0xC);
    u32 p9off = (u32)(memsearch(pos, "code", size, 4) + 0x1FF);

    unsigned char pattern[] = {0xB0, 0x04, 0x98, 0x0D};

    *off = (u32)memsearch(pos, pattern, size, 4) - 2 - p9off + p9addr;
}
Beispiel #16
0
void patchFirmWrites(u8 *pos, u32 size)
{
    const u16 writeBlock[2] = {0x2000, 0x46C0};

    //Look for FIRM writing code
    u8 *const off1 = memsearch(pos, "exe:", size, 4);
    const u8 pattern[] = {0x00, 0x28, 0x01, 0xDA};

    u16 *off2 = (u16 *)memsearch(off1 - 0x100, pattern, 0x100, 4);

    off2[0] = writeBlock[0];
    off2[1] = writeBlock[1];
}
Beispiel #17
0
void MPG::searchPackets(){

  packets = (packet *)malloc(buf_size / 12);
  packets_size = 0;
  
  const BYTE *j;
  const BYTE *last_j;
  const BYTE *last_packet;
  pack p;
  long z;

  for (int i=0; i < packs_size; i++) {

    p = packs[i];

    last_j = memsearch(p.start, p.size, CODE_PACKET, 3);
    last_packet = last_j;
    
    while (true) {
      j = memsearch(last_j+1, (p.end - last_j),
                    CODE_PACKET, 3);
      if (j == NULL) break;
      if (j + 3 - p.end > 0) {
        break;
        last_j = j;
        continue;
      }

      z = (long)j[3];
      if (z < 0xBD || z > 0xFF) {
        last_j = j;
        continue;
      }

      packet pp = {last_packet + 4, j-1, j-(last_packet + 4),
                   PACKET_TYPE[(z & 0xF0) >> 4]};
      packets[packets_size++] = pp;
      last_packet = j;
      last_j = j;
    }

    if (p.end - last_j > 30) {  
      // for last packet
      z = (long)last_j[3];
      if (z < 0xBD || z > 0xFF) continue;
      packet pp = {last_packet + 4, p.end, p.end-(last_packet+4)+1,
                   PACKET_TYPE[(z & 0xF0) >> 4]};
      packets[packets_size++] = pp;
    }
  }
Beispiel #18
0
void patchSignatureChecks(u8 *pos, u32 size)
{
    const u16 sigPatch[2] = {0x2000, 0x4770};

    //Look for signature checks
    const u8 pattern[] = {0xC0, 0x1C, 0x76, 0xE7},
             pattern2[] = {0xB5, 0x22, 0x4D, 0x0C};

    u16 *off = (u16 *)memsearch(pos, pattern, size, 4),
        *off2 = (u16 *)(memsearch(pos, pattern2, size, 4) - 1);

    *off = sigPatch[0];
    off2[0] = sigPatch[0];
    off2[1] = sigPatch[1];
}
Beispiel #19
0
static Result ProcessPatchesMenu_DoPatchUnpatchFS(u32 textTotalRoundedSize)
{
    static bool patched = false;
    static u16 *off;
    static u16 origData[2];
    static const u16 pattern[2] = {
        0x7401, // strb r1, [r0, #16]
        0x2000, // movs r0, #0
    };

    if(patched)
    {
        memcpy(off, &origData, sizeof(origData));
        patched = false;
    }
    else
    {
        off = (u16 *)memsearch((u8 *)0x00100000, &pattern, textTotalRoundedSize, sizeof(pattern));
        if(off == NULL)
            return -1;

        for(; (*off & 0xFF00) != 0xB500; off++); // Find function start

        memcpy(origData, off, 4);
        off[0] = 0x2001; // mov r0, #1
        off[1] = 0x4770; // bx lr

        patched = true;
    }

    processPatchesMenu.items[1].title = patched ? "Unpatch FS for the archive checks" : "Patch FS for the archive checks";
    return 0;
}
Beispiel #20
0
void reimplementSvcBackdoor(u8 *pos, u32 size)
{
    //Official implementation of svcBackdoor
    const u8  svcBackdoor[40] = {0xFF, 0x10, 0xCD, 0xE3,  //bic   r1, sp, #0xff
                                 0x0F, 0x1C, 0x81, 0xE3,  //orr   r1, r1, #0xf00
                                 0x28, 0x10, 0x81, 0xE2,  //add   r1, r1, #0x28
                                 0x00, 0x20, 0x91, 0xE5,  //ldr   r2, [r1]
                                 0x00, 0x60, 0x22, 0xE9,  //stmdb r2!, {sp, lr}
                                 0x02, 0xD0, 0xA0, 0xE1,  //mov   sp, r2
                                 0x30, 0xFF, 0x2F, 0xE1,  //blx   r0
                                 0x03, 0x00, 0xBD, 0xE8,  //pop   {r0, r1}
                                 0x00, 0xD0, 0xA0, 0xE1,  //mov   sp, r0
                                 0x11, 0xFF, 0x2F, 0xE1}; //bx    r1

    const u8 pattern[] = {0x00, 0xB0, 0x9C, 0xE5}; //cpsid aif
    
    u32 *exceptionsPage = (u32 *)memsearch(pos, pattern, size, 4) - 0xB;

    u32 svcOffset = (-((exceptionsPage[2] & 0xFFFFFF) << 2) & (0xFFFFFF << 2)) - 8; //Branch offset + 8 for prefetch
    u32 *svcTable = (u32 *)(pos + *(u32 *)(pos + 0xFFFF0008 - svcOffset - 0xFFF00000 + 8) - 0xFFF00000); //SVC handler address
    while(*svcTable) svcTable++; //Look for SVC0 (NULL)

    if(svcTable[0x7B] == 0)
    {
        u32 *freeSpace;
        for(freeSpace = exceptionsPage; *freeSpace != 0xFFFFFFFF; freeSpace++);

        memcpy(freeSpace, svcBackdoor, 40);

        svcTable[0x7B] = 0xFFFF0000 + ((u8 *)freeSpace - (u8 *)exceptionsPage);
    }
}
Beispiel #21
0
u32 *getMPU(u8 *pos, u32 size)
{
    //Look for MPU pattern
    const u8 pattern[] = {0x03, 0x00, 0x24, 0x00};

    return (u32 *)memsearch(pos, pattern, size, 4);
}
Beispiel #22
0
u32 getSDMMC(void *pos, u32 size){
    //Look for struct code
    const u8 pattern[] = {0x21, 0x20, 0x18, 0x20};
    const u8 *off = (u8 *)memsearch(pos, pattern, size, 4) - 1;

    return *(u32 *)(off + 0x0A) + *(u32 *)(off + 0x0E);
}
Beispiel #23
0
void *getEmuCode(u8 *pos)
{
    const u8 pattern[] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};

    //Looking for the last free space before Process9
    return memsearch(pos + 0x13500, pattern, 0x1000, 6) + 0x455;
}
Beispiel #24
0
u16 *getFirmWriteSafe(u8 *pos, u32 size)
{
    //Look for FIRM writing code
    const u8 pattern[] = {0x04, 0x1E, 0x1D, 0xDB};

    return (u16 *)memsearch(pos, pattern, size, 4);
}
Beispiel #25
0
void *getEmuCode(u8 *proc9Offset)
{
    const u8 pattern[] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};

    //Looking for the last free space before Process9
    return memsearch(proc9Offset - 0x3000, pattern, 0x3000, 6) + 0x455;
}
Beispiel #26
0
//Nand redirection
void loadEmu(void){
    
    //Read emunand code from SD
    u32 code = emuCode();
    fileRead(code, "/rei/emunand/emunand.bin", 0);
    u32 *pos_offset = memsearch(code, "NAND", 0x218, 4);
    u32 *pos_header = memsearch(code, "NCSD", 0x218, 4);
    if (pos_offset && pos_header) {
        *pos_offset = emuOffset;
        *pos_header = emuHeader;
    }
    
    //Add emunand hooks
    memcpy((u8*)emuHook(1), nandRedir, sizeof(nandRedir));
    memcpy((u8*)emuHook(2), nandRedir, sizeof(nandRedir));
}
Beispiel #27
0
void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr)
{
    //Look for firmlaunch code
    const u8 pattern[] = {0xDE, 0x1F, 0x8D, 0xE2};

    u8 *off = memsearch(pos, pattern, size, 4) - 0x10;

    //Firmlaunch function offset - offset in BLX opcode (A4-16 - ARM DDI 0100E) + 1
    u32 fOpenOffset = (u32)(off + 9 - (-((*(u32 *)off & 0x00FFFFFF) << 2) & (0xFFFFFF << 2)) - pos + process9MemAddr);

    //Copy firmlaunch code
    memcpy(off, reboot, reboot_size);

    //Put the fOpen offset in the right location
    u32 *pos_fopen = (u32 *)memsearch(off, "OPEN", reboot_size, 4);
    *pos_fopen = fOpenOffset;
}
Beispiel #28
0
void patchTitleInstallMinVersionCheck(u8 *pos, u32 size)
{
    const u8 pattern[] = {0x0A, 0x81, 0x42, 0x02};
    
    u8 *off = memsearch(pos, pattern, size, 4);
    
    if(off != NULL) off[4] = 0xE0;
}
Beispiel #29
0
u32 getSDMMC(u8 *pos, u32 size)
{
    //Look for struct code
    const u8 pattern[] = {0x21, 0x20, 0x18, 0x20};
    const u8 *off = memsearch(pos, pattern, size, 4);

    return *(u32 *)(off + 9) + *(u32 *)(off + 0xD);
}
Beispiel #30
0
void MPG::searchPacks(){

  packs = (pack *)malloc(buf_size / 128);
  packs_size = 0;
  
  const BYTE *i;
  BYTE z1[10];
  BYTE z2[10];
  const BYTE *last = memsearch(buf, buf_size, CODE_PACK, 4);
  std::cout << "first pack : " << (last - buf) << std::endl;
  
  while (1) {
    i = memsearch(last+1, (buf_end-last) + 1, CODE_PACK, 4);
    if (i == NULL) break;
    
    // classify pack
    bitAnd(last+4, (const BYTE *)MPG1_PACK_MASK, z1, 10);
    bitAnd(last+4, (const BYTE *)MPG2_PACK_MASK, z2, 10);
    
    if(memcmp(z1, MPG1_PACK_HEAD, 10)==0){
      pack p = {last+12, i-1, i-(last+12)};
      packs[packs_size++] = p;
    }
    else if(memcmp(z2,MPG2_PACK_HEAD, 10)==0){
      pack p = {last+14, i-1, i-(last+14)};
      packs[packs_size++] = p;
    }
    last = i;
  }

  // for last pack (bigger than 30bytes)
  if (buf_end - last > 30) {  
    bitAnd(last+4, (const BYTE *)MPG1_PACK_MASK, z1, 10);
    bitAnd(last+4, (const BYTE *)MPG2_PACK_MASK, z2, 10);    
    if(memcmp(z1, MPG1_PACK_HEAD, 10) == 0){
      pack p = {last+12, buf_end, buf_end-(last+12) + 1};
      packs[packs_size++] = p;
    }
    else if(memcmp(z2, MPG2_PACK_HEAD, 10) == 0){
      pack p = {last+14, buf_end, buf_end-(last+14) + 1};
      packs[packs_size++] = p;
    }
  }
  std::cout << "packs num : " << packs_size << std::endl;
}