01 NDS 롬(ROM) 파일 포맷(Format) 분석

원문 : http://kkamagui.springnote.com/pages/417484

 

들어가기 전에...

0. 시작하면서...

 devkitARM이 *.nds 파일을 만드는 과정을 살펴보면 makefile을 참조해서 살펴보면 아래와 같은 과정을 거친다.

  1. object 파일을 링크하여 *.elf 파일을 만든다.
  2. *.elf 파일을 objcopy -O binary 옵션을 이용하여 코드와 데이터 영역만 추려내서 순수한 바이너리 파일인 *.arm9 or *.arm7 파일을 만든다.
  3. ndstool을 사용해서 *.arm9파일을 *.nds 파일로 만든다.

 

 그럼 도대체 이 NDS Rom 파일은 어떤 구조로 되어있는 것일까? 자세히 살펴보자.

 

1. NDS 롬(ROM) 헤더(Header) 구조

http://www.bottledlight.com/ds/index.php/FileFormats/NDSFormat를 참조하면 실제 어떤 구조로 되어있는지 알 수 있다.

Header format

Field Start End Size Example data (Metroid demo)
Game title 0x000 0x00B 12 "FIRST HUNT "
Game code 0x00C 0x00F 4 "AMFE"
Maker code 0x010 0x011 2 "01" (Nintendo)
Unit code 0x012 0x012 1 0x00
Device code 0x013 0x013 1 0x00
Card size 0x014 0x014 1 0x07 (2^(20 + 7) = 128Mb = 16 MB)
Card info 0x015 0x01E 10 0x00's
Flags 0x01F 0x01F 1 0x00
ARM9 source (ROM) 0x020 0x023 4 0x00004000 (must be 4 KB aligned)
ARM9 execute addr 0x024 0x027 4 0x02004800
ARM9 copy to addr 0x028 0x02B 4 0x02004000
ARM9 binary size 0x02C 0x02F 4 0x00081D58
ARM7 source (ROM) 0x030 0x033 4 0x000B3000
ARM7 execute addr 0x034 0x037 4 0x02380000
ARM7 copy to addr 0x038 0x03B 4 0x02380000
ARM7 binary size 0x03C 0x03F 4 0x00026494
Filename table offset (ROM) 0x040 0x043 4 0x000D9600
Filename table size 0x044 0x047 4 0x11B6
FAT offset (ROM) 0x048 0x04B 4 0x000DA800
FAT size 0x04C 0x04F 4 0x678
ARM9 overlay src (ROM) 0x050 0x053 4 0x00085E00
ARM9 overlay size 0x054 0x057 4 0x60
ARM7 overlay src (ROM) 0x058 0x05B 4 0
ARM7 overlay size 0x05C 0x05F 4 0
Control register flags for read 0x060 0x063 4 0x00586000
Control register flags for init 0x064 0x067 4 0x001808F8
Icon+titles (ROM) 0x068 0x06B 4 0x000DB000
Secure CRC16 0x06C 0x06D 2 0xC44D
ROM timeout 0x06E 0x06F 2 0x051E
ARM9 unk addr 0x070 0x073 4 0x020049EC
ARM7 unk addr 0x074 0x077 4 0x02380110
Magic number for unencrypted mode 0x078 0x07F 8 0x00's
ROM size 0x080 0x083 4 0x00EE3E44
Header size 0x084 0x087 4 0x4000
Unknown 5 0x088 0x0BF 56 0x00's
GBA logo 0x0C0 0x15B 156 data
Logo CRC16 0x15C 0x15D 2 0xCF56
Header CRC16 0x15E 0x15F 2 0x00F8
Reserved 0x160 0x1FF 160 0x00's

 

The control register flags contain latency settings and depends on the ROM manufacturer (Macronix, Matrix Memory).

Unknown2a and 'Header Size' contain flags that are (somewhat) used during boot as part of card CR writes. Unknown2b contains the size of a certain type of transfer done during boot, but it's range checked and cannot be reduced. Unknown3c is seemingly unused, and some code paths get data from 0x160 onward (only 0x170 bytes of a header fetch are actually retained by the BIOS)

Secure CRC16 calculation is performed on the ROM from 0x4000 to 0x7FFF, with an initial value of 0xFFFF.

Logo CRC16 calculation is performed on the header from 0x0C0 to 0x15B, with an initial value of 0xFFFF.

Header CRC16 calculation is performed on the header (after the previous two CRCs are filled) from 0x000 to 0x15D with an initial value of 0xFFFF.

Device code needs lower 3 bits to be 0. This is a similar behavior as GBA header.

 위의 정보를 보면 롬 영역 안쪽에 FAT File System이 들어가는 것을 알 수 있다. 즉 게임에서 필요한 데이터를 내부에 플래쉬에 저장하여 읽고 쓴다는 이야기다. @0@)/~ 참으로 놀라운 사실이 아닐 수 없다.

 저 부분을 분석하면 게임 내부에서 사용하는 데이터도 추출해 낼 수 있다는 말이된다. 물론 좀더 분석해봐야 알겠지만 상당히 흥미로운 사실이다.

  

1.1 ARM9 ROM의 시작 위치

 위에서 Header Size를 보면 0x4000으로 설정되어있다. ARM9 ROM의 시작위치는? 0x4000 인걸 알 수 있다. 옆에 "4Kbyte로 반드시 정렬해라"라는 이야기가 있는데, 게임롬에만 해당하는 건지 확실히 알 수 없지만 굳이 하지 않아도 될 것 같다. 특히 홈브루 같은 경우는 더욱...

 위 결과로 미루어 보면 ROM Header의 바로 뒤에 ARM9의 코드가 들어감을 알 수 있다.

  

1.2 ARM7 ROM의 시작 위치

 ARM7의 코드가 포함된 ROM의 위치는 ARM9의 바로 뒤에 연결 되어있지 않다. 다만 0x1000의 배수(4Kbyte)에 맞추어서 시작하고 있다.

 ARM7 코드가 로딩되는 위치의 주소를 보면 0x2380000으로 4Mybte의 메인 메모리 뒷쪽에 자리잡고 있다. NDS 게임의 경우 ARM7이 하는 일이 그렇게 많지 않아 뒷쪽으로 할당한 것 처럼 보인다.

  

1.3 롬 실행 시 메모리 배치

 롬 헤더에 보면 롬파일 내에 ARM9/7 코드가 어디서 시작하고 크기는 얼마나 되며 메모리에 어느 위치에 복사해주는지 정보가 나와있다. 또한 Entry 정보도 나와있는 걸로 보아 시작 시에 해당 메모리 위치로 코드를 복사하고 시작함을 알 수 있다.

  

2.아이콘(Icon) 및 광고(Banner) 헤더(Header) 구조

Icon + logo format (the banner)

This is a structure of size 32+512+32+256*6 = 2112 bytes with the following format:

 

Banner structure

Offset Size Description
0 2 Version (always 1)
2 2 CRC-16 of structure, not including first 32 bytes
4 28 Reserved
32 512 Tile Data
544 32 Palette
576 256 Japanese Title
832 256 English Title
1088 256 French Title
1344 256 German Title
1600 256 Italian Title
1856 256 Spanish Title

 

The icon is a 32x32 picture formed out of 4x4 16 color tiles and a single 16 color palette.

Following the icon data (icon offset + 576 bytes), are 6 unicode game titles, displayed in the DS menu depending on the selected language mode. Each title is padded to 128 characters (256 bytes).

The strings are in the same order as the language choice in Firmware.

 게임 아이콘 및 설명을 넣는 부분 같다. 아이콘이나 게임 타이틀 부분도 ndstool.exe를 이용하면 쉽게 넣을 수 있으므로 나중에 참고하자.

 

3.실제 롬 파일 분석

