📜 ⬆️ ⬇️

jParser: analyzing binary files just works

jParser makes it easy to read data structures from binary files with javascript.


API

Elementary structures:


JParser methods:
')

JParser Constructor:



Examples


Common C Structure

You can describe C-like data structures. This is a javascript object in which the fields are data names and their values ​​are types.

var parser = new jParser(file, { header: { fileId: 'int32', recordIndex: 'int32', hash: ['array', 'uint32', 4], fileName: ['string', 256], } }); parser.parse('header'); // { // fileId: 42, // recordIndex: 6002, // hash: [4237894687, 3491173757, 3626834111, 2631772842], // fileName: ".\\Resources\\Excel\\Items_Weapons.xls" // } 


Links

Structures may contain other structures. Use the structure name as a string to refer to its description. The following example is part of the file structure that contains the model for World of Warcraft:

 nofs: { count: 'uint32', offset: 'uint32' }, animationBlock: { interpolationType: 'uint16', globalSequenceID: 'int16', timestamps: 'nofs', keyFrame: 'nofs' }, uvAnimation: { translation: 'animationBlock', rotation: 'animationBlock', scaling: 'animationBlock' } 


Helper Functions

It will be easy for you to define new elementary types. You can use existing kinds of constructions, such as objects ( float3 in the example below) or arrays ( float4 in the example). If you want to define a more complex type, it is always possible to define a new function that relies on the this.parse method for the primary analysis ( hex32 and string0 in the following example):

 float3: { x: 'float32', y: 'float32', z: 'float32' }, float4: ['array', 'float32', 4], hex32: function () { return '0x' + this.parse('uint32').toString(16); }, string0: function (length) { return this.parse(['string', length]).replace(/\0+$/g, ''); } 


Feedback

If the size of the array is not known in advance, you can put in its place in the structure a function that returns an integer. In this function, you can refer to the object currently being analyzed, through this.current , to read its already received fields.

 image: { width: 'uint8', height: 'uint8', pixels: [ 'array', ['array', 'rgba', function () { return this.current.width; }], function () { return this.current.height; } ] } 


Advanced data analysis

A nice feature of jParser is that complex processing algorithms can be expressed by functions within the description of the data structure. This allows you to analyze complex files without separating the structure description from the code of its handlers.

 entryHeader: { start: 'int32', count: 'int32' }, entry: function (type) { var that = this; var header = this.parse('entryHeader'); var res = []; this.seek(header.start, function () { for (var i = 0; i < header.count; ++i) { res.push(that.parse(type)); } }); return res; }, name: { language: 'int32', text: ['string', 256] }, file: { names: ['entry', 'name'] } 


Beginning of work


On the engine NodeJS

Just use npm to install jParser - and you are ready :-)

 npm install jParser 

 var fs = require('fs'); var jParser = require('jParser'); fs.readFile('file.bin', function (err, data) { var parser = new jParser(data, { magic: ['array', 'uint8', 4] }); console.log(parser.parse('magic')); }); 


In the browser

I patched jQuery , provided I downloaded binary files in the best binary format. Connect this patched jQuery code, as well as jDataView and jParser - and you are ready :-)

 <script src="https://raw.github.com/vjeux/jDataView/master/jquery/jquery-1.7.1-binary-ajax.js"></script> <script src="https://raw.github.com/vjeux/jDataView/master/src/jdataview.js"></script> <script src="https://raw.github.com/vjeux/jParser/master/src/jparser.js"></script> <script> $.get('file.bin', function (data) { var parser = new jParser(data, { magic: ['array', 'uint8', 4] }); console.log(parser.parse('magic')); }, 'dataview'); </script> 


Precautions


This tool relies on an undocumented JavaScript feature in its work: bypassing the fields of an object works in the order in which they are specified. Keep in mind that in Chrome and in Opera, this implicit rule does not work for fields with numeric names.

Follow these two rules for this library to work in all existing implementations of the JavaScript language:



Demo


ICO analysis . This is a simple example of analyzing a binary file on the NodeJS engine. It shows how many typical problems that arise when parsing binary data are solved.


Tar unpacker . This is a simple example of parsing a binary file inside a browser.


A means of displaying models of World of Warcraft . Uses jParser to read the binary code of the three-dimensional model, then WebGL to display it.


[screenshot]

Diablo 3 internal files

Source: https://habr.com/ru/post/144008/


All Articles