reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Inspect an APK (ZIP) and inventory its DEX, native libraries, and assets.
|
||||
|
||||
Lists the components relevant to triage — DEX files, native ``.so`` libraries, the manifest,
|
||||
and notable assets — without decompiling or executing anything. Use jadx/apktool for the
|
||||
actual decompilation step.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def inspect(path: str) -> dict:
|
||||
if not zipfile.is_zipfile(path):
|
||||
return {"error": "not a ZIP/APK"}
|
||||
dex, native, assets, other = [], [], [], []
|
||||
with zipfile.ZipFile(path) as zf:
|
||||
for name in zf.namelist():
|
||||
if name.endswith(".dex"):
|
||||
dex.append(name)
|
||||
elif name.startswith("lib/") and name.endswith(".so"):
|
||||
native.append(name)
|
||||
elif name.startswith("assets/"):
|
||||
assets.append(name)
|
||||
elif name == "AndroidManifest.xml":
|
||||
other.append(name)
|
||||
return {
|
||||
"dex": sorted(dex),
|
||||
"native_libs": sorted(native),
|
||||
"assets": sorted(assets),
|
||||
"has_manifest": "AndroidManifest.xml" in other,
|
||||
"multidex": len(dex) > 1,
|
||||
"notes": _notes(dex, native, assets),
|
||||
}
|
||||
|
||||
|
||||
def _notes(dex, native, assets) -> list[str]:
|
||||
notes = []
|
||||
if len(dex) > 1:
|
||||
notes.append("multidex: analyze all classesN.dex")
|
||||
if native:
|
||||
notes.append("native libraries present: analyze .so separately")
|
||||
enc = [a for a in assets if a.endswith((".enc", ".dat", ".bin"))]
|
||||
if enc:
|
||||
notes.append(f"possible encrypted payload assets: {enc}")
|
||||
return notes
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(description="Inspect an APK")
|
||||
sub = parser.add_subparsers(dest="cmd", required=True)
|
||||
p = sub.add_parser("inspect")
|
||||
p.add_argument("file")
|
||||
args = parser.parse_args(argv)
|
||||
print(json.dumps(inspect(args.file), indent=2))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user