You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+16-2Lines changed: 16 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# AGENTS
2
2
3
-
This repository contains ToCode, a Python-only binary exporter. ToCode takes one binary or IDA database path and writes one source-like project directory for reverse-engineering agents.
3
+
This repository contains ToCode, a Python-only binary exporter. ToCode takes one binary, IDA database, or Android APK path and writes one source-like project directory for reverse-engineering agents.
4
4
5
5
## Scope
6
6
@@ -15,7 +15,8 @@ This repository contains ToCode, a Python-only binary exporter. ToCode takes one
15
15
-`src/tocode/cli.py`: command-line entry point for `tocode`.
16
16
-`src/tocode/__init__.py`: package version and `export_from_binaryview()`, the in-UI Binary Ninja library entry.
17
17
-`src/tocode/analysis.py`: backend-neutral binary inventory and call graph normalization.
18
-
-`src/tocode/backends/`: IDA Domain, radare2, angr, and Binary Ninja (`binja.py`) session adapters.
18
+
-`src/tocode/backends/`: IDA Domain, radare2, angr, and Binary Ninja (`binja.py`) session adapters, plus the ASC/droidasc APK backend (`asc.py`: APK set discovery, DEX inventory, worker-side class decompilation).
19
+
-`src/tocode/apk.py`: APK export pipeline (extraction, decompile pool, resource decoding, metadata); `apk_metadata.py`: manifest parsing and Android JSON documents; `apk_native.py`: extraction and background native export of every `.so`.
19
20
-`src/tocode/exporter.py`: project writer, function rendering, worker-session rendering, generated export `AGENTS.md`.
20
21
-`src/tocode/metadata.py`: JSON metadata and triage documents.
21
22
-`src/tocode/cluster.py`: call-graph clustering.
@@ -59,6 +60,17 @@ When `--tree` is passed, the export also contains:
59
60
-`src/tree/**/*.c`
60
61
-`function-index-tree.json`
61
62
63
+
APK input (`.apk`, `.apks`, `.xapk`) uses the ASC backend and writes instead:
64
+
65
+
-`src/raw/<package>/**/*.java` (one file per class, folders are Java packages; no clusters, no summaries)
-`functions.json`, `function-index.json`, `strings.json`, `imports.json`, `exports.json`, `sections.json`, `reachable.json`, `triage.json`, `project.json`, `export-manifest.json` (same shapes as the native export where applicable)
68
+
-`lib/<abi>/*.so` (every native library, always extracted) and `native/<abi>/<lib>/` (a full nested ToCode export per library, all ABIs, unless `--no-native`)
69
+
-`data/apk/**` (all other entries verbatim), `data/res/**/*.xml`, `data/resources.json`
70
+
-`tocode.log`, generated `AGENTS.md` and `CLAUDE.md`
71
+
72
+
`base.apk` merges sibling `split_*.apk` files unless `--no-splits`; bundles are unpacked and merged. `--backend` selects the native backend for the `.so` exports (`binja` is rejected).
73
+
62
74
## Development
63
75
64
76
- Prefer `uv` for local commands.
@@ -74,6 +86,8 @@ When `--tree` is passed, the export also contains:
74
86
- IDA Domain is the preferred backend when available.
75
87
- radare2/r2pipe is a fallback backend.
76
88
- angr is the optional pure-Python fallback backend (`[angr]` extra).
89
+
- ASC (`droidasc`, PyPI) is the APK/DEX backend and a core runtime dependency. It pulls androguard. `backends/asc.py` is the only module that imports it; it pre-imports the modules ASC would otherwise stub in `sys.modules` and silences androguard's loguru logging. Class decompilation is not thread-safe, so it runs in spawned worker processes (recycled in rounds; do not use `max_tasks_per_child`, it deadlocks spawn pools on some CPython builds). The big per-method/per-class/per-string JSON documents are streamed row by row (`apk_metadata.write_json_rows`), never built as one object.
90
+
- APK native libraries are exported by `apk_native.py` on a background thread, each `export_binary` in its own spawned process so a backend OOM-kill or crash only fails that library (`native-libs.json` status). The thread waits for `TOCODE_APK_NATIVE_MIN_FREE_MB` (default 1024) of free memory before starting each library so it does not starve the DEX pool. `TOCODE_WORKER_TMP_DIR` also places the unpacked `.apks` bundle.
77
91
- Binary Ninja is an opt-in backend (`--backend binja`, never auto-selected). The
78
92
`binaryninja` module is supplied by the Binary Ninja install (in-UI) or the
79
93
remote VM, so it is not a pip dependency. `rpyc`, the client used for the
Copy file name to clipboardExpand all lines: README.md
+40-4Lines changed: 40 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# ToCode
2
2
3
-
ToCode exports a binary or IDA databaseinto a source-like project tree: raw recovered C, matching assembly, function summaries, section data, optional IDA database, and metadata that coding agents can read directly.
3
+
ToCode exports a binary, IDA database, or Android APK into a source-like project tree: raw recovered C (or Java for APKs), matching assembly, function summaries, section data, optional IDA database, and metadata that coding agents can read directly.
4
4
5
5
## Why
6
6
@@ -23,11 +23,22 @@ sample_decompiler/
23
23
src/raw/**/*.c
24
24
src/raw/**/*.asm
25
25
src/raw/**/*.summary
26
+
src/raw/<package>/**/*.java # Only for APK files (replaces the .c/.asm/.summary tree)
26
27
include/*.h
27
28
include/*.types.h
28
29
data/*.bin
29
30
data/variables.json
30
31
data/variables_interesting.json
32
+
data/apk/<apk>/** # Only for APK files: every non-code APK entry, verbatim
33
+
data/res/<apk>/**/*.xml # Only for APK files: binary XML resources decoded to text
34
+
data/resources.json # Only for APK files: decoded resources.arsc
35
+
lib/<abi>/*.so # Only for APK files: extracted native libraries
36
+
native/<abi>/<lib>/ # Only for APK files: full nested ToCode export per .so
37
+
AndroidManifest.xml # Only for APK files
38
+
manifest.json # Only for APK files
39
+
classes.json # Only for APK files
40
+
package-graph.json # Only for APK files (replaces cluster-graph.json)
41
+
native-libs.json # Only for APK files
31
42
function-index.json
32
43
functions.json
33
44
types.json
@@ -47,11 +58,19 @@ sample_decompiler/
47
58
| Path | Description |
48
59
| --- | --- |
49
60
|`src/raw`| Decompiled C-like output, assembly, and summaries. Grouped by call-graph cluster, or by the original source file/directory when the binary has debug info (DWARF). |
50
-
|`include`| Generated headers, including `*.types.h` with the structs/enums/typedefs recovered from the binary. |
61
+
|`src/raw/<package>/**/*.java`|**Only for APK files.** Decompiled Java (ASC + androguard DAD), one file per class, folders follow Java packages; inner classes are `Outer$Inner.java`. No clustering, no `.summary` files. |
62
+
|`include`| Generated headers, including `*.types.h` with the structs/enums/typedefs recovered from the binary. Not written for APK files. |
51
63
|`data`| Raw section dumps and variable metadata. |
64
+
|`data/apk`, `data/res`, `data/resources.json`|**Only for APK files.** Every non-code entry of each APK in the set verbatim, `res/**/*.xml` decoded from binary XML, and the decoded `resources.arsc` tables. |
65
+
|`lib/<abi>/*.so`|**Only for APK files.** Every native library found in the APK set (all ABIs), always extracted. |
66
+
|`native/<abi>/<lib>/`|**Only for APK files.** A complete nested ToCode export for each native library (own `AGENTS.md` with an Origin section naming the APK, `src/raw/*.c`, `functions.json`, `exports.json`, ...). Skipped with `--no-native`. |
67
+
|`AndroidManifest.xml` / `manifest.json`|**Only for APK files.** Decoded manifest and its parsed form: package, versions, SDKs, permissions, components with intent filters and exported state, application attributes, split manifests. |
68
+
|`classes.json`|**Only for APK files.** Every class with superclass, interfaces, access flags, fields, methods, source file, and Java file/line ranges. |
69
+
|`package-graph.json`|**Only for APK files.** Inter-package call graph (the APK counterpart of `cluster-graph.json`). |
70
+
|`native-libs.json`|**Only for APK files.** ABI, hash, source APK, export directory, and decompilation status of every native library. |
52
71
|`types.json`| Catalog of types recovered from the binary's debug info or type library, with C declarations. |
53
-
|`*.json`| Functions (with recovered types and original source decl file/line), sections, strings, imports, exports, relocations, reachability, clusters, triage, project metadata, and export manifest. |
54
-
|`tocode.log`| Export log with checkpoint, resume, and per-function render history. |
72
+
|`*.json`| Functions (with recovered types and original source decl file/line), sections, strings, imports, exports, relocations, reachability, clusters, triage, project metadata, and export manifest. For APK files the same documents describe DEX methods, strings, framework imports, exported components/JNI methods, and reachability from manifest components; `relocations.json`, `cluster-graph.json`, and `types.json` are not written. |
73
+
|`tocode.log`| Export log with checkpoint, resume, and per-function render history. For APK files it also carries the native library export status. |
55
74
|`AGENTS.md` / `CLAUDE.md`| Instructions for agents analyzing the exported binary. |
56
75
|`src/tree`| Optional scanner-friendly C output when `--tree` is used. |
57
76
@@ -76,6 +95,23 @@ Three backends are supported, selected with `--backend` (default `auto`, which p
76
95
77
96
Other disassemblers may be added in the future.
78
97
98
+
### Android APKs
99
+
100
+
`tocode app.apk` (also `.apks`/`.xapk` bundles) uses [ASC](https://github.com/MG1937/ASC) (`droidasc`, a core dependency) for the DEX side and the regular native backends for every shared object in the package:
101
+
102
+
-`src/raw/<package>/<Class>.java`: one decompiled Java file per class, folders follow Java packages (no clustering, no summaries).
103
+
-`AndroidManifest.xml` + `manifest.json`: decoded and parsed manifest (permissions, components with intent filters and exported state, application attributes, split manifests).
-`lib/<abi>/*.so`: every native library extracted; `native/<abi>/<lib>/`: a complete nested ToCode export per library (all ABIs), produced on a background thread while the DEX side decompiles. `native-libs.json` records the status of each (each library runs in its own process; one failing or being OOM-killed never fails the APK export, and the native thread waits for `TOCODE_APK_NATIVE_MIN_FREE_MB`, default 1024 MB, of free memory before each library). Pass `--no-native` to skip the native decompilation (libraries are still extracted). `--backend` picks the native backend (`auto`/`ida`/`r2`/`angr`; `binja` is not supported for APKs).
106
+
-`data/apk/**`: every other APK entry verbatim; `data/res/**/*.xml` and `data/resources.json`: decoded binary XML and `resources.arsc`.
107
+
108
+
`base.apk` automatically merges sibling `split_*.apk` files (config and ABI splits) into the same project; `--no-splits` exports it alone. The default output directory is `<manifest package>_decompiler`.
0 commit comments