SoftCloak
The goal of this repository is to try and make reverse engineering more difficult. Currently only focused on APK files but will eventually move on to IPA files, binaries, firmware, and other software.
SoftCloak replaces text inside an APK, then signs the rebuilt package. Substring matches are swapped for one generated token of the same length. Exact matches are swapped for text you choose. The APK is signed with a new JAR v1 signature and an APK v2 signature.
Same-length replacements keep the DEX, manifest, and resource table aligned, so the file can still be installed.
Install
pip install softcloak
That install is enough to replace strings and sign the APK. SoftCloak creates the signing key itself and writes a JAR v1 signature plus an APK v2 signature. A JDK and the Android SDK are not required.
If softcloak is not found after that, the scripts directory is not on PATH. Use python -m softcloak in the examples below.
Command line
Generate a token for every occurrence of a substring:
python -m softcloak app.apk -o rebuilt.apk --contains com.example --contains CompanyName
Replace one exact string with your own text. The new text has to be the same length:
python -m softcloak app.apk -o rebuilt.apk --exact "Old full sentence" "New full sentence"
Both can be combined. Exact replacements run first, then substring tokens. The command prints each mapping and checks the signature before it finishes.
python -m softcloak app.apk -o rebuilt.apk --dry-run --contains CompanyName
python -m softcloak app.apk -o rebuilt.apk --exact "abcdef" "xy" --fit pad
--fit pad fills a shorter exact replacement. --fit clip cuts a longer one and pads a shorter one. The default is to stop when the lengths differ.
--contains replaces that text wherever it sits inside a longer string, in every file, in both UTF-8 and UTF-16. A dotted name also rewrites the DEX form with slashes, so com.example changes Lcom/example/... as well. An exact replacement does the same, and keeps the separator you would expect: com.example to org.example also rewrites com/example to org/example. Matching is case-sensitive. Pass AppName and appname separately. Patterns shorter than 4 characters are allowed, but they can hit unrelated bytes, and SoftCloak prints a warning.
Image, audio, font, and native-library files are copied into the output unchanged. If a search string still occurs inside one of them, SoftCloak prints a warning and does not edit those bytes. A stored native library is repacked so its bytes start on a 16384-byte boundary, which covers 4 KB and 16 KB memory pages. Signature files are removed and replaced by the new signature. Other META-INF files are kept and edited.
SoftCloak generates an RSA key and a self-signed certificate with subject CN=SoftCloak, then signs the APK with it. The default alias is repack. The zip writer uses the classic zip format, so an archive over 4 GB or with more than 65535 entries is out of scope.
Python
Skip the command line and call the same operation from a script:
from softcloak import rewrite_apk
result = rewrite_apk(
"app.apk",
"rebuilt.apk",
contains=["com.example", "CompanyName"],
exact=[("Old full sentence", "New full sentence")],
)
for rule in result.rules:
utf8_count, utf16_count = result.counts[rule.old]
print(f"{rule.old} -> {rule.new} utf8={utf8_count} utf16={utf16_count}")
print(result.output)
Preview the mapping without writing a file:
result = rewrite_apk(
"app.apk",
"rebuilt.apk",
contains=["CompanyName"],
dry_run=True,
)
result.counts maps each original string to (utf8_matches, utf16_matches). result.warnings lists matches that were left unchanged. result.output is the signed APK, or None when dry_run is true.
Other arguments match the command line: seed, fit ("error", "pad", or "clip"), pad_char, and allow_missing. Omit keystore and SoftCloak creates the key.
Development
From a checkout of this repository:
pip install -e ".[dev]"
The dev extra installs Ruff. The test suite runs ruff check and ruff format --check.
What can break the app
SoftCloak changes only the text you pass in. A same-length rename of your own package or class name can still install and run, because the manifest and classes.dex are updated together.
The app can crash or fail a lookup when a replacement has to match something that was not changed:
- Framework names such as
androidorjavaappear inside system class names. Replacing them makes those calls invalid. A short warning exists for patterns under 4 characters, and it does not stop the run.androidis long enough to pass through with no warning. - Resource paths, such as
res/layout/..., must match the file names in the APK. SoftCloak does not rename those files. - Native libraries are left unchanged. If code now looks up a new name and the library still has the old one, that call fails.
- Intent actions, content-provider authorities, and server URLs fail when only one side of the match is replaced.
- The rebuilt APK is signed with a new certificate. Android will not install it over a copy signed by the previous certificate. Uninstall the old copy first.
Metadata
Release files for softcloak 2.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| softcloak-2.0.1.tar.gz | 19.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| softcloak-2.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 35.1 kB
Release files / softcloak-2.0.1.tar.gz
| Download URL | softcloak-2.0.1.tar.gz |
|---|---|
| Size | 19.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
04b8f2b7f38fcd22e6e8366b309230b9c1ecd80870d61ff5ab7fb907c05a2b33
|
|
BLAKE2b-256 checksum How to use checksums |
5df9e3f171122140bf95e0c9a792e13697bff17a6bc086565a33083d2a12d918
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / softcloak-2.0.1-py3-none-any.whl
| Download URL | softcloak-2.0.1-py3-none-any.whl |
|---|---|
| Size | 15.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1e59492992500457bc837cd6648f259cda7122a47ab5cfe84752931a84f6b433
|
|
BLAKE2b-256 checksum How to use checksums |
61daa5e72a7bf9c999375d6fb79d33aaa607bab2f9d51975c2b8ad44b8f7a793
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency log