/* * By http://github.com/LotemBY * This is a frida script for unpinning and reversing of ObjC applications. Intercept method's which match regex. You may change the following regex arrays to match your needs: */ // The list of regexs for the moudle name var moduleKeyWords = [/.*/]; // (It is not recommended to search all the moudles) // The list of regexs for the method name var methodKeyWords = [/cert/i, /trust/i, /ssl/i, /verify/i, /509/]; // The list of regexs for the method to override their return value with "1" var overrideKeyWords = []; /* To run this script with frida on iPhone, follow these steps: 1. Make sure the iPhone is jailbreaked 2. Download the frida server from Cydia (package: re.frida.server) 3. Connect the iPhone to your computer with USB and open the application 4. Type in console "frida-ps -U" to get the list of running proccess on the iPhone, and find the proccess name of your app 5. Type in console "frida -U -l " to run this script 6. Now you should use the app to trigger some of the intercepted methods */ var onCompleteCallback = function (retval) {}; setImmediate(function () { if (!ObjC.available) { console.log("[-] Objective-C Runtime is not available!"); return; } console.log("=======================================================\n"); console.log("[*] Searching methods..."); var moduleUsed = false; Process.enumerateModules({ onMatch: function(module) { if (!matchesRegex(moduleKeyWords, module.name)) { return; } moduleUsed = false; Module.enumerateSymbols(module.name, { onMatch: function(exp) { if (matchesRegex(methodKeyWords, exp.name)) { if (!moduleUsed) { console.log("[*] In module \"" + module.name + "\""); moduleUsed = true; } console.log("\t[*] Matching method: \"" + exp.name + "\", Address: " + Module.findExportByName(module.name, exp.name)); if (intercept(module.name, exp.name)) { console.log("\t\t[+] Now intercepting " + exp.name); } else { console.log("\t\t[-] Could not intercept " + exp.name); } } }, onComplete: onCompleteCallback }); }, onComplete: onCompleteCallback }); console.log("[*] Completed!"); console.log("=======================================================\n\n"); }); // Return if 'str' match any of the regexs in the array 'regexList' function matchesRegex(regexList, str) { regexList.forEach(function(el) { if (str.search(el) != -1) return true; }); return false; } // Try to intercept a method by moudle name and function name. // Return 'true' on success and 'false' on failor. function intercept(module, func) { try { Interceptor.attach(Module.findExportByName(module, func), { onEnter: function(args) { console.log("[*] Method CALL:\t\"" + func + "\" called!"); }, onLeave: function (retval) { console.log("[*] Method RETURN:\t\"" + func + "\" (return value: " + retval + ")"); if (matchesRegex(overrideKeyWords, func)) { console.log("[!] CHANGED RETURN VALUE of method:\t\"" + func + "\" (new value: " + 1 + ")"); retval.replace(1); } } }); return true; } catch (err) { return false; } }