Comments (4)
AssetCryptImpl.java
has changed. Here are the new relevant bits:
public class AssetCryptImpl implements AssetCrypt {
private static final String BIN_EXT = ".bin";
private static final Collection<String> assets = new ArrayList(Arrays.asList(new String[]{"Resources/source1.js", "Resources/source2.js", "etc."}));
private static byte[] salt = new byte[]{(byte) -39, (byte) -51, (byte) 24, (byte) 15, (byte) 102, (byte) 98, (byte) 103, (byte) 67, (byte) -4, (byte) 45, (byte) 24, (byte) -41, (byte) -88, (byte) -54, (byte) 116, (byte) 101};
private static InputStream getAssetStream(String str) {
if (!assets.contains(str)) {
return null;
}
if (!str.endsWith(BIN_EXT)) {
str = str + BIN_EXT;
}
try {
Cipher instance = Cipher.getInstance("AES/CBC/PKCS5Padding");
instance.init(2, new SecretKeySpec(Binding.getKey(salt), "AES"), new IvParameterSpec(salt));
return new CipherInputStream(KrollAssetHelper.getAssetManager().open(str), instance);
} catch (Exception e) {
Log.e(TAG, "Could not decrypt '" + str + "'");
Log.e(TAG, e.toString());
return null;
}
}
}
Here are the things to note:
- Encrypted resources (including the JavaScript code) are declared in the
assets
collection. The encrypted filenames are calculated by appending theBIN_EXT
value to the entries. - Assets are encrypted with
AES/CBC/PKCS5Padding
, using a key provided by the native "cloak" library and an IV generated with a hardcoded salt.
To obtain the encryption key, I first attempted analysing the native library. Unfortunately, my assembly skills were not good enough to decode the key generation code.
Instead, the Java Binding.getKey
can be intercepted. Using apktool, I decompiled the app, and found the following in AssetCryptImpl.smali
:
sget-object v4, Lorg/kosher/app/AssetCryptImpl;->salt:[B
invoke-static {v4}, Lti/cloak/Binding;->getKey([B)[B
move-result-object v4
This is the part of bytecode that obtains the key from the native library and stores it in a register (v4
). To obtain this key, I added the following code directly after it:
invoke-static {v4}, Ljava/util/Arrays;->toString([B)Ljava/lang/String; # Convert the key to a string
move-result-object v5 # Save the string in register v5
invoke-static {v5, v5}, Landroid/util/Log;->wtf(Ljava/lang/String;Ljava/lang/String;)I # Log the key in the logcat WTF channel
This prints the key to log cat's WTF channel. The key is used as the tag because no other registers are free at this time to store a tag in.
Once the key is obtained, decrypting the resources is a trivial matter:
for file in $(find . -name '*.bin')
do
openssl enc -d -aes-128-cbc -K <KEY_HEX> -iv <SALT_HEX> -in "$file" -out "${file//.bin}"
done
I hope this helps!
from ti_recover.
@hacker1024 I reverse engineered libti.cloak.so (android) and ti.cloak-linux-x64.node (pc bindings)
bindings.js (https://github.com/tidev/titanium_mobile/blob/master/support/ti.cloak.zip) contains this function
/**
* Synchrounously set key in platform 'ti.cloak' libraries for functioning runtime decryption.
*
* @param {string} platform Platform of libraries to process.
* @param {string[]} archs Array for architectures supported by the platform.
* @param {string} destination Destination for processed libraries to be stored.
*/
setKeySync(platform, archs, destination) {
if (platform === 'android') {
for (const arch of archs) {
// Load stub library into buffer and set key, throws exception upon failure.
const buffer = _fsExtra.default.readFileSync(_path.default.join(__dirname, 'android', arch, 'libti.cloak.so'));
Binding.setKey(buffer, this.key, this.salt); // Write buffer to target destination.
const target = _path.default.join(destination, arch, 'libti.cloak.so');
_fsExtra.default.ensureDirSync(_path.default.dirname(target));
_fsExtra.default.writeFileSync(target, buffer);
}
}
}
which writes a fixed block of 64 bytes in all libti.cloak.so files on each compile:
the block contains a xor key (combine with the salt to get the AES key) and is split in 4 parts:
... putting it all together:
const salt = Buffer.from('ddce8e80f1cf129a63224e719496d4dd', 'hex'); // from your AssetCryptImpl
const lib = fs.readFileSync('./lib/arm64-v8a/libti.cloak.so'); // extracted from your apk
const baseOffset = 0x2008;
const randomOffset = lib.readUint8(baseOffset + 0x3e);
const xor = Buffer.concat([
lib.subarray(baseOffset + 1, baseOffset + 5),
lib.subarray(baseOffset + randomOffset, baseOffset + randomOffset + 4),
lib.subarray(baseOffset + 0xf, baseOffset + 0xf + 4),
lib.subarray(baseOffset + 0x1e, baseOffset + 0x1e + 4),
]);
const key = salt.map((byte, i) => byte ^ xor[i]).toString('hex');
console.log(key);
from ti_recover.
Sorry can't help you, but my APK also had two classes.dex files, but ti_recover worked flawlessly on it so I don't think that is your problem
from ti_recover.
Are you sure @weltmeyer that the APK was made with Appcelerator Titanium ? Do you know the versión ? It's being already 4 years since I made this app, so maybe it doesn't work with the newest versions de Titanium.
from ti_recover.
Related Issues (12)
- -bash: ti_recover: command not found HOT 9
- Unpacking zip failed HOT 1
- Writting command - No Error? HOT 1
- All good except my controllers HOT 3
- Add java/node requirements in the readme HOT 2
- HELP HOT 1
- Error during installation or run HOT 2
- No output
- Installation issue on apk_unpack
- I have generated a similarity of the environment you describe in Docker HOT 2
- Output and maximum call stack problem
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ti_recover.