Added ELF extractor. You can now specific which categories to search for in file type operations.

This commit is contained in:
n1474335 2019-01-14 18:55:10 +00:00
parent 2307325af8
commit cd2c8078c8
5 changed files with 111 additions and 38 deletions

View file

@ -678,7 +678,7 @@ export const FILE_SIGNATURES = {
2: 0x4c,
3: 0x46
},
extractor: null
extractor: extractELF
},
{
name: "Adobe Flash",
@ -1474,6 +1474,50 @@ export function extractZlib(bytes, offset) {
}
/**
* ELF extractor.
*
* @param {Uint8Array} bytes
* @param {number} offset
* @returns {Uint8Array}
*/
export function extractELF(bytes, offset) {
const stream = new Stream(bytes.slice(offset));
// Skip over magic number
stream.moveForwardsBy(4);
// Read architecture (x86 == 1, x64 == 2)
const x86 = stream.readInt(1) === 1;
// Read endianness (1 == little, 2 == big)
const endian = stream.readInt(1) === 1 ? "le" : "be";
// Skip over header values
stream.moveForwardsBy(x86 ? 26 : 34);
// Read section header table offset
const shoff = x86 ? stream.readInt(4, endian) : stream.readInt(8, endian);
// Skip over flags, header size and program header size and entries
stream.moveForwardsBy(10);
// Read section header table entry size
const shentsize = stream.readInt(2, endian);
// Read number of entries in the section header table
const shnum = stream.readInt(2, endian);
// Jump to section header table
stream.moveTo(shoff);
// Move past each section header
stream.moveForwardsBy(shentsize * shnum);
return stream.carve();
}
/**
* Steps through a DEFLATE stream
*

View file

@ -75,22 +75,29 @@ function bytesMatch(sig, buf, offset=0) {
* extension and mime type.
*
* @param {Uint8Array} buf
* @param {string[]} [categories=All] - Which categories of file to look for
* @returns {Object[]} types
* @returns {string} type.name - Name of file type
* @returns {string} type.ext - File extension
* @returns {string} type.mime - Mime type
* @returns {string} [type.desc] - Description
*/
export function detectFileType(buf) {
export function detectFileType(buf, categories=Object.keys(FILE_SIGNATURES)) {
if (!(buf && buf.length > 1)) {
return [];
}
const matchingFiles = [];
const signatures = {};
// TODO allow user to select which categories to check
for (const cat in FILE_SIGNATURES) {
const category = FILE_SIGNATURES[cat];
if (categories.includes(cat)) {
signatures[cat] = FILE_SIGNATURES[cat];
}
}
for (const cat in signatures) {
const category = signatures[cat];
category.forEach(filetype => {
if (signatureMatches(filetype.signature, buf)) {
@ -107,6 +114,7 @@ export function detectFileType(buf) {
* the extensions and mime types.
*
* @param {Uint8Array} buf
* @param {string[]} [categories=All] - Which categories of file to look for
* @returns {Object[]} foundFiles
* @returns {number} foundFiles.offset - The position in the buffer at which this file was found
* @returns {Object} foundFiles.fileDetails
@ -115,16 +123,22 @@ export function detectFileType(buf) {
* @returns {string} foundFiles.fileDetails.mime - Mime type
* @returns {string} [foundFiles.fileDetails.desc] - Description
*/
export function scanForFileTypes(buf) {
export function scanForFileTypes(buf, categories=Object.keys(FILE_SIGNATURES)) {
if (!(buf && buf.length > 1)) {
return [];
}
const foundFiles = [];
const signatures = {};
// TODO allow user to select which categories to check
for (const cat in FILE_SIGNATURES) {
const category = FILE_SIGNATURES[cat];
if (categories.includes(cat)) {
signatures[cat] = FILE_SIGNATURES[cat];
}
}
for (const cat in signatures) {
const category = signatures[cat];
for (let i = 0; i < category.length; i++) {
const filetype = category[i];