Split the Exe kind into NativeExe / ManagedExe

The detector already used the CLR data-directory RVA to split DLLs into
NativeDll / ManagedDll; EXEs were a single undifferentiated Exe kind.
Apply the same CLR check to EXEs so callers can tell a protected .NET
executable from a native one without unpacking. Routing is unchanged:
both EXE kinds go to the EXE pipeline.

- CLI per-file lines and the run log now print NativeExe / ManagedExe
  (the kind comes from the same Debug formatting as the DLL variants).
- The web API's detect()/unpack_file() kind strings become
  'native-exe' / 'managed-exe'; the web UI gains matching labels, and
  the trap-retry guard (DLL-probe recovery) keys off both EXE kinds.

Golden corpus unchanged (35/35 byte-identical); kind is classification
only and never affects output bytes.
This commit is contained in:
2026-08-16 05:47:16 +08:00
parent fe4f904409
commit dc6e72a8bb
5 changed files with 34 additions and 31 deletions
+4 -2
View File
@@ -45,7 +45,8 @@ const files = new Map();
const rowEls = new Map();
const KIND_LABEL = {
exe: 'protected EXE',
'native-exe': 'protected native EXE',
'managed-exe': 'protected managed EXE',
'native-dll': 'protected native DLL',
'managed-dll': 'protected managed DLL',
metadata: 'il2cpp metadata',
@@ -323,7 +324,8 @@ async function unpackModule(name, entry) {
let comp = compEntry ? await read(compEntry.file) : undefined;
let r = await runUnpack(input, comp, false);
if (!r.ok && r.trap && entry.kind !== 'exe') {
const isExe = entry.kind === 'native-exe' || entry.kind === 'managed-exe';
if (!r.ok && r.trap && !isExe) {
// The DLL-routing probe trapped (panics can't be caught in wasm). Retry
// once with the forced-EXE pipeline in a fresh worker — this mirrors the
// CLI's dll-first/exe-fallback outcome for EXE-shell-layout DLLs.