An ATAK plugin that loads locally-built plugins on official ATAK releases, bypassing TAK's signature verification. Designed to eliminate the multi-day signing pipeline wait during plugin development.
Official ATAK verifies plugin signatures before loading them. Plugins not signed by the TAK pipeline are rejected. Gadget bypasses this with a JNI-based ART method hook:
- Gadget is signed through the TAK pipeline and loads normally on official ATAK
- On first plugin load, it loads
libhooker.sowhich patchesAtakPluginRegistry.verifySignatureandverifyTrustat the ART method level — replacing their entry points with a trivialreturn true - Then calls
AtakPluginRegistry.loadPlugin()— ATAK handles all classloader setup, ProGuard name resolution, shared library loaders, and resource contexts - The loaded plugin runs with full ATAK access, identical to a pipeline-signed plugin
Official ATAK obfuscates SDK class names (e.g. IServiceController becomes gov.tak.api.plugin.a). Locally-built plugins must use the same obfuscated names, or ATAK can't resolve them.
Download mapping.zip from the Releases page. It contains mapping.txt files for each ATAK version. Copy the one matching your ATAK version into your SDK root:
# Example for ATAK 5.7.0
cp mapping-5.7.0.txt /path/to/ATAK-CIV-5.7.0.0-SDK/mapping.txtThe SDK's build system (-applymapping <atak.proguard.mapping>) picks this up automatically. All subsequent ./gradlew assembleCivRelease builds will produce correctly obfuscated bytecode.
Download the signed Gadget APK for your ATAK version from Releases and install it:
adb install gadget-5.7.0-signed.apkBuild your plugin locally and install it on the device:
cd /path/to/your-plugin
./gradlew assembleCivRelease
adb install app/build/outputs/apk/civ/release/*.apkATAK will discover the plugin but refuse to load it (signature mismatch). Gadget picks up the difference.
- Open ATAK
- Load the Gadget plugin from the plugin manager
- Tap the Gadget toolbar icon (open padlock)
- You'll see a list of installed-but-unloaded plugins
- Tap Load on any plugin
- Green dot = loaded and running
- Tap Unload to stop it
| Element | Meaning |
|---|---|
| Red dot | Not loaded |
| Yellow dot | Loading |
| Green dot | Loaded and running |
| LOAD | Load the plugin |
| UNLOAD | Stop the plugin |
| RETRY | Shown after a failed attempt |
Once set up, the development cycle is:
- Edit plugin code
./gradlew assembleCivReleaseadb install app/build/outputs/apk/civ/release/*.apk- Tap Load in Gadget
No pipeline submission, no signing wait.
The JNI hooker (hooker.c) performs ART method replacement:
- Gets
jmethodIDforverifySignatureandverifyTrust— on ART,jmethodIDIS theArtMethod*pointer - Detects
ArtMethodstruct size by comparing pointers of two consecutive methods (alwaysTrue1,alwaysTrue2) - Copies
data_andentry_point_from_quick_compiled_code_(offset 16+) fromalwaysTrue1to each target method - Preserves
declaring_class_andaccess_flags_(offset 0-15) so ART's method resolution still works
alwaysTrue1 is a trivial Java method (return true) whose bytecode (const/4 v0, 1; return v0) needs zero DEX constant pool resolution — safe to run in any DEX context.
After hooking, AtakPluginRegistry.loadPlugin() is called. ATAK handles everything: classloader creation with shared library loaders, ProGuard-obfuscated class resolution, resource contexts, native library loading, and plugin lifecycle management.
cp template.local.properties local.properties
# Edit local.properties: sdk.dir=/path/to/android/sdk
./gradlew assembleCivReleaseThe APK will be at app/build/outputs/apk/civ/release/ATAK-Plugin-gadget-*.apk. This SDK-signed build works on the SDK developer build of ATAK. For official ATAK, submit the source to the TAK signing pipeline.
app/src/main/
java/.../plugin/
Gadget.java # Plugin discovery, UI, hook loading, loadPlugin
PluginNativeLoader.java # Native library loader utility
cpp/
hooker.c # ART method replacement (verifySignature/verifyTrust)
CMakeLists.txt # Native build config
res/
layout/
main_layout.xml # Plugin list pane
plugin_row.xml # Card per plugin
drawable/
ic_launcher.xml # Open padlock icon
assets/
plugin.xml # ATAK plugin descriptor
- Plugins must be installed as Android packages (
adb install, file manager, etc.) - The ProGuard mapping must match the ATAK version on the device — a 5.7.0 mapping won't work with ATAK 5.6.0
- Gadget must be signed through the TAK pipeline for each ATAK version you target
- The ART method hook assumes a 32-byte
ArtMethodstruct withdata_at offset 16 andentry_pointat offset 24 (ARM64, Android 12+). Other architectures or future ART changes may require adjustment
See license/ in the ATAK SDK.