// frida -U com.xxx.package -l FridaAndroidSelfVomitCrypt.js
// frida -U com.wepie.snake --load FridaAndroidSelfVomitCrypt.js --output frida_out.log
//{
//javax.crypto.Cipher
// * Constant used to initialize cipher to encryption mode.
// public static final int ENCRYPT_MODE = 1;
// * Constant used to initialize cipher to decryption mode.
// public static final int DECRYPT_MODE = 2;
// * Constant used to initialize cipher to key-wrapping mode.
// public static final int WRAP_MODE = 3;
// * Constant used to initialize cipher to key-unwrapping mode.
// public static final int UNWRAP_MODE = 4;
class javax_crypto_Cipher{
}
//}
class StackUtil{
}
/**
* @param {String} name
*/
function showStacks(name="") {
StackUtil.print_stack(name);
}
// class BytesToX {
/**
*
* @param {Boolean} _raw
* @param {Boolean} _toString
* @param {Boolean} _toHex
* @param {Boolean} _toBase64
* @param {Boolean} _toHex
*/
function BytesToX(_raw=false,_toString=false,_toHex=false,_toBase64=false) {
this._raw = _raw;
this._toString = _toString;
this._toHex = _toHex;
this._toBase64 = _toBase64;
}
BytesToX.prototype.toString = function dogToString() {
return ` BytesToX:( _raw:${this._raw} , _toString:${this._toString } , _toHex:${this._toHex } , _toBase64:${this._toBase64} ) . `;
}
// }
const _BytesToRawStringHex=new BytesToX(/* _raw= */true,/* _toString= */true,/* _toHex= */true);
const _BytesToRaw=new BytesToX(/* _raw= */true);
const _BytesToString=new BytesToX(/* _toString= */true);
const _BytesToStringHex=new BytesToX(/* _raw= */false,/* _toString= */true,/* _toHex= */true,/* _toBase64= */false);
//TODO t
// console.log(`debug____BytesToRawStringHex:${_BytesToRawStringHex.toString()}`);
// console.log(`debug_____BytesToRaw:${_BytesToRaw.toString()}`);
// console.log(`debug_____BytesToString:${_BytesToString.toString()}`);
// console.log(`debug_____BytesToStringHex:${_BytesToStringHex.toString()}`);
// class Param {
/**
*
* @param {String} param_name
* @param {ArrayBuffer} param_value
* @param {BytesToX} bytesToX
*/
function Param(param_name,param_value,bytesToX=_BytesToStringHex) {
this.param_name = param_name;
this.param_value = param_value;
this.bytesToX=bytesToX;
// console.log(`debug_____Param_new:${param_name} ${param_value} ${bytesToX.toString()}`);
}
Param.prototype.toString = function dogToString() {
return ` Param:( param_name:${this.param_name} , param_value:${this.param_value } , bytesToX:${this.bytesToX.toString() } ) . `;
}
// }
/**
*
* @param {String} param_name
* @param {ArrayBuffer} param_value
*/
function NewParam(param_name,param_value){
var p = new Param(param_name,param_value);
// console.log(`NewParam___:${p}`);
return p;
}
/**
*
* @param {String} param_name
* @param {ArrayBuffer} param_value
*/
function NewParam_BytesToRawStringHex(param_name,param_value){
var p= new Param(param_name,param_value,_BytesToRawStringHex);
// console.log(`NewParam_BytesToRawStringHex___:${p}`);
return p;
}
/**
*
* @param {String} param_name
* @param {ArrayBuffer} param_value
*/
function NewParam_BytesToRaw(param_name,param_value){
var p= new Param(param_name,param_value,_BytesToRaw);
// console.log(`NewParam_BytesToRaw___:${p}`);
return p;
}
/**
*
* @param {String} param_name
* @param {ArrayBuffer} param_value
*/
function NewParam_BytesToString(param_name,param_value){
var p= new Param(param_name,param_value,_BytesToString);
// console.log(`NewParam_BytesToString___:${p}`);
return p;
}
/**
*
* @param {String} param_name
* @param {ArrayBuffer} param_value
*/
function NewParam_BytesToStringHex(param_name,param_value){
var p= new Param(param_name,param_value,_BytesToStringHex);
// console.log(`NewParam_BytesToStringHex___:${p}`);
return p;
}
/**
*
* @param {String} clazz
* @param {...Param} param_ls
* @returns {String} log
*/
function generate_log(clazz,...param_ls){
var log_message=`clazz:${clazz};`;
// console.log(`param_ls____:${param_ls.length},${typeof(param_ls)},${typeof(param_ls[0])},${param_ls[0][1].toString()} `)
for (var param of param_ls[0]) {
// console.log(`param____:${param.toString()}`)
if (!param.param_value){
continue;
}
if (param.bytesToX._raw){
log_message+=`${param.param_name}.raw:${param.param_value}~`;
}
if (param.bytesToX._toString){
log_message+=`${param.param_name}.str:${bytesToString(param.param_value)}~`;
}
if (param.bytesToX._toHex){
log_message+=`${param.param_name}.hex:${bytesToHex(param.param_value)}~`;
}
log_message+=";"
}
return log_message;
}
/**
* @param {String} clazz
* @param {...Param} param_ls
*/
function print_generated_log(clazz,...param_ls){
console.log(
generate_log(clazz,param_ls)
);
}
Java.perform(function () {
{
const clazz='javax.crypto.spec.SecretKeySpec';
var SecretKeySpec = Java.use(clazz);
// public SecretKeySpec(byte[] key, String algorithm) {}
SecretKeySpec.$init.overload('[B', 'java.lang.String').implementation = function (security_key, algorithm) {
showStacks(SecretKeySpec.class.getCanonicalName());
var result = this.$init(security_key, algorithm);
print_generated_log(clazz,
NewParam("security_key",security_key),
NewParam_BytesToRaw("algorithm",algorithm),
NewParam_BytesToRaw("return_value",result) ) ;
return result;
}
}
{
const clazz='javax.crypto.spec.DESKeySpec';
var DESKeySpec = Java.use(clazz);
// public DESKeySpec(byte[] key) throws InvalidKeyException
DESKeySpec.$init.overload('[B').implementation = function (security_key) {
showStacks(DESKeySpec.class.getCanonicalName());
var result = this.$init(security_key);
print_generated_log(clazz,
NewParam_BytesToString("security_key",security_key),
NewParam("return_value",result) ) ;
return result;
}
// public DESKeySpec(byte[] key, int offset) throws InvalidKeyException
DESKeySpec.$init.overload('[B', 'int').implementation = function (security_key, offset) {
showStacks(DESKeySpec.class.getCanonicalName());
var result = this.$init(security_key, offset);
print_generated_log(clazz,
NewParam("security_key",security_key),
NewParam("offset",offset),
NewParam("return_value",result) ) ;
return result;
}
}
{
const clazz='javax.crypto.Mac';
var Mac = Java.use(clazz);
// public static final Mac getInstance(String algorithm)
Mac.getInstance.overload('java.lang.String').implementation = function (algorithm) {
showStacks(Mac.class.getCanonicalName());
var result = this.getInstance(algorithm);
print_generated_log(clazz,
NewParam_BytesToString("algorithm",algorithm),
NewParam("return_value",result) ) ;
return result;
}
// public final void update(byte[] input) throws IllegalStateException
Mac.update.overload('[B').implementation = function (input) {
showStacks(Mac.class.getCanonicalName());
this.update(input);
print_generated_log(clazz,
NewParam_BytesToString("input",input) ) ;
}
// public final void update(byte[] input, int offset, int len)
Mac.update.overload('[B', 'int', 'int').implementation = function (input, offset, len) {
showStacks(Mac.class.getCanonicalName());
this.update(input, offset, len)
print_generated_log(clazz,
NewParam("input",input),
NewParam("offset",offset),
NewParam("len",len),
NewParam("return_value",result) ) ;
}
// public final byte[] doFinal() throws IllegalStateException
Mac.doFinal.overload().implementation = function () {
showStacks(Mac.class.getCanonicalName());
var result = this.doFinal();
print_generated_log(clazz,
NewParam("return_value",result) ) ;
return result;
}
// public final byte[] doFinal(byte[] input) throws IllegalStateException
Mac.doFinal.overload('[B').implementation = function (input) {
showStacks(Mac.class.getCanonicalName());
var result = this.doFinal(input);
print_generated_log(clazz,
NewParam("input",input),
NewParam("return_value",result) ) ;
return result;
}
}
{
const clazz='java.security.MessageDigest';
var MessageDigest = Java.use(clazz);
// public static MessageDigest getInstance(String algorithm, String provider)
MessageDigest.getInstance.overload('java.lang.String', 'java.lang.String').implementation = function (algorithm, provider) {
showStacks(MessageDigest.class.getCanonicalName());
var return_value=this.getInstance(algorithm, provider);
print_generated_log(clazz,
NewParam("algorithm",algorithm),
NewParam("provider",provider),
NewParam("return_value",return_value) ) ;
return return_value;
}
// public static MessageDigest getInstance(String algorithm)
MessageDigest.getInstance.overload('java.lang.String').implementation = function (algorithm) {
showStacks(MessageDigest.class.getCanonicalName());
var return_value= this.getInstance(algorithm);
print_generated_log(clazz,
NewParam("algorithm",algorithm),
NewParam("return_value",return_value) ) ;
return return_value;
}
// public void update(byte[] input)
MessageDigest.update.overload('[B').implementation = function (input) {
showStacks(MessageDigest.class.getCanonicalName());
this.update(input);
print_generated_log(clazz,
NewParam("input",input)
) ;
return ;
}
// public void update(byte[] input, int offset, int len)
MessageDigest.update.overload('[B', 'int', 'int').implementation = function (input, offset, len) {
showStacks(MessageDigest.class.getCanonicalName());
this.update(input, offset, len)
print_generated_log(clazz,
NewParam("input",input),
NewParam("offset",offset),
NewParam("len",len)
) ;
return ;
}
// public byte[] digest()
MessageDigest.digest.overload().implementation = function () {
showStacks(MessageDigest.class.getCanonicalName());
var return_value = this.digest();
print_generated_log(clazz,
NewParam("return_value",return_value)
) ;
return return_value;
}
// public byte[] digest(byte[] input)
MessageDigest.digest.overload('[B').implementation = function (input) {
showStacks(MessageDigest.class.getCanonicalName());
var return_value = this.digest(input);
print_generated_log(clazz,
NewParam("input",input),
NewParam("return_value",return_value)
) ;
return return_value;
}
}
{
const clazz='javax.crypto.spec.IvParameterSpec';
var IvParameterSpec = Java.use(clazz);
// public IvParameterSpec(byte[] initialization_vector)
IvParameterSpec.$init.overload('[B').implementation = function (initialization_vector) {
showStacks(IvParameterSpec.class.getCanonicalName());
var return_value = this.$init(initialization_vector);
print_generated_log(clazz,
NewParam("initialization_vector",initialization_vector),
NewParam("return_value",return_value)
) ;
return return_value;
}
}
{
const clazz='javax.crypto.Cipher';
var Cipher = Java.use(clazz);
//javax.crypto.Cipher: public static final Cipher getInstance(String transformation) throws NoSuchAlgorithmException, NoSuchPaddingException
Cipher.getInstance.overload('java.lang.String').implementation = function (transformation) {
showStacks(Cipher.class.getCanonicalName());
var return_value = this.getInstance(transformation);
print_generated_log(clazz,
NewParam("transformation",transformation),
NewParam("return_value",return_value)
) ;
return return_value;
}
//javax.crypto.Cipher: public final void init(int operation_mode, Key security_key) throws InvalidKeyException
Cipher.init.overload('int', 'java.security.Key').implementation = function (operation_mode, security_key) {
showStacks(Cipher.class.getCanonicalName());
var return_value = this.init(operation_mode, security_key);
var mode_name=javax_crypto_Cipher.get_mode_name(operation_mode);
//java.security.Key: public byte[] getEncoded()
var security_key_encoded = security_key.getEncoded();
print_generated_log(clazz,
NewParam("mode_name",mode_name),
NewParam("security_key_encoded",security_key_encoded),
NewParam("return_value",return_value)
) ;
return return_value;
}
//javax.crypto.Cipher: public final void init(int operation_mode, Certificate certificate) throws InvalidKeyException
Cipher.init.overload('int', 'java.security.cert.Certificate').implementation = function (operation_mode, certificate) {
showStacks(Cipher.class.getCanonicalName());
var return_value = this.init(operation_mode, certificate);
var mode_name=javax_crypto_Cipher.get_mode_name(operation_mode);
//java.security.cert.Certificate: public abstract byte[] getEncoded() throws CertificateEncodingException;
var certificate_encoded=certificate.getEncoded();
print_generated_log(clazz,
NewParam("mode_name",mode_name),
NewParam("certificate_encoded",certificate_encoded),
NewParam("return_value",return_value)
) ;
return return_value;
}
// public final void init(int operation_mode, Key key, AlgorithmParameterSpec algorithmParameterSpec) throws InvalidKeyException, InvalidAlgorithmParameterException
Cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function (operation_mode, security_key, algorithmParameterSpec) {
showStacks(Cipher.class.getCanonicalName());
var return_value = this.init(operation_mode, security_key, algorithmParameterSpec);
var mode_name=javax_crypto_Cipher.get_mode_name(operation_mode);
var security_key_encoded = security_key.getEncoded();
print_generated_log(clazz,
NewParam("mode_name",mode_name),
NewParam("security_key_encoded",security_key_encoded),
NewParam("return_value",return_value)
) ;
return return_value;
}
// public final void init(int operation_mode, Certificate certificate, SecureRandom secureRandom) throws InvalidKeyException
Cipher.init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom').implementation = function (operation_mode, certificate, secureRandom) {
showStacks(Cipher.class.getCanonicalName());
var return_value = this.init(operation_mode, certificate, secureRandom);
//忽略secureRandom(对secureRandom操作对加解密会影响?)
var mode_name=javax_crypto_Cipher.get_mode_name(operation_mode);
//java.security.cert.Certificate: public abstract byte[] getEncoded() throws CertificateEncodingException;
var certificate_encoded=certificate.getEncoded();
print_generated_log(clazz,
NewParam("mode_name",mode_name),
NewParam("certificate_encoded",certificate_encoded),
NewParam("return_value",return_value)
) ;
return return_value;
}
// public final void init(int operation_mode, Key security_key, SecureRandom secureRandom) throws InvalidKeyException
Cipher.init.overload('int', 'java.security.Key', 'java.security.SecureRandom').implementation = function (operation_mode, security_key, secureRandom) {
showStacks(Cipher.class.getCanonicalName());
var return_value = this.init(operation_mode, security_key, secureRandom);
var mode_name=javax_crypto_Cipher.get_mode_name(operation_mode);
var security_key_encoded = security_key.getEncoded();
print_generated_log(clazz,
NewParam("mode_name",mode_name),
NewParam("security_key_encoded",security_key_encoded),
NewParam("return_value",return_value)
) ;
return return_value;
}
// public final void init(int operation_mode, Key security_key, AlgorithmParameters algorithmParameters) throws InvalidKeyException, InvalidAlgorithmParameterException
Cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters').implementation = function (operation_mode, security_key, algorithmParameters) {
showStacks(Cipher.class.getCanonicalName());
var return_value = this.init(operation_mode, security_key, algorithmParameters);
var security_key_encoded = security_key.getEncoded();
var algorithmParametersToString=algorithmParameters.toString();
print_generated_log(clazz,
NewParam("mode_name",mode_name),
NewParam("security_key_encoded",security_key_encoded),
NewParam("algorithmParametersToString",algorithmParametersToString),
NewParam("return_value",return_value)
) ;
return return_value;
}
// public final void init(int operation_mode, Key security_key, AlgorithmParameters algorithmParameters,SecureRandom secureRandom) throws InvalidKeyException, InvalidAlgorithmParameterException
Cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function (operation_mode, security_key, algorithmParameters, secureRandom) {
showStacks(Cipher.class.getCanonicalName());
var return_value = this.init(operation_mode, security_key, algorithmParameters, secureRandom);
var security_key_encoded = security_key.getEncoded();
var algorithmParametersToString=algorithmParameters.toString();
print_generated_log(clazz,
NewParam("mode_name",mode_name),
NewParam("security_key_encoded",security_key_encoded),
NewParam("algorithmParametersToString",algorithmParametersToString),
NewParam("return_value",return_value)
) ;
return return_value;
}
// public final void init(int operation_mode, Key security_key, AlgorithmParameterSpec algorithmParameterSpec,SecureRandom secureRandom) throws InvalidKeyException, InvalidAlgorithmParameterException
Cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom').implementation = function (operation_mode, security_key, algorithmParameterSpec, secureRandom) {
showStacks(Cipher.class.getCanonicalName());
var return_value = this.update(operation_mode, security_key, algorithmParameters, secureRandom);
var security_key_encoded = security_key.getEncoded();
var algorithmParametersToString=algorithmParameters.toString();
print_generated_log(clazz,
NewParam("mode_name",mode_name),
NewParam("security_key_encoded",security_key_encoded),
NewParam("algorithmParametersToString",algorithmParametersToString),
NewParam("return_value",return_value)
) ;
return return_value;
}
// public final byte[] update(byte[] input)
Cipher.update.overload('[B').implementation = function (input) {
showStacks(Cipher.class.getCanonicalName());
var return_value = this.update(input);
print_generated_log(clazz,
NewParam("input",input),
NewParam("return_value",return_value)
) ;
return return_value;
}
// public final byte[] update(byte[] input, int inputOffset, int inputLen)
Cipher.update.overload('[B', 'int', 'int').implementation = function (input, inputOffset, inputLen) {
showStacks(Cipher.class.getCanonicalName());
var return_value = this.update(input, inputOffset, inputLen);
print_generated_log(clazz,
NewParam("input",input),
NewParam("inputOffset",inputOffset),
NewParam("inputLen",inputLen),
NewParam("return_value",return_value)
) ;
return return_value;
}
// public final byte[] doFinal() throws IllegalBlockSizeException, BadPaddingException
Cipher.doFinal.overload().implementation = function () {
showStacks(Cipher.class.getCanonicalName());
var return_value = this.doFinal();
print_generated_log(clazz,
NewParam("return_value",return_value)
) ;
return return_value;
}
// public final byte[] doFinal(byte[] input) throws IllegalBlockSizeException, BadPaddingException
Cipher.doFinal.overload('[B').implementation = function (input) {
showStacks(Cipher.class.getCanonicalName());
var return_value = this.doFinal(input);
print_generated_log(clazz,
NewParam("input",input),
NewParam("return_value",return_value)
) ;
//TODO bytesToBase64(return_value)
return return_value;
}
}
{
const clazz='java.security.spec.X509EncodedKeySpec';
var X509EncodedKeySpec = Java.use(clazz);
// public X509EncodedKeySpec(byte[] encoded_key)
X509EncodedKeySpec.$init.overload('[B').implementation = function (encoded_key) {
showStacks(X509EncodedKeySpec.class.getCanonicalName());
var return_value = this.$init(encoded_key);
print_generated_log(clazz,
NewParam("encoded_key",encoded_key),
NewParam("return_value",return_value)
) ;
//TODO bytesToBase64(return_value)
return return_value;
}
}
{
const clazz='java.security.spec.RSAPublicKeySpec';
var RSAPublicKeySpec = Java.use(clazz);
// public RSAPublicKeySpec(BigInteger modulus, BigInteger public_exponent)
RSAPublicKeySpec.$init.overload('java.math.BigInteger', 'java.math.BigInteger').implementation = function (modulus, public_exponent) {
showStacks(RSAPublicKeySpec.class.getCanonicalName());
var return_value = this.$init(modulus, public_exponent);
//TODO bytesToBase64(modulus)
print_generated_log(clazz,
NewParam("modulus",modulus),
NewParam("public_exponent",public_exponent),
NewParam("return_value",return_value)
) ;
return return_value;
}
}
{
const clazz='java.security.KeyPairGenerator';
var KeyPairGenerator = Java.use(clazz);
// public KeyPair generateKeyPair()
KeyPairGenerator.generateKeyPair.implementation = function ()
{
showStacks(KeyPairGenerator.class.getCanonicalName());
var return_value = this.generateKeyPair();
var private_key = return_value.getPrivate().getEncoded();
var public_key = return_value.getPublic().getEncoded();
//change to bytesToHex(private_key) bytesToHex(public_key)
print_generated_log(clazz,
NewParam("private_key",private_key),
NewParam("public_key",public_key),
NewParam("return_value",return_value)
) ;
return return_value;
}
// public final KeyPair genKeyPair()
KeyPairGenerator.genKeyPair.implementation = function ()
{
showStacks(KeyPairGenerator.class.getCanonicalName());
var return_value = this.genKeyPair();
var private_key = return_value.getPrivate().getEncoded();
var public_key = return_value.getPublic().getEncoded();
//TODO bytesToHex(private_key) bytesToHex(public_key)
print_generated_log(clazz,
NewParam("private_key",private_key),
NewParam("public_key",public_key),
NewParam("return_value",return_value)
) ;
return return_value;
}
}
});
frida android hook java层 加解密自吐(仅供学习使用,请遵纪守法)
于 2021-04-06 14:24:31 首次发布