Frida Android

Frid'Android

Par Tristan SALAÜN

Les origines

Le début
BarbHack
27 Août - 21h00-22h00
How to create your ultimate osint tool!

Barb'Hack 2022 logo

Qui je suis ?

  • Android expert/formateur
  • Light4Events
  • Hackeur/bricoleur
  • HIP
  • STid

Frida c'est quoi ?

Frida logo

By https://frida.re/

Mise en place de frida.
https://frida.re/docs/android/

Téléphone rooté, simulateur

Android root logo

C'est plus facile.
Sinon Frida Gadget, on repackage l'application.

Frida serveur

Sur le téléphone, install et lancer

Frida client

Sur le pc

Choix de l'application

Choose application to target

Choix du script à lancer

Choose script to launch

Sélection de scripts sur CodeShare

Codeshare logo

https://codeshare.frida.re/

Mise en place d'un proxy
si besoin

Proxy

Automatisation du process

Améliorations au niveau des scripts

Création de mes propres scripts à la main pour commencer (Bluetooth).
Write code

Image by DC Studio on Freepik

Partir de la documentation :
https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner#summary

Pour arriver à un script utilisable :
https://github.com/Tristus1er/FridaScripts/blob/main/ble_log.js

Automatisation du process

Application Android pour faire de la reflexion des API standards (Chiffrement, Signature, Hash, ...) Android Application
A partir d'une API standard, utiliser la reflexion ...

val myClassKClass: KClass<Cipher> = javax.crypto.Cipher::class
					
Android frida reflexion
Pour obtenir un script frida de hooking/log :

