diff --git a/src/core/lib/FileSignatures.mjs b/src/core/lib/FileSignatures.mjs index 477ed753..8861859b 100644 --- a/src/core/lib/FileSignatures.mjs +++ b/src/core/lib/FileSignatures.mjs @@ -1739,7 +1739,7 @@ export const FILE_SIGNATURES = { 6: 0x0a, 7: 0x1a }, - extractor: null + extractor: extractLZOP }, { name: "Linux deb", @@ -2070,7 +2070,7 @@ export const FILE_SIGNATURES = { 6: [0x4d, 0x36], 7: [0x50, 0x34] }, - extractor: null + extractor: extractDMP }, { name: "Windows Prefetch", @@ -2087,7 +2087,7 @@ export const FILE_SIGNATURES = { 6: 0x43, 7: 0x41 }, - extractor: null + extractor: extractPF }, { name: "Windows Prefetch (Win 10)", @@ -2101,7 +2101,7 @@ export const FILE_SIGNATURES = { 3: 0x04, 7: 0x0 }, - extractor: null + extractor: extractPFWin10 }, { name: "PList (XML)", @@ -2374,7 +2374,7 @@ export const FILE_SIGNATURES = { 18: 0x00, 19: 0x46 }, - extractor: null + extractor: extractLNK }, { name: "Bash", @@ -3749,3 +3749,161 @@ export function extractEVT(bytes, offset) { stream.moveForwardsBy(eofSize-4); return stream.carve(); } + + +/** + * DMP extractor. + * + * @param {Uint8Array} bytes + * @param {Number} offset + * @returns {Uint8Array} + */ +export function extractDMP(bytes, offset) { + const stream = new Stream(bytes.slice(offset)); + + // Move to fileSize field. + stream.moveTo(0x70); + + // Multiply number of pages by page size. Plus 1 since the header is a page. + stream.moveTo((stream.readInt(4, "le") + 1) * 0x1000); + + return stream.carve(); +} + + +/** + * PF extractor. + * + * @param {Uint8Array} bytes + * @param {Number} offset + * @returns {Uint8Array} + */ +export function extractPF(bytes, offset) { + const stream = new Stream(bytes.slice(offset)); + + // Move to file size. + stream.moveTo(12); + stream.moveTo(stream.readInt(4, "be")); + + return stream.carve(); +} + + +/** + * PF (Win 10) extractor. + * + * @param {Uint8Array} bytes + * @param {Number} offset + * @returns {Uint8Array} + */ +export function extractPFWin10(bytes, offset) { + const stream = new Stream(bytes.slice(offset)); + + // Read in file size. + stream.moveTo(stream.readInt(4, "be")); + + return stream.carve(); +} + + +/** + * LNK extractor. + * + * @param {Uint8Array} bytes + * @param {Number} offset + * @returns {Uint8Array} + */ +export function extractLNK(bytes, offset) { + const stream = new Stream(bytes.slice(offset)); + + // Move to file size field. + stream.moveTo(0x34); + stream.moveTo(stream.readInt(4, "le")); + + return stream.carve(); +} + + +/** + * LZOP extractor. + * + * @param {Uint8Array} bytes + * @param {Number} offset + * @returns {Uint8Array} + */ +export function extractLZOP(bytes, offset) { + const stream = new Stream(bytes.slice(offset)); + + // Flag bits. + const F_ADLER32_D = 0x00000001; + const F_ADLER32_C = 0x00000002; + const F_CRC32_D = 0x00000100; + const F_CRC32_C = 0x00000200; + const F_H_FILTER = 0x00000800; + const F_H_EXTRA_FIELD = 0x00000040; + + let numCheckSumC = 0, numCheckSumD = 0; + + // Move over magic bytes. + stream.moveForwardsBy(9); + + const version = stream.readInt(2, "be"); + + // Move to flag register offset. + stream.moveForwardsBy(6); + const flags = stream.readInt(4, "be"); + + if (version & F_H_FILTER) + stream.moveForwardsBy(4); + + if (flags & F_ADLER32_C) + numCheckSumC++; + + if (flags & F_CRC32_C) + numCheckSumC++; + + if (flags & F_ADLER32_D) + numCheckSumD++; + + if (flags & F_CRC32_D) + numCheckSumD++; + + // Move over the mode, mtime_low + stream.moveForwardsBy(8); + + if (version >= 0x0940) + stream.moveForwardsBy(4); + + const fnameSize = stream.readInt(1, "be"); + + // Move forwards by size of file name and the following 4 byte checksum. + stream.moveForwardsBy(fnameSize); + + if (flags & F_H_EXTRA_FIELD) { + const extraSize = stream.readInt(4, "be"); + stream.moveForwardsBy(extraSize); + } + + // Move past checksum. + stream.moveForwardsBy(4); + + try { + while (stream.hasMore()) { + const uncompSize = stream.readInt(4, "be"); + + // If data has no length, break. + if (uncompSize === 0) + break; + + const compSize = stream.readInt(4, "be"); + + const numCheckSumSkip = (uncompSize === compSize) ? numCheckSumD : numCheckSumD + numCheckSumC; + + // skip forwards by compressed data size and the size of the checksum(s). + stream.moveForwardsBy(compSize + (numCheckSumSkip * 4)); + } + } catch (error) { + } + return stream.carve(); + +}