Reverse-engineered, source-level Android Studio / Gradle project for the
DamnWrapper32_ARMv7+1.apk wrapper (com.damnwrapper32armv7.xaview).
The Java side was reconstructed from the original APK with
jadx and patched until it compiles with the
Android Gradle Plugin. The native logic lives in
app/src/main/jniLibs/armeabi-v7a/libDamnWrapper32.so and is shipped as-is (closed-source prebuilt binary).
Russian version: README.ru.md.
./gradlew :app:assembleDebugand:app:assembleReleasesucceed.- CI (
build-apk) produces signed APKs as workflow artifacts on every push / PR. - Built APK file list matches the original APK 1-to-1 modulo:
- the standard Gradle/AGP packaging (multi-dex
classes.dex+classes2.dex, Gradle build metadata, fresh signature), - the resource qualifier
mipmap-xxxhdpi-v4/ic_launcher.png(vs. the originalmipmap-xxxhdpi/ic_launcher.png); AGP adds the-v4qualifier when targeting any version ≥ Android 4.
- the standard Gradle/AGP packaging (multi-dex
| Field | Value |
|---|---|
applicationId |
com.damnwrapper32armv7.xaview |
versionCode / versionName |
1 / 1.0 |
minSdk / targetSdk / compileSdk |
21 / 28 / 34 |
| ABI | armeabi-v7a only |
| AGP / Gradle / JDK | 8.5.0 / 8.7 / 17 |
| Main activity | com.damnwrapper32armv7.xaview.MainActivity |
Native entrypoints in libDamnWrapper32.so |
Java_..._initWrapper, onSurfaceCreated, onSurfaceChanged, onTouchEventNative, onSensorChangedNative, onVideoFinishedNative |
app/
build.gradle.kts # Android module config (AGP 8.5)
src/main/
AndroidManifest.xml
java/com/damnwrapper32armv7/xaview/
MainActivity.java # main Activity (~2680 lines)
AppInfo.java # POJO describing an IPA / installed iOS app
BplistParser.java # minimal binary plist (Info.plist) parser
MainActivity$$ExternalSyntheticLambda30.java # D8-synthetic lambda class
res/ # Decoded resources (strings, launcher icon)
assets/ # Roboto font + default wallpaper
jniLibs/armeabi-v7a/ # Prebuilt libDamnWrapper32.so
build.gradle.kts # Root Gradle config
settings.gradle.kts
gradle/wrapper/ # Gradle 8.7 wrapper
gradlew, gradlew.bat
.github/workflows/build.yml # CI build + signed APK artifact
native-decompiled/ # Ghidra pseudo-C of libDamnWrapper32.so (read-only)
The original APK ships 3 classes in its single classes.dex (~75 KB), so this Gradle
project does too — the entire codebase is exactly the files listed below. The bulk of the
UI logic lives inside MainActivity as anonymous View.OnClickListener / Runnable /
adapter inner classes (this is how it was written in the original APK).
| File | Notes |
|---|---|
MainActivity.java |
Main Activity. Owns the SurfaceView, sensors, audio, IPA scanner, settings UI, log viewer, video player, and all the wrapper plumbing. Native methods (initWrapper, onSurfaceCreated, onSurfaceChanged, onTouchEventNative, onSensorChangedNative, onVideoFinishedNative) bridge to libDamnWrapper32.so. Inner classes AppsAdapter and FallbackWallpaperView are kept here because they reference outer state. |
AppInfo.java |
POJO with the metadata of an IPA / installed iOS app (bundleId, name, version, iconPath, deviceFamily, minOS, targetOS, internalName, appDirPath). Originally an inner static class of MainActivity. |
BplistParser.java |
Reads enough of Apple's binary property list format (bplist00) to pull metadata out of an Info.plist. Falls back to a coarse XML scan for non-binary plists. Originally an inner static class of MainActivity. |
MainActivity$$ExternalSyntheticLambda30.java |
Lambda class generated by the D8 compiler for the scanAndUnpackApps Runnable passed to Handler.post. Re-shipped verbatim. The rest of D8's synthetic lambdas are regenerated from MainActivity's code by the build. |
The R class is not committed — AGP generates R.java from app/src/main/res/ on every build. After running ./gradlew :app:assembleDebug you can find it at
app/build/generated/source/r/release/com/damnwrapper32armv7/xaview/R.java.
Requirements:
- JDK 17 (e.g.
openjdk-17-jdk-headless) - Android SDK with
platforms;android-34andbuild-tools;34.0.0installed - The
ANDROID_HOME(orANDROID_SDK_ROOT) environment variable pointing at the SDK, or alocal.propertiesfile in the repo root containingsdk.dir=/absolute/path/to/Android/Sdk
Then:
./gradlew :app:assembleDebug
# APK: app/build/outputs/apk/debug/app-debug.apkFor a release build (debug-signed by default — see app/build.gradle.kts):
./gradlew :app:assembleRelease
# APK: app/build/outputs/apk/release/app-release.apkInstall with:
adb install -r app/build/outputs/apk/debug/app-debug.apkEvery push to main and every pull request runs
build-apk on GitHub Actions and uploads:
DamnWrapper32-debug—app-debug.apkDamnWrapper32-release—app-release.apk
Download from the workflow run summary on GitHub.
This is the whole point of the project: you can now edit Java directly and rebuild a working APK.
- Java code — edit
app/src/main/java/com/damnwrapper32armv7/xaview/MainActivity.java(or add new classes alongside). Note the JADX-reconstructed source has a few patched spots — search for the stringjadxin the file to find them. They are best-effort reconstructions of code that jadx could not decompile cleanly. - Resources —
app/src/main/res/values/strings.xml,mipmap-xxxhdpi/ic_launcher.png, etc. Add new layouts / drawables under the usual Android Studio paths. - Assets — drop files into
app/src/main/assets/. - Native code —
libDamnWrapper32.sois a prebuilt binary; replaceapp/src/main/jniLibs/armeabi-v7a/libDamnWrapper32.soto update it. Thenative-decompiled/directory contains a Ghidra-decompiled pseudo-C view of every function in the library (5,681 of 5,685 functions, ~10 MB of C text split into 4 files by symbol category). This is read-only reference material for reverse engineering — not a compilable C source tree. Seenative-decompiled/README.mdfor the file layout and limitations. - Permissions / manifest —
app/src/main/AndroidManifest.xml.
After any change run ./gradlew :app:assembleDebug to produce a new APK.
Search MainActivity.java for the keyword jadx to find every spot where the
decompiled source was patched. As of the initial commit:
onCreate— JADX collapsedint 1andboolean trueinto a single??variable. Each usage site now uses the appropriate literal directly.peekIpaInfo— added an explicitreturn null;at the end of a fall-through catch block.scanAndUnpackApps— fixed afinal File filereassignment, removed a no-opfile5 = file10;assignment, and reconstructed the inner icon-lookup loop (jadx had emitted an empty body).unzipWithProgressandm19lambda$27$...— replaced two brokenif (0 == 0) throw th;rethrow patterns withthrow new RuntimeException(th);so the public methods don't need to declarethrows IOException.BplistParser.parse— defaultedlength/bArrto0/new byte[0]so the bytes-read-failed fallback path compiles.
This repository contains code reconstructed from a third-party APK provided by
the project owner, for personal study and rebuild experimentation. All rights
to the original native binary (libDamnWrapper32.so), assets, and any other
non-reconstructable components remain with their respective authors.