DAR

From mgsdevwiki
Jump to: navigation, search

DAR is a general archive used in Metal Gear Solid games. It's format varies slightly depending on the game.

Format Specifications

Metal Gear Solid (PC)

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)

?

Metal Gear Solid 2 (PC)

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)

?

Metal Gear Solid 4

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')