Remedy Archive System

From Just Solve the File Format Problem
(Difference between revisions)
Jump to: navigation, search
m (Format details: LE)
m (translate description to C due to range of int32_t)
Line 37: Line 37:
  
 
<pre>
 
<pre>
function decrypt(data: byte[], key: uint32):
+
void decrypt(uint8_t *buf, size_t count, int32_t key) {
   if key == 0:
+
  size_t i;
     key := 1
+
  uint8_t a;
+
  uint8_t b;
   for i from 0 to data.length-1:
+
 
     a := data[i]
+
   if (key == 0) {
     b := i mod 5         -- such that 0 ≤ b &lt; 5
+
     key = 1;
     c := rotateByteLeft(a by b)
+
  }
     d := key / 177
+
   for (i = 0; i &lt; count; i++) {
    e := d * 30269
+
     uint8_t a = buf[i];
    f := key * 171
+
     uint8_t b = ((uint8_t)(i % 5)) & 7;
    key := f - e
+
     buf[i] = rotateLeftByte(a, b);
     g := i mod 256
+
     key = key * 171 + (key / 177) * -30269;
    h := g + 3
+
     buf[i] = (((((uint8_t)i) + 3) * 6) ^ buf[i]) + ((uint8_t)key);
    k := h * 6
+
  }
    m := k bitwiseXor data[i]
+
}
    p := key mod 256    -- such that 0 ≤ p &lt; 256
+
    q := m + p
+
    data[i] := q mod 256
+
 
</pre>
 
</pre>
  
If your programming language doesn't support the <code>rotateLeft</code> operation, it can be emulated using:
+
If your programming language doesn't support the <code>rotateLeftByte</code> operation, it can be emulated using:
  
 
<pre>
 
<pre>
function rotateByteLeft(i by n):
+
uint8_t rotateLeftByte(uint8_t a, uint8_t b) {
   return (i bitShiftLeft n) bitwiseOr (i bitShiftRight (8 - n))
+
   return (a &lt;&lt; b) | (a &gt;&gt; (8 - b));
 +
}
 
</pre>
 
</pre>
  
 
[[Category:Remedy Entertainment]]
 
[[Category:Remedy Entertainment]]

Revision as of 16:12, 21 November 2025

File Format
Name Remedy Archive System
Ontology
Extension(s) .ras
Released 2001

Remedy Archive System is used to store game data for Remedy Entertainment games such as Max Payne and Max Payne 2. The metadata (central directory) following the header is encrypted.

Contents

Identification

Files begin with signature bytes 52 41 53 00.

Format details

Numbers are in little-endian byte order.

The file's header has the following structure:

struct RASHeader {
  uint8_t magic[4]; // "RAS\0"
  uint32_t encryptionKey;
};

The next section of the header must be decrypted first:

// decrypted structure
struct RASMetadata {
  
};

Encryption

Depending on the generation of the RAS file format, different encryption schemes are used.

RAS1 (Max Payne)

void decrypt(uint8_t *buf, size_t count, int32_t key) {
  size_t i;
  uint8_t a;
  uint8_t b;

  if (key == 0) {
    key = 1;
  }
  for (i = 0; i < count; i++) {
    uint8_t a = buf[i];
    uint8_t b = ((uint8_t)(i % 5)) & 7;
    buf[i] = rotateLeftByte(a, b);
    key = key * 171 + (key / 177) * -30269;
    buf[i] = (((((uint8_t)i) + 3) * 6) ^ buf[i]) + ((uint8_t)key);
  }
}

If your programming language doesn't support the rotateLeftByte operation, it can be emulated using:

uint8_t rotateLeftByte(uint8_t a, uint8_t b) {
  return (a << b) | (a >> (8 - b));
}
Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox