pompelmi 0.35.0 → 0.35.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/pompelmi.browser.cjs +45 -58
- package/dist/pompelmi.browser.cjs.map +1 -1
- package/dist/pompelmi.browser.esm.js +45 -58
- package/dist/pompelmi.browser.esm.js.map +1 -1
- package/dist/pompelmi.cjs +52 -61
- package/dist/pompelmi.cjs.map +1 -1
- package/dist/pompelmi.esm.js +52 -61
- package/dist/pompelmi.esm.js.map +1 -1
- package/dist/pompelmi.react.cjs +45 -58
- package/dist/pompelmi.react.cjs.map +1 -1
- package/dist/pompelmi.react.esm.js +45 -58
- package/dist/pompelmi.react.esm.js.map +1 -1
- package/package.json +2 -2
package/dist/pompelmi.cjs
CHANGED
|
@@ -1001,7 +1001,7 @@ function composeScanners(...args) {
|
|
|
1001
1001
|
const all = [];
|
|
1002
1002
|
if (opts.parallel) {
|
|
1003
1003
|
// Parallel execution — collect all results then return
|
|
1004
|
-
const results = await Promise.allSettled(entries.map(([
|
|
1004
|
+
const results = await Promise.allSettled(entries.map(([_name, scanner]) => runWithTimeout(() => toScanFn(scanner)(input, ctx), opts.timeoutMsPerScanner)));
|
|
1005
1005
|
for (let i = 0; i < results.length; i++) {
|
|
1006
1006
|
const result = results[i];
|
|
1007
1007
|
if (result.status === "fulfilled" && Array.isArray(result.value)) {
|
|
@@ -1055,75 +1055,62 @@ function composeScanners(...args) {
|
|
|
1055
1055
|
};
|
|
1056
1056
|
}
|
|
1057
1057
|
function createPresetScanner(preset, opts = {}) {
|
|
1058
|
-
const
|
|
1059
|
-
|
|
1060
|
-
scanners.push(CommonHeuristicsScanner);
|
|
1058
|
+
const baseScanners = [CommonHeuristicsScanner];
|
|
1059
|
+
const dynamicScannerPromises = [];
|
|
1061
1060
|
// Add decompilation scanners based on preset
|
|
1062
1061
|
if (preset === "decompilation-basic" ||
|
|
1063
1062
|
preset === "decompilation-deep" ||
|
|
1064
1063
|
preset === "malware-analysis" ||
|
|
1065
1064
|
opts.enableDecompilation) {
|
|
1066
|
-
const depth = preset === "decompilation-deep"
|
|
1065
|
+
const depth = preset === "decompilation-deep" || preset === "malware-analysis"
|
|
1067
1066
|
? "deep"
|
|
1068
1067
|
: preset === "decompilation-basic"
|
|
1069
1068
|
? "basic"
|
|
1070
1069
|
: opts.decompilationDepth || "basic";
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
// Dynamic import to avoid bundling issues - using Function to bypass TypeScript type checking
|
|
1076
|
-
const importModule = new Function("specifier", "return import(specifier)");
|
|
1077
|
-
importModule("@pompelmi/engine-binaryninja")
|
|
1078
|
-
.then((mod) => {
|
|
1079
|
-
const binjaScanner = mod.createBinaryNinjaScanner({
|
|
1080
|
-
timeout: opts.decompilationTimeout || opts.timeout || 30000,
|
|
1081
|
-
depth,
|
|
1082
|
-
pythonPath: opts.pythonPath,
|
|
1083
|
-
binaryNinjaPath: opts.binaryNinjaPath,
|
|
1084
|
-
});
|
|
1085
|
-
scanners.push(binjaScanner);
|
|
1086
|
-
})
|
|
1087
|
-
.catch(() => {
|
|
1088
|
-
// Binary Ninja engine not available - silently skip
|
|
1089
|
-
});
|
|
1090
|
-
}
|
|
1091
|
-
catch {
|
|
1092
|
-
// Engine not installed
|
|
1093
|
-
}
|
|
1094
|
-
}
|
|
1095
|
-
if (!opts.decompilationEngine ||
|
|
1096
|
-
opts.decompilationEngine === "ghidra-pcode" ||
|
|
1097
|
-
opts.decompilationEngine === "both") {
|
|
1098
|
-
try {
|
|
1099
|
-
// Dynamic import for Ghidra engine (when implemented) - using Function to bypass TypeScript type checking
|
|
1100
|
-
const importModule = new Function("specifier", "return import(specifier)");
|
|
1101
|
-
importModule("@pompelmi/engine-ghidra")
|
|
1102
|
-
.then((mod) => {
|
|
1103
|
-
const ghidraScanner = mod.createGhidraScanner({
|
|
1104
|
-
timeout: opts.decompilationTimeout || opts.timeout || 30000,
|
|
1105
|
-
depth,
|
|
1106
|
-
ghidraPath: opts.ghidraPath,
|
|
1107
|
-
analyzeHeadless: opts.analyzeHeadless,
|
|
1108
|
-
});
|
|
1109
|
-
scanners.push(ghidraScanner);
|
|
1110
|
-
})
|
|
1111
|
-
.catch(() => {
|
|
1112
|
-
// Ghidra engine not available - silently skip
|
|
1113
|
-
});
|
|
1114
|
-
}
|
|
1115
|
-
catch {
|
|
1116
|
-
// Engine not installed
|
|
1117
|
-
}
|
|
1070
|
+
let importModule;
|
|
1071
|
+
try {
|
|
1072
|
+
// Dynamic import to avoid bundling issues - using Function to bypass TypeScript type checking
|
|
1073
|
+
importModule = new Function("specifier", "return import(specifier)");
|
|
1118
1074
|
}
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1075
|
+
catch {
|
|
1076
|
+
importModule = undefined;
|
|
1077
|
+
}
|
|
1078
|
+
if (importModule &&
|
|
1079
|
+
(!opts.decompilationEngine ||
|
|
1080
|
+
opts.decompilationEngine === "binaryninja-hlil" ||
|
|
1081
|
+
opts.decompilationEngine === "both")) {
|
|
1082
|
+
dynamicScannerPromises.push(importModule("@pompelmi/engine-binaryninja")
|
|
1083
|
+
.then((mod) => mod.createBinaryNinjaScanner({
|
|
1084
|
+
timeout: opts.decompilationTimeout || opts.timeout || 30000,
|
|
1085
|
+
depth,
|
|
1086
|
+
pythonPath: opts.pythonPath,
|
|
1087
|
+
binaryNinjaPath: opts.binaryNinjaPath,
|
|
1088
|
+
}))
|
|
1089
|
+
.catch(() => null));
|
|
1090
|
+
}
|
|
1091
|
+
if (importModule &&
|
|
1092
|
+
(!opts.decompilationEngine ||
|
|
1093
|
+
opts.decompilationEngine === "ghidra-pcode" ||
|
|
1094
|
+
opts.decompilationEngine === "both")) {
|
|
1095
|
+
dynamicScannerPromises.push(importModule("@pompelmi/engine-ghidra")
|
|
1096
|
+
.then((mod) => mod.createGhidraScanner({
|
|
1097
|
+
timeout: opts.decompilationTimeout || opts.timeout || 30000,
|
|
1098
|
+
depth,
|
|
1099
|
+
ghidraPath: opts.ghidraPath,
|
|
1100
|
+
analyzeHeadless: opts.analyzeHeadless,
|
|
1101
|
+
}))
|
|
1102
|
+
.catch(() => null));
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
let composedScannerPromise;
|
|
1106
|
+
const getComposedScanner = async () => {
|
|
1107
|
+
composedScannerPromise ?? (composedScannerPromise = Promise.all(dynamicScannerPromises).then((dynamicScanners) => composeScanners(...baseScanners, ...dynamicScanners.filter((scanner) => scanner !== null))));
|
|
1108
|
+
return composedScannerPromise;
|
|
1109
|
+
};
|
|
1110
|
+
return async (input, ctx) => {
|
|
1111
|
+
const scanner = await getComposedScanner();
|
|
1112
|
+
return scanner(input, ctx);
|
|
1113
|
+
};
|
|
1127
1114
|
}
|
|
1128
1115
|
|
|
1129
1116
|
/**
|
|
@@ -2015,10 +2002,14 @@ class BatchScanner {
|
|
|
2015
2002
|
processingQueue.push(promise);
|
|
2016
2003
|
currentIndex++;
|
|
2017
2004
|
// Remove completed promises from queue
|
|
2018
|
-
promise
|
|
2005
|
+
promise
|
|
2006
|
+
.finally(() => {
|
|
2019
2007
|
const idx = processingQueue.indexOf(promise);
|
|
2020
2008
|
if (idx > -1)
|
|
2021
2009
|
processingQueue.splice(idx, 1);
|
|
2010
|
+
})
|
|
2011
|
+
.catch(() => {
|
|
2012
|
+
// Rejections are handled by the main queue waits; swallow the cleanup chain.
|
|
2022
2013
|
});
|
|
2023
2014
|
}
|
|
2024
2015
|
// Wait for at least one task to complete before continuing
|