1. frida

  1. //自吐
  2. Java.perform(function () {
  3. function showStacks() {
  4. console.log(
  5. Java.use("android.util.Log")
  6. .getStackTraceString(
  7. Java.use("java.lang.Throwable").$new()
  8. )
  9. );
  10. }
  11. var ByteString = Java.use("com.android.okhttp.okio.ByteString");
  12. function toBase64(tag, data) {
  13. console.log(tag + " Base64: ", ByteString.of(data).base64());
  14. }
  15. function toHex(tag, data) {
  16. console.log(tag + " Hex: ", ByteString.of(data).hex());
  17. }
  18. function toUtf8(tag, data) {
  19. console.log(tag + " Utf8: ", ByteString.of(data).utf8());
  20. }
  21. // toBase64([48,49,50,51,52]);
  22. // toHex([48,49,50,51,52]);
  23. // toUtf8([48,49,50,51,52]);
  24. //console.log(Java.enumerateLoadedClassesSync().join("\n"));
  25. // MD5/SHA等
  26. var messageDigest = Java.use("java.security.MessageDigest");
  27. messageDigest.update.overload('byte').implementation = function (data) {
  28. console.log("MessageDigest.update('byte') is called!");
  29. return this.update(data);
  30. }
  31. messageDigest.update.overload('java.nio.ByteBuffer').implementation = function (data) {
  32. console.log("MessageDigest.update('java.nio.ByteBuffer') is called!");
  33. return this.update(data);
  34. }
  35. messageDigest.update.overload('[B').implementation = function (data) {
  36. console.log("MessageDigest.update('[B') is called!");
  37. var algorithm = this.getAlgorithm();
  38. var tag = algorithm + " update data";
  39. toUtf8(tag, data);
  40. toHex(tag, data);
  41. toBase64(tag, data);
  42. console.log("=======================================================");
  43. return this.update(data);
  44. }
  45. messageDigest.update.overload('[B', 'int', 'int').implementation = function (data, start, length) {
  46. console.log("MessageDigest.update('[B', 'int', 'int') is called!");
  47. var algorithm = this.getAlgorithm();
  48. var tag = algorithm + " update data";
  49. toUtf8(tag, data);
  50. toHex(tag, data);
  51. toBase64(tag, data);
  52. console.log("=======================================================", start, length);
  53. return this.update(data, start, length);
  54. }
  55. messageDigest.digest.overload().implementation = function () {
  56. console.log("MessageDigest.digest() is called!");
  57. var result = this.digest();
  58. var algorithm = this.getAlgorithm();
  59. var tag = algorithm + " digest result";
  60. toHex(tag, result);
  61. toBase64(tag, result);
  62. console.log("=======================================================");
  63. return result;
  64. }
  65. messageDigest.digest.overload('[B').implementation = function (data) {
  66. console.log("MessageDigest.digest('[B') is called!");
  67. var algorithm = this.getAlgorithm();
  68. var tag = algorithm + " digest data";
  69. toUtf8(tag, data);
  70. toHex(tag, data);
  71. toBase64(tag, data);
  72. var result = this.digest(data);
  73. var tags = algorithm + " digest result";
  74. toHex(tags, result);
  75. toBase64(tags, result);
  76. console.log("=======================================================");
  77. return result;
  78. }
  79. messageDigest.digest.overload('[B', 'int', 'int').implementation = function (data, start, length) {
  80. console.log("MessageDigest.digest('[B', 'int', 'int') is called!");
  81. var algorithm = this.getAlgorithm();
  82. var tag = algorithm + " digest data";
  83. toUtf8(tag, data);
  84. toHex(tag, data);
  85. toBase64(tag, data);
  86. var result = this.digest(data, start, length);
  87. var tags = algorithm + " digest result";
  88. toHex(tags, result);
  89. toBase64(tags, result);
  90. console.log("=======================================================", start, length);
  91. return result;
  92. }
  93. //Mac
  94. var mac = Java.use("javax.crypto.Mac");
  95. mac.init.overload('java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function (key, AlgorithmParameterSpec) {
  96. console.log("Mac.init('java.security.Key', 'java.security.spec.AlgorithmParameterSpec') is called!");
  97. return this.init(key, AlgorithmParameterSpec);
  98. }
  99. mac.init.overload('java.security.Key').implementation = function (key) {
  100. console.log("Mac.init('java.security.Key') is called!");
  101. var algorithm = this.getAlgorithm();
  102. var tag = algorithm + " init Key";
  103. var keyBytes = key.getEncoded();
  104. toUtf8(tag, keyBytes);
  105. toHex(tag, keyBytes);
  106. toBase64(tag, keyBytes);
  107. console.log("=======================================================");
  108. return this.init(key);
  109. }
  110. mac.update.overload('byte').implementation = function (data) {
  111. console.log("Mac.update('byte') is called!");
  112. return this.update(data);
  113. }
  114. mac.update.overload('java.nio.ByteBuffer').implementation = function (data) {
  115. console.log("Mac.update('java.nio.ByteBuffer') is called!");
  116. return this.update(data);
  117. }
  118. mac.update.overload('[B').implementation = function (data) {
  119. console.log("Mac.update('[B') is called!");
  120. var algorithm = this.getAlgorithm();
  121. var tag = algorithm + " update data";
  122. toUtf8(tag, data);
  123. toHex(tag, data);
  124. toBase64(tag, data);
  125. console.log("=======================================================");
  126. return this.update(data);
  127. }
  128. mac.update.overload('[B', 'int', 'int').implementation = function (data, start, length) {
  129. console.log("Mac.update('[B', 'int', 'int') is called!");
  130. var algorithm = this.getAlgorithm();
  131. var tag = algorithm + " update data";
  132. toUtf8(tag, data);
  133. toHex(tag, data);
  134. toBase64(tag, data);
  135. console.log("=======================================================", start, length);
  136. return this.update(data, start, length);
  137. }
  138. mac.doFinal.overload().implementation = function () {
  139. console.log("Mac.doFinal() is called!");
  140. var result = this.doFinal();
  141. var algorithm = this.getAlgorithm();
  142. var tag = algorithm + " doFinal result";
  143. toHex(tag, result);
  144. toBase64(tag, result);
  145. console.log("=======================================================");
  146. return result;
  147. }
  148. //cipher
  149. var cipher = Java.use("javax.crypto.Cipher");
  150. cipher.init.overload('int', 'java.security.cert.Certificate').implementation = function () {
  151. console.log("Cipher.init('int', 'java.security.cert.Certificate') is called!");
  152. return this.init.apply(this, arguments);
  153. }
  154. cipher.init.overload('int', 'java.security.Key', 'java.security.SecureRandom').implementation = function () {
  155. console.log("Cipher.init('int', 'java.security.Key', 'java.security.SecureRandom') is called!");
  156. return this.init.apply(this, arguments);
  157. }
  158. cipher.init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom').implementation = function () {
  159. console.log("Cipher.init('int', 'java.security.cert.Certificate', 'java.security.SecureRandom') is called!");
  160. return this.init.apply(this, arguments);
  161. }
  162. cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function () {
  163. console.log("Cipher.init('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom') is called!");
  164. return this.init.apply(this, arguments);
  165. }
  166. cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom').implementation = function () {
  167. console.log("Cipher.init('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom') is called!");
  168. return this.init.apply(this, arguments);
  169. }
  170. cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters').implementation = function () {
  171. console.log("Cipher.init('int', 'java.security.Key', 'java.security.AlgorithmParameters') is called!");
  172. return this.init.apply(this, arguments);
  173. }
  174. cipher.init.overload('int', 'java.security.Key').implementation = function () {
  175. console.log("Cipher.init('int', 'java.security.Key') is called!");
  176. var algorithm = this.getAlgorithm();
  177. var tag = algorithm + " init Key";
  178. var className = JSON.stringify(arguments[1]);
  179. if (className.indexOf("OpenSSLRSAPrivateKey") === -1) {
  180. var keyBytes = arguments[1].getEncoded();
  181. toUtf8(tag, keyBytes);
  182. toHex(tag, keyBytes);
  183. toBase64(tag, keyBytes);
  184. }
  185. console.log("=======================================================");
  186. return this.init.apply(this, arguments);
  187. }
  188. cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function () {
  189. console.log("Cipher.init('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec') is called!");
  190. var algorithm = this.getAlgorithm();
  191. var tag = algorithm + " init Key";
  192. var keyBytes = arguments[1].getEncoded();
  193. toUtf8(tag, keyBytes);
  194. toHex(tag, keyBytes);
  195. toBase64(tag, keyBytes);
  196. var tags = algorithm + " init iv";
  197. var iv = Java.cast(arguments[2], Java.use("javax.crypto.spec.IvParameterSpec"));
  198. var ivBytes = iv.getIV();
  199. toUtf8(tags, ivBytes);
  200. toHex(tags, ivBytes);
  201. toBase64(tags, ivBytes);
  202. console.log("=======================================================");
  203. return this.init.apply(this, arguments);
  204. }
  205. cipher.doFinal.overload('java.nio.ByteBuffer', 'java.nio.ByteBuffer').implementation = function () {
  206. console.log("Cipher.doFinal('java.nio.ByteBuffer', 'java.nio.ByteBuffer') is called!");
  207. showStacks();
  208. return this.doFinal.apply(this, arguments);
  209. }
  210. cipher.doFinal.overload('[B', 'int').implementation = function () {
  211. console.log("Cipher.doFinal('[B', 'int') is called!");
  212. showStacks();
  213. return this.doFinal.apply(this, arguments);
  214. }
  215. cipher.doFinal.overload('[B', 'int', 'int', '[B').implementation = function () {
  216. console.log("Cipher.doFinal('[B', 'int', 'int', '[B') is called!");
  217. showStacks();
  218. return this.doFinal.apply(this, arguments);
  219. }
  220. cipher.doFinal.overload('[B', 'int', 'int', '[B', 'int').implementation = function () {
  221. console.log("Cipher.doFinal('[B', 'int', 'int', '[B', 'int') is called!");
  222. showStacks();
  223. return this.doFinal.apply(this, arguments);
  224. }
  225. cipher.doFinal.overload().implementation = function () {
  226. console.log("Cipher.doFinal() is called!");
  227. showStacks();
  228. return this.doFinal.apply(this, arguments);
  229. }
  230. cipher.doFinal.overload('[B').implementation = function () {
  231. console.log("Cipher.doFinal('[B') is called!");
  232. showStacks();
  233. var algorithm = this.getAlgorithm();
  234. var tag = algorithm + " doFinal data";
  235. var data = arguments[0];
  236. toUtf8(tag, data);
  237. toHex(tag, data);
  238. toBase64(tag, data);
  239. var result = this.doFinal.apply(this, arguments);
  240. var tags = algorithm + " doFinal result";
  241. toHex(tags, result);
  242. toBase64(tags, result);
  243. console.log("=======================================================");
  244. return result;
  245. }
  246. cipher.doFinal.overload('[B', 'int', 'int').implementation = function () {
  247. console.log("Cipher.doFinal('[B', 'int', 'int') is called!");
  248. showStacks();
  249. var algorithm = this.getAlgorithm();
  250. var tag = algorithm + " doFinal data";
  251. var data = arguments[0];
  252. toUtf8(tag, data);
  253. toHex(tag, data);
  254. toBase64(tag, data);
  255. var result = this.doFinal.apply(this, arguments);
  256. var tags = algorithm + " doFinal result";
  257. toHex(tags, result);
  258. toBase64(tags, result);
  259. console.log("=======================================================", arguments[1], arguments[2]);
  260. return result;
  261. }
  262. //signature
  263. var signature = Java.use("java.security.Signature");
  264. signature.update.overload('byte').implementation = function (data) {
  265. console.log("Signature.update('byte') is called!");
  266. return this.update(data);
  267. }
  268. signature.update.overload('java.nio.ByteBuffer').implementation = function (data) {
  269. console.log("Signature.update('java.nio.ByteBuffer') is called!");
  270. return this.update(data);
  271. }
  272. signature.update.overload('[B', 'int', 'int').implementation = function (data, start, length) {
  273. console.log("Signature.update('[B', 'int', 'int') is called!");
  274. var algorithm = this.getAlgorithm();
  275. var tag = algorithm + " update data";
  276. toUtf8(tag, data);
  277. toHex(tag, data);
  278. toBase64(tag, data);
  279. console.log("=======================================================", start, length);
  280. return this.update(data, start, length);
  281. }
  282. signature.sign.overload('[B', 'int', 'int').implementation = function () {
  283. console.log("Signature.sign('[B', 'int', 'int') is called!");
  284. return this.sign.apply(this, arguments);
  285. }
  286. signature.sign.overload().implementation = function () {
  287. console.log("Signature.sign() is called!");
  288. var result = this.sign();
  289. var algorithm = this.getAlgorithm();
  290. var tag = algorithm + " sign result";
  291. toHex(tag, result);
  292. toBase64(tag, result);
  293. console.log("=======================================================");
  294. return result;
  295. }
  296. });
  1. /**
  2. * Java层标准算法hook
  3. */
  4. Java.perform(function () {
  5. /**
  6. 打印堆栈
  7. */
  8. function showStack() {
  9. let Throwable = Java.use("java.lang.Throwable");
  10. let stackTraceString = Java.use("android.util.Log").getStackTraceString(Throwable.$new())
  11. console.log(stackTraceString);
  12. }
  13. let ByteString = Java.use("com.android.okhttp.okio.ByteString");
  14. /**
  15. * 字节数组转为Base64
  16. */
  17. function toBase64(tag, data) {
  18. console.log(tag + " Base64:" + ByteString.of(data).base64());
  19. }
  20. /**
  21. * 字节数组转为16进制
  22. */
  23. function toHex(tag, data) {
  24. console.log(tag + " Hex:" + ByteString.of(data).hex());
  25. }
  26. /**
  27. * 字节数组转为明文
  28. */
  29. function toUtf8(tag, data) {
  30. console.log(tag + " Utf8:" + ByteString.of(data).utf8());
  31. }
  32. /**
  33. * 打印字节数组对应的输出数据
  34. */
  35. function printData(tag, data) {
  36. toBase64(tag, data);
  37. toHex(tag, data);
  38. toUtf8(tag, data);
  39. }
  40. /***
  41. * 消息摘要算法hook
  42. * update 压入数据
  43. * digest 返回加密结果
  44. */
  45. function hookMessageDigest() {
  46. let MessageDigest = Java.use("java.security.MessageDigest");
  47. MessageDigest.update.overload('byte').implementation = function (b) {
  48. showStack();
  49. console.log("MessageDigest.update.overload('byte') is called!");
  50. let result = this.update.apply(this, arguments);
  51. let algorithm = this.getAlgorithm();
  52. printData(algorithm + " update param", Java.array('byte', [b]))
  53. console.log("============================================================");
  54. return result;
  55. }
  56. MessageDigest.update.overload('[B').implementation = function (byteArr) {
  57. showStack();
  58. console.log("MessageDigest.update.overload('[B') is called!");
  59. let result = this.update.apply(this, arguments);
  60. let algorithm = this.getAlgorithm();
  61. printData(algorithm + " update param", byteArr);
  62. console.log("============================================================");
  63. return result;
  64. }
  65. MessageDigest.digest.overload().implementation = function () {
  66. showStack();
  67. console.log("MessageDigest.digest.overload() is called!");
  68. let result = this.digest.apply(this, arguments);
  69. let algorithm = this.getAlgorithm();
  70. printData(algorithm + " digest result", result);
  71. console.log("============================================================");
  72. return result;
  73. }
  74. MessageDigest.digest.overload('[B').implementation = function (byteArr) {
  75. showStack();
  76. console.log("MessageDigest.digest.overload('[B') is called!");
  77. let result = this.digest.apply(this, arguments);
  78. let algorithm = this.getAlgorithm();
  79. printData(algorithm + " digest param", byteArr);
  80. printData(algorithm + " digest result", result);
  81. console.log("============================================================");
  82. return result;
  83. }
  84. MessageDigest.digest.overload('[B', 'int', 'int').implementation = function (byteArr, start, length) {
  85. showStack();
  86. console.log("MessageDigest.digest.overload('[B', 'int', 'int') is called!");
  87. let result = this.digest.apply(this, arguments);
  88. let algorithm = this.getAlgorithm();
  89. printData(algorithm + " digest param", byteArr);
  90. printData(algorithm + " digest result", result);
  91. console.log("============================================================" + "开始位置:" + start + " 截取长度:" + length);
  92. return result;
  93. }
  94. }
  95. /**
  96. * Mac算法hook
  97. * 1.init 初始化,秘钥
  98. * 2.update 压入数据
  99. * 3.doFinal 加密
  100. */
  101. function hookMac() {
  102. let Mac = Java.use("javax.crypto.Mac");
  103. Mac.init.overload('java.security.Key').implementation = function (key) {
  104. showStack();
  105. console.log("Mac.init.overload('java.security.Key') is called!");
  106. let result = this.init.apply(this, arguments);
  107. let algorithm = this.getAlgorithm();
  108. printData(algorithm + " init key", key.getEncoded())
  109. console.log("============================================================");
  110. return result;
  111. }
  112. Mac.update.overload('byte').implementation = function (b) {
  113. showStack();
  114. console.log("Mac.update.overload('byte') is called!");
  115. let result = this.update.apply(this, arguments);
  116. let algorithm = this.getAlgorithm();
  117. printData(algorithm + " update param", Java.array('byte', [b]))
  118. console.log("============================================================");
  119. return result;
  120. }
  121. Mac.update.overload('[B').implementation = function (byteArr) {
  122. showStack();
  123. console.log("Mac.update.overload('[B') is called!");
  124. let result = this.update.apply(this, arguments);
  125. let algorithm = this.getAlgorithm();
  126. printData(algorithm + " update param", byteArr)
  127. console.log("============================================================");
  128. return result;
  129. }
  130. Mac.update.overload('[B', 'int', 'int').implementation = function (byteArr, start, length) {
  131. showStack();
  132. console.log("Mac.update.overload('[B', 'int', 'int') is called!");
  133. let result = this.update.apply(this, arguments);
  134. let algorithm = this.getAlgorithm();
  135. printData(algorithm + " update param", byteArr)
  136. console.log("============================================================" + "开始位置:" + start + " 截取长度:" + length);
  137. return result;
  138. }
  139. Mac.doFinal.overload().implementation = function () {
  140. showStack();
  141. console.log("Mac.doFinal.overload() is called!");
  142. let result = this.doFinal.apply(this, arguments);
  143. let algorithm = this.getAlgorithm();
  144. printData(algorithm + " doFinal result", result)
  145. console.log("============================================================");
  146. return result;
  147. }
  148. }
  149. /**
  150. * DES,DESEde,AES,RSA
  151. * 1.init 加密类型,key,iv
  152. * 2.donFinal压入数据,得到结果 update压入结果有问题
  153. */
  154. function hookCipher() {
  155. function printResult(cipherObj, result, args) {
  156. let algorithm = cipherObj.getAlgorithm();
  157. let mode;
  158. if (cipherObj.opmode.value === 1) {
  159. mode = "加密";
  160. } else {
  161. mode = "解密";
  162. }
  163. console.log(algorithm + " mode:", mode);
  164. if (cipherObj.getParameters() != null) {
  165. printData(algorithm + " key", cipherObj.getParameters().getEncoded());
  166. printData(algorithm + " iv", cipherObj.getIV());
  167. }
  168. printData(algorithm + " doFinal param", args[0]);
  169. printData(algorithm + " doFinal result", result);
  170. console.log("============================================================");
  171. }
  172. let Cipher = Java.use("javax.crypto.Cipher");
  173. // 不常用重载,打印调用即可,根据堆栈信息在具体去看
  174. // init暂时注释
  175. Cipher.init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom').implementation = function (key) {
  176. showStack();
  177. console.log("Cipher.init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom') is called!");
  178. let result = this.apply(this, arguments);
  179. return result;
  180. }
  181. Cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function (key) {
  182. showStack();
  183. console.log("Cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom') is called!");
  184. let result = this.apply(this, arguments);
  185. return result;
  186. }
  187. // ECB模式,不带iv
  188. Cipher.init.overload('int', 'java.security.Key', 'java.security.SecureRandom').implementation = function () {
  189. showStack();
  190. console.log("Cipher.init.overload('int', 'java.security.Key', 'java.security.SecureRandom') is called!");
  191. let result = this.init.apply(this, arguments);
  192. let algorithm = this.getAlgorithm();
  193. let mode;
  194. if (arguments[0] === 1) {
  195. mode = "加密";
  196. } else {
  197. mode = "解密";
  198. }
  199. console.log(algorithm + " init mode:" + mode);
  200. try {
  201. // RSA使用私钥调用getEncoded() 会报错,异常捕获,具体逻辑,根据堆栈,去APP分析
  202. printData(algorithm + " init key", arguments[1].getEncoded());
  203. } catch (e) {
  204. console.log(e);
  205. }
  206. console.log("============================================================");
  207. return result;
  208. }
  209. // CBC模式,带iv
  210. Cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom').implementation = function () {
  211. showStack();
  212. console.log("Cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom') is called!");
  213. let result = this.init.apply(this, arguments);
  214. let algorithm = this.getAlgorithm();
  215. let ivParameterSpecObj = Java.cast(arguments[2], Java.use("javax.crypto.spec.IvParameterSpec"));
  216. let mode;
  217. if (arguments[0] === 1) {
  218. mode = "加密";
  219. } else {
  220. mode = "解密";
  221. }
  222. console.log(algorithm + " init mode:" + mode);
  223. printData(algorithm + " init key", arguments[1].getEncoded());
  224. printData(algorithm + " init iv", ivParameterSpecObj.getIV());
  225. console.log("============================================================");
  226. return result;
  227. }
  228. Cipher.doFinal.overload().implementation = function () {
  229. showStack();
  230. console.log("Cipher.doFinal.overload() is called!");
  231. let result = this.doFinal.apply(this, arguments);
  232. printResult(this, result, arguments);
  233. return result;
  234. }
  235. Cipher.doFinal.overload('[B').implementation = function () {
  236. showStack();
  237. console.log("Cipher.doFinal.overload('[B') is called!");
  238. let result = this.doFinal.apply(this, arguments);
  239. printResult(this, result, arguments);
  240. return result;
  241. }
  242. Cipher.doFinal.overload('[B', 'int').implementation = function () {
  243. showStack();
  244. console.log("Cipher.doFinal.overload('[B', 'int') is called!");
  245. let result = this.doFinal.apply(this, arguments);
  246. printResult(this, result, arguments);
  247. return result;
  248. }
  249. Cipher.doFinal.overload('[B', 'int', 'int').implementation = function () {
  250. showStack();
  251. console.log("Cipher.doFinal.overload('[B', 'int', 'int') is called!");
  252. let result = this.doFinal.apply(this, arguments);
  253. printResult(this, result, arguments);
  254. return result;
  255. }
  256. Cipher.doFinal.overload('[B', 'int', 'int', '[B').implementation = function () {
  257. showStack();
  258. console.log("Cipher.doFinal.overload('[B', 'int', 'int', '[B') is called!");
  259. let result = this.doFinal.apply(this, arguments);
  260. printResult(this, result, arguments);
  261. return result;
  262. }
  263. Cipher.doFinal.overload('[B', 'int', 'int', '[B', 'int').implementation = function () {
  264. showStack();
  265. console.log("Cipher.doFinal.overload('[B', 'int', 'int', '[B', 'int') is called!");
  266. let result = this.doFinal.apply(this, arguments);
  267. printResult(this, result, arguments);
  268. return result;
  269. }
  270. }
  271. /**
  272. * 签名算法hook
  273. * 私钥
  274. */
  275. function hookSignature() {
  276. let Signature = Java.use("java.security.Signature");
  277. Signature.initSign.overload('java.security.PrivateKey').implementation = function () {
  278. showStack();
  279. console.log("Signature.initSign.overload('java.security.PrivateKey') is called!");
  280. let result = this.initSign.apply(this, arguments);
  281. let algorithm = this.getAlgorithm();
  282. try {
  283. // RSA使用Hex编码的私钥调用getEncoded() 会报错,异常捕获,具体逻辑,根据堆栈,去APP分析
  284. printData(algorithm + " init key", arguments[0].getEncoded());
  285. } catch (e) {
  286. console.log(JSON.stringify(arguments[0]) + "|" + e);
  287. }
  288. console.log("============================================================");
  289. return result;
  290. }
  291. Signature.update.overload('byte').implementation = function () {
  292. showStack();
  293. console.log("Signature.update.overload('byte') is called!");
  294. let result = this.update.apply(this, arguments);
  295. let algorithm = this.getAlgorithm();
  296. printData(algorithm + " update param", Java.array('byte', [b]))
  297. console.log("============================================================");
  298. return result;
  299. }
  300. Signature.update.overload('[B', 'int', 'int').implementation = function () {
  301. showStack();
  302. console.log("Signature.update.overload('[B', 'int', 'int') is called!");
  303. let result = this.update.apply(this, arguments);
  304. let algorithm = this.getAlgorithm();
  305. printData(algorithm + " update param", arguments[0]);
  306. console.log("============================================================");
  307. return result;
  308. }
  309. Signature.sign.overload().implementation = function () {
  310. showStack();
  311. console.log("Signature.sign.overload() is called!");
  312. let result = this.sign.apply(this, arguments);
  313. let algorithm = this.getAlgorithm();
  314. printData(algorithm + " sign result", result);
  315. console.log("============================================================");
  316. return result;
  317. }
  318. Signature.sign.overload('[B', 'int', 'int').implementation = function () {
  319. showStack();
  320. console.log("Signature.sign.overload('[B', 'int', 'int') is called!");
  321. let result = this.sign.apply(this, arguments);
  322. let algorithm = this.getAlgorithm();
  323. printData(algorithm + " sign param", arguments[0]);
  324. printData(algorithm + " sign result", result);
  325. console.log("============================================================");
  326. return result;
  327. }
  328. }
  329. /**
  330. * Base64hook
  331. */
  332. function hookBase64() {
  333. let Base64 = Java.use("android.util.Base64");
  334. Base64.encodeToString.overload('[B', 'int').implementation = function () {
  335. let result = this.encodeToString.apply(this, arguments);
  336. printData("Base64 param", arguments[0]);
  337. console.log("-------------------------------");
  338. console.log("Base64 result:" + result);
  339. console.log("============================================================");
  340. return result;
  341. }
  342. }
  343. // 消息摘要算法hook
  344. hookMessageDigest();
  345. // Mac算法hook
  346. hookMac();
  347. // hookCipher
  348. hookCipher();
  349. // 数据签名算法hook
  350. hookSignature();
  351. // hookBase64编码
  352. hookBase64();
  353. })