frida-tutorial-1.md (6503B)
1 --- 2 title: "Frida Tutorial 1" 3 section: "Mobile" 4 sectionSlug: "mobile-pentesting" 5 sourcePath: "src/mobile-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-1.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/mobile-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-1.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # Frida Tutorial 1 14 15 **This is a summary of the post**: [https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1](https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1)<sup>[[3]](#references)</sup>\ 16 **APK**: [https://github.com/t0thkr1s/frida-demo/releases](https://github.com/t0thkr1s/frida-demo/releases)\ 17 **Source Code**: [https://github.com/t0thkr1s/frida-demo](https://github.com/t0thkr1s/frida-demo) 18 19 ## Python 20 21 Frida allows you to **insert JavaScript code** inside functions of a running application. But you can use **python** to **call** the hooks and even to **interact** with the **hooks**. 22 23 This is a easy python script that you can use with all the proposed examples in this tutorial: 24 25 ```python 26 #hooking.py 27 import frida, sys 28 29 with open(sys.argv[1], 'r') as f: 30 jscode = f.read() 31 process = frida.get_usb_device().attach('infosecadventures.fridademo') 32 script = process.create_script(jscode) 33 print('[ * ] Running Frida Demo application') 34 script.load() 35 sys.stdin.read() 36 ``` 37 38 Call the script: 39 40 ```bash 41 python hooking.py <hookN.js> 42 ``` 43 44 It is useful to know how to use python with frida, but for this examples you could also call directly Frida using command line frida tools: 45 46 ```bash 47 frida -U --no-pause -l hookN.js -f infosecadventures.fridademo 48 ``` 49 50 ## Hook 1 - Boolean Bypass 51 52 Here you can see how to **hook** a **boolean** method (_checkPin_) from the class: _infosecadventures.fridademo.utils.PinUtil_ 53 54 ```javascript 55 //hook1.js 56 Java.perform(function () { 57 console.log("[ * ] Starting implementation override...") 58 var MainActivity = Java.use("infosecadventures.fridademo.utils.PinUtil") 59 MainActivity.checkPin.implementation = function (pin) { 60 console.log("[ + ] PIN check successfully bypassed!") 61 return true 62 } 63 }) 64 ``` 65 66 ```text 67 python hooking.py hook1.js 68 ``` 69 70 Mirar: La funcion recibe como parametro un String, no hace falta overload? 71 72 ## Hook 2 - Function Bruteforce 73 74 ### Non-Static Function 75 76 If you want to call a non-static function of a class, you **first need a instance** of that class. Then, you can use that instance to call the function.\ 77 To do so, you could **find and existing instance** and use it: 78 79 ```javascript 80 Java.perform(function () { 81 console.log("[ * ] Starting PIN Brute-force, please wait...") 82 Java.choose("infosecadventures.fridademo.utils.PinUtil", { 83 onMatch: function (instance) { 84 console.log("[ * ] Instance found in memory: " + instance) 85 for (var i = 1000; i < 9999; i++) { 86 if (instance.checkPin(i + "") == true) { 87 console.log("[ + ] Found correct PIN: " + i) 88 break 89 } 90 } 91 }, 92 onComplete: function () {}, 93 }) 94 }) 95 ``` 96 97 In this case this is not working as there isn't any instance and the function is Static 98 99 ### Static Function 100 101 If the function is static, you could just call it: 102 103 ```javascript 104 //hook2.js 105 Java.perform(function () { 106 console.log("[ * ] Starting PIN Brute-force, please wait...") 107 var PinUtil = Java.use("infosecadventures.fridademo.utils.PinUtil") 108 109 for (var i = 1000; i < 9999; i++) { 110 if (PinUtil.checkPin(i + "") == true) { 111 console.log("[ + ] Found correct PIN: " + i) 112 } 113 } 114 }) 115 ``` 116 117 ## Hook 3 - Retrieving arguments and return value 118 119 You could hook a function and make it **print** the value of the **passed arguments** and the value of the **return value:** 120 121 ```javascript 122 //hook3.js 123 Java.perform(function () { 124 console.log("[ * ] Starting implementation override...") 125 126 var EncryptionUtil = Java.use( 127 "infosecadventures.fridademo.utils.EncryptionUtil" 128 ) 129 EncryptionUtil.encrypt.implementation = function (key, value) { 130 console.log("Key: " + key) 131 console.log("Value: " + value) 132 var encrypted_ret = this.encrypt(key, value) //Call the original function 133 console.log("Encrypted value: " + encrypted_ret) 134 return encrypted_ret 135 } 136 }) 137 ``` 138 139 ## Hooking on recent Android versions (14/15/16) 140 141 - From **Frida 17.1.x+** Java hooking on Android 14–16 is stable again (ART quick entrypoint offsets were fixed). If `Java.choose` returns nothing on Android 14+, upgrade **frida-server/gadget** and the **CLI/Python** packages to >=17.1.5.<sup>[[1]](#references)</sup> 142 - Apps with early anti-debug checks often die before `attach`. Use **spawn** so hooks load before `onCreate`: 143 144 ```bash 145 frida -U -f infosecadventures.fridademo -l hook1.js --no-pause 146 ``` 147 148 - When multiple overloads exist, select the target explicitly: 149 150 ```javascript 151 var Cls = Java.use("com.example.Class") 152 Cls.doThing.overload('java.lang.String', 'int').implementation = function(s, i) { 153 return this.doThing(s, i) 154 } 155 ``` 156 157 ## Stealthier injection with Zygisk Gadget 158 159 Some apps detect **ptrace** or `frida-server`. Magisk/Zygisk modules can load **frida-gadget** inside Zygote so no process is ptraced:<sup>[[2]](#references)</sup> 160 161 1. Install a Zygisk gadget module (e.g., `zygisk-gadget`) and reboot. 162 2. Configure the target package and an optional delay to bypass startup checks: 163 164 ```bash 165 adb shell "su -c 'echo infosecadventures.fridademo,5000 > /data/local/tmp/re.zyg.fri/target_packages'" 166 ``` 167 168 3. Launch the app and attach to the gadget name: 169 170 ```bash 171 frida -U -n Gadget -l hook3.js 172 ``` 173 174 Because the gadget is injected by Zygote, APK integrity checks stay untouched and basic ptrace/Frida string checks usually fail. 175 176 ## Important 177 178 In this tutorial you have hooked methods using the name of the method and _.implementation_. But if there were **more than one method** with the same name, you will need to **specify the method** that you want to hook **indicating the type of the arguments**. 179 180 You can see that in [the next tutorial](/hacktricks/mobile-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-2). 181 182 ## References 183 184 - [1] [Frida News (Android 14–16 fixes & Frida 17.x releases)](https://frida.re/news/) 185 - [2] [zygisk-gadget – Zygisk module that loads frida-gadget](https://github.com/hackcatml/zygisk-gadget) 186 - [3] [medium.com - Introduction To Frida](https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1)