Advertisement
savsanta

Universal Root Detection and SSL Pinning Bypass

Aug 23rd, 2024
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 49.64 KB | None | 0 0
  1. /*
  2. * This script combines, fixes & extends a long list of other scripts, most notably including:
  3. *
  4. * - https://codeshare.frida.re/@akabe1/frida-multiple-unpinning/
  5. * - https://codeshare.frida.re/@avltree9798/universal-android-ssl-pinning-bypass/
  6. * - https://pastebin.com/TVJD63uM
  7. * - https://codeshare.frida.re/@dzonerzy/fridantiroot/
  8. * - https://github.com/AshenOneYe/FridaAntiRootDetection/blob/main/antiroot.js
  9. */
  10.  
  11. setTimeout(function () {
  12. Java.perform(function () {
  13. console.log("---");
  14. console.log("Unpinning Android app...");
  15.  
  16. /// -- Generic hook to protect against SSLPeerUnverifiedException -- ///
  17.  
  18. // In some cases, with unusual cert pinning approaches, or heavy obfuscation, we can't
  19. // match the real method & package names. This is a problem! Fortunately, we can still
  20. // always match built-in types, so here we spot all failures that use the built-in cert
  21. // error type (notably this includes OkHttp), and after the first failure, we dynamically
  22. // generate & inject a patch to completely disable the method that threw the error.
  23. try {
  24. const UnverifiedCertError = Java.use('javax.net.ssl.SSLPeerUnverifiedException');
  25. UnverifiedCertError.$init.implementation = function (str) {
  26. console.log(' --> Unexpected SSL verification failure, adding dynamic patch...');
  27.  
  28. try {
  29. const stackTrace = Java.use('java.lang.Thread').currentThread().getStackTrace();
  30. const exceptionStackIndex = stackTrace.findIndex(stack =>
  31. stack.getClassName() === "javax.net.ssl.SSLPeerUnverifiedException"
  32. );
  33. const callingFunctionStack = stackTrace[exceptionStackIndex + 1];
  34.  
  35. const className = callingFunctionStack.getClassName();
  36. const methodName = callingFunctionStack.getMethodName();
  37.  
  38. console.log(` Thrown by ${className}->${methodName}`);
  39.  
  40. const callingClass = Java.use(className);
  41. const callingMethod = callingClass[methodName];
  42.  
  43. if (callingMethod.implementation) return; // Already patched by Frida - skip it
  44.  
  45. console.log(' Attempting to patch automatically...');
  46. const returnTypeName = callingMethod.returnType.type;
  47.  
  48. callingMethod.implementation = function () {
  49. console.log(` --> Bypassing ${className}->${methodName} (automatic exception patch)`);
  50.  
  51. // This is not a perfect fix! Most unknown cases like this are really just
  52. // checkCert(cert) methods though, so doing nothing is perfect, and if we
  53. // do need an actual return value then this is probably the best we can do,
  54. // and at least we're logging the method name so you can patch it manually:
  55.  
  56. if (returnTypeName === 'void') {
  57. return;
  58. } else {
  59. return null;
  60. }
  61. };
  62.  
  63. console.log(` [+] ${className}->${methodName} (automatic exception patch)`);
  64. } catch (e) {
  65. console.log(' [ ] Failed to automatically patch failure');
  66. }
  67.  
  68. return this.$init(str);
  69. };
  70. console.log('[+] SSLPeerUnverifiedException auto-patcher');
  71. } catch (err) {
  72. console.log('[ ] SSLPeerUnverifiedException auto-patcher');
  73. }
  74.  
  75. /// -- Specific targeted hooks: -- ///
  76.  
  77. // HttpsURLConnection
  78. try {
  79. const HttpsURLConnection = Java.use("javax.net.ssl.HttpsURLConnection");
  80. HttpsURLConnection.setDefaultHostnameVerifier.implementation = function (hostnameVerifier) {
  81. console.log(' --> Bypassing HttpsURLConnection (setDefaultHostnameVerifier)');
  82. return; // Do nothing, i.e. don't change the hostname verifier
  83. };
  84. console.log('[+] HttpsURLConnection (setDefaultHostnameVerifier)');
  85. } catch (err) {
  86. console.log('[ ] HttpsURLConnection (setDefaultHostnameVerifier)');
  87. }
  88. try {
  89. const HttpsURLConnection = Java.use("javax.net.ssl.HttpsURLConnection");
  90. HttpsURLConnection.setSSLSocketFactory.implementation = function (SSLSocketFactory) {
  91. console.log(' --> Bypassing HttpsURLConnection (setSSLSocketFactory)');
  92. return; // Do nothing, i.e. don't change the SSL socket factory
  93. };
  94. console.log('[+] HttpsURLConnection (setSSLSocketFactory)');
  95. } catch (err) {
  96. console.log('[ ] HttpsURLConnection (setSSLSocketFactory)');
  97. }
  98. try {
  99. const HttpsURLConnection = Java.use("javax.net.ssl.HttpsURLConnection");
  100. HttpsURLConnection.setHostnameVerifier.implementation = function (hostnameVerifier) {
  101. console.log(' --> Bypassing HttpsURLConnection (setHostnameVerifier)');
  102. return; // Do nothing, i.e. don't change the hostname verifier
  103. };
  104. console.log('[+] HttpsURLConnection (setHostnameVerifier)');
  105. } catch (err) {
  106. console.log('[ ] HttpsURLConnection (setHostnameVerifier)');
  107. }
  108.  
  109. // SSLContext
  110. try {
  111. const X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
  112. const SSLContext = Java.use('javax.net.ssl.SSLContext');
  113.  
  114. const TrustManager = Java.registerClass({
  115. // Implement a custom TrustManager
  116. name: 'dev.asd.test.TrustManager',
  117. implements: [X509TrustManager],
  118. methods: {
  119. checkClientTrusted: function (chain, authType) { },
  120. checkServerTrusted: function (chain, authType) { },
  121. getAcceptedIssuers: function () { return []; }
  122. }
  123. });
  124.  
  125. // Prepare the TrustManager array to pass to SSLContext.init()
  126. const TrustManagers = [TrustManager.$new()];
  127.  
  128. // Get a handle on the init() on the SSLContext class
  129. const SSLContext_init = SSLContext.init.overload(
  130. '[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom'
  131. );
  132.  
  133. // Override the init method, specifying the custom TrustManager
  134. SSLContext_init.implementation = function (keyManager, trustManager, secureRandom) {
  135. console.log(' --> Bypassing Trustmanager (Android < 7) request');
  136. SSLContext_init.call(this, keyManager, TrustManagers, secureRandom);
  137. };
  138. console.log('[+] SSLContext');
  139. } catch (err) {
  140. console.log('[ ] SSLContext');
  141. }
  142.  
  143. // TrustManagerImpl (Android > 7)
  144. try {
  145. const array_list = Java.use("java.util.ArrayList");
  146. const TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl');
  147.  
  148. // This step is notably what defeats the most common case: network security config
  149. TrustManagerImpl.checkTrustedRecursive.implementation = function(a1, a2, a3, a4, a5, a6) {
  150. console.log(' --> Bypassing TrustManagerImpl checkTrusted ');
  151. return array_list.$new();
  152. }
  153.  
  154. TrustManagerImpl.verifyChain.implementation = function (untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {
  155. console.log(' --> Bypassing TrustManagerImpl verifyChain: ' + host);
  156. return untrustedChain;
  157. };
  158. console.log('[+] TrustManagerImpl');
  159. } catch (err) {
  160. console.log('[ ] TrustManagerImpl');
  161. }
  162.  
  163. // OkHTTPv3 (quadruple bypass)
  164. try {
  165. // Bypass OkHTTPv3 {1}
  166. const okhttp3_Activity_1 = Java.use('okhttp3.CertificatePinner');
  167. okhttp3_Activity_1.check.overload('java.lang.String', 'java.util.List').implementation = function (a, b) {
  168. console.log(' --> Bypassing OkHTTPv3 (list): ' + a);
  169. return;
  170. };
  171. console.log('[+] OkHTTPv3 (list)');
  172. } catch (err) {
  173. console.log('[ ] OkHTTPv3 (list)');
  174. }
  175. try {
  176. // Bypass OkHTTPv3 {2}
  177. // This method of CertificatePinner.check could be found in some old Android app
  178. const okhttp3_Activity_2 = Java.use('okhttp3.CertificatePinner');
  179. okhttp3_Activity_2.check.overload('java.lang.String', 'java.security.cert.Certificate').implementation = function (a, b) {
  180. console.log(' --> Bypassing OkHTTPv3 (cert): ' + a);
  181. return;
  182. };
  183. console.log('[+] OkHTTPv3 (cert)');
  184. } catch (err) {
  185. console.log('[ ] OkHTTPv3 (cert)');
  186. }
  187. try {
  188. // Bypass OkHTTPv3 {3}
  189. const okhttp3_Activity_3 = Java.use('okhttp3.CertificatePinner');
  190. okhttp3_Activity_3.check.overload('java.lang.String', '[Ljava.security.cert.Certificate;').implementation = function (a, b) {
  191. console.log(' --> Bypassing OkHTTPv3 (cert array): ' + a);
  192. return;
  193. };
  194. console.log('[+] OkHTTPv3 (cert array)');
  195. } catch (err) {
  196. console.log('[ ] OkHTTPv3 (cert array)');
  197. }
  198. try {
  199. // Bypass OkHTTPv3 {4}
  200. const okhttp3_Activity_4 = Java.use('okhttp3.CertificatePinner');
  201. okhttp3_Activity_4['check$okhttp'].implementation = function (a, b) {
  202. console.log(' --> Bypassing OkHTTPv3 ($okhttp): ' + a);
  203. return;
  204. };
  205. console.log('[+] OkHTTPv3 ($okhttp)');
  206. } catch (err) {
  207. console.log('[ ] OkHTTPv3 ($okhttp)');
  208. }
  209.  
  210. // Trustkit (triple bypass)
  211. try {
  212. // Bypass Trustkit {1}
  213. const trustkit_Activity_1 = Java.use('com.datatheorem.android.trustkit.pinning.OkHostnameVerifier');
  214. trustkit_Activity_1.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function (a, b) {
  215. console.log(' --> Bypassing Trustkit OkHostnameVerifier(SSLSession): ' + a);
  216. return true;
  217. };
  218. console.log('[+] Trustkit OkHostnameVerifier(SSLSession)');
  219. } catch (err) {
  220. console.log('[ ] Trustkit OkHostnameVerifier(SSLSession)');
  221. }
  222. try {
  223. // Bypass Trustkit {2}
  224. const trustkit_Activity_2 = Java.use('com.datatheorem.android.trustkit.pinning.OkHostnameVerifier');
  225. trustkit_Activity_2.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function (a, b) {
  226. console.log(' --> Bypassing Trustkit OkHostnameVerifier(cert): ' + a);
  227. return true;
  228. };
  229. console.log('[+] Trustkit OkHostnameVerifier(cert)');
  230. } catch (err) {
  231. console.log('[ ] Trustkit OkHostnameVerifier(cert)');
  232. }
  233. try {
  234. // Bypass Trustkit {3}
  235. const trustkit_PinningTrustManager = Java.use('com.datatheorem.android.trustkit.pinning.PinningTrustManager');
  236. trustkit_PinningTrustManager.checkServerTrusted.implementation = function () {
  237. console.log(' --> Bypassing Trustkit PinningTrustManager');
  238. };
  239. console.log('[+] Trustkit PinningTrustManager');
  240. } catch (err) {
  241. console.log('[ ] Trustkit PinningTrustManager');
  242. }
  243.  
  244. // Appcelerator Titanium
  245. try {
  246. const appcelerator_PinningTrustManager = Java.use('appcelerator.https.PinningTrustManager');
  247. appcelerator_PinningTrustManager.checkServerTrusted.implementation = function () {
  248. console.log(' --> Bypassing Appcelerator PinningTrustManager');
  249. };
  250. console.log('[+] Appcelerator PinningTrustManager');
  251. } catch (err) {
  252. console.log('[ ] Appcelerator PinningTrustManager');
  253. }
  254.  
  255. // OpenSSLSocketImpl Conscrypt
  256. try {
  257. const OpenSSLSocketImpl = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl');
  258. OpenSSLSocketImpl.verifyCertificateChain.implementation = function (certRefs, JavaObject, authMethod) {
  259. console.log(' --> Bypassing OpenSSLSocketImpl Conscrypt');
  260. };
  261. console.log('[+] OpenSSLSocketImpl Conscrypt');
  262. } catch (err) {
  263. console.log('[ ] OpenSSLSocketImpl Conscrypt');
  264. }
  265.  
  266. // OpenSSLEngineSocketImpl Conscrypt
  267. try {
  268. const OpenSSLEngineSocketImpl_Activity = Java.use('com.android.org.conscrypt.OpenSSLEngineSocketImpl');
  269. OpenSSLEngineSocketImpl_Activity.verifyCertificateChain.overload('[Ljava.lang.Long;', 'java.lang.String').implementation = function (a, b) {
  270. console.log(' --> Bypassing OpenSSLEngineSocketImpl Conscrypt: ' + b);
  271. };
  272. console.log('[+] OpenSSLEngineSocketImpl Conscrypt');
  273. } catch (err) {
  274. console.log('[ ] OpenSSLEngineSocketImpl Conscrypt');
  275. }
  276.  
  277. // OpenSSLSocketImpl Apache Harmony
  278. try {
  279. const OpenSSLSocketImpl_Harmony = Java.use('org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl');
  280. OpenSSLSocketImpl_Harmony.verifyCertificateChain.implementation = function (asn1DerEncodedCertificateChain, authMethod) {
  281. console.log(' --> Bypassing OpenSSLSocketImpl Apache Harmony');
  282. };
  283. console.log('[+] OpenSSLSocketImpl Apache Harmony');
  284. } catch (err) {
  285. console.log('[ ] OpenSSLSocketImpl Apache Harmony');
  286. }
  287.  
  288. // PhoneGap sslCertificateChecker (https://github.com/EddyVerbruggen/SSLCertificateChecker-PhoneGap-Plugin)
  289. try {
  290. const phonegap_Activity = Java.use('nl.xservices.plugins.sslCertificateChecker');
  291. phonegap_Activity.execute.overload('java.lang.String', 'org.json.JSONArray', 'org.apache.cordova.CallbackContext').implementation = function (a, b, c) {
  292. console.log(' --> Bypassing PhoneGap sslCertificateChecker: ' + a);
  293. return true;
  294. };
  295. console.log('[+] PhoneGap sslCertificateChecker');
  296. } catch (err) {
  297. console.log('[ ] PhoneGap sslCertificateChecker');
  298. }
  299.  
  300. // IBM MobileFirst pinTrustedCertificatePublicKey (double bypass)
  301. try {
  302. // Bypass IBM MobileFirst {1}
  303. const WLClient_Activity_1 = Java.use('com.worklight.wlclient.api.WLClient');
  304. WLClient_Activity_1.getInstance().pinTrustedCertificatePublicKey.overload('java.lang.String').implementation = function (cert) {
  305. console.log(' --> Bypassing IBM MobileFirst pinTrustedCertificatePublicKey (string): ' + cert);
  306. return;
  307. };
  308. console.log('[+] IBM MobileFirst pinTrustedCertificatePublicKey (string)');
  309. } catch (err) {
  310. console.log('[ ] IBM MobileFirst pinTrustedCertificatePublicKey (string)');
  311. }
  312. try {
  313. // Bypass IBM MobileFirst {2}
  314. const WLClient_Activity_2 = Java.use('com.worklight.wlclient.api.WLClient');
  315. WLClient_Activity_2.getInstance().pinTrustedCertificatePublicKey.overload('[Ljava.lang.String;').implementation = function (cert) {
  316. console.log(' --> Bypassing IBM MobileFirst pinTrustedCertificatePublicKey (string array): ' + cert);
  317. return;
  318. };
  319. console.log('[+] IBM MobileFirst pinTrustedCertificatePublicKey (string array)');
  320. } catch (err) {
  321. console.log('[ ] IBM MobileFirst pinTrustedCertificatePublicKey (string array)');
  322. }
  323.  
  324. // IBM WorkLight (ancestor of MobileFirst) HostNameVerifierWithCertificatePinning (quadruple bypass)
  325. try {
  326. // Bypass IBM WorkLight {1}
  327. const worklight_Activity_1 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');
  328. worklight_Activity_1.verify.overload('java.lang.String', 'javax.net.ssl.SSLSocket').implementation = function (a, b) {
  329. console.log(' --> Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning (SSLSocket): ' + a);
  330. return;
  331. };
  332. console.log('[+] IBM WorkLight HostNameVerifierWithCertificatePinning (SSLSocket)');
  333. } catch (err) {
  334. console.log('[ ] IBM WorkLight HostNameVerifierWithCertificatePinning (SSLSocket)');
  335. }
  336. try {
  337. // Bypass IBM WorkLight {2}
  338. const worklight_Activity_2 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');
  339. worklight_Activity_2.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function (a, b) {
  340. console.log(' --> Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning (cert): ' + a);
  341. return;
  342. };
  343. console.log('[+] IBM WorkLight HostNameVerifierWithCertificatePinning (cert)');
  344. } catch (err) {
  345. console.log('[ ] IBM WorkLight HostNameVerifierWithCertificatePinning (cert)');
  346. }
  347. try {
  348. // Bypass IBM WorkLight {3}
  349. const worklight_Activity_3 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');
  350. worklight_Activity_3.verify.overload('java.lang.String', '[Ljava.lang.String;', '[Ljava.lang.String;').implementation = function (a, b) {
  351. console.log(' --> Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning (string string): ' + a);
  352. return;
  353. };
  354. console.log('[+] IBM WorkLight HostNameVerifierWithCertificatePinning (string string)');
  355. } catch (err) {
  356. console.log('[ ] IBM WorkLight HostNameVerifierWithCertificatePinning (string string)');
  357. }
  358. try {
  359. // Bypass IBM WorkLight {4}
  360. const worklight_Activity_4 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');
  361. worklight_Activity_4.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function (a, b) {
  362. console.log(' --> Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning (SSLSession): ' + a);
  363. return true;
  364. };
  365. console.log('[+] IBM WorkLight HostNameVerifierWithCertificatePinning (SSLSession)');
  366. } catch (err) {
  367. console.log('[ ] IBM WorkLight HostNameVerifierWithCertificatePinning (SSLSession)');
  368. }
  369.  
  370. // Conscrypt CertPinManager
  371. try {
  372. const conscrypt_CertPinManager_Activity = Java.use('com.android.org.conscrypt.CertPinManager');
  373. conscrypt_CertPinManager_Activity.isChainValid.overload('java.lang.String', 'java.util.List').implementation = function (a, b) {
  374. console.log(' --> Bypassing Conscrypt CertPinManager: ' + a);
  375. return true;
  376. };
  377. console.log('[+] Conscrypt CertPinManager');
  378. } catch (err) {
  379. console.log('[ ] Conscrypt CertPinManager');
  380. }
  381.  
  382. // CWAC-Netsecurity (unofficial back-port pinner for Android<4.2) CertPinManager
  383. try {
  384. const cwac_CertPinManager_Activity = Java.use('com.commonsware.cwac.netsecurity.conscrypt.CertPinManager');
  385. cwac_CertPinManager_Activity.isChainValid.overload('java.lang.String', 'java.util.List').implementation = function (a, b) {
  386. console.log(' --> Bypassing CWAC-Netsecurity CertPinManager: ' + a);
  387. return true;
  388. };
  389. console.log('[+] CWAC-Netsecurity CertPinManager');
  390. } catch (err) {
  391. console.log('[ ] CWAC-Netsecurity CertPinManager');
  392. }
  393.  
  394. // Worklight Androidgap WLCertificatePinningPlugin
  395. try {
  396. const androidgap_WLCertificatePinningPlugin_Activity = Java.use('com.worklight.androidgap.plugin.WLCertificatePinningPlugin');
  397. androidgap_WLCertificatePinningPlugin_Activity.execute.overload('java.lang.String', 'org.json.JSONArray', 'org.apache.cordova.CallbackContext').implementation = function (a, b, c) {
  398. console.log(' --> Bypassing Worklight Androidgap WLCertificatePinningPlugin: ' + a);
  399. return true;
  400. };
  401. console.log('[+] Worklight Androidgap WLCertificatePinningPlugin');
  402. } catch (err) {
  403. console.log('[ ] Worklight Androidgap WLCertificatePinningPlugin');
  404. }
  405.  
  406. // Netty FingerprintTrustManagerFactory
  407. try {
  408. const netty_FingerprintTrustManagerFactory = Java.use('io.netty.handler.ssl.util.FingerprintTrustManagerFactory');
  409. netty_FingerprintTrustManagerFactory.checkTrusted.implementation = function (type, chain) {
  410. console.log(' --> Bypassing Netty FingerprintTrustManagerFactory');
  411. };
  412. console.log('[+] Netty FingerprintTrustManagerFactory');
  413. } catch (err) {
  414. console.log('[ ] Netty FingerprintTrustManagerFactory');
  415. }
  416.  
  417. // Squareup CertificatePinner [OkHTTP<v3] (double bypass)
  418. try {
  419. // Bypass Squareup CertificatePinner {1}
  420. const Squareup_CertificatePinner_Activity_1 = Java.use('com.squareup.okhttp.CertificatePinner');
  421. Squareup_CertificatePinner_Activity_1.check.overload('java.lang.String', 'java.security.cert.Certificate').implementation = function (a, b) {
  422. console.log(' --> Bypassing Squareup CertificatePinner (cert): ' + a);
  423. return;
  424. };
  425. console.log('[+] Squareup CertificatePinner (cert)');
  426. } catch (err) {
  427. console.log('[ ] Squareup CertificatePinner (cert)');
  428. }
  429. try {
  430. // Bypass Squareup CertificatePinner {2}
  431. const Squareup_CertificatePinner_Activity_2 = Java.use('com.squareup.okhttp.CertificatePinner');
  432. Squareup_CertificatePinner_Activity_2.check.overload('java.lang.String', 'java.util.List').implementation = function (a, b) {
  433. console.log(' --> Bypassing Squareup CertificatePinner (list): ' + a);
  434. return;
  435. };
  436. console.log('[+] Squareup CertificatePinner (list)');
  437. } catch (err) {
  438. console.log('[ ] Squareup CertificatePinner (list)');
  439. }
  440.  
  441. // Squareup OkHostnameVerifier [OkHTTP v3] (double bypass)
  442. try {
  443. // Bypass Squareup OkHostnameVerifier {1}
  444. const Squareup_OkHostnameVerifier_Activity_1 = Java.use('com.squareup.okhttp.internal.tls.OkHostnameVerifier');
  445. Squareup_OkHostnameVerifier_Activity_1.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function (a, b) {
  446. console.log(' --> Bypassing Squareup OkHostnameVerifier (cert): ' + a);
  447. return true;
  448. };
  449. console.log('[+] Squareup OkHostnameVerifier (cert)');
  450. } catch (err) {
  451. console.log('[ ] Squareup OkHostnameVerifier (cert)');
  452. }
  453. try {
  454. // Bypass Squareup OkHostnameVerifier {2}
  455. const Squareup_OkHostnameVerifier_Activity_2 = Java.use('com.squareup.okhttp.internal.tls.OkHostnameVerifier');
  456. Squareup_OkHostnameVerifier_Activity_2.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function (a, b) {
  457. console.log(' --> Bypassing Squareup OkHostnameVerifier (SSLSession): ' + a);
  458. return true;
  459. };
  460. console.log('[+] Squareup OkHostnameVerifier (SSLSession)');
  461. } catch (err) {
  462. console.log('[ ] Squareup OkHostnameVerifier (SSLSession)');
  463. }
  464.  
  465. // Android WebViewClient (double bypass)
  466. try {
  467. // Bypass WebViewClient {1} (deprecated from Android 6)
  468. const AndroidWebViewClient_Activity_1 = Java.use('android.webkit.WebViewClient');
  469. AndroidWebViewClient_Activity_1.onReceivedSslError.overload('android.webkit.WebView', 'android.webkit.SslErrorHandler', 'android.net.http.SslError').implementation = function (obj1, obj2, obj3) {
  470. console.log(' --> Bypassing Android WebViewClient (SslErrorHandler)');
  471. };
  472. console.log('[+] Android WebViewClient (SslErrorHandler)');
  473. } catch (err) {
  474. console.log('[ ] Android WebViewClient (SslErrorHandler)');
  475. }
  476. try {
  477. // Bypass WebViewClient {2}
  478. const AndroidWebViewClient_Activity_2 = Java.use('android.webkit.WebViewClient');
  479. AndroidWebViewClient_Activity_2.onReceivedSslError.overload('android.webkit.WebView', 'android.webkit.WebResourceRequest', 'android.webkit.WebResourceError').implementation = function (obj1, obj2, obj3) {
  480. console.log(' --> Bypassing Android WebViewClient (WebResourceError)');
  481. };
  482. console.log('[+] Android WebViewClient (WebResourceError)');
  483. } catch (err) {
  484. console.log('[ ] Android WebViewClient (WebResourceError)');
  485. }
  486.  
  487. // Apache Cordova WebViewClient
  488. try {
  489. const CordovaWebViewClient_Activity = Java.use('org.apache.cordova.CordovaWebViewClient');
  490. CordovaWebViewClient_Activity.onReceivedSslError.overload('android.webkit.WebView', 'android.webkit.SslErrorHandler', 'android.net.http.SslError').implementation = function (obj1, obj2, obj3) {
  491. console.log(' --> Bypassing Apache Cordova WebViewClient');
  492. obj3.proceed();
  493. };
  494. } catch (err) {
  495. console.log('[ ] Apache Cordova WebViewClient');
  496. }
  497.  
  498. // Boye AbstractVerifier
  499. try {
  500. const boye_AbstractVerifier = Java.use('ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier');
  501. boye_AbstractVerifier.verify.implementation = function (host, ssl) {
  502. console.log(' --> Bypassing Boye AbstractVerifier: ' + host);
  503. };
  504. } catch (err) {
  505. console.log('[ ] Boye AbstractVerifier');
  506. }
  507.  
  508. // Appmattus
  509. try {
  510. const appmatus_Activity = Java.use('com.appmattus.certificatetransparency.internal.verifier.CertificateTransparencyInterceptor');
  511. appmatus_Activity['intercept'].implementation = function (a) {
  512. console.log(' --> Bypassing Appmattus (Transparency)');
  513. return a.proceed(a.request());
  514. };
  515. console.log('[+] Appmattus (CertificateTransparencyInterceptor)');
  516. } catch (err) {
  517. console.log('[ ] Appmattus (CertificateTransparencyInterceptor)');
  518. }
  519.  
  520. try {
  521. const CertificateTransparencyTrustManager = Java.use(
  522. 'com.appmattus.certificatetransparency.internal.verifier.CertificateTransparencyTrustManager'
  523. );
  524. CertificateTransparencyTrustManager['checkServerTrusted'].overload(
  525. '[Ljava.security.cert.X509Certificate;',
  526. 'java.lang.String'
  527. ).implementation = function (x509CertificateArr, str) {
  528. console.log(' --> Bypassing Appmattus (CertificateTransparencyTrustManager)');
  529. };
  530. CertificateTransparencyTrustManager['checkServerTrusted'].overload(
  531. '[Ljava.security.cert.X509Certificate;',
  532. 'java.lang.String',
  533. 'java.lang.String'
  534. ).implementation = function (x509CertificateArr, str, str2) {
  535. console.log(' --> Bypassing Appmattus (CertificateTransparencyTrustManager)');
  536. return Java.use('java.util.ArrayList').$new();
  537. };
  538. console.log('[+] Appmattus (CertificateTransparencyTrustManager)');
  539. } catch (err) {
  540. console.log('[ ] Appmattus (CertificateTransparencyTrustManager)');
  541. }
  542.  
  543. console.log("Unpinning setup completed");
  544. console.log("---");
  545. });
  546.  
  547. }, 0);
  548.  
  549. Java.perform(function() {
  550. var RootPackages = ["com.noshufou.android.su", "com.noshufou.android.su.elite", "eu.chainfire.supersu",
  551. "com.koushikdutta.superuser", "com.thirdparty.superuser", "com.yellowes.su", "com.koushikdutta.rommanager",
  552. "com.koushikdutta.rommanager.license", "com.dimonvideo.luckypatcher", "com.chelpus.lackypatch",
  553. "com.ramdroid.appquarantine", "com.ramdroid.appquarantinepro", "com.devadvance.rootcloak", "com.devadvance.rootcloakplus",
  554. "de.robv.android.xposed.installer", "com.saurik.substrate", "com.zachspong.temprootremovejb", "com.amphoras.hidemyroot",
  555. "com.amphoras.hidemyrootadfree", "com.formyhm.hiderootPremium", "com.formyhm.hideroot", "me.phh.superuser",
  556. "eu.chainfire.supersu.pro", "com.kingouser.com", "com.topjohnwu.magisk"
  557. ];
  558.  
  559. var RootBinaries = ["su", "busybox", "supersu", "Superuser.apk", "KingoUser.apk", "SuperSu.apk", "magisk"];
  560.  
  561. var RootProperties = {
  562. "ro.build.selinux": "1",
  563. "ro.debuggable": "0",
  564. "service.adb.root": "0",
  565. "ro.secure": "1"
  566. };
  567.  
  568. var RootPropertiesKeys = [];
  569.  
  570. for (var k in RootProperties) RootPropertiesKeys.push(k);
  571.  
  572. var PackageManager = Java.use("android.app.ApplicationPackageManager");
  573.  
  574. var Runtime = Java.use('java.lang.Runtime');
  575.  
  576. var NativeFile = Java.use('java.io.File');
  577.  
  578. var String = Java.use('java.lang.String');
  579.  
  580. var SystemProperties = Java.use('android.os.SystemProperties');
  581.  
  582. var BufferedReader = Java.use('java.io.BufferedReader');
  583.  
  584. var ProcessBuilder = Java.use('java.lang.ProcessBuilder');
  585.  
  586. var StringBuffer = Java.use('java.lang.StringBuffer');
  587.  
  588. var loaded_classes = Java.enumerateLoadedClassesSync();
  589.  
  590. send("Loaded " + loaded_classes.length + " classes!");
  591.  
  592. var useKeyInfo = false;
  593.  
  594. var useProcessManager = false;
  595.  
  596. send("loaded: " + loaded_classes.indexOf('java.lang.ProcessManager'));
  597.  
  598. if (loaded_classes.indexOf('java.lang.ProcessManager') != -1) {
  599. try {
  600. //useProcessManager = true;
  601. //var ProcessManager = Java.use('java.lang.ProcessManager');
  602. } catch (err) {
  603. send("ProcessManager Hook failed: " + err);
  604. }
  605. } else {
  606. send("ProcessManager hook not loaded");
  607. }
  608.  
  609. var KeyInfo = null;
  610.  
  611. if (loaded_classes.indexOf('android.security.keystore.KeyInfo') != -1) {
  612. try {
  613. //useKeyInfo = true;
  614. //var KeyInfo = Java.use('android.security.keystore.KeyInfo');
  615. } catch (err) {
  616. send("KeyInfo Hook failed: " + err);
  617. }
  618. } else {
  619. send("KeyInfo hook not loaded");
  620. }
  621.  
  622. PackageManager.getPackageInfo.overload('java.lang.String', 'int').implementation = function(pname, flags) {
  623. var shouldFakePackage = (RootPackages.indexOf(pname) > -1);
  624. if (shouldFakePackage) {
  625. send("Bypass root check for package: " + pname);
  626. pname = "set.package.name.to.a.fake.one.so.we.can.bypass.it";
  627. }
  628. return this.getPackageInfo.overload('java.lang.String', 'int').call(this, pname, flags);
  629. };
  630.  
  631. NativeFile.exists.implementation = function() {
  632. var name = NativeFile.getName.call(this);
  633. var shouldFakeReturn = (RootBinaries.indexOf(name) > -1);
  634. if (shouldFakeReturn) {
  635. send("Bypass return value for binary: " + name);
  636. return false;
  637. } else {
  638. return this.exists.call(this);
  639. }
  640. };
  641.  
  642. var exec = Runtime.exec.overload('[Ljava.lang.String;');
  643. var exec1 = Runtime.exec.overload('java.lang.String');
  644. var exec2 = Runtime.exec.overload('java.lang.String', '[Ljava.lang.String;');
  645. var exec3 = Runtime.exec.overload('[Ljava.lang.String;', '[Ljava.lang.String;');
  646. var exec4 = Runtime.exec.overload('[Ljava.lang.String;', '[Ljava.lang.String;', 'java.io.File');
  647. var exec5 = Runtime.exec.overload('java.lang.String', '[Ljava.lang.String;', 'java.io.File');
  648.  
  649. exec5.implementation = function(cmd, env, dir) {
  650. if (cmd.indexOf("getprop") != -1 || cmd == "mount" || cmd.indexOf("build.prop") != -1 || cmd == "id" || cmd == "sh") {
  651. var fakeCmd = "grep";
  652. send("Bypass " + cmd + " command");
  653. return exec1.call(this, fakeCmd);
  654. }
  655. if (cmd == "su") {
  656. var fakeCmd = "justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
  657. send("Bypass " + cmd + " command");
  658. return exec1.call(this, fakeCmd);
  659. }
  660. return exec5.call(this, cmd, env, dir);
  661. };
  662.  
  663. exec4.implementation = function(cmdarr, env, file) {
  664. for (var i = 0; i < cmdarr.length; i = i + 1) {
  665. var tmp_cmd = cmdarr[i];
  666. if (tmp_cmd.indexOf("getprop") != -1 || tmp_cmd == "mount" || tmp_cmd.indexOf("build.prop") != -1 || tmp_cmd == "id" || tmp_cmd == "sh") {
  667. var fakeCmd = "grep";
  668. send("Bypass " + cmdarr + " command");
  669. return exec1.call(this, fakeCmd);
  670. }
  671.  
  672. if (tmp_cmd == "su") {
  673. var fakeCmd = "justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
  674. send("Bypass " + cmdarr + " command");
  675. return exec1.call(this, fakeCmd);
  676. }
  677. }
  678. return exec4.call(this, cmdarr, env, file);
  679. };
  680.  
  681. exec3.implementation = function(cmdarr, envp) {
  682. for (var i = 0; i < cmdarr.length; i = i + 1) {
  683. var tmp_cmd = cmdarr[i];
  684. if (tmp_cmd.indexOf("getprop") != -1 || tmp_cmd == "mount" || tmp_cmd.indexOf("build.prop") != -1 || tmp_cmd == "id" || tmp_cmd == "sh") {
  685. var fakeCmd = "grep";
  686. send("Bypass " + cmdarr + " command");
  687. return exec1.call(this, fakeCmd);
  688. }
  689.  
  690. if (tmp_cmd == "su") {
  691. var fakeCmd = "justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
  692. send("Bypass " + cmdarr + " command");
  693. return exec1.call(this, fakeCmd);
  694. }
  695. }
  696. return exec3.call(this, cmdarr, envp);
  697. };
  698.  
  699. exec2.implementation = function(cmd, env) {
  700. if (cmd.indexOf("getprop") != -1 || cmd == "mount" || cmd.indexOf("build.prop") != -1 || cmd == "id" || cmd == "sh") {
  701. var fakeCmd = "grep";
  702. send("Bypass " + cmd + " command");
  703. return exec1.call(this, fakeCmd);
  704. }
  705. if (cmd == "su") {
  706. var fakeCmd = "justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
  707. send("Bypass " + cmd + " command");
  708. return exec1.call(this, fakeCmd);
  709. }
  710. return exec2.call(this, cmd, env);
  711. };
  712.  
  713. exec.implementation = function(cmd) {
  714. for (var i = 0; i < cmd.length; i = i + 1) {
  715. var tmp_cmd = cmd[i];
  716. if (tmp_cmd.indexOf("getprop") != -1 || tmp_cmd == "mount" || tmp_cmd.indexOf("build.prop") != -1 || tmp_cmd == "id" || tmp_cmd == "sh") {
  717. var fakeCmd = "grep";
  718. send("Bypass " + cmd + " command");
  719. return exec1.call(this, fakeCmd);
  720. }
  721.  
  722. if (tmp_cmd == "su") {
  723. var fakeCmd = "justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
  724. send("Bypass " + cmd + " command");
  725. return exec1.call(this, fakeCmd);
  726. }
  727. }
  728.  
  729. return exec.call(this, cmd);
  730. };
  731.  
  732. exec1.implementation = function(cmd) {
  733. if (cmd.indexOf("getprop") != -1 || cmd == "mount" || cmd.indexOf("build.prop") != -1 || cmd == "id" || cmd == "sh") {
  734. var fakeCmd = "grep";
  735. send("Bypass " + cmd + " command");
  736. return exec1.call(this, fakeCmd);
  737. }
  738. if (cmd == "su") {
  739. var fakeCmd = "justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled";
  740. send("Bypass " + cmd + " command");
  741. return exec1.call(this, fakeCmd);
  742. }
  743. return exec1.call(this, cmd);
  744. };
  745.  
  746. String.contains.implementation = function(name) {
  747. if (name == "test-keys") {
  748. send("Bypass test-keys check");
  749. return false;
  750. }
  751. return this.contains.call(this, name);
  752. };
  753.  
  754. var get = SystemProperties.get.overload('java.lang.String');
  755.  
  756. get.implementation = function(name) {
  757. if (RootPropertiesKeys.indexOf(name) != -1) {
  758. send("Bypass " + name);
  759. return RootProperties[name];
  760. }
  761. return this.get.call(this, name);
  762. };
  763.  
  764. Interceptor.attach(Module.findExportByName("libc.so", "fopen"), {
  765. onEnter: function(args) {
  766. var path = Memory.readCString(args[0]);
  767. path = path.split("/");
  768. var executable = path[path.length - 1];
  769. var shouldFakeReturn = (RootBinaries.indexOf(executable) > -1)
  770. if (shouldFakeReturn) {
  771. Memory.writeUtf8String(args[0], "/notexists");
  772. send("Bypass native fopen");
  773. }
  774. },
  775. onLeave: function(retval) {
  776.  
  777. }
  778. });
  779.  
  780. Interceptor.attach(Module.findExportByName("libc.so", "system"), {
  781. onEnter: function(args) {
  782. var cmd = Memory.readCString(args[0]);
  783. send("SYSTEM CMD: " + cmd);
  784. if (cmd.indexOf("getprop") != -1 || cmd == "mount" || cmd.indexOf("build.prop") != -1 || cmd == "id") {
  785. send("Bypass native system: " + cmd);
  786. Memory.writeUtf8String(args[0], "grep");
  787. }
  788. if (cmd == "su") {
  789. send("Bypass native system: " + cmd);
  790. Memory.writeUtf8String(args[0], "justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled");
  791. }
  792. },
  793. onLeave: function(retval) {
  794.  
  795. }
  796. });
  797.  
  798. /*
  799.  
  800. TO IMPLEMENT:
  801.  
  802. Exec Family
  803.  
  804. int execl(const char *path, const char *arg0, ..., const char *argn, (char *)0);
  805. int execle(const char *path, const char *arg0, ..., const char *argn, (char *)0, char *const envp[]);
  806. int execlp(const char *file, const char *arg0, ..., const char *argn, (char *)0);
  807. int execlpe(const char *file, const char *arg0, ..., const char *argn, (char *)0, char *const envp[]);
  808. int execv(const char *path, char *const argv[]);
  809. int execve(const char *path, char *const argv[], char *const envp[]);
  810. int execvp(const char *file, char *const argv[]);
  811. int execvpe(const char *file, char *const argv[], char *const envp[]);
  812.  
  813. */
  814.  
  815.  
  816. BufferedReader.readLine.overload('boolean').implementation = function() {
  817. var text = this.readLine.overload('boolean').call(this);
  818. if (text === null) {
  819. // just pass , i know it's ugly as hell but test != null won't work :(
  820. } else {
  821. var shouldFakeRead = (text.indexOf("ro.build.tags=test-keys") > -1);
  822. if (shouldFakeRead) {
  823. send("Bypass build.prop file read");
  824. text = text.replace("ro.build.tags=test-keys", "ro.build.tags=release-keys");
  825. }
  826. }
  827. return text;
  828. };
  829.  
  830. var executeCommand = ProcessBuilder.command.overload('java.util.List');
  831.  
  832. ProcessBuilder.start.implementation = function() {
  833. var cmd = this.command.call(this);
  834. var shouldModifyCommand = false;
  835. for (var i = 0; i < cmd.size(); i = i + 1) {
  836. var tmp_cmd = cmd.get(i).toString();
  837. if (tmp_cmd.indexOf("getprop") != -1 || tmp_cmd.indexOf("mount") != -1 || tmp_cmd.indexOf("build.prop") != -1 || tmp_cmd.indexOf("id") != -1) {
  838. shouldModifyCommand = true;
  839. }
  840. }
  841. if (shouldModifyCommand) {
  842. send("Bypass ProcessBuilder " + cmd);
  843. this.command.call(this, ["grep"]);
  844. return this.start.call(this);
  845. }
  846. if (cmd.indexOf("su") != -1) {
  847. send("Bypass ProcessBuilder " + cmd);
  848. this.command.call(this, ["justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled"]);
  849. return this.start.call(this);
  850. }
  851.  
  852. return this.start.call(this);
  853. };
  854.  
  855. if (useProcessManager) {
  856. var ProcManExec = ProcessManager.exec.overload('[Ljava.lang.String;', '[Ljava.lang.String;', 'java.io.File', 'boolean');
  857. var ProcManExecVariant = ProcessManager.exec.overload('[Ljava.lang.String;', '[Ljava.lang.String;', 'java.lang.String', 'java.io.FileDescriptor', 'java.io.FileDescriptor', 'java.io.FileDescriptor', 'boolean');
  858.  
  859. ProcManExec.implementation = function(cmd, env, workdir, redirectstderr) {
  860. var fake_cmd = cmd;
  861. for (var i = 0; i < cmd.length; i = i + 1) {
  862. var tmp_cmd = cmd[i];
  863. if (tmp_cmd.indexOf("getprop") != -1 || tmp_cmd == "mount" || tmp_cmd.indexOf("build.prop") != -1 || tmp_cmd == "id") {
  864. var fake_cmd = ["grep"];
  865. send("Bypass " + cmdarr + " command");
  866. }
  867.  
  868. if (tmp_cmd == "su") {
  869. var fake_cmd = ["justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled"];
  870. send("Bypass " + cmdarr + " command");
  871. }
  872. }
  873. return ProcManExec.call(this, fake_cmd, env, workdir, redirectstderr);
  874. };
  875.  
  876. ProcManExecVariant.implementation = function(cmd, env, directory, stdin, stdout, stderr, redirect) {
  877. var fake_cmd = cmd;
  878. for (var i = 0; i < cmd.length; i = i + 1) {
  879. var tmp_cmd = cmd[i];
  880. if (tmp_cmd.indexOf("getprop") != -1 || tmp_cmd == "mount" || tmp_cmd.indexOf("build.prop") != -1 || tmp_cmd == "id") {
  881. var fake_cmd = ["grep"];
  882. send("Bypass " + cmdarr + " command");
  883. }
  884.  
  885. if (tmp_cmd == "su") {
  886. var fake_cmd = ["justafakecommandthatcannotexistsusingthisshouldthowanexceptionwheneversuiscalled"];
  887. send("Bypass " + cmdarr + " command");
  888. }
  889. }
  890. return ProcManExecVariant.call(this, fake_cmd, env, directory, stdin, stdout, stderr, redirect);
  891. };
  892. }
  893.  
  894. if (useKeyInfo) {
  895. KeyInfo.isInsideSecureHardware.implementation = function() {
  896. send("Bypass isInsideSecureHardware");
  897. return true;
  898. }
  899. }
  900.  
  901. });
  902.  
  903. const commonPaths = [
  904. "/data/local/bin/su",
  905. "/data/local/su",
  906. "/data/local/xbin/su",
  907. "/dev/com.koushikdutta.superuser.daemon/",
  908. "/sbin/su",
  909. "/system/app/Superuser.apk",
  910. "/system/bin/failsafe/su",
  911. "/system/bin/su",
  912. "/su/bin/su",
  913. "/system/etc/init.d/99SuperSUDaemon",
  914. "/system/sd/xbin/su",
  915. "/system/xbin/busybox",
  916. "/system/xbin/daemonsu",
  917. "/system/xbin/su",
  918. "/system/sbin/su",
  919. "/vendor/bin/su",
  920. "/cache/su",
  921. "/data/su",
  922. "/dev/su",
  923. "/system/bin/.ext/su",
  924. "/system/usr/we-need-root/su",
  925. "/system/app/Kinguser.apk",
  926. "/data/adb/magisk",
  927. "/sbin/.magisk",
  928. "/cache/.disable_magisk",
  929. "/dev/.magisk.unblock",
  930. "/cache/magisk.log",
  931. "/data/adb/magisk.img",
  932. "/data/adb/magisk.db",
  933. "/data/adb/magisk_simple",
  934. "/init.magisk.rc",
  935. "/system/xbin/ku.sud",
  936. "/data/adb/ksu",
  937. "/data/adb/ksud"
  938. ];
  939.  
  940. const ROOTmanagementApp = [
  941. "com.noshufou.android.su",
  942. "com.noshufou.android.su.elite",
  943. "eu.chainfire.supersu",
  944. "com.koushikdutta.superuser",
  945. "com.thirdparty.superuser",
  946. "com.yellowes.su",
  947. "com.koushikdutta.rommanager",
  948. "com.koushikdutta.rommanager.license",
  949. "com.dimonvideo.luckypatcher",
  950. "com.chelpus.lackypatch",
  951. "com.ramdroid.appquarantine",
  952. "com.ramdroid.appquarantinepro",
  953. "com.topjohnwu.magisk",
  954. "me.weishu.kernelsu"
  955. ];
  956.  
  957.  
  958.  
  959. function stackTraceHere(isLog){
  960. var Exception = Java.use('java.lang.Exception');
  961. var Log = Java.use('android.util.Log');
  962. var stackinfo = Log.getStackTraceString(Exception.$new())
  963. if(isLog){
  964. console.log(stackinfo)
  965. }else{
  966. return stackinfo
  967. }
  968. }
  969.  
  970. function stackTraceNativeHere(isLog){
  971. var backtrace = Thread.backtrace(this.context, Backtracer.ACCURATE)
  972. .map(DebugSymbol.fromAddress)
  973. .join("\n\t");
  974. console.log(backtrace)
  975. }
  976.  
  977.  
  978. function bypassJavaFileCheck(){
  979. var UnixFileSystem = Java.use("java.io.UnixFileSystem")
  980. UnixFileSystem.checkAccess.implementation = function(file,access){
  981.  
  982. var stack = stackTraceHere(false)
  983.  
  984. const filename = file.getAbsolutePath();
  985.  
  986. if (filename.indexOf("magisk") >= 0) {
  987. console.log("Anti Root Detect - check file: " + filename)
  988. return false;
  989. }
  990.  
  991. if (commonPaths.indexOf(filename) >= 0) {
  992. console.log("Anti Root Detect - check file: " + filename)
  993. return false;
  994. }
  995.  
  996. return this.checkAccess(file,access)
  997. }
  998. }
  999.  
  1000. function bypassNativeFileCheck(){
  1001. var fopen = Module.findExportByName("libc.so","fopen")
  1002. Interceptor.attach(fopen,{
  1003. onEnter:function(args){
  1004. this.inputPath = args[0].readUtf8String()
  1005. },
  1006. onLeave:function(retval){
  1007. if(retval.toInt32() != 0){
  1008. if (commonPaths.indexOf(this.inputPath) >= 0) {
  1009. console.log("Anti Root Detect - fopen : " + this.inputPath)
  1010. retval.replace(ptr(0x0))
  1011. }
  1012. }
  1013. }
  1014. })
  1015.  
  1016. var access = Module.findExportByName("libc.so","access")
  1017. Interceptor.attach(access,{
  1018. onEnter:function(args){
  1019. this.inputPath = args[0].readUtf8String()
  1020. },
  1021. onLeave:function(retval){
  1022. if(retval.toInt32()==0){
  1023. if(commonPaths.indexOf(this.inputPath) >= 0){
  1024. console.log("Anti Root Detect - access : " + this.inputPath)
  1025. retval.replace(ptr(-1))
  1026. }
  1027. }
  1028. }
  1029. })
  1030. }
  1031.  
  1032. function setProp(){
  1033. var Build = Java.use("android.os.Build")
  1034. var TAGS = Build.class.getDeclaredField("TAGS")
  1035. TAGS.setAccessible(true)
  1036. TAGS.set(null,"release-keys")
  1037.  
  1038. var FINGERPRINT = Build.class.getDeclaredField("FINGERPRINT")
  1039. FINGERPRINT.setAccessible(true)
  1040. FINGERPRINT.set(null,"google/crosshatch/crosshatch:10/QQ3A.200805.001/6578210:user/release-keys")
  1041.  
  1042. // Build.deriveFingerprint.inplementation = function(){
  1043. // var ret = this.deriveFingerprint() //该函数无法通过反射调用
  1044. // console.log(ret)
  1045. // return ret
  1046. // }
  1047.  
  1048. var system_property_get = Module.findExportByName("libc.so", "__system_property_get")
  1049. Interceptor.attach(system_property_get,{
  1050. onEnter(args){
  1051. this.key = args[0].readCString()
  1052. this.ret = args[1]
  1053. },
  1054. onLeave(ret){
  1055. if(this.key == "ro.build.fingerprint"){
  1056. var tmp = "google/crosshatch/crosshatch:10/QQ3A.200805.001/6578210:user/release-keys"
  1057. var p = Memory.allocUtf8String(tmp)
  1058. Memory.copy(this.ret,p,tmp.length+1)
  1059. }
  1060. }
  1061. })
  1062.  
  1063. }
  1064.  
  1065. //android.app.PackageManager
  1066. function bypassRootAppCheck(){
  1067. var ApplicationPackageManager = Java.use("android.app.ApplicationPackageManager")
  1068. ApplicationPackageManager.getPackageInfo.overload('java.lang.String', 'int').implementation = function(str,i){
  1069. // console.log(str)
  1070. if (ROOTmanagementApp.indexOf(str) >= 0) {
  1071. console.log("Anti Root Detect - check package : " + str)
  1072. str = "ashen.one.ye.not.found"
  1073. }
  1074. return this.getPackageInfo(str,i)
  1075. }
  1076.  
  1077. //shell pm check
  1078. }
  1079.  
  1080. function bypassShellCheck(){
  1081. var String = Java.use('java.lang.String')
  1082.  
  1083. var ProcessImpl = Java.use("java.lang.ProcessImpl")
  1084. ProcessImpl.start.implementation = function(cmdarray,env,dir,redirects,redirectErrorStream){
  1085.  
  1086. if(cmdarray[0] == "mount"){
  1087. console.log("Anti Root Detect - Shell : " + cmdarray.toString())
  1088. arguments[0] = Java.array('java.lang.String',[String.$new("")])
  1089. return ProcessImpl.start.apply(this,arguments)
  1090. }
  1091.  
  1092. if(cmdarray[0] == "getprop"){
  1093. console.log("Anti Root Detect - Shell : " + cmdarray.toString())
  1094. const prop = [
  1095. "ro.secure",
  1096. "ro.debuggable"
  1097. ];
  1098. if(prop.indexOf(cmdarray[1]) >= 0){
  1099. arguments[0] = Java.array('java.lang.String',[String.$new("")])
  1100. return ProcessImpl.start.apply(this,arguments)
  1101. }
  1102. }
  1103.  
  1104. if(cmdarray[0].indexOf("which") >= 0){
  1105. const prop = [
  1106. "su"
  1107. ];
  1108. if(prop.indexOf(cmdarray[1]) >= 0){
  1109. console.log("Anti Root Detect - Shell : " + cmdarray.toString())
  1110. arguments[0] = Java.array('java.lang.String',[String.$new("")])
  1111. return ProcessImpl.start.apply(this,arguments)
  1112. }
  1113. }
  1114.  
  1115. return ProcessImpl.start.apply(this,arguments)
  1116. }
  1117. }
  1118.  
  1119.  
  1120. console.log("Attach")
  1121. bypassNativeFileCheck()
  1122. bypassJavaFileCheck()
  1123. setProp()
  1124. bypassRootAppCheck()
  1125. bypassShellCheck()
Tags: Android frida
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement