mirror of
https://github.com/rvtr/GodMode9i.git
synced 2025-11-02 00:11:07 -04:00
Full DS(i) ROM with arm9i/7i bins now dumpable
This commit is contained in:
parent
e153f57e10
commit
6cdf5046ac
@ -31,6 +31,7 @@
|
||||
#include "screenshot.h"
|
||||
#include "driveOperations.h"
|
||||
#include "fileOperations.h"
|
||||
#include "ndsheaderbanner.h"
|
||||
#include "read_card.h"
|
||||
#include "tonccpy.h"
|
||||
|
||||
@ -73,15 +74,6 @@ void ndsCardDump(void) {
|
||||
|
||||
if ((pressed & KEY_A) || (pressed & KEY_Y)) {
|
||||
consoleClear();
|
||||
sysSetCardOwner (BUS_OWNER_ARM9); // Allow arm9 to access NDS cart
|
||||
if (!flashcardMounted && isDSiMode()) {
|
||||
// Reset card slot
|
||||
disableSlot1();
|
||||
for(int i = 0; i < 25; i++) { swiWaitForVBlank(); }
|
||||
enableSlot1();
|
||||
for(int i = 0; i < 15; i++) { swiWaitForVBlank(); }
|
||||
}
|
||||
|
||||
char folderPath[2][256];
|
||||
sprintf(folderPath[0], "%s:/gm9i", (sdMounted ? "sd" : "fat"));
|
||||
sprintf(folderPath[1], "%s:/gm9i/out", (sdMounted ? "sd" : "fat"));
|
||||
@ -96,7 +88,7 @@ void ndsCardDump(void) {
|
||||
}
|
||||
consoleClear();
|
||||
// Read header
|
||||
tNDSHeader* ndsCardHeader = (tNDSHeader*)malloc(0x1000);
|
||||
sNDSHeaderExt* ndsCardHeader = (sNDSHeaderExt*)malloc(0x1000);
|
||||
if (cardInit (ndsCardHeader) == 0) {
|
||||
printf("Dumping...\n");
|
||||
printf("Do not remove the NDS card.\n");
|
||||
@ -121,7 +113,8 @@ void ndsCardDump(void) {
|
||||
// Determine ROM size
|
||||
u32 romSize = 0;
|
||||
if (trimRom) {
|
||||
romSize = ndsCardHeader->romSize;
|
||||
romSize = ((ndsCardHeader->unitCode != 0) && (ndsCardHeader->twlRomSize > 0))
|
||||
? ndsCardHeader->twlRomSize : ndsCardHeader->romSize;
|
||||
} else switch (ndsCardHeader->deviceSize) {
|
||||
case 0x00:
|
||||
romSize = 0x20000;
|
||||
|
||||
138
arm9/source/ndsheaderbanner.h
Normal file
138
arm9/source/ndsheaderbanner.h
Normal file
@ -0,0 +1,138 @@
|
||||
/*---------------------------------------------------------------------------------
|
||||
|
||||
memory.h -- Declaration of memory regions
|
||||
|
||||
|
||||
Copyright (C) 2005 Michael Noland (joat) and Jason Rogers (dovoto)
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
---------------------------------------------------------------------------------*/
|
||||
/*! \file ndsheaderbanner.h
|
||||
\brief Defines the Nintendo DS file header and icon/title structs.
|
||||
*/
|
||||
|
||||
#ifndef NDS_HEADER2
|
||||
#define NDS_HEADER2
|
||||
|
||||
#include <nds.h>
|
||||
|
||||
/*!
|
||||
\brief the NDS file header format
|
||||
See gbatek for more info.
|
||||
*/
|
||||
typedef struct {
|
||||
char gameTitle[12]; //!< 12 characters for the game title.
|
||||
char gameCode[4]; //!< 4 characters for the game code.
|
||||
char makercode[2]; //!< identifies the (commercial) developer.
|
||||
u8 unitCode; //!< identifies the required hardware.
|
||||
u8 deviceType; //!< type of device in the game card
|
||||
u8 deviceSize; //!< capacity of the device (1 << n Mbit)
|
||||
u8 reserved1[9];
|
||||
u8 romversion; //!< version of the ROM.
|
||||
u8 flags; //!< bit 2: auto-boot flag.
|
||||
|
||||
u32 arm9romOffset; //!< offset of the arm9 binary in the nds file.
|
||||
u32 arm9executeAddress; //!< adress that should be executed after the binary has been copied.
|
||||
u32 arm9destination; //!< destination address to where the arm9 binary should be copied.
|
||||
u32 arm9binarySize; //!< size of the arm9 binary.
|
||||
|
||||
u32 arm7romOffset; //!< offset of the arm7 binary in the nds file.
|
||||
u32 arm7executeAddress; //!< adress that should be executed after the binary has been copied.
|
||||
u32 arm7destination; //!< destination address to where the arm7 binary should be copied.
|
||||
u32 arm7binarySize; //!< size of the arm7 binary.
|
||||
|
||||
u32 filenameOffset; //!< File Name Table (FNT) offset.
|
||||
u32 filenameSize; //!< File Name Table (FNT) size.
|
||||
u32 fatOffset; //!< File Allocation Table (FAT) offset.
|
||||
u32 fatSize; //!< File Allocation Table (FAT) size.
|
||||
|
||||
u32 arm9overlaySource; //!< File arm9 overlay offset.
|
||||
u32 arm9overlaySize; //!< File arm9 overlay size.
|
||||
u32 arm7overlaySource; //!< File arm7 overlay offset.
|
||||
u32 arm7overlaySize; //!< File arm7 overlay size.
|
||||
|
||||
u32 cardControl13; //!< Port 40001A4h setting for normal commands (used in modes 1 and 3)
|
||||
u32 cardControlBF; //!< Port 40001A4h setting for KEY1 commands (used in mode 2)
|
||||
u32 bannerOffset; //!< offset to the banner with icon and titles etc.
|
||||
|
||||
u16 secureCRC16; //!< Secure Area Checksum, CRC-16.
|
||||
|
||||
u16 readTimeout; //!< Secure Area Loading Timeout.
|
||||
|
||||
u32 unknownRAM1; //!< ARM9 Auto Load List RAM Address (?)
|
||||
u32 unknownRAM2; //!< ARM7 Auto Load List RAM Address (?)
|
||||
|
||||
u32 bfPrime1; //!< Secure Area Disable part 1.
|
||||
u32 bfPrime2; //!< Secure Area Disable part 2.
|
||||
u32 romSize; //!< total size of the ROM.
|
||||
|
||||
u32 headerSize; //!< ROM header size.
|
||||
u32 zeros88[14];
|
||||
u8 gbaLogo[156]; //!< Nintendo logo needed for booting the game.
|
||||
u16 logoCRC16; //!< Nintendo Logo Checksum, CRC-16.
|
||||
u16 headerCRC16; //!< header checksum, CRC-16.
|
||||
|
||||
u32 debugRomSource; //!< debug ROM offset.
|
||||
u32 debugRomSize; //!< debug size.
|
||||
u32 debugRomDestination; //!< debug RAM destination.
|
||||
u32 offset_0x16C; //reserved?
|
||||
|
||||
u8 zero[0x40];
|
||||
u32 region;
|
||||
u32 accessControl;
|
||||
u32 arm7SCFGSettings;
|
||||
u16 dsi_unk1;
|
||||
u8 dsi_unk2;
|
||||
u8 dsi_flags;
|
||||
|
||||
u32 arm9iromOffset; //!< offset of the arm9 binary in the nds file.
|
||||
u32 arm9iexecuteAddress;
|
||||
u32 arm9idestination; //!< destination address to where the arm9 binary should be copied.
|
||||
u32 arm9ibinarySize; //!< size of the arm9 binary.
|
||||
|
||||
u32 arm7iromOffset; //!< offset of the arm7 binary in the nds file.
|
||||
u32 deviceListDestination;
|
||||
u32 arm7idestination; //!< destination address to where the arm7 binary should be copied.
|
||||
u32 arm7ibinarySize; //!< size of the arm7 binary.
|
||||
|
||||
u8 zero2[0x20];
|
||||
|
||||
// 0x200
|
||||
// TODO: More DSi-specific fields.
|
||||
u8 dsi1[0x10];
|
||||
u32 twlRomSize;
|
||||
u32 dsi_unk3;
|
||||
u32 dsi_unk4;
|
||||
u32 dsi_unk5;
|
||||
u8 dsi2[0x10];
|
||||
u32 dsi_tid;
|
||||
u32 dsi_tid2;
|
||||
u32 pubSavSize;
|
||||
u32 prvSavSize;
|
||||
u8 dsi3[0x174];
|
||||
} sNDSHeaderExt;
|
||||
|
||||
//#define __NDSHeader ((tNDSHeader *)0x02FFFE00)
|
||||
|
||||
// Make sure the header size is correct.
|
||||
//static_assert(sizeof(sNDSHeaderExt) == 0x3B4, "sizeof(sNDSHeaderExt) is not 0x3B4 bytes");
|
||||
|
||||
#endif // NDS_HEADER2
|
||||
@ -48,9 +48,12 @@ typedef union
|
||||
u32 key;
|
||||
} GameCode;
|
||||
|
||||
static bool twlBlowfish = false;
|
||||
|
||||
static bool normalChip = false; // As defined by GBAtek, normal chip secure area is accessed in blocks of 0x200, other chip in blocks of 0x1000
|
||||
static u32 portFlags = 0;
|
||||
static u32 headerData[0x1000/sizeof(u32)] = {0};
|
||||
static u32 secureAreaData[CARD_SECURE_AREA_SIZE/sizeof(u32)] = {0};
|
||||
static u32 secureArea[CARD_SECURE_AREA_SIZE/sizeof(u32)] = {0};
|
||||
|
||||
static const u8 cardSeedBytes[] = {0xE8, 0x4D, 0x5A, 0xB1, 0x17, 0x8F, 0x99, 0xD5};
|
||||
|
||||
@ -151,67 +154,37 @@ static void cardDelay (u16 readTimeout) {
|
||||
TIMER_DATA(0) = 0;
|
||||
}
|
||||
|
||||
static void switchToTwlBlowfish(sNDSHeaderExt* ndsHeader) {
|
||||
if (twlBlowfish || ndsHeader->unitCode == 0) return;
|
||||
|
||||
// Used for dumping the DSi arm9i/7i binaries
|
||||
|
||||
int cardInit (tNDSHeader* ndsHeader)
|
||||
{
|
||||
u32 portFlagsKey1, portFlagsSecRead;
|
||||
bool normalChip; // As defined by GBAtek, normal chip secure area is accessed in blocks of 0x200, other chip in blocks of 0x1000
|
||||
u32* secureArea;
|
||||
int secureBlockNumber;
|
||||
int i;
|
||||
u8 cmdData[8] __attribute__ ((aligned));
|
||||
GameCode* gameCode;
|
||||
|
||||
if (isDSiMode()) {
|
||||
cardReset();
|
||||
} else {
|
||||
// Reset card slot
|
||||
disableSlot1();
|
||||
for(int i = 0; i < 25; i++) { swiWaitForVBlank(); }
|
||||
enableSlot1();
|
||||
for(int i = 0; i < 15; i++) { swiWaitForVBlank(); }
|
||||
|
||||
// Dummy command sent after card reset
|
||||
cardParamCommand (CARD_CMD_DUMMY, 0,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
NULL, 0);
|
||||
} else {
|
||||
cardReset();
|
||||
}
|
||||
|
||||
u32 iCardId=cardReadID(CARD_CLK_SLOW);
|
||||
u32 iCheapCard=iCardId&0x80000000;
|
||||
|
||||
// Read the header
|
||||
if(iCheapCard)
|
||||
{
|
||||
//this is magic of wood goblins
|
||||
for(size_t ii=0;ii<8;++ii) {
|
||||
cardParamCommand (CARD_CMD_HEADER_READ, ii*0x200,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
(u32*)(void*)(ndsHeader+ii*0x200), 0x200);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cardParamCommand (CARD_CMD_HEADER_READ, 0,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(4) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
(u32*)(void*)ndsHeader, 0x1000);
|
||||
}
|
||||
|
||||
// Check header CRC
|
||||
if (ndsHeader->headerCRC16 != swiCRC16(0xFFFF, (void*)ndsHeader, 0x15E)) {
|
||||
return ERR_HEAD_CRC;
|
||||
}
|
||||
|
||||
tonccpy(headerData, ndsHeader, 0x1000);
|
||||
|
||||
u32 nds9Offset = *(u32*)(headerData+0x20);
|
||||
|
||||
int iCardDevice = ((*(u8*)(headerData+0x12) != 0) ? 1 : 0);
|
||||
|
||||
/*
|
||||
// Check logo CRC
|
||||
if (ndsHeader->logoCRC16 != 0xCF56) {
|
||||
return ERR_LOGO_CRC;
|
||||
}
|
||||
*/
|
||||
//int iCardDevice = 1;
|
||||
|
||||
// Initialise blowfish encryption for KEY1 commands and decrypting the secure area
|
||||
gameCode = (GameCode*)ndsHeader->gameCode;
|
||||
init_keycode (gameCode->key, iCardDevice?1:2, 8, iCardDevice);
|
||||
init_keycode (gameCode->key, 1, 8, 1);
|
||||
|
||||
// Port 40001A4h setting for normal reads (command B7)
|
||||
portFlags = ndsHeader->cardControl13 & ~CARD_BLK_SIZE(7);
|
||||
@ -220,13 +193,12 @@ int cardInit (tNDSHeader* ndsHeader)
|
||||
((ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF))) + ((ndsHeader->cardControlBF & CARD_DELAY2(0x3F)) >> 16));
|
||||
|
||||
// Adjust card transfer method depending on the most significant bit of the chip ID
|
||||
normalChip = (iCardId & 0x80000000) != 0; // ROM chip ID MSB
|
||||
if (!normalChip) {
|
||||
portFlagsKey1 |= CARD_SEC_LARGE;
|
||||
}
|
||||
|
||||
// 3Ciiijjj xkkkkkxx - Activate KEY1 Encryption Mode
|
||||
initKey1Encryption (cmdData, iCardDevice);
|
||||
initKey1Encryption (cmdData, 1);
|
||||
cardPolledTransfer((ndsHeader->cardControl13 & (CARD_WR|CARD_nRESET|CARD_CLK_SLOW)) | CARD_ACTIVATE, NULL, 0, cmdData);
|
||||
|
||||
// 4llllmmm nnnkkkkk - Activate KEY2 Encryption Mode
|
||||
@ -259,10 +231,10 @@ int cardInit (tNDSHeader* ndsHeader)
|
||||
cardPolledTransfer(portFlagsKey1 | CARD_BLK_SIZE(7), NULL, 0, cmdData);
|
||||
|
||||
// 2bbbbiii jjjkkkkk - Get Secure Area Block
|
||||
secureArea = secureAreaData;
|
||||
portFlagsSecRead = (ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF)|CARD_DELAY2(0x3F)))
|
||||
| CARD_ACTIVATE | CARD_nRESET | CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
int secureAreaOffset = 0;
|
||||
for (secureBlockNumber = 4; secureBlockNumber < 8; secureBlockNumber++) {
|
||||
createEncryptedCommand (CARD_CMD_SECURE_READ, cmdData, secureBlockNumber);
|
||||
|
||||
@ -270,12 +242,158 @@ int cardInit (tNDSHeader* ndsHeader)
|
||||
cardPolledTransfer(portFlagsSecRead, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
for (i = 8; i > 0; i--) {
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(1), secureArea, 0x200, cmdData);
|
||||
secureArea += 0x200/sizeof(u32);
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(1), secureArea + secureAreaOffset, 0x200, cmdData);
|
||||
secureAreaOffset += 0x200/sizeof(u32);
|
||||
}
|
||||
} else {
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(4) | CARD_SEC_LARGE, secureArea, 0x1000, cmdData);
|
||||
secureArea += 0x1000/sizeof(u32);
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(4) | CARD_SEC_LARGE, secureArea + secureAreaOffset, 0x1000, cmdData);
|
||||
secureAreaOffset += 0x1000/sizeof(u32);
|
||||
}
|
||||
}
|
||||
|
||||
// Alllliii jjjkkkkk - Enter Main Data Mode
|
||||
createEncryptedCommand (CARD_CMD_DATA_MODE, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
|
||||
decryptSecureArea (gameCode->key, secureArea, 1);
|
||||
|
||||
twlBlowfish = true;
|
||||
}
|
||||
|
||||
|
||||
int cardInit (sNDSHeaderExt* ndsHeader)
|
||||
{
|
||||
u32 portFlagsKey1, portFlagsSecRead;
|
||||
normalChip = false; // As defined by GBAtek, normal chip secure area is accessed in blocks of 0x200, other chip in blocks of 0x1000
|
||||
int secureBlockNumber;
|
||||
int i;
|
||||
u8 cmdData[8] __attribute__ ((aligned));
|
||||
GameCode* gameCode;
|
||||
|
||||
twlBlowfish = false;
|
||||
|
||||
if (isDSiMode()) {
|
||||
sysSetCardOwner (BUS_OWNER_ARM9); // Allow arm9 to access NDS cart
|
||||
// Reset card slot
|
||||
disableSlot1();
|
||||
for(int i = 0; i < 25; i++) { swiWaitForVBlank(); }
|
||||
enableSlot1();
|
||||
for(int i = 0; i < 15; i++) { swiWaitForVBlank(); }
|
||||
|
||||
// Dummy command sent after card reset
|
||||
cardParamCommand (CARD_CMD_DUMMY, 0,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
NULL, 0);
|
||||
} else {
|
||||
cardReset();
|
||||
}
|
||||
|
||||
u32 iCardId=cardReadID(CARD_CLK_SLOW);
|
||||
u32 iCheapCard=iCardId&0x80000000;
|
||||
|
||||
// Read the header
|
||||
if(iCheapCard)
|
||||
{
|
||||
//this is magic of wood goblins
|
||||
for(size_t ii=0;ii<8;++ii) {
|
||||
cardParamCommand (CARD_CMD_HEADER_READ, ii*0x200,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
(u32*)(void*)(ndsHeader+ii*0x200), 0x200);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cardParamCommand (CARD_CMD_HEADER_READ, 0,
|
||||
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(4) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
|
||||
(u32*)(void*)ndsHeader, 0x1000);
|
||||
}
|
||||
|
||||
// Check header CRC
|
||||
if (ndsHeader->headerCRC16 != swiCRC16(0xFFFF, (void*)ndsHeader, 0x15E)) {
|
||||
return ERR_HEAD_CRC;
|
||||
}
|
||||
|
||||
tonccpy(headerData, ndsHeader, 0x1000);
|
||||
|
||||
/*
|
||||
// Check logo CRC
|
||||
if (ndsHeader->logoCRC16 != 0xCF56) {
|
||||
return ERR_LOGO_CRC;
|
||||
}
|
||||
*/
|
||||
|
||||
// Initialise blowfish encryption for KEY1 commands and decrypting the secure area
|
||||
gameCode = (GameCode*)ndsHeader->gameCode;
|
||||
init_keycode (gameCode->key, 2, 8, 0);
|
||||
|
||||
// Port 40001A4h setting for normal reads (command B7)
|
||||
portFlags = ndsHeader->cardControl13 & ~CARD_BLK_SIZE(7);
|
||||
// Port 40001A4h setting for KEY1 commands (usually 001808F8h)
|
||||
portFlagsKey1 = CARD_ACTIVATE | CARD_nRESET | (ndsHeader->cardControl13 & (CARD_WR|CARD_CLK_SLOW)) |
|
||||
((ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF))) + ((ndsHeader->cardControlBF & CARD_DELAY2(0x3F)) >> 16));
|
||||
|
||||
// Adjust card transfer method depending on the most significant bit of the chip ID
|
||||
normalChip = (iCardId & 0x80000000) != 0; // ROM chip ID MSB
|
||||
if (!normalChip) {
|
||||
portFlagsKey1 |= CARD_SEC_LARGE;
|
||||
}
|
||||
|
||||
// 3Ciiijjj xkkkkkxx - Activate KEY1 Encryption Mode
|
||||
initKey1Encryption (cmdData, 0);
|
||||
cardPolledTransfer((ndsHeader->cardControl13 & (CARD_WR|CARD_nRESET|CARD_CLK_SLOW)) | CARD_ACTIVATE, NULL, 0, cmdData);
|
||||
|
||||
// 4llllmmm nnnkkkkk - Activate KEY2 Encryption Mode
|
||||
createEncryptedCommand (CARD_CMD_ACTIVATE_SEC, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
|
||||
// Set the KEY2 encryption registers
|
||||
REG_ROMCTRL = 0;
|
||||
REG_CARD_1B0 = cardSeedBytes[ndsHeader->deviceType & 0x07] | (key1data.nnn << 15) | (key1data.mmm << 27) | 0x6000;
|
||||
REG_CARD_1B4 = 0x879b9b05;
|
||||
REG_CARD_1B8 = key1data.mmm >> 5;
|
||||
REG_CARD_1BA = 0x5c;
|
||||
REG_ROMCTRL = CARD_nRESET | CARD_SEC_SEED | CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
// Update the DS card flags to suit KEY2 encryption
|
||||
portFlagsKey1 |= CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
// 1lllliii jjjkkkkk - 2nd Get ROM Chip ID / Get KEY2 Stream
|
||||
createEncryptedCommand (CARD_CMD_SECURE_CHIPID, cmdData, 0);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
}
|
||||
cardPolledTransfer(portFlagsKey1 | CARD_BLK_SIZE(7), NULL, 0, cmdData);
|
||||
|
||||
// 2bbbbiii jjjkkkkk - Get Secure Area Block
|
||||
portFlagsSecRead = (ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF)|CARD_DELAY2(0x3F)))
|
||||
| CARD_ACTIVATE | CARD_nRESET | CARD_SEC_EN | CARD_SEC_DAT;
|
||||
|
||||
int secureAreaOffset = 0;
|
||||
for (secureBlockNumber = 4; secureBlockNumber < 8; secureBlockNumber++) {
|
||||
createEncryptedCommand (CARD_CMD_SECURE_READ, cmdData, secureBlockNumber);
|
||||
|
||||
if (normalChip) {
|
||||
cardPolledTransfer(portFlagsSecRead, NULL, 0, cmdData);
|
||||
cardDelay(ndsHeader->readTimeout);
|
||||
for (i = 8; i > 0; i--) {
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(1), secureArea + secureAreaOffset, 0x200, cmdData);
|
||||
secureAreaOffset += 0x200/sizeof(u32);
|
||||
}
|
||||
} else {
|
||||
cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(4) | CARD_SEC_LARGE, secureArea + secureAreaOffset, 0x1000, cmdData);
|
||||
secureAreaOffset += 0x1000/sizeof(u32);
|
||||
}
|
||||
}
|
||||
|
||||
@ -289,12 +407,11 @@ int cardInit (tNDSHeader* ndsHeader)
|
||||
cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData);
|
||||
|
||||
//CycloDS doesn't like the dsi secure area being decrypted
|
||||
if(!iCardDevice && ((nds9Offset != 0x4000) || secureAreaData[0] || secureAreaData[1]))
|
||||
if((ndsHeader->arm9romOffset != 0x4000) || secureArea[0] || secureArea[1])
|
||||
{
|
||||
decryptSecureArea (gameCode->key, secureAreaData, iCardDevice);
|
||||
decryptSecureArea (gameCode->key, secureArea, 0);
|
||||
}
|
||||
|
||||
secureArea = secureAreaData;
|
||||
if (secureArea[0] == 0x72636e65 /*'encr'*/ && secureArea[1] == 0x6a624f79 /*'yObj'*/) {
|
||||
// Secure area exists, so just clear the tag
|
||||
secureArea[0] = 0xe7ffdeff;
|
||||
@ -308,6 +425,8 @@ int cardInit (tNDSHeader* ndsHeader)
|
||||
|
||||
void cardRead (u32 src, void* dest)
|
||||
{
|
||||
sNDSHeaderExt* ndsHeader = (sNDSHeaderExt*)headerData;
|
||||
|
||||
if (src >= 0 && src < 0x1000) {
|
||||
// Read header
|
||||
tonccpy (dest, (u8*)headerData + src, 0x200);
|
||||
@ -317,7 +436,11 @@ void cardRead (u32 src, void* dest)
|
||||
return;
|
||||
} else if (src < CARD_DATA_OFFSET) {
|
||||
// Read data from secure area
|
||||
tonccpy (dest, (u8*)secureAreaData + src - CARD_SECURE_AREA_OFFSET, 0x200);
|
||||
tonccpy (dest, (u8*)secureArea + src - CARD_SECURE_AREA_OFFSET, 0x200);
|
||||
return;
|
||||
} else if ((ndsHeader->unitCode != 0) && (src >= ndsHeader->arm9iromOffset) && (src < ndsHeader->arm9iromOffset+MODC_AREA_SIZE)) {
|
||||
// Read data from secure area
|
||||
tonccpy (dest, (u8*)secureArea + src - ndsHeader->arm9iromOffset, 0x200);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -325,30 +448,32 @@ void cardRead (u32 src, void* dest)
|
||||
portFlags | CARD_ACTIVATE | CARD_nRESET | CARD_BLK_SIZE(1),
|
||||
dest, 0x200);
|
||||
|
||||
/*int iCardDevice = ((*(u8*)(headerData+0x12) != 0) ? 1 : 0);
|
||||
u32 arm9i_rom_offset = *(u32*)(headerData + 0x1C0);
|
||||
if (src > ndsHeader->romSize) {
|
||||
switchToTwlBlowfish(ndsHeader);
|
||||
|
||||
if (iCardDevice && (src > arm9i_rom_offset) &&
|
||||
(src < arm9i_rom_offset + MODC_AREA_SIZE))
|
||||
{
|
||||
u8* buffer8 = (u8*) dest;
|
||||
u8* buff = buffer8;
|
||||
/*
|
||||
if ((ndsHeader->unitCode != 0)
|
||||
&& (src > ndsHeader->arm9iromOffset) && (src < ndsHeader->arm9iromOffset + MODC_AREA_SIZE))
|
||||
{
|
||||
u8* buffer8 = (u8*) dest;
|
||||
//u8* buff = buffer8;
|
||||
|
||||
// modcrypt area handling
|
||||
u8* buffer_arm9i = buffer8;
|
||||
u32 offset_i = 0;
|
||||
u32 size_i = MODC_AREA_SIZE;
|
||||
if (arm9i_rom_offset < (src))
|
||||
offset_i = (src) - arm9i_rom_offset;
|
||||
else buffer_arm9i = buffer8 + (arm9i_rom_offset - (src));
|
||||
size_i = MODC_AREA_SIZE - offset_i;
|
||||
if (size_i > (0x4000) - (buffer_arm9i - buffer8))
|
||||
size_i = (0x4000) - (buffer_arm9i - buffer8);
|
||||
if (size_i) {
|
||||
cardParamCommand (CARD_CMD_DATA_READ, (0x4000 + offset_i),
|
||||
portFlags | CARD_ACTIVATE | CARD_nRESET | CARD_BLK_SIZE(1),
|
||||
buffer_arm9i, size_i);
|
||||
}
|
||||
}*/
|
||||
// modcrypt area handling
|
||||
u8* buffer_arm9i = buffer8;
|
||||
u32 offset_i = 0;
|
||||
u32 size_i = MODC_AREA_SIZE;
|
||||
if (arm9i_rom_offset < (src))
|
||||
offset_i = (src) - arm9i_rom_offset;
|
||||
else buffer_arm9i = buffer8 + (arm9i_rom_offset - (src));
|
||||
size_i = MODC_AREA_SIZE - offset_i;
|
||||
if (size_i > (0x4000) - (buffer_arm9i - buffer8))
|
||||
size_i = (0x4000) - (buffer_arm9i - buffer8);
|
||||
if (size_i) {
|
||||
cardParamCommand (CARD_CMD_DATA_READ, (0x4000 + offset_i),
|
||||
portFlags | CARD_ACTIVATE | CARD_nRESET | CARD_BLK_SIZE(1),
|
||||
buffer_arm9i, size_i);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -23,6 +23,8 @@
|
||||
#include <nds/memory.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ndsheaderbanner.h"
|
||||
|
||||
#define CARD_NDS_HEADER_SIZE (0x200)
|
||||
#define CARD_SECURE_AREA_OFFSET (0x4000)
|
||||
#define CARD_SECURE_AREA_SIZE (0x4000)
|
||||
@ -34,7 +36,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int cardInit (tNDSHeader* ndsHeader);
|
||||
int cardInit (sNDSHeaderExt* ndsHeader);
|
||||
|
||||
void cardRead (u32 src, void* dest);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user