Skip to content

Instantly share code, notes, and snippets.

@davidsharp
Created January 20, 2021 12:16
Show Gist options
  • Select an option

  • Save davidsharp/047998f0bef1b3b838362d654f66d903 to your computer and use it in GitHub Desktop.

Select an option

Save davidsharp/047998f0bef1b3b838362d654f66d903 to your computer and use it in GitHub Desktop.
Read asar headers and naively unpack them
import {read,writeFile,mkdir} from 'react-native-fs';
var Buffer = require('buffer/').Buffer;
import pickle from 'chromium-pickle-js';
// read an asar and return its header data
// expects to take a valid asar path
// returns an object with the file structure, header size and asar path (for later reference)
const readAsarHeader = async archive => {
let size;
let headerBuf;
try {
const sizeBuf = Buffer.from(await read(archive, 8, 0, 'base64'),'base64');
const sizePickle = pickle.createFromBuffer(sizeBuf);
size = sizePickle.createIterator().readUInt32();
headerBuf = Buffer.from(await read(archive, size, 8, 'base64'),'base64');
} finally {
}
const headerPickle = pickle.createFromBuffer(headerBuf);
const header = headerPickle.createIterator().readString();
const files = JSON.parse(header).files;
return ({files, headerSize: size, path:archive});
};
// unpack an asar file using its header
// used like: unpackAsar(asarHeader,asarHeader.path,'path/to/write/to')
// returns an array of promises, representing the top level directory
const unpackAsar = async ({files,headerSize},asarPath,to) => {
return Object.keys(files).map(async key => {
if(files[key].files){
await mkdir(`${to}/${key}`)
return Promise.all(
unpackAsar({files:files[key].files,headerSize},asarPath,`${to}/${key}`)
)
}
else{
const {offset,size} = files[key]
const contents = await read(asarPath,size,8+parseInt(offset)+parseInt(headerSize),'base64')
return writeFile(`${to}/${key}`,contents,'base64').then(console.log,console.error)
}
})
}
export {readAsarHeader,unpackAsar}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment