DAR
From mgsdevwiki
DAR is a general archive used in Metal Gear Solid games. It's format varies slightly depending on the game.
Contents
Format Specifications
Metal Gear Solid (PC)
- Endian Order : Little Endian
Header | ||
---|---|---|
uint32 {4} | Number of Files | |
For each file | ||
char {X} | Filename (ASCIZ) | |
byte {0-3} | null padding 4-byte alignment (file position) | |
uint32 {4} | File Length | |
byte {X} | File Data | |
byte {1} | null File Data terminator |
Metal Gear Solid (PSX)
- Endian Order : ?
?
Metal Gear Solid 2 (PC)
- Endian Order : Little Endian
Header | ||
---|---|---|
uint32 {4} | Number of FIles | |
For each file | ||
char {X} | Filename (ASCIZ) | |
byte {0-3} | null padding 4-byte alignment (file position) | |
uint32 {4} | File Length | |
byte {0-15} | null padding 16-byte alignment (file position) | |
byte {X} | File Data | |
byte {1} | null File Data terminator |
Metal Gear Solid 2 (PS2)
- Endian Order : ?
?
Metal Gear Solid 4
- Endian Order : Big Endian
Header | ||
---|---|---|
uint32 {4} | Number of FIles | |
For each file | ||
char {X} | Filename (ASCIZ) | |
byte {0-3} | null padding 4-byte alignment (file position) | |
uint32 {4} | File Length | |
byte {0-15} | null padding 16-byte alignment (file position) | |
byte {X} | File Data | |
byte {1} | null File Data terminator |
Tools
Python Script
'To Do'
- Extract files (write to new directory)
- Create DAR Archive (Accept directory as argument and build a DAR)
- Clean argument parser / format
Source
1 import struct
2
3 class Dar(object):
4 """Parse the data inside of a Metal Gear Solid DAR file"""
5
6 def __init__(self, darFile, version):
7 self.files = {}
8 with open(darFile, "rb") as f:
9 self.num_files = struct.unpack("<I", f.read(4))[0] # Number of files in DAR
10 curr_pos = 4 # Position in file
11 curr_count = 1 # Current file number
12 while (curr_count <= self.num_files):
13 self.file_name = f.read(255).split('\0')[0] + '\0' # Name of file
14 f.seek(curr_pos + len(self.file_name))
15 padding = (4 - (f.tell() % 4)) % 4 # Padding for 4-byte alignment
16 f.seek(padding, 1)
17 self.file_size = struct.unpack("<I", f.read(4))[0] # Size of file
18
19 if (version == "mgs2"):
20 padding = (16 - (f.tell() % 16)) % 16 # Padding for 16-byte alignment
21 f.seek(padding, 1)
22
23 self.file_data = f.read(self.file_size) # File data
24 f.seek(1, 1) # Move past null byte
25
26 self.files.update({self.file_name: self.file_data}) # Store file_name : file_data in dictionary
27
28 curr_pos = f.tell()
29 curr_count = curr_count + 1
30
31 if __name__ == "__main__":
32 import sys
33
34 if len(sys.argv) != 2:
35 dar = Dar(sys.argv[1], sys.argv[2])
36
37 print "Number of files: %s" % dar.num_files
38 print "Size\tName"
39 for file,data in dar.files.items():
40 print "%s\t%s" % (len(data), file)
41
42 else:
43 print('You need to pass a DAR file (arg1) and game version mgs, mgs2 (arg2).\r\nExample: python file.py cache.dar mgs2')