All files / binary101/analyzers mz-probe.ts

94.11% Statements 32/34
80.95% Branches 17/21
100% Functions 1/1
94.11% Lines 32/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 351x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 154x 154x 154x 91x 108x 89x 16x 16x 16x 89x     89x 17x 89x 4x 4x 4x 4x 154x 1x 1x  
"use strict";
 
import { peProbe } from "./pe/security/signature.js";
 
export type MzProbeKind = "mz" | "pe" | "ne" | "le" | "lx";
 
export interface MzProbeResult {
  kind: MzProbeKind;
  eLfanew: number;
}
 
const probeMzFormat = async (file: File, dv: DataView): Promise<MzProbeResult | null> => {
  const mz = peProbe(dv);
  if (!mz) return null;
  const eLfanew = mz.e_lfanew >>> 0;
  if (eLfanew === 0) return { kind: "mz", eLfanew };
  if (eLfanew + 4 > file.size) return { kind: "mz", eLfanew };
  const sigLength = Math.min(4, file.size - eLfanew);
  let sigBytes: Uint8Array;
  if (eLfanew + sigLength <= dv.byteLength) {
    sigBytes = new Uint8Array(dv.buffer, dv.byteOffset + eLfanew, sigLength);
  } else {
    sigBytes = new Uint8Array(await file.slice(eLfanew, eLfanew + sigLength).arrayBuffer());
  }
  const sigText = String.fromCharCode(...sigBytes);
  if (sigText.startsWith("PE\0\0")) return { kind: "pe", eLfanew };
  const shortSig = sigText.slice(0, 2);
  if (shortSig === "NE") return { kind: "ne", eLfanew };
  if (shortSig === "LE") return { kind: "le", eLfanew };
  if (shortSig === "LX") return { kind: "lx", eLfanew };
  return { kind: "mz", eLfanew };
};
 
export { probeMzFormat };