3.1 헤더 분석

 devkitPro를 설치하면 자동으로 설치되는 ndstool.exe 프로그램을 이용해서 KKAMAGUI NOTEPAD 롬파일을 분석해 보자. KKAMAGUI NOTEPAD의 롬파일은 00 KKAMAGUI NOTEPAD 에서 구할 수 있다. dstool.exe 프로그램은 아래와 같은 다양한 옵션을 가지고 있다.

 

 위의 옵션 중에 -i 옵션을 이용하면 롬의 정보를 볼 수 있다. i 옵션을 이용하여 롬 파일을 분석해 보자.

  1. D:\devkitPro\MyProject\NotePad>ndstool -i NotePad.nds

     

    Nintendo DS rom tool 1.33 - Jan 28 2007 21:02:20
    by Rafael Vuijk, Dave Murphy,  Alexei Karpenko
    Header information:
    0x00    Game title                      .
    0x0C    Game code                       ####
    0x10    Maker code
    0x12    Unit code                       0x00
    0x13    Device type                     0x00
    0x14    Device capacity                 0x01 (2 Mbit)
    0x15    reserved 1                      000000000000000000
    0x1E    ROM version                     0x00
    0x1F    reserved 2                      0x04
    0x20    ARM9 ROM offset                 0x200
    0x24    ARM9 entry address              0x2000000
    0x28    ARM9 RAM address                0x2000000
    0x2C    ARM9 code size                  0x31794
    0x30    ARM7 ROM offset                 0x31A00
    0x34    ARM7 entry address              0x37F8000

    0x38    ARM7 RAM address                0x37F8000
    0x3C    ARM7 code size                  0x12B8
    0x40    File name table offset          0x32E00
    0x44    File name table size            0x9
    0x48    FAT offset                      0x33000
    0x4C    FAT size                        0x0
    0x50    ARM9 overlay offset             0x0
    0x54    ARM9 overlay size               0x0
    0x58    ARM7 overlay offset             0x0
    0x5C    ARM7 overlay size               0x0
    0x60    ROM control info 1              0x007F7FFF
    0x64    ROM control info 2              0x203F1FFF
    0x68    Icon/title offset               0x0
    0x6C    Secure area CRC                 0x0000 (-, homebrew)
    0x6E    ROM control info 3              0x051E
    0x70    ARM9 ?                          0x0
    0x74    ARM7 ?                          0x0
    0x78    Magic 1                         0x00000000
    0x7C    Magic 2                         0x00000000
    0x80    Application end offset          0x00033000
    0x84    ROM header size                 0x00000200
    0xA0    ?                               0x4D415253
    0xA4    ?                               0x3131565F
    0xA8    ?                               0x00000030
    0xAC    ?                               0x53534150
    0xB0    ?                               0x00963130
    0x15C   Logo CRC                        0x9E1A (OK)
    0x15E   Header CRC                      0x32B1 (OK)

 홈브루의 경우는 게임의 경우와 조금 달리 ARM7의 이미지가 0x1000에서 시작하지 않고 있음을 알 수 있다. 그리고 ARM7의 코드가 4Mbyte의 공유영역에 올라가있는 것이 아니라 0x37F8000 주소에 Private RAM(64Kbyte)에 위치하고 있다. 02 NDS Spec에 보면 메모리 맵에 대한 자세한 내용을 알 수 있다.

 Secure area CRC 부분을 보면 이 값이 0x0000 이고 homebrew라고 표시되어있다. 실제 게임은 이 값이 0이 아닌 것일까? 몇가지 게임 롬을 분석해본 결과... 0x0000 이 아님을 알 수 있었다. 보안에 관련된 영역을 검사하는데 사용되는 것으로 생각된다.

 

3.2 FAT 영역 분석

 롬 파일 내부에 FAT 영역을 가진다. ndstool.exe 를 이용하면 -l 옵션으로 FAT 영역의 데이터를 볼 수 있다. KKAMAGUI NOTEPAD의 경우 FAT 영역에 별다른 데이터를 가지지 않으므로 다른 홈브루나 게임 롬을 열어봐야 된다. 홈브루 중에서는 아마 찾기 힘들 것이므로 게임 롬을 열어보자. 디렉토리 구조와 파일들이 줄줄이 나오는 것을 알 수 있다.

FATList.PNG

<ndstool.exe를 이용해서 롬 파일의 FAT 영역을 분석한 화면>

 

 그렇다면 ROM 파일에 있는 FAT 파일 시스템은 우리가 윈도우에서 포맷할 때 만들어지는 모든 파일 시스템 정보를 포함하고 있을까?

 이 부분은 ROM 파일을 열어서 확인을 해봐야 할 것 같다.

 

여기 체우기...

 

4. 데이터 영역 분석

 롬 데이터 영역은 .arm9 및 .arm7의 파일의 덤프 형태로 되어잇는데, 자세한 내용은 00 NDS makefile 및 NDS 파일 생성 과정 분석 페이지를 참조하자.

 

마치며...

 이상으로 NDS 롬 파일 구조에 대해서 알아보았다. 특별히 암호화도 되어있지 않고 checksum을 이용해서 롬 파일의 유효성을 체크한다.

 롬 파일의 구조를 알았으니, 그 안에서 데이터를 뽑아내어 언어를 한글화 한다던지, 그림 파일을 바꾼다던지 하는 것고 그리 어렵지 않을꺼라 생각한다.

 다시 NDS의 세계로 빠져보자 @0@)/~~

 이 글은 스프링노트에서 작성되었습니다.


+ Recent posts