Commit Graph
24 Commits
Author SHA1 Message Date
Momoko-Ayase d3dd1a8ff8 Merge Android (AArch64) shared-library restoration, bump to 1.2.0
Adds the Android protection-scheme pipeline: hollowed ELF64/AArch64
libraries are restored statically (stage-1/stage-2 module extraction,
container decode, dynamic-linker table rebuild), with app-package
(.apk/.apks/.xapk) container handling, cross-source content dedup, and
il2cpp metadata support for the Android variants (seeded RID permutation;
embedded XOR-wrapped blob extraction).

The single senbei CLI now routes single .so files, packages, and folders
by content; outputs follow the existing .unpack-infix naming under
<root>/unpack or --out. PE behavior is unchanged (35/35 goldens).
2026-09-02 03:09:21 +08:00
Momoko-Ayase 0c3f29f93a Split web/ into senbei-wasm crate + static assets
The Rust bindings move from web/src to a top-level senbei-wasm crate (still
outside the workspace, own Cargo.lock), matching the other senbei-* crates.
web/ keeps only the static frontend; wasm-pack emits the JS/wasm package into
web/pkg/ via --out-dir. JS glue renamed senbei_web -> senbei_wasm with the
crate.
v1.1.0
2026-08-30 22:44:15 +08:00
Momoko-Ayase f80749ffd6 Merge bfloat16-senbei workspace restructure, bump to 1.1.0
Adopts the fork's workspace split (senbei-cli / senbei-crypto / senbei-io /
senbei-metadata / senbei-pe), its structured error taxonomy, entry-transform
and layout validation, PE32 dd8 key-formula selection with a skip floor, the
CRT entry-stub dd8 oracle, and the extensionless-file scan skip.

Kept from senbei on top of the restructure:
- ManagedExe detection/routing and the CLR (COR20 + BSJB) metadata restore
  in the EXE pipeline.
- The RET+int3 padding fingerprint as the primary dd8 padding signal, ahead
  of the mutated-position 0xCC fallback.
- docs/, .github/, samples/, tests/ (moved to senbei-cli/tests), and the
  web/ wasm frontend (rewired to the split crates), all of which the fork
  had dropped.
- The fork's README compatibility matrix is not taken: it names real games,
  which the public-repo hygiene rules forbid.
- The wasm32 localtime fallback in logfile and unpack_bytes_force_exe (the
  web app's trap-recovery entry point), both lost in the restructure.

Golden corpus: 35/35 byte-identical. clippy -D warnings clean; wasm32 check
clean for the full workspace.
2026-08-30 22:31:21 +08:00
Momoko-Ayase ef13419b93 Bump version to 1.0.1 v1.0.1 2026-08-16 05:51:39 +08:00
Momoko-Ayase dc6e72a8bb 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.
2026-08-16 05:47:16 +08:00
Momoko-Ayase fe4f904409 Strengthen the dd8 shift detector with a RET+int3 padding fingerprint
The selector replayed each candidate shift over three sample pages and
counted 0xCC bytes at dd8-mutated positions. That signal is biased
upward for wrong candidates (255 pseudo-random XORs manufacture ~1
spurious 0xCC per page for free) and cannot express 'this candidate
destroys real padding', so the decision leaned on a 2x-margin-plus-floor
rule tuned around the noise.

Score candidates instead by a structural fingerprint of real x64 code:
the MSVC function-end padding pattern (a 0xC3 RET followed by a run of
>= 4 0xCC bytes), summed over up to four sample pages taken with a
head/tail margin. Because dd8 touches only 255 of 4096 bytes per page,
an encrypted page keeps most runs under 'no dd8' and restores them only
under the correct shift, while an already-plaintext page loses runs
under any shift — wrong candidates score *below* the baseline, which the
old count could never say. The gate becomes a positive delta over the
baseline (floor 8) instead of the 2x margin.

When every candidate's fingerprint is silent (sampled pages with no
padded epilogues), fall back to the previous mutated-position count with
its 2x-margin-plus-floor rule, so pages without padding still resolve.

Across the 35-input golden corpus every decision now comes from the
fingerprint with wide, sign-correct margins; all outputs are unchanged
(byte-identical goldens).
2026-08-16 05:33:44 +08:00
Momoko-Ayase 7f143b3b27 Support managed (CLR) EXEs in the old-layout EXE pipeline
Managed EXE builds differ from their native counterparts in the old
layout: the encrypted import-name table pointer is null (their imports
are just the CLR bootstrap stub), the config block's entry-point field
is 0, and the COR20 header / BSJB metadata stream / CLR resources are
stored verbatim in the protected file rather than arriving through the
section-block pass.

- Skip the import-string walk when the table pointer is null instead of
  chasing header garbage as a pointer chain (previously a caught
  out-of-bounds panic reported as corrupt input).
- Keep the protected header's entry point when the config block stores
  0, instead of overwriting it with 0.
- Restore the COR20 header, BSJB metadata stream, and CLR resources
  verbatim from the protected file after the .text dd8 pass, and
  suppress the native COR20-directory clearing when the restore ran.

Validated by decompiling the unpacked managed EXEs with ilspycmd: full
assemblies (types, methods, IL bodies) decompile cleanly. Golden corpus
unchanged (35/35 byte-identical).
2026-08-16 05:33:44 +08:00
bfloat16 35076848b6 chore: ignore local test corpus 2026-08-16 03:49:11 +08:00
bfloat16 18886272e5 docs: note embedded metadata compatibility 2026-08-16 03:43:12 +08:00
bfloat16 b534de872d refactor: move library implementations into modules 2026-08-16 03:38:42 +08:00
bfloat16 a9aaf95e01 docs: add Android compatibility matrix 2026-08-16 03:31:25 +08:00
bfloat16 7f827d6400 feat: add folder-based Android unpack workflow 2026-08-16 02:38:07 +08:00
bfloat16 131ced6db5 feat: add static stage extraction and metadata detection 2026-08-16 01:47:25 +08:00
bfloat16 b1d3699df3 feat: add static Android il2cpp restoration 2026-08-16 00:34:08 +08:00
bfloat16 9433b4dcca Initial commit 2026-08-15 22:20:03 +08:00
bfloat16 763bdbb21f docs(readme): organize compatibility matrix by game 2026-08-13 10:49:44 +08:00
bfloat16 c5982a64b9 fix(unpacker): classify checksum range failures 2026-08-13 10:49:07 +08:00
bfloat16 55a31a2371 doc(none): add README.md 2026-08-12 23:57:00 +08:00
bfloat16 caadbd5325 fix(unpacker): validate executable entry transforms 2026-08-11 19:24:45 +08:00
bfloat16 ab1a14c9d1 perf(scan): skip extensionless files by default 2026-08-11 19:24:32 +08:00
bfloat16 e9ead4dc5f refactor: init 2026-08-11 14:19:56 +08:00
bfloat16 a89900a812 fix(unpacker): refine layout validation and diagnostics 2026-08-11 11:42:12 +08:00
bfloat16 67178d34af feat: Optimize error reporting 2026-08-11 10:51:37 +08:00
Momoko-Ayase 21cd151e15 First public commit v1.0.0 2026-08-09 00:08:31 +08:00