From d240d65c5f10d4b4c954b912cfca87f95b4aa95c Mon Sep 17 00:00:00 2001 From: n1073645 Date: Mon, 11 Nov 2019 15:47:16 +0000 Subject: [PATCH] Improved continueUntil, added consumeWhile and made the EVTX extractor more complete --- src/core/lib/FileSignatures.mjs | 8 ++--- src/core/lib/Stream.mjs | 61 +++++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/core/lib/FileSignatures.mjs b/src/core/lib/FileSignatures.mjs index b93a7c9f..da4509c8 100644 --- a/src/core/lib/FileSignatures.mjs +++ b/src/core/lib/FileSignatures.mjs @@ -3348,11 +3348,11 @@ export function extractEVTX(bytes, offset) { while (stream.hasMore()) { // Loop through ELFCHNKs. - if (stream.getBytes(7).join("") === [0x45, 0x6c, 0x66, 0x43, 0x68, 0x6e, 0x6b].join("")) - stream.moveForwardsBy(0xfff9); - else - break; + if (stream.getBytes(7).join("") !== [0x45, 0x6c, 0x66, 0x43, 0x68, 0x6e, 0x6b].join("")) + break; + stream.moveForwardsBy(0xfff9); } + stream.consumeWhile(0x00); return stream.carve(); } diff --git a/src/core/lib/Stream.mjs b/src/core/lib/Stream.mjs index 7e82a5eb..dca390e5 100644 --- a/src/core/lib/Stream.mjs +++ b/src/core/lib/Stream.mjs @@ -155,19 +155,66 @@ export default class Stream { } // val is an array - let found = false; - while (!found && this.position < this.length) { - while (++this.position < this.length && this.bytes[this.position] !== val[0]) { - continue; - } + + + /** + * Build's the skip forward table from the value to be searched. + * + * @param val + * @param len + */ + function preprocess(val, len) { + const skiptable = new Array(); + val.forEach(function(element, index) { + skiptable[element] = len - index; + }); + return skiptable; + } + + const length = val.length; + + const initial = val[length-1]; + + this.position = length; + + // Get the skip table. + const skiptable = preprocess(val, length); + let found = true; + + while (this.position < this.length) { + + // Until we hit the final element of val in the stream. + while ((this.position < this.length) && (this.bytes[this.position++] !== initial)); + found = true; - for (let i = 1; i < val.length; i++) { - if (this.position + i > this.length || this.bytes[this.position + i] !== val[i]) + + // Loop through the elements comparing them to val. + for (let x = length-1; x != -1; x--) { + if (this.bytes[(this.position-length) + x] !== val[x]) { found = false; + + // If element is not equal to val's element then jump forward by the correct amount. + this.position += skiptable[val[x]]; + break; + } + } + if (found) { + this.position = (this.position - length); + break; } } } + + /** + * Consume bytes if it matches the supplied value. + * + * @param val + */ + consumeWhile(val) { + while ((this.position < this.length) && (this.bytes[this.position++] === val)); + } + /** * Consume the next byte if it matches the supplied value. *