/*  Android TODO: Describe
	by Tristan SALAUN

	Run with:
	frida -U -f [APP_ID] -l NAME_OF_THE_SCRIPT.js --no-pause
*/

 function toHexString(byteArray) {
	return '[0x' + Array.from(byteArray, function(byte) {
		return ('0' + (byte & 0xFF).toString(16)).slice(-2);
	}).join(' 0x') + ']'
}
function toAsciiString(byteArray) {
	return Array.from(byteArray, function(byte) {
		return String.fromCharCode(byte);
	}).join('')
}

  Java.perform(function() {
      console.log('');
      console.log('======');
      console.log('[#] Hook of javax.crypto.Cipher [#]');
      console.log('======');
      // **************************************************
      // ----- Constructor -----
      try {
          Java.use('javax.crypto.Cipher').$init.overload('javax.crypto.CipherSpi', 'java.security.Provider', 'java.lang.String').implementation = function(arg0, arg1, arg2) {
              console.log("javax.crypto.Cipher.constructor (0)");
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              return this.$init.apply(this, arguments);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.Constructor pinner (0) not found');
          console.log(err);
      }
      // ----- Constructor -----
      try {
          Java.use('javax.crypto.Cipher').$init.overload('javax.crypto.CipherSpi', 'java.security.Provider', 'java.lang.String', 'kotlin.Array<(out) kotlin.String!>').implementation = function(arg0, arg1, arg2, arg3) {
              console.log("javax.crypto.Cipher.constructor (1)");
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              console.log("arg3: " + arg3);
              return this.$init.apply(this, arguments);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.Constructor pinner (1) not found');
          console.log(err);
      }




      // ----- checkCipherState -----
      try {
          Java.use('javax.crypto.Cipher').checkCipherState.overload().implementation = function() {
              console.log("javax.crypto.Cipher.checkCipherState" + this);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.checkCipherState pinner not found');
          console.log(err);
      }

      // ----- chooseProvider -----
      try {
          Java.use('javax.crypto.Cipher').chooseProvider.overload('javax.crypto.Cipher.InitType', 'int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function(arg0, arg1, arg2, arg3, arg4, arg5) {
              console.log("javax.crypto.Cipher.chooseProvider" + this);
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              console.log("arg3: " + arg3);
              console.log("arg4: " + arg4);
              console.log("arg5: " + arg5);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.chooseProvider pinner not found');
          console.log(err);
      }

      // ----- getAlgorithmParameterSpec -----
      try {
          Java.use('javax.crypto.Cipher').getAlgorithmParameterSpec.overload('java.security.AlgorithmParameters').implementation = function(arg0) {
              console.log("javax.crypto.Cipher.getAlgorithmParameterSpec" + this);
              console.log("arg0: " + arg0);
              // Return type: java.security.spec.AlgorithmParameterSpec!
              const returnValue = this.getAlgorithmParameterSpec.apply(this, arguments);
              console.log('Cipher.getAlgorithmParameterSpec return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getAlgorithmParameterSpec pinner not found');
          console.log(err);
      }

      // ----- doFinal -----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload('java.nio.ByteBuffer', 'java.nio.ByteBuffer').implementation = function(arg0, arg1) {
              console.log("javax.crypto.Cipher.doFinal" + this);
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
              // Return type: kotlin.Int
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner not found');
          console.log(err);
      }

      // ----- doFinal (1)-----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload('[B', 'int').implementation = function(arg0, arg1) {
              console.log("javax.crypto.Cipher.doFinal (1)" + this);
              console.log("arg0: " + toHexString(arg0) + " | " + toAsciiString(arg0));
              console.log("arg1: " + arg1);
              // Return type: kotlin.Int
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal (1) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner (1) not found');
          console.log(err);
      }

      // ----- doFinal (2)-----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload('[B', 'int', 'int', '[B').implementation = function(arg0, arg1, arg2, arg3) {
              console.log("javax.crypto.Cipher.doFinal (2)" + this);
              console.log("arg0: " + toHexString(arg0) + " | " + toAsciiString(arg0));
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              console.log("arg3: " + toHexString(arg3) + " | " + toAsciiString(arg3));
              // Return type: kotlin.Int
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal (2) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner (2) not found');
          console.log(err);
      }

      // ----- doFinal (3)-----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload('[B', 'int', 'int', '[B', 'int').implementation = function(arg0, arg1, arg2, arg3, arg4) {
              console.log("javax.crypto.Cipher.doFinal (3)" + this);
              console.log("arg0: " + toHexString(arg0) + " | " + toAsciiString(arg0));
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              console.log("arg3: " + toHexString(arg3) + " | " + toAsciiString(arg3));
              console.log("arg4: " + arg4);
              // Return type: kotlin.Int
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal (3) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner (3) not found');
          console.log(err);
      }

      // ----- doFinal (4)-----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload().implementation = function() {
              console.log("javax.crypto.Cipher.doFinal (4)" + this);
              // Return type: kotlin.ByteArray!
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal (4) return value: ' + toHexString(returnValue) + " | " + toAsciiString(returnValue));
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner (4) not found');
          console.log(err);
      }

      // ----- doFinal (5)-----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload('[B').implementation = function(arg0) {
              console.log("javax.crypto.Cipher.doFinal (5)" + this);
              console.log("arg0: " + toHexString(arg0) + " | " + toAsciiString(arg0));
              // Return type: kotlin.ByteArray!
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal (5) return value: ' + toHexString(returnValue) + " | " + toAsciiString(returnValue));
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner (5) not found');
          console.log(err);
      }

      // ----- doFinal (6)-----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload('[B', 'int', 'int').implementation = function(arg0, arg1, arg2) {
              console.log("javax.crypto.Cipher.doFinal (6)" + this);
              console.log("arg0: " + toHexString(arg0) + " | " + toAsciiString(arg0));
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              // Return type: kotlin.ByteArray!
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal (6) return value: ' + toHexString(returnValue) + " | " + toAsciiString(returnValue));
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner (6) not found');
          console.log(err);
      }

      // ----- getAlgorithm -----
      try {
          Java.use('javax.crypto.Cipher').getAlgorithm.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getAlgorithm" + this);
              // Return type: kotlin.String!
              const returnValue = this.getAlgorithm.apply(this, arguments);
              console.log('Cipher.getAlgorithm return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getAlgorithm pinner not found');
          console.log(err);
      }

      // ----- getBlockSize -----
      try {
          Java.use('javax.crypto.Cipher').getBlockSize.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getBlockSize" + this);
              // Return type: kotlin.Int
              const returnValue = this.getBlockSize.apply(this, arguments);
              console.log('Cipher.getBlockSize return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getBlockSize pinner not found');
          console.log(err);
      }

      // ----- getCurrentSpi -----
      try {
          Java.use('javax.crypto.Cipher').getCurrentSpi.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getCurrentSpi" + this);
              // Return type: javax.crypto.CipherSpi!
              const returnValue = this.getCurrentSpi.apply(this, arguments);
              console.log('Cipher.getCurrentSpi return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getCurrentSpi pinner not found');
          console.log(err);
      }

      // ----- getExemptionMechanism -----
      try {
          Java.use('javax.crypto.Cipher').getExemptionMechanism.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getExemptionMechanism" + this);
              // Return type: javax.crypto.ExemptionMechanism!
              const returnValue = this.getExemptionMechanism.apply(this, arguments);
              console.log('Cipher.getExemptionMechanism return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getExemptionMechanism pinner not found');
          console.log(err);
      }

      // ----- getIV -----
      try {
          Java.use('javax.crypto.Cipher').getIV.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getIV" + this);
              // Return type: kotlin.ByteArray!
              const returnValue = this.getIV.apply(this, arguments);
              console.log('Cipher.getIV return value: ' + toHexString(returnValue) + " | " + toAsciiString(returnValue));
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getIV pinner not found');
          console.log(err);
      }

      // ----- getOutputSize -----
      try {
          Java.use('javax.crypto.Cipher').getOutputSize.overload('int').implementation = function(arg0) {
              console.log("javax.crypto.Cipher.getOutputSize" + this);
              console.log("arg0: " + arg0);
              // Return type: kotlin.Int
              const returnValue = this.getOutputSize.apply(this, arguments);
              console.log('Cipher.getOutputSize return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getOutputSize pinner not found');
          console.log(err);
      }

      // ----- getParameters -----
      try {
          Java.use('javax.crypto.Cipher').getParameters.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getParameters" + this);
              // Return type: java.security.AlgorithmParameters!
              const returnValue = this.getParameters.apply(this, arguments);
              console.log('Cipher.getParameters return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getParameters pinner not found');
          console.log(err);
      }

      // ----- getProvider -----
      try {
          Java.use('javax.crypto.Cipher').getProvider.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getProvider" + this);
              // Return type: java.security.Provider!
              const returnValue = this.getProvider.apply(this, arguments);
              console.log('Cipher.getProvider return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getProvider pinner not found');
          console.log(err);
      }

      // ----- init -----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.Key').implementation = function(arg0, arg1) {
              console.log("javax.crypto.Cipher.init" + this);
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner not found');
          console.log(err);
      }

      // ----- init (1)-----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters').implementation = function(arg0, arg1, arg2) {
              console.log("javax.crypto.Cipher.init (1)" + this);
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner (1) not found');
          console.log(err);
      }

      // ----- init (2)-----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function(arg0, arg1, arg2, arg3) {
              console.log("javax.crypto.Cipher.init (2)" + this);
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              console.log("arg3: " + arg3);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner (2) not found');
          console.log(err);
      }

      // ----- init (3)-----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.Key', 'java.security.SecureRandom').implementation = function(arg0, arg1, arg2) {
              console.log("javax.crypto.Cipher.init (3)" + this);
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner (3) not found');
          console.log(err);
      }

      // ----- init (4)-----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function(arg0, arg1, arg2) {
              console.log("javax.crypto.Cipher.init (4)" + this);
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner (4) not found');
          console.log(err);
      }

      // ----- init (5)-----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom').implementation = function(arg0, arg1, arg2, arg3) {
              console.log("javax.crypto.Cipher.init (5)" + this);
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              console.log("arg3: " + arg3);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner (5) not found');
          console.log(err);
      }

      // ----- init (6)-----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.cert.Certificate').implementation = function(arg0, arg1) {
              console.log("javax.crypto.Cipher.init (6)" + this);
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner (6) not found');
          console.log(err);
      }

      // ----- init (7)-----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom').implementation = function(arg0, arg1, arg2) {
              console.log("javax.crypto.Cipher.init (7)" + this);
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner (7) not found');
          console.log(err);
      }

      // ----- unwrap -----
      try {
          Java.use('javax.crypto.Cipher').unwrap.overload('[B', 'java.lang.String', 'int').implementation = function(arg0, arg1, arg2) {
              console.log("javax.crypto.Cipher.unwrap" + this);
              console.log("arg0: " + toHexString(arg0) + " | " + toAsciiString(arg0));
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              // Return type: java.security.Key!
              const returnValue = this.unwrap.apply(this, arguments);
              console.log('Cipher.unwrap return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.unwrap pinner not found');
          console.log(err);
      }

      // ----- update -----
      try {
          Java.use('javax.crypto.Cipher').update.overload('java.nio.ByteBuffer', 'java.nio.ByteBuffer').implementation = function(arg0, arg1) {
              console.log("javax.crypto.Cipher.update" + this);
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
              // Return type: kotlin.Int
              const returnValue = this.update.apply(this, arguments);
              console.log('Cipher.update return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.update pinner not found');
          console.log(err);
      }

      // ----- update (1)-----
      try {
          Java.use('javax.crypto.Cipher').update.overload('[B', 'int', 'int', '[B').implementation = function(arg0, arg1, arg2, arg3) {
              console.log("javax.crypto.Cipher.update (1)" + this);
              console.log("arg0: " + toHexString(arg0) + " | " + toAsciiString(arg0));
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              console.log("arg3: " + toHexString(arg3) + " | " + toAsciiString(arg3));
              // Return type: kotlin.Int
              const returnValue = this.update.apply(this, arguments);
              console.log('Cipher.update (1) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.update pinner (1) not found');
          console.log(err);
      }

      // ----- update (2)-----
      try {
          Java.use('javax.crypto.Cipher').update.overload('[B', 'int', 'int', '[B', 'int').implementation = function(arg0, arg1, arg2, arg3, arg4) {
              console.log("javax.crypto.Cipher.update (2)" + this);
              console.log("arg0: " + toHexString(arg0) + " | " + toAsciiString(arg0));
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              console.log("arg3: " + toHexString(arg3) + " | " + toAsciiString(arg3));
              console.log("arg4: " + arg4);
              // Return type: kotlin.Int
              const returnValue = this.update.apply(this, arguments);
              console.log('Cipher.update (2) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.update pinner (2) not found');
          console.log(err);
      }

      // ----- update (3)-----
      try {
          Java.use('javax.crypto.Cipher').update.overload('[B').implementation = function(arg0) {
              console.log("javax.crypto.Cipher.update (3)" + this);
              console.log("arg0: " + toHexString(arg0) + " | " + toAsciiString(arg0));
              // Return type: kotlin.ByteArray!
              const returnValue = this.update.apply(this, arguments);
              console.log('Cipher.update (3) return value: ' + toHexString(returnValue) + " | " + toAsciiString(returnValue));
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.update pinner (3) not found');
          console.log(err);
      }

      // ----- update (4)-----
      try {
          Java.use('javax.crypto.Cipher').update.overload('[B', 'int', 'int').implementation = function(arg0, arg1, arg2) {
              console.log("javax.crypto.Cipher.update (4)" + this);
              console.log("arg0: " + toHexString(arg0) + " | " + toAsciiString(arg0));
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              // Return type: kotlin.ByteArray!
              const returnValue = this.update.apply(this, arguments);
              console.log('Cipher.update (4) return value: ' + toHexString(returnValue) + " | " + toAsciiString(returnValue));
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.update pinner (4) not found');
          console.log(err);
      }

      // ----- updateAAD -----
      try {
          Java.use('javax.crypto.Cipher').updateAAD.overload('java.nio.ByteBuffer').implementation = function(arg0) {
              console.log("javax.crypto.Cipher.updateAAD" + this);
              console.log("arg0: " + arg0);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.updateAAD pinner not found');
          console.log(err);
      }

      // ----- updateAAD (1)-----
      try {
          Java.use('javax.crypto.Cipher').updateAAD.overload('[B').implementation = function(arg0) {
              console.log("javax.crypto.Cipher.updateAAD (1)" + this);
              console.log("arg0: " + toHexString(arg0) + " | " + toAsciiString(arg0));
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.updateAAD pinner (1) not found');
          console.log(err);
      }

      // ----- updateAAD (2)-----
      try {
          Java.use('javax.crypto.Cipher').updateAAD.overload('[B', 'int', 'int').implementation = function(arg0, arg1, arg2) {
              console.log("javax.crypto.Cipher.updateAAD (2)" + this);
              console.log("arg0: " + toHexString(arg0) + " | " + toAsciiString(arg0));
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.updateAAD pinner (2) not found');
          console.log(err);
      }

      // ----- updateProviderIfNeeded -----
      try {
          Java.use('javax.crypto.Cipher').updateProviderIfNeeded.overload().implementation = function() {
              console.log("javax.crypto.Cipher.updateProviderIfNeeded" + this);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.updateProviderIfNeeded pinner not found');
          console.log(err);
      }

      // ----- wrap -----
      try {
          Java.use('javax.crypto.Cipher').wrap.overload('java.security.Key').implementation = function(arg0) {
              console.log("javax.crypto.Cipher.wrap" + this);
              console.log("arg0: " + arg0);
              // Return type: kotlin.ByteArray!
              const returnValue = this.wrap.apply(this, arguments);
              console.log('Cipher.wrap return value: ' + toHexString(returnValue) + " | " + toAsciiString(returnValue));
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.wrap pinner not found');
          console.log(err);
      }

      // ----- checkOpmode -----
      try {
          Java.use('javax.crypto.Cipher').checkOpmode.overload().implementation = function() {
              console.log("javax.crypto.Cipher.checkOpmode" + this);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.checkOpmode pinner not found');
          console.log(err);
      }

      // ----- createCipher -----
      try {
          Java.use('javax.crypto.Cipher').createCipher.overload('java.security.Provider').implementation = function(arg1) {
              console.log("javax.crypto.Cipher.createCipher" + this);
              console.log("arg1: " + arg1);
              // Return type: javax.crypto.Cipher!
              const returnValue = this.createCipher.apply(this, arguments);
              console.log('Cipher.createCipher return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.createCipher pinner not found');
          console.log(err);
      }

      // ----- getInstance -----
      try {
          Java.use('javax.crypto.Cipher').getInstance.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getInstance" + this);
              // Return type: javax.crypto.Cipher!
              const returnValue = this.getInstance.apply(this, arguments);
              console.log('Cipher.getInstance return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getInstance pinner not found');
          console.log(err);
      }

      // ----- getInstance (1)-----
      try {
          Java.use('javax.crypto.Cipher').getInstance.overload('java.lang.String').implementation = function(arg1) {
              console.log("javax.crypto.Cipher.getInstance (1)" + this);
              console.log("arg1: " + arg1);
              // Return type: javax.crypto.Cipher!
              const returnValue = this.getInstance.apply(this, arguments);
              console.log('Cipher.getInstance (1) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getInstance pinner (1) not found');
          console.log(err);
      }

      // ----- getInstance (2)-----
      try {
          Java.use('javax.crypto.Cipher').getInstance.overload('java.security.Provider').implementation = function(arg1) {
              console.log("javax.crypto.Cipher.getInstance (2)" + this);
              console.log("arg1: " + arg1);
              // Return type: javax.crypto.Cipher!
              const returnValue = this.getInstance.apply(this, arguments);
              console.log('Cipher.getInstance (2) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getInstance pinner (2) not found');
          console.log(err);
      }

      // ----- getMaxAllowedKeyLength -----
      try {
          Java.use('javax.crypto.Cipher').getMaxAllowedKeyLength.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getMaxAllowedKeyLength" + this);
              // Return type: kotlin.Int
              const returnValue = this.getMaxAllowedKeyLength.apply(this, arguments);
              console.log('Cipher.getMaxAllowedKeyLength return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getMaxAllowedKeyLength pinner not found');
          console.log(err);
      }

      // ----- getMaxAllowedParameterSpec -----
      try {
          Java.use('javax.crypto.Cipher').getMaxAllowedParameterSpec.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getMaxAllowedParameterSpec" + this);
              // Return type: java.security.spec.AlgorithmParameterSpec!
              const returnValue = this.getMaxAllowedParameterSpec.apply(this, arguments);
              console.log('Cipher.getMaxAllowedParameterSpec return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getMaxAllowedParameterSpec pinner not found');
          console.log(err);
      }

      // ----- getOpmodeString -----
      try {
          Java.use('javax.crypto.Cipher').getOpmodeString.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getOpmodeString" + this);
              // Return type: kotlin.String!
              const returnValue = this.getOpmodeString.apply(this, arguments);
              console.log('Cipher.getOpmodeString return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getOpmodeString pinner not found');
          console.log(err);
      }

      // ----- matchAttribute -----
      try {
          Java.use('javax.crypto.Cipher').matchAttribute.overload('java.lang.String', 'java.lang.String').implementation = function(arg1, arg2) {
              console.log("javax.crypto.Cipher.matchAttribute" + this);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              // Return type: kotlin.Boolean
              const returnValue = this.matchAttribute.apply(this, arguments);
              console.log('Cipher.matchAttribute return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.matchAttribute pinner not found');
          console.log(err);
      }

      // ----- tokenizeTransformation -----
      try {
          Java.use('javax.crypto.Cipher').tokenizeTransformation.overload().implementation = function() {
              console.log("javax.crypto.Cipher.tokenizeTransformation" + this);
              // Return type: kotlin.Array<(out) kotlin.String!>!
              const returnValue = this.tokenizeTransformation.apply(this, arguments);
              console.log('Cipher.tokenizeTransformation return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.tokenizeTransformation pinner not found');
          console.log(err);
      }

      // ----- tryCombinations -----
      try {
          Java.use('javax.crypto.Cipher').tryCombinations.overload('java.security.Provider', 'kotlin.Array<(out) kotlin.String!>').implementation = function(arg1, arg2) {
              console.log("javax.crypto.Cipher.tryCombinations" + this);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              // Return type: javax.crypto.Cipher.CipherSpiAndProvider!
              const returnValue = this.tryCombinations.apply(this, arguments);
              console.log('Cipher.tryCombinations return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.tryCombinations pinner not found');
          console.log(err);
      }

      // ----- tryTransformWithProvider -----
      try {
          Java.use('javax.crypto.Cipher').tryTransformWithProvider.overload('kotlin.Array<(out) kotlin.String!>', 'javax.crypto.Cipher.NeedToSet', 'java.security.Provider.Service').implementation = function(arg1, arg2, arg3) {
              console.log("javax.crypto.Cipher.tryTransformWithProvider" + this);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              console.log("arg3: " + arg3);
              // Return type: javax.crypto.Cipher.CipherSpiAndProvider!
              const returnValue = this.tryTransformWithProvider.apply(this, arguments);
              console.log('Cipher.tryTransformWithProvider return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.tryTransformWithProvider pinner not found');
          console.log(err);
      }

  });
					

Focus sur une méthode


// ----- doFinal (3)-----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload('[B', 'int', 'int', '[B', 'int').implementation = function(arg0, arg1, arg2, arg3, arg4) {
              console.log("javax.crypto.Cipher.doFinal (3)" + this);
              console.log("arg0: " + toHexString(arg0) + " | " + toAsciiString(arg0));
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              console.log("arg3: " + toHexString(arg3) + " | " + toAsciiString(arg3));
              console.log("arg4: " + arg4);
              // Return type: kotlin.Int
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal (3) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner (3) not found');
          console.log(err);
      }

Génération plus propre

Donner un nom aux paramètres
La source de vérité : la documentation en ligne.

https://developer.android.com/reference
https://jsoup.org/

Pour obtenir un script frida de hooking/log :

/*  Android TODO: Describe
	by Tristan SALAUN

	Run with:
	frida -U -f [APP_ID] -l NAME_OF_THE_SCRIPT.js --no-pause
*/

 function toHexString(byteArray) {
	return '[0x' + Array.from(byteArray, function(byte) {
		return ('0' + (byte & 0xFF).toString(16)).slice(-2);
	}).join(' 0x') + ']'
}
function toAsciiString(byteArray) {
	return Array.from(byteArray, function(byte) {
		return String.fromCharCode(byte);
	}).join('')
}

  Java.perform(function() {
      console.log('');
      console.log('======');
      console.log('[#] Hook of javax.crypto.Cipher [#]');
      console.log('======');
      // **************************************************
      // ----- Constructor -----
      try {
          Java.use('javax.crypto.Cipher').$init.overload('javax.crypto.CipherSpi', 'java.security.Provider', 'java.lang.String').implementation = function(arg0, arg1, arg2) {
              console.log("javax.crypto.Cipher.constructor (0)");
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              return this.$init.apply(this, arguments);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.Constructor pinner (0) not found');
          console.log(err);
      }
      // ----- Constructor -----
      try {
          Java.use('javax.crypto.Cipher').$init.overload('javax.crypto.CipherSpi', 'java.security.Provider', 'java.lang.String', 'kotlin.Array<(out) kotlin.String!>').implementation = function(arg0, arg1, arg2, arg3) {
              console.log("javax.crypto.Cipher.constructor (1)");
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              console.log("arg3: " + arg3);
              return this.$init.apply(this, arguments);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.Constructor pinner (1) not found');
          console.log(err);
      }




      // ----- checkCipherState -----
      try {
          Java.use('javax.crypto.Cipher').checkCipherState.overload().implementation = function() {
              console.log("javax.crypto.Cipher.checkCipherState" + this);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.checkCipherState pinner not found');
          console.log(err);
      }

      // ----- chooseProvider -----
      try {
          Java.use('javax.crypto.Cipher').chooseProvider.overload('javax.crypto.Cipher.InitType', 'int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function(arg0, arg1, arg2, arg3, arg4, arg5) {
              console.log("javax.crypto.Cipher.chooseProvider" + this);
              console.log("arg0: " + arg0);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              console.log("arg3: " + arg3);
              console.log("arg4: " + arg4);
              console.log("arg5: " + arg5);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.chooseProvider pinner not found');
          console.log(err);
      }

      // ----- getAlgorithmParameterSpec -----
      try {
          Java.use('javax.crypto.Cipher').getAlgorithmParameterSpec.overload('java.security.AlgorithmParameters').implementation = function(arg0) {
              console.log("javax.crypto.Cipher.getAlgorithmParameterSpec" + this);
              console.log("arg0: " + arg0);
              // Return type: java.security.spec.AlgorithmParameterSpec!
              const returnValue = this.getAlgorithmParameterSpec.apply(this, arguments);
              console.log('Cipher.getAlgorithmParameterSpec return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getAlgorithmParameterSpec pinner not found');
          console.log(err);
      }

      // ----- doFinal -----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload('java.nio.ByteBuffer', 'java.nio.ByteBuffer').implementation = function(input, output) {
              console.log("javax.crypto.Cipher.doFinal" + this);
              console.log("input: " + input);
              console.log("output: " + output);
              // Return type: kotlin.Int
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner not found');
          console.log(err);
      }

      // ----- doFinal (1)-----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload('[B', 'int').implementation = function(output, outputOffset) {
              console.log("javax.crypto.Cipher.doFinal (1)" + this);
              console.log("output: " + toHexString(output) + " | " + toAsciiString(output));
              console.log("outputOffset: " + outputOffset);
              // Return type: kotlin.Int
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal (1) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner (1) not found');
          console.log(err);
      }

      // ----- doFinal (2)-----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload('[B', 'int', 'int', '[B').implementation = function(input, inputOffset, inputLen, output) {
              console.log("javax.crypto.Cipher.doFinal (2)" + this);
              console.log("input: " + toHexString(input) + " | " + toAsciiString(input));
              console.log("inputOffset: " + inputOffset);
              console.log("inputLen: " + inputLen);
              console.log("output: " + toHexString(output) + " | " + toAsciiString(output));
              // Return type: kotlin.Int
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal (2) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner (2) not found');
          console.log(err);
      }

      // ----- doFinal (3)-----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload('[B', 'int', 'int', '[B', 'int').implementation = function(input, inputOffset, inputLen, output, outputOffset) {
              console.log("javax.crypto.Cipher.doFinal (3)" + this);
              console.log("input: " + toHexString(input) + " | " + toAsciiString(input));
              console.log("inputOffset: " + inputOffset);
              console.log("inputLen: " + inputLen);
              console.log("output: " + toHexString(output) + " | " + toAsciiString(output));
              console.log("outputOffset: " + outputOffset);
              // Return type: kotlin.Int
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal (3) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner (3) not found');
          console.log(err);
      }

      // ----- doFinal (4)-----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload().implementation = function() {
              console.log("javax.crypto.Cipher.doFinal (4)" + this);
              // Return type: kotlin.ByteArray!
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal (4) return value: ' + toHexString(returnValue) + " | " + toAsciiString(returnValue));
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner (4) not found');
          console.log(err);
      }

      // ----- doFinal (5)-----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload('[B').implementation = function(input) {
              console.log("javax.crypto.Cipher.doFinal (5)" + this);
              console.log("input: " + toHexString(input) + " | " + toAsciiString(input));
              // Return type: kotlin.ByteArray!
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal (5) return value: ' + toHexString(returnValue) + " | " + toAsciiString(returnValue));
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner (5) not found');
          console.log(err);
      }

      // ----- doFinal (6)-----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload('[B', 'int', 'int').implementation = function(input, inputOffset, inputLen) {
              console.log("javax.crypto.Cipher.doFinal (6)" + this);
              console.log("input: " + toHexString(input) + " | " + toAsciiString(input));
              console.log("inputOffset: " + inputOffset);
              console.log("inputLen: " + inputLen);
              // Return type: kotlin.ByteArray!
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal (6) return value: ' + toHexString(returnValue) + " | " + toAsciiString(returnValue));
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner (6) not found');
          console.log(err);
      }

      // ----- getAlgorithm -----
      try {
          Java.use('javax.crypto.Cipher').getAlgorithm.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getAlgorithm" + this);
              // Return type: kotlin.String!
              const returnValue = this.getAlgorithm.apply(this, arguments);
              console.log('Cipher.getAlgorithm return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getAlgorithm pinner not found');
          console.log(err);
      }

      // ----- getBlockSize -----
      try {
          Java.use('javax.crypto.Cipher').getBlockSize.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getBlockSize" + this);
              // Return type: kotlin.Int
              const returnValue = this.getBlockSize.apply(this, arguments);
              console.log('Cipher.getBlockSize return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getBlockSize pinner not found');
          console.log(err);
      }

      // ----- getCurrentSpi -----
      try {
          Java.use('javax.crypto.Cipher').getCurrentSpi.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getCurrentSpi" + this);
              // Return type: javax.crypto.CipherSpi!
              const returnValue = this.getCurrentSpi.apply(this, arguments);
              console.log('Cipher.getCurrentSpi return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getCurrentSpi pinner not found');
          console.log(err);
      }

      // ----- getExemptionMechanism -----
      try {
          Java.use('javax.crypto.Cipher').getExemptionMechanism.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getExemptionMechanism" + this);
              // Return type: javax.crypto.ExemptionMechanism!
              const returnValue = this.getExemptionMechanism.apply(this, arguments);
              console.log('Cipher.getExemptionMechanism return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getExemptionMechanism pinner not found');
          console.log(err);
      }

      // ----- getIV -----
      try {
          Java.use('javax.crypto.Cipher').getIV.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getIV" + this);
              // Return type: kotlin.ByteArray!
              const returnValue = this.getIV.apply(this, arguments);
              console.log('Cipher.getIV return value: ' + toHexString(returnValue) + " | " + toAsciiString(returnValue));
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getIV pinner not found');
          console.log(err);
      }

      // ----- getOutputSize -----
      try {
          Java.use('javax.crypto.Cipher').getOutputSize.overload('int').implementation = function(inputLen) {
              console.log("javax.crypto.Cipher.getOutputSize" + this);
              console.log("inputLen: " + inputLen);
              // Return type: kotlin.Int
              const returnValue = this.getOutputSize.apply(this, arguments);
              console.log('Cipher.getOutputSize return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getOutputSize pinner not found');
          console.log(err);
      }

      // ----- getParameters -----
      try {
          Java.use('javax.crypto.Cipher').getParameters.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getParameters" + this);
              // Return type: java.security.AlgorithmParameters!
              const returnValue = this.getParameters.apply(this, arguments);
              console.log('Cipher.getParameters return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getParameters pinner not found');
          console.log(err);
      }

      // ----- getProvider -----
      try {
          Java.use('javax.crypto.Cipher').getProvider.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getProvider" + this);
              // Return type: java.security.Provider!
              const returnValue = this.getProvider.apply(this, arguments);
              console.log('Cipher.getProvider return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getProvider pinner not found');
          console.log(err);
      }

      // ----- init -----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.Key').implementation = function(opmode, key) {
              console.log("javax.crypto.Cipher.init" + this);
              console.log("opmode: " + opmode);
              console.log("key: " + key);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner not found');
          console.log(err);
      }

      // ----- init (1)-----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters').implementation = function(opmode, key, params) {
              console.log("javax.crypto.Cipher.init (1)" + this);
              console.log("opmode: " + opmode);
              console.log("key: " + key);
              console.log("params: " + params);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner (1) not found');
          console.log(err);
      }

      // ----- init (2)-----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function(opmode, key, params, random) {
              console.log("javax.crypto.Cipher.init (2)" + this);
              console.log("opmode: " + opmode);
              console.log("key: " + key);
              console.log("params: " + params);
              console.log("random: " + random);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner (2) not found');
          console.log(err);
      }

      // ----- init (3)-----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.Key', 'java.security.SecureRandom').implementation = function(opmode, key, random) {
              console.log("javax.crypto.Cipher.init (3)" + this);
              console.log("opmode: " + opmode);
              console.log("key: " + key);
              console.log("random: " + random);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner (3) not found');
          console.log(err);
      }

      // ----- init (4)-----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function(opmode, key, params) {
              console.log("javax.crypto.Cipher.init (4)" + this);
              console.log("opmode: " + opmode);
              console.log("key: " + key);
              console.log("params: " + params);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner (4) not found');
          console.log(err);
      }

      // ----- init (5)-----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom').implementation = function(opmode, key, params, random) {
              console.log("javax.crypto.Cipher.init (5)" + this);
              console.log("opmode: " + opmode);
              console.log("key: " + key);
              console.log("params: " + params);
              console.log("random: " + random);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner (5) not found');
          console.log(err);
      }

      // ----- init (6)-----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.cert.Certificate').implementation = function(opmode, certificate) {
              console.log("javax.crypto.Cipher.init (6)" + this);
              console.log("opmode: " + opmode);
              console.log("certificate: " + certificate);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner (6) not found');
          console.log(err);
      }

      // ----- init (7)-----
      try {
          Java.use('javax.crypto.Cipher').init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom').implementation = function(opmode, certificate, random) {
              console.log("javax.crypto.Cipher.init (7)" + this);
              console.log("opmode: " + opmode);
              console.log("certificate: " + certificate);
              console.log("random: " + random);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.init pinner (7) not found');
          console.log(err);
      }

      // ----- unwrap -----
      try {
          Java.use('javax.crypto.Cipher').unwrap.overload('[B', 'java.lang.String', 'int').implementation = function(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType) {
              console.log("javax.crypto.Cipher.unwrap" + this);
              console.log("wrappedKey: " + toHexString(wrappedKey) + " | " + toAsciiString(wrappedKey));
              console.log("wrappedKeyAlgorithm: " + wrappedKeyAlgorithm);
              console.log("wrappedKeyType: " + wrappedKeyType);
              // Return type: java.security.Key!
              const returnValue = this.unwrap.apply(this, arguments);
              console.log('Cipher.unwrap return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.unwrap pinner not found');
          console.log(err);
      }

      // ----- update -----
      try {
          Java.use('javax.crypto.Cipher').update.overload('java.nio.ByteBuffer', 'java.nio.ByteBuffer').implementation = function(input, output) {
              console.log("javax.crypto.Cipher.update" + this);
              console.log("input: " + input);
              console.log("output: " + output);
              // Return type: kotlin.Int
              const returnValue = this.update.apply(this, arguments);
              console.log('Cipher.update return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.update pinner not found');
          console.log(err);
      }

      // ----- update (1)-----
      try {
          Java.use('javax.crypto.Cipher').update.overload('[B', 'int', 'int', '[B').implementation = function(input, inputOffset, inputLen, output) {
              console.log("javax.crypto.Cipher.update (1)" + this);
              console.log("input: " + toHexString(input) + " | " + toAsciiString(input));
              console.log("inputOffset: " + inputOffset);
              console.log("inputLen: " + inputLen);
              console.log("output: " + toHexString(output) + " | " + toAsciiString(output));
              // Return type: kotlin.Int
              const returnValue = this.update.apply(this, arguments);
              console.log('Cipher.update (1) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.update pinner (1) not found');
          console.log(err);
      }

      // ----- update (2)-----
      try {
          Java.use('javax.crypto.Cipher').update.overload('[B', 'int', 'int', '[B', 'int').implementation = function(input, inputOffset, inputLen, output, outputOffset) {
              console.log("javax.crypto.Cipher.update (2)" + this);
              console.log("input: " + toHexString(input) + " | " + toAsciiString(input));
              console.log("inputOffset: " + inputOffset);
              console.log("inputLen: " + inputLen);
              console.log("output: " + toHexString(output) + " | " + toAsciiString(output));
              console.log("outputOffset: " + outputOffset);
              // Return type: kotlin.Int
              const returnValue = this.update.apply(this, arguments);
              console.log('Cipher.update (2) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.update pinner (2) not found');
          console.log(err);
      }

      // ----- update (3)-----
      try {
          Java.use('javax.crypto.Cipher').update.overload('[B').implementation = function(input) {
              console.log("javax.crypto.Cipher.update (3)" + this);
              console.log("input: " + toHexString(input) + " | " + toAsciiString(input));
              // Return type: kotlin.ByteArray!
              const returnValue = this.update.apply(this, arguments);
              console.log('Cipher.update (3) return value: ' + toHexString(returnValue) + " | " + toAsciiString(returnValue));
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.update pinner (3) not found');
          console.log(err);
      }

      // ----- update (4)-----
      try {
          Java.use('javax.crypto.Cipher').update.overload('[B', 'int', 'int').implementation = function(input, inputOffset, inputLen) {
              console.log("javax.crypto.Cipher.update (4)" + this);
              console.log("input: " + toHexString(input) + " | " + toAsciiString(input));
              console.log("inputOffset: " + inputOffset);
              console.log("inputLen: " + inputLen);
              // Return type: kotlin.ByteArray!
              const returnValue = this.update.apply(this, arguments);
              console.log('Cipher.update (4) return value: ' + toHexString(returnValue) + " | " + toAsciiString(returnValue));
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.update pinner (4) not found');
          console.log(err);
      }

      // ----- updateAAD -----
      try {
          Java.use('javax.crypto.Cipher').updateAAD.overload('java.nio.ByteBuffer').implementation = function(src) {
              console.log("javax.crypto.Cipher.updateAAD" + this);
              console.log("src: " + src);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.updateAAD pinner not found');
          console.log(err);
      }

      // ----- updateAAD (1)-----
      try {
          Java.use('javax.crypto.Cipher').updateAAD.overload('[B').implementation = function(src) {
              console.log("javax.crypto.Cipher.updateAAD (1)" + this);
              console.log("src: " + toHexString(src) + " | " + toAsciiString(src));
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.updateAAD pinner (1) not found');
          console.log(err);
      }

      // ----- updateAAD (2)-----
      try {
          Java.use('javax.crypto.Cipher').updateAAD.overload('[B', 'int', 'int').implementation = function(src, offset, len) {
              console.log("javax.crypto.Cipher.updateAAD (2)" + this);
              console.log("src: " + toHexString(src) + " | " + toAsciiString(src));
              console.log("offset: " + offset);
              console.log("len: " + len);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.updateAAD pinner (2) not found');
          console.log(err);
      }

      // ----- updateProviderIfNeeded -----
      try {
          Java.use('javax.crypto.Cipher').updateProviderIfNeeded.overload().implementation = function() {
              console.log("javax.crypto.Cipher.updateProviderIfNeeded" + this);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.updateProviderIfNeeded pinner not found');
          console.log(err);
      }

      // ----- wrap -----
      try {
          Java.use('javax.crypto.Cipher').wrap.overload('java.security.Key').implementation = function(key) {
              console.log("javax.crypto.Cipher.wrap" + this);
              console.log("key: " + key);
              // Return type: kotlin.ByteArray!
              const returnValue = this.wrap.apply(this, arguments);
              console.log('Cipher.wrap return value: ' + toHexString(returnValue) + " | " + toAsciiString(returnValue));
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.wrap pinner not found');
          console.log(err);
      }

      // ----- checkOpmode -----
      try {
          Java.use('javax.crypto.Cipher').checkOpmode.overload().implementation = function() {
              console.log("javax.crypto.Cipher.checkOpmode" + this);
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.checkOpmode pinner not found');
          console.log(err);
      }

      // ----- createCipher -----
      try {
          Java.use('javax.crypto.Cipher').createCipher.overload('java.security.Provider').implementation = function(arg1) {
              console.log("javax.crypto.Cipher.createCipher" + this);
              console.log("arg1: " + arg1);
              // Return type: javax.crypto.Cipher!
              const returnValue = this.createCipher.apply(this, arguments);
              console.log('Cipher.createCipher return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.createCipher pinner not found');
          console.log(err);
      }

      // ----- getInstance -----
      try {
          Java.use('javax.crypto.Cipher').getInstance.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getInstance" + this);
              // Return type: javax.crypto.Cipher!
              const returnValue = this.getInstance.apply(this, arguments);
              console.log('Cipher.getInstance return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getInstance pinner not found');
          console.log(err);
      }

      // ----- getInstance (1)-----
      try {
          Java.use('javax.crypto.Cipher').getInstance.overload('java.lang.String').implementation = function(transformation) {
              console.log("javax.crypto.Cipher.getInstance (1)" + this);
              console.log("transformation: " + transformation);
              // Return type: javax.crypto.Cipher!
              const returnValue = this.getInstance.apply(this, arguments);
              console.log('Cipher.getInstance (1) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getInstance pinner (1) not found');
          console.log(err);
      }

      // ----- getInstance (2)-----
      try {
          Java.use('javax.crypto.Cipher').getInstance.overload('java.security.Provider').implementation = function(transformation) {
              console.log("javax.crypto.Cipher.getInstance (2)" + this);
              console.log("transformation: " + transformation);
              // Return type: javax.crypto.Cipher!
              const returnValue = this.getInstance.apply(this, arguments);
              console.log('Cipher.getInstance (2) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getInstance pinner (2) not found');
          console.log(err);
      }

      // ----- getMaxAllowedKeyLength -----
      try {
          Java.use('javax.crypto.Cipher').getMaxAllowedKeyLength.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getMaxAllowedKeyLength" + this);
              // Return type: kotlin.Int
              const returnValue = this.getMaxAllowedKeyLength.apply(this, arguments);
              console.log('Cipher.getMaxAllowedKeyLength return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getMaxAllowedKeyLength pinner not found');
          console.log(err);
      }

      // ----- getMaxAllowedParameterSpec -----
      try {
          Java.use('javax.crypto.Cipher').getMaxAllowedParameterSpec.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getMaxAllowedParameterSpec" + this);
              // Return type: java.security.spec.AlgorithmParameterSpec!
              const returnValue = this.getMaxAllowedParameterSpec.apply(this, arguments);
              console.log('Cipher.getMaxAllowedParameterSpec return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getMaxAllowedParameterSpec pinner not found');
          console.log(err);
      }

      // ----- getOpmodeString -----
      try {
          Java.use('javax.crypto.Cipher').getOpmodeString.overload().implementation = function() {
              console.log("javax.crypto.Cipher.getOpmodeString" + this);
              // Return type: kotlin.String!
              const returnValue = this.getOpmodeString.apply(this, arguments);
              console.log('Cipher.getOpmodeString return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.getOpmodeString pinner not found');
          console.log(err);
      }

      // ----- matchAttribute -----
      try {
          Java.use('javax.crypto.Cipher').matchAttribute.overload('java.lang.String', 'java.lang.String').implementation = function(arg1, arg2) {
              console.log("javax.crypto.Cipher.matchAttribute" + this);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              // Return type: kotlin.Boolean
              const returnValue = this.matchAttribute.apply(this, arguments);
              console.log('Cipher.matchAttribute return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.matchAttribute pinner not found');
          console.log(err);
      }

      // ----- tokenizeTransformation -----
      try {
          Java.use('javax.crypto.Cipher').tokenizeTransformation.overload().implementation = function() {
              console.log("javax.crypto.Cipher.tokenizeTransformation" + this);
              // Return type: kotlin.Array<(out) kotlin.String!>!
              const returnValue = this.tokenizeTransformation.apply(this, arguments);
              console.log('Cipher.tokenizeTransformation return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.tokenizeTransformation pinner not found');
          console.log(err);
      }

      // ----- tryCombinations -----
      try {
          Java.use('javax.crypto.Cipher').tryCombinations.overload('java.security.Provider', 'kotlin.Array<(out) kotlin.String!>').implementation = function(arg1, arg2) {
              console.log("javax.crypto.Cipher.tryCombinations" + this);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              // Return type: javax.crypto.Cipher.CipherSpiAndProvider!
              const returnValue = this.tryCombinations.apply(this, arguments);
              console.log('Cipher.tryCombinations return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.tryCombinations pinner not found');
          console.log(err);
      }

      // ----- tryTransformWithProvider -----
      try {
          Java.use('javax.crypto.Cipher').tryTransformWithProvider.overload('kotlin.Array<(out) kotlin.String!>', 'javax.crypto.Cipher.NeedToSet', 'java.security.Provider.Service').implementation = function(arg1, arg2, arg3) {
              console.log("javax.crypto.Cipher.tryTransformWithProvider" + this);
              console.log("arg1: " + arg1);
              console.log("arg2: " + arg2);
              console.log("arg3: " + arg3);
              // Return type: javax.crypto.Cipher.CipherSpiAndProvider!
              const returnValue = this.tryTransformWithProvider.apply(this, arguments);
              console.log('Cipher.tryTransformWithProvider return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.tryTransformWithProvider pinner not found');
          console.log(err);
      }

  });
					

Focus sur une méthode


// ----- doFinal (3)-----
      try {
          Java.use('javax.crypto.Cipher').doFinal.overload('[B', 'int', 'int', '[B', 'int').implementation = function(input, inputOffset, inputLen, output, outputOffset) {
              console.log("javax.crypto.Cipher.doFinal (3)" + this);
              console.log("input: " + toHexString(input) + " | " + toAsciiString(input));
              console.log("inputOffset: " + inputOffset);
              console.log("inputLen: " + inputLen);
              console.log("output: " + toHexString(output) + " | " + toAsciiString(output));
              console.log("outputOffset: " + outputOffset);
              // Return type: kotlin.Int
              const returnValue = this.doFinal.apply(this, arguments);
              console.log('Cipher.doFinal (3) return value: ' + returnValue);
              return returnValue;
          };
      } catch (err) {
          console.log('[-] javax.crypto.Cipher.doFinal pinner (3) not found');
          console.log(err);
      }

Hooker le code des applications

FridaHookingFromJava
Android root logo
val filePath = "C:\\temp\\ctf\\app\\src\\main\\java\\com\\example\\basic_rev\\MainActivity.java"

https://github.com/javaparser/javaparser

Améliorations côté run

Sélection de plusieurs scripts

Logs frida

Pas top, donc mise en place des événements. Communication avec un autre processus `hostMulti.js` mise en forme des résultats sous forme d'arbre.

https://www.npmjs.com/package/treeify

Logs frida

Paramètres en ligne de commande

Pour lancer plusieurs fois le même script sur une même application, il est possible d'ajouter des paramètres pour lancer le script, et aller encore plus vite. Frida script parameters

Exemple


 ./frida_install.sh -a 11 -m 2 -p true -r

L'usage

  • Reverse statique de l'application de réseautage du MWC => hooking pour voir en clair ce qui transite
  • Analyse de base de donnée sécurisée, ...
  • CTF, Bug Bounty, ...

La suite

Web, génération de rapports, API de chiffrement, ...

https://github.com/Tristus1er

Frida script parameters