3.8 KiB
Android protection removal
One pipeline removes AnoSDK (overseas) or Mobile ACE/TSS (CN); the
variants differ only in the constants in protection/profile.rs, and
--variant auto picks one from the libraries present. It restores four
protected ARM64 libraries, neutralizes the SDK startup and native API
calls, drops the protection libraries, and signs a new APK.
Variant profiles
| Field | AnoSDK | Mobile ACE/TSS |
|---|---|---|
| Regions | SEA, GLB, JP, KR, TW | CN |
| Decoder library | libanort.so |
libtprt.so |
| Guard library | libanogs.so |
libtersafe2.so |
| Key record XOR | 0xDF |
0x49 |
| Decoder symbol | g_acf_array |
g_tprt_pfn_array |
Application class |
com.ano.gshell.AnoApplication |
com.ace.gshell.AceApplication |
| SDK class | com.gamesafe.ano.AnoSdk |
com.tencent.tp.TssSdk |
| Native APIs | 6 AnoSDK* |
5 tp2_* |
Identification (protection/mod.rs)
Checks ChannelConfig (ChannelName/BundleIdentifier) against the
variant's regions, confirms both protection libraries are ARM64 ELFs, and
rejects APKs that also contain the other variant's libraries. ARM64 is
the only supported ABI.
Restore (protection/loader.rs)
permutationfollows the decoder symbol through its routine and GOT reference to the eight-page permutation (a digit string permuting0..8).- Each 48-byte protected-section descriptor is matched to an ELF section
by name, RVA, file offset and size. The Base64 key record at descriptor
table
+0x1A4is XORed with the variant byte: magic0x20240829, key id 1 drives restoration, and the mode at+0x184(1 or 2) selects page treatment. Each restored section must match its recorded CRC-32.- Large sections: AES-128-CBC over
0x4000bytes in0x800-byte chunks from0x2000 - (RVA & 0xFFF)(key: the value's repeated lowercase hex; IV0x02..0x11, reset per chunk). Mode 1 XORs and shuffles0x4000fragments across eight0x10000strides; mode 2 XORs the remainder. - Small sections: whole-section XOR.
- Large sections: AES-128-CBC over
BBMG311DIS12IMPgives the protected import count (+16),.rela.pltRVA (+24), entry count (+28) and excluded GOT slots (+32/+36); selected importr_infovalues are rotated back into order.BBMG311ENC12IAIgives the constructor array RVA (+16) and count (+20). The wrapperDT_INIT, the decoder library'sDT_NEEDEDentry and the APS2/RELA wrapper relocations are cleared, and thefread/fwrite/fcloseGOT imports are restored. The removedDT_INITRVA is passed to the API helper.
Neutralize (protection/native.rs)
In restored libil2cpp.so, finds the SDK API names and the guard library
name in .rodata, traces ADRP/ADD references to them, and redirects each
resolver BL to a 16-byte helper written over the removed DT_INIT
initializer. The helper returns a pointer to a function that returns
zero; other P/Invoke resolutions are untouched. Aborts if the initializer
is still active, an API is missing, or the call graph is ambiguous.
DEX edits (protection/dex.rs)
Three methods are edited after each call is validated:
| Method | Edit |
|---|---|
Application.<clinit> |
NOP both native library loads (20 bytes) |
Application.attachBaseContext |
Replace the invoke + move-result after the superclass call with return/NOPs (8 bytes) |
SDK class <clinit> |
NOP the guard library load (const-string 10 bytes, or const-string/jumbo 12 bytes); keep the return |
All 8 attachBaseContext bytes are rewritten because leftover operand
words after the return would still fail DEX verification. Checksums are
recomputed.
Output
The decoder and guard libraries are dropped; the restored libraries and
edited DEX files are repacked and signed by android::sign. Any
mismatched marker, CRC, method or resolver layout aborts the patch.