Преглед изворни кода

Improved continueUntil, added consumeWhile and made the EVTX extractor more complete

n1073645 пре 5 година
родитељ
комит
d240d65c5f
2 измењених фајлова са 58 додато и 11 уклоњено
  1. 4 4
      src/core/lib/FileSignatures.mjs
  2. 54 7
      src/core/lib/Stream.mjs

+ 4 - 4
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();
 }
 

+ 54 - 7
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.
      *