Skip to content

Instantly share code, notes, and snippets.

@unisys12
Last active January 24, 2023 00:49
Show Gist options
  • Save unisys12/30ecb24e447831d36e0dbc8a5624613a to your computer and use it in GitHub Desktop.
Save unisys12/30ecb24e447831d36e0dbc8a5624613a to your computer and use it in GitHub Desktop.
First attempt at decoding a PSARC Binary or .PAK file(from No Mans Sky) using Nodejs. This merely decodes the Header and TOC Table
const fs = require("node:fs");
const psarc_file = "./NMSARC.5A3E0C7D.pak";
// const psarc_file = "./NMSARC.2E9559C7.pak";
const hexToDecimal = (hex) => parseInt(hex, 16);
// Attempts to read a *pak file and decode it's header and
// return it as an object. Result in file below.
//
// Yes! This could be written better, but it's first draft.
// Ever wake up one morning and ask yourself, "Self! What's
// this all about? I wonder if we can do that?".
//
// This is just that.
//
const decode = fs.readFile(psarc_file, (err, buffer) => {
if (err) {
console.log(err);
}
// Grab only the header and toc_table of the psarc archive
let header = buffer.subarray(0, 62);
/**
* Converts the section of buffer to decimal.
* Removes any NULL bytes, then uses parseInt
* to convert to a decimal. Followed by comcat
* to conbine the result into a string
*
* @param start int
* @param end int
* @returns string
*/
const toDecString = (start, end) => {
let result = [];
header.subarray(start, end).forEach((x) => {
if (x != 00) {
result.push(parseInt(x));
}
});
const string = "".concat(...result);
return hexToDecimal(string);
};
/**
* Converts the section of buffer to decimal without
* destroying the orignal value.
*
* @param start int
* @param end int
* @returns int
*/
const fromBinarytoDecString = (start, end) => {
let result = [];
const head_section = header.subarray(start, end);
head_section.forEach((x) => result.push("0" + x));
const binary = "".concat(...result);
return hexToDecimal(binary);
};
const header_data = {
magic: header.subarray(0, 4).toString(), // parse to string (type of file/archive)
version: header.subarray(4, 8), // versinn of archive used
compression_type: header.subarray(8, 12).toString(), //parse to string (type of compression used)
toc_length: toDecString(12, 16),
toc_entry_size: toDecString(16, 20),
toc_entries: toDecString(20, 24),
block_size: fromBinarytoDecString(24, 28),
archive_flags: fromBinarytoDecString(28, 32),
name_digest: header.subarray(32, 48).toString(),
block_offset: fromBinarytoDecString(48, 52),
uncompressed_size: toDecString(52, 57),
file_offset: toDecString(57, 62),
};
console.log(header_data);
});
return decode;
{
magic: 'PSAR',
version: <Buffer 00 01 00 04>,
compression_type: 'zlib',
toc_length: 82264,
toc_entry_size: 48,
toc_entries: 265,
block_size: 65536,
archive_flags: 1,
name_digest: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
block_offset: 0,
uncompressed_size: 9257,
file_offset: 82264
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment