### hook常用js函数封装
#### Bytes 转 String,常用于MD5,Base64等加密
```
function bytesToString(value) {
var buffer = Java.array('byte', value);
var StringClass = Java.use('java.lang.String');
return StringClass.$new(buffer);
}
```
#### byte[]转字符串 frida使用会中文乱码
```
function uint8arrayToStringMethod(myUint8Arr){
return String.fromCharCode.apply(null, myUint8Arr);
}
```
```
function bytes2String(arr) {
if(typeof arr === 'string') {
return arr;
}
var str = '',
_arr = arr;
for(var i = 0; i < _arr.length; i++) {
var one = _arr[i].toString(2),
v = one.match(/^1+?(?=0)/);
if(v && one.length == 8) {
var bytesLength = v[0].length;
var store = _arr[i].toString(2).slice(7 - bytesLength);
for(var st = 1; st < bytesLength; st++) {
store += _arr[st + i].toString(2).slice(2);
}
try {
str += String.fromCharCode(parseInt(store, 2));
} catch (error) {
str += parseInt(store, 2).toString();
console.log(error);
}
i += bytesLength - 1;
} else {
try {
str += String.fromCharCode(_arr[i]);
} catch (error) {
str += parseInt(store, 2).toString();
console.log(error);
}
}
}
return str;
}
```
```
function Uint8ArrayToString(fileData){
var dataString = "";
for (var i = 0; i < fileData.length; i++) {
dataString += String.fromCharCode(fileData[i]);
}
return dataString
}
```
```
function byteToHexString(uint8arr) {
if (!uint8arr) {
return '';
}
var hexStr = '';
for (var i = 0; i < uint8arr.length; i++) {
var hex = (uint8arr[i] & 0xff).toString(16);
hex = (hex.length === 1) ? '0' + hex : hex;
hexStr += hex;
}
return hexStr.toUpperCase();
}
```
#### Bytes数组转 16进制
```
function bytes2Hex16(arrBytes){
var str = "";
for (var i = 0; i < arrBytes.length; i++) {
var tmp;
var num = arrBytes[i];
if (num < 0) {
//此处填坑,当byte因为符合位导致数值为负时候,需要对数据进行处理
tmp = (255 + num + 1).toString(16);
} else {
tmp = num.toString(16);
}
if (tmp.length == 1) {
tmp = "0" + tmp;
}
if(i>0){
str += ""+tmp;
}else{
str += tmp;
}
}
return str;
}
```
```
function bytes2Hex16(bytes_ary){
var ByteString = Java.use("com.android.okhttp.okio.ByteString");
var str_hex = ByteString.of(bytes_ary).hex();
return str_hex;
}
```
#### Bytes数组转 16进制,字母大写
```
function bytes2Hex16(uint8arr) {
if (!uint8arr) {
return '';
}
var hexStr = '';
for (var i = 0; i < uint8arr.length; i++) {
var hex = (uint8arr[i] & 0xff).toString(16);
hex = (hex.length === 1) ? '0' + hex : hex;
hexStr += hex;
}
return hexStr.toUpperCase();
}
```
#### Bytes数组转 10进制
```
function bytes2Hex10(arrBytes){
var str_hex = JSON.stringify(arrBytes);
return str_hex;
}
```
#### 字符串转byte[]
```
function stringToUint8Array(str){
var arr = [];
for (var i = 0, j = str.length; i < j; ++i) {
arr.push(str.charCodeAt(i));
}
var tmpUint8Array = new Uint8Array(arr);
return tmpUint8Array
}
```
```
function stringToByte(str) {
var bytes = new Array();
var len, c;
len = str.length;
for (var i = 0; i < len; i++) {
c = str.charCodeAt(i);
if (c >= 0x010000 && c <= 0x10FFFF) {
bytes.push(((c >> 18) & 0x07) | 0xF0);
bytes.push(((c >> 12) & 0x3F) | 0x80);
bytes.push(((c >> 6) & 0x3F) | 0x80);
bytes.push((c & 0x3F) | 0x80);
} else if (c >= 0x000800 && c <= 0x00FFFF) {
bytes.push(((c >> 12) & 0x0F) | 0xE0);
bytes.push(((c >> 6) & 0x3F) | 0x80);
bytes.push((c & 0x3F) | 0x80);
} else if (c >= 0x000080 && c <= 0x0007FF) {
bytes.push(((c >> 6) & 0x1F) | 0xC0);
bytes.push((c & 0x3F) | 0x80);
} else {
bytes.push(c & 0xFF);
}
}
return bytes;
}
```
#### byte[]进行base64编码
```
// 编码
function byte2Base64(byteArray) {
var jBase64 = Java.use('java.util.Base64');
return jBase64.getEncoder().encodeToString(byteArray);
}
// 解码
function byte2Base642(base64Str) {
var jBase64 = Java.use('java.util.Base64');
return jBase64.getDecoder().decode(base64Str);
}
```
#### 获取时间
```
/**
* 获取格式化时间 2022-05-10 19:17:49
* @returns {string}
*/
function getFormatDate() {
var date = new Date();
var month = date.getMonth() + 1;
var strDate = date.getDate();
var strHours = date.getHours();
var strMinutes = date.getMinutes();
var strSeconds = date.getSeconds()
if (month >= 1 && month <= 9) {
month = "0" + month;
}
if (strDate >= 0 && strDate <= 9) {
strDate = "0" + strDate;
}
if (strHours >= 0 && strHours <= 9) {
strHours = "0" + strHours;
}
if (strMinutes >= 0 && strMinutes <= 9) {
strMinutes = "0" + strMinutes;
}
if (strSeconds >= 0 && strSeconds <= 9) {
strSeconds = "0" + strSeconds;
}
var currentDate = date.getFullYear() + "-" + month + "-" + strDate
+ " " + strHours + ":" + strMinutes + ":" + strSeconds;
return currentDate;
}
/**
* 2022-05-10 19:17:49
* @param inputTime 参数是毫秒级时间戳
*
*/
function formatDate() {
var date = new Date(new Date().getTime());
var y = date.getFullYear();
var m = date.getMonth() + 1;
m = m < 10 ? ('0' + m) : m;
var d = date.getDate();
d = d < 10 ? ('0' + d) : d;
var h = date.getHours();
h = h < 10 ? ('0' + h) : h;
var minute = date.getMinutes();
var second = date.getSeconds();
minute = minute < 10 ? ('0' + minute) : minute;
second = second < 10 ? ('0' + second) : second;
return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
}
```
#### Map对象转String
```
/**
* Map对象转String
* @param map
* @returns {string}
*/
function mapToString(map) {
var keyset = map.keySet();
var it = keyset.iterator();
var str = "{";
while (it.hasNext()) {
var keystr = it.next().toString();
var valuestr = map.get(keystr);
str += '"' + keystr + '":"' + valuestr + '",';
}
return str.trim(',') + "}";
}
```
#### java对象转String
```
/**
* java对象转String
* @param javaObj
* @returns {*}
*/
function objectToString(javaObj) {
var gson = Java.use('com.google.gson.Gson').$new();
return gson.toJson(javaObj);
}
```
#### 打印堆栈
```
function showStack() {
let Throwable = Java.use("java.lang.Throwable");
let stackTraceString = Java.use("android.util.Log").getStackTraceString(Throwable.$new())
console.log(stackTraceString);
}
```
### 万能算法
```
/**
* Java层标准算法hook
*/
Java.perform(function () {
/**
打印堆栈
*/
function showStack() {
let Throwable = Java.use("java.lang.Throwable");
let stackTraceString = Java.use("android.util.Log").getStackTraceString(Throwable.$new())
console.log(stackTraceString);
}
let ByteString = Java.use("com.android.okhttp.okio.ByteString");
/**
* 字节数组转为Base64
*/
function toBase64(tag, data) {
console.log(tag + " Base64:" + ByteString.of(data).base64());
}
/**
* 字节数组转为16进制
*/
function toHex(tag, data) {
console.log(tag + " Hex:" + ByteString.of(data).hex());
}
/**
* 字节数组转为明文
*/
function toUtf8(tag, data) {
console.log(tag + " Utf8:" + ByteString.of(data).utf8());
}
/**
* 打印字节数组对应的输出数据
*/
function printData(tag, data) {
toBase64(tag, data);
toHex(tag, data);
toUtf8(tag, data);
}
/***
* 消息摘要算法hook
* update 压入数据
* digest 返回加密结果
*/
function hookMessageDigest() {
let MessageDigest = Java.use("java.security.MessageDigest");
MessageDigest.update.overload('byte').implementation = function (b) {
showStack();
console.log("MessageDigest.update.overload('byte') is called!");
let result = this.update.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " update param", Java.array('byte', [b]))
console.log("============================================================");
return result;
}
MessageDigest.update.overload('[B').implementation = function (byteArr) {
showStack();
console.log("MessageDigest.update.overload('[B') is called!");
let result = this.update.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " update param", byteArr);
console.log("============================================================");
return result;
}
MessageDigest.digest.overload().implementation = function () {
showStack();
console.log("MessageDigest.digest.overload() is called!");
let result = this.digest.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " digest result", result);
console.log("============================================================");
return result;
}
MessageDigest.digest.overload('[B').implementation = function (byteArr) {
showStack();
console.log("MessageDigest.digest.overload('[B') is called!");
let result = this.digest.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " digest param", byteArr);
printData(algorithm + " digest result", result);
console.log("============================================================");
return result;
}
MessageDigest.digest.overload('[B', 'int', 'int').implementation = function (byteArr, start, length) {
showStack();
console.log("MessageDigest.digest.overload('[B', 'int', 'int') is called!");
let result = this.digest.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " digest param", byteArr);
printData(algorithm + " digest result", result);
console.log("============================================================" + "开始位置:" + start + " 截取长度:" + length);
return result;
}
}
/**
* Mac算法hook
* 1.init 初始化,秘钥
* 2.update 压入数据
* 3.doFinal 加密
*/
function hookMac() {
let Mac = Java.use("javax.crypto.Mac");
Mac.init.overload('java.security.Key').implementation = function (key) {
showStack();
console.log("Mac.init.overload('java.security.Key') is called!");
let result = this.init.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " init key", key.getEncoded())
console.log("============================================================");
return result;
}
Mac.update.overload('byte').implementation = function (b) {
showStack();
console.log("Mac.update.overload('byte') is called!");
let result = this.update.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " update param", Java.array('byte', [b]))
console.log("============================================================");
return result;
}
Mac.update.overload('[B').implementation = function (byteArr) {
showStack();
console.log("Mac.update.overload('[B') is called!");
let result = this.update.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " update param", byteArr)
console.log("============================================================");
return result;
}
Mac.update.overload('[B', 'int', 'int').implementation = function (byteArr, start, length) {
showStack();
console.log("Mac.update.overload('[B', 'int', 'int') is called!");
let result = this.update.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " update param", byteArr)
console.log("============================================================" + "开始位置:" + start + " 截取长度:" + length);
return result;
}
Mac.doFinal.overload().implementation = function () {
showStack();
console.log("Mac.doFinal.overload() is called!");
let result = this.doFinal.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " doFinal result", result)
console.log("============================================================");
return result;
}
}
/**
* DES,DESEde,AES,RSA
* 1.init 加密类型,key,iv
* 2.donFinal压入数据,得到结果 update压入结果有问题
*/
function hookCipher() {
function printResult(cipherObj, result, args) {
let algorithm = cipherObj.getAlgorithm();
let mode;
if (cipherObj.opmode.value === 1) {
mode = "加密";
} else {
mode = "解密";
}
console.log(algorithm + " mode:", mode);
if (cipherObj.getParameters() != null) {
printData(algorithm + " key", cipherObj.getParameters().getEncoded());
printData(algorithm + " iv", cipherObj.getIV());
}
printData(algorithm + " doFinal param", args[0]);
printData(algorithm + " doFinal result", result);
console.log("============================================================");
}
let Cipher = Java.use("javax.crypto.Cipher");
// 不常用重载,打印调用即可,根据堆栈信息在具体去看
// init暂时注释
Cipher.init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom').implementation = function (key) {
showStack();
console.log("Cipher.init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom') is called!");
let result = this.apply(this, arguments);
return result;
}
Cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function (key) {
showStack();
console.log("Cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom') is called!");
let result = this.apply(this, arguments);
return result;
}
// ECB模式,不带iv
Cipher.init.overload('int', 'java.security.Key', 'java.security.SecureRandom').implementation = function () {
showStack();
console.log("Cipher.init.overload('int', 'java.security.Key', 'java.security.SecureRandom') is called!");
let result = this.init.apply(this, arguments);
let algorithm = this.getAlgorithm();
let mode;
if (arguments[0] === 1) {
mode = "加密";
} else {
mode = "解密";
}
console.log(algorithm + " init mode:" + mode);
try {
// RSA使用私钥调用getEncoded() 会报错,异常捕获,具体逻辑,根据堆栈,去APP分析
printData(algorithm + " init key", arguments[1].getEncoded());
} catch (e) {
console.log(e);
}
console.log("============================================================");
return result;
}
// CBC模式,带iv
Cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom').implementation = function () {
showStack();
console.log("Cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom') is called!");
let result = this.init.apply(this, arguments);
let algorithm = this.getAlgorithm();
let ivParameterSpecObj = Java.cast(arguments[2], Java.use("javax.crypto.spec.IvParameterSpec"));
let mode;
if (arguments[0] === 1) {
mode = "加密";
} else {
mode = "解密";
}
console.log(algorithm + " init mode:" + mode);
printData(algorithm + " init key", arguments[1].getEncoded());
printData(algorithm + " init iv", ivParameterSpecObj.getIV());
console.log("============================================================");
return result;
}
Cipher.doFinal.overload().implementation = function () {
showStack();
console.log("Cipher.doFinal.overload() is called!");
let result = this.doFinal.apply(this, arguments);
printResult(this, result, arguments);
return result;
}
Cipher.doFinal.overload('[B').implementation = function () {
showStack();
console.log("Cipher.doFinal.overload('[B') is called!");
let result = this.doFinal.apply(this, arguments);
printResult(this, result, arguments);
return result;
}
Cipher.doFinal.overload('[B', 'int').implementation = function () {
showStack();
console.log("Cipher.doFinal.overload('[B', 'int') is called!");
let result = this.doFinal.apply(this, arguments);
printResult(this, result, arguments);
return result;
}
Cipher.doFinal.overload('[B', 'int', 'int').implementation = function () {
showStack();
console.log("Cipher.doFinal.overload('[B', 'int', 'int') is called!");
let result = this.doFinal.apply(this, arguments);
printResult(this, result, arguments);
return result;
}
Cipher.doFinal.overload('[B', 'int', 'int', '[B').implementation = function () {
showStack();
console.log("Cipher.doFinal.overload('[B', 'int', 'int', '[B') is called!");
let result = this.doFinal.apply(this, arguments);
printResult(this, result, arguments);
return result;
}
Cipher.doFinal.overload('[B', 'int', 'int', '[B', 'int').implementation = function () {
showStack();
console.log("Cipher.doFinal.overload('[B', 'int', 'int', '[B', 'int') is called!");
let result = this.doFinal.apply(this, arguments);
printResult(this, result, arguments);
return result;
}
}
/**
* 签名算法hook
* 私钥
*/
function hookSignature() {
let Signature = Java.use("java.security.Signature");
Signature.initSign.overload('java.security.PrivateKey').implementation = function () {
showStack();
console.log("Signature.initSign.overload('java.security.PrivateKey') is called!");
let result = this.initSign.apply(this, arguments);
let algorithm = this.getAlgorithm();
try {
// RSA使用Hex编码的私钥调用getEncoded() 会报错,异常捕获,具体逻辑,根据堆栈,去APP分析
printData(algorithm + " init key", arguments[0].getEncoded());
} catch (e) {
console.log(JSON.stringify(arguments[0]) + "|" + e);
}
console.log("============================================================");
return result;
}
Signature.update.overload('byte').implementation = function () {
showStack();
console.log("Signature.update.overload('byte') is called!");
let result = this.update.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " update param", Java.array('byte', [b]))
console.log("============================================================");
return result;
}
Signature.update.overload('[B', 'int', 'int').implementation = function () {
showStack();
console.log("Signature.update.overload('[B', 'int', 'int') is called!");
let result = this.update.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " update param", arguments[0]);
console.log("============================================================");
return result;
}
Signature.sign.overload().implementation = function () {
showStack();
console.log("Signature.sign.overload() is called!");
let result = this.sign.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " sign result", result);
console.log("============================================================");
return result;
}
Signature.sign.overload('[B', 'int', 'int').implementation = function () {
showStack();
console.log("Signature.sign.overload('[B', 'int', 'int') is called!");
let result = this.sign.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " sign param", arguments[0]);
printData(algorithm + " sign result", result);
console.log("============================================================");
return result;
}
}
/**
* Base64hook
*/
function hookBase64() {
let Base64 = Java.use("android.util.Base64");
Base64.encodeToString.overload('[B', 'int').implementation = function () {
let result = this.encodeToString.apply(this, arguments);
printData("Base64 param", arguments[0]);
console.log("-------------------------------");
console.log("Base64 result:" + result);
console.log("============================================================");
return result;
}
}
// 消息摘要算法hook
hookMessageDigest();
// Mac算法hook
hookMac();
// hookCipher
hookCipher();
// 数据签名算法hook
hookSignature();
// hookBase64编码
hookBase64();
})
```
```
var N_ENCRYPT_MODE = 1
var N_DECRYPT_MODE = 2
function showStacks() {
var Exception = Java.use("java.lang.Exception");
var ins = Exception.$new("Exception");
var straces = ins.getStackTrace();
if (undefined == straces || null == straces) {
return;
}
console.log("============================= Stack strat=======================");
console.log("");
for (var i = 0; i < straces.length; i++) {
var str = " " + straces[i].toString();
console.log(str);
}
console.log("");
console.log("============================= Stack end=======================rn");
Exception.$dispose();
}
//工具相关函数
var base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
base64DecodeChars = new Array((-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), 62, (-1), (-1), (-1), 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, (-1), (-1), (-1), (-1), (-1), (-1), (-1), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, (-1), (-1), (-1), (-1), (-1), (-1), 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, (-1), (-1), (-1), (-1), (-1));
function stringToBase64(e) {
var r, a, c, h, o, t;
for (c = e.length, a = 0, r = ''; a < c;) {
if (h = 255 & e.charCodeAt(a++), a == c) {
r += base64EncodeChars.charAt(h >> 2),
r += base64EncodeChars.charAt((3 & h) << 4),
r += '==';
break
}
if (o = e.charCodeAt(a++), a == c) {
r += base64EncodeChars.charAt(h >> 2),
r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),
r += base64EncodeChars.charAt((15 & o) << 2),
r += '=';
break
}
t = e.charCodeAt(a++),
r += base64EncodeChars.charAt(h >> 2),
r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),
r += base64EncodeChars.charAt((15 & o) << 2 | (192 & t) >> 6),
r += base64EncodeChars.charAt(63 & t)
}
return r
}
function base64ToString(e) {
var r, a, c, h, o, t, d;
for (t = e.length, o = 0, d = ''; o < t;) {
do
r = base64DecodeChars[255 & e.charCodeAt(o++)];
while (o < t && r == -1);
if (r == -1)
break;
do
a = base64DecodeChars[255 & e.charCodeAt(o++)];
while (o < t && a == -1);
if (a == -1)
break;
d += String.fromCharCode(r << 2 | (48 & a) >> 4);
do {
if (c = 255 & e.charCodeAt(o++), 61 == c)
return d;
c = base64DecodeChars[c]
} while (o < t && c == -1);
if (c == -1)
break;
d += String.fromCharCode((15 & a) << 4 | (60 & c) >> 2);
do {
if (h = 255 & e.charCodeAt(o++), 61 == h)
return d;
h = base64DecodeChars[h]
} while (o < t && h == -1);
if (h == -1)
break;
d += String.fromCharCode((3 & c) << 6 | h)
}
return d
}
function hexToBase64(str) {
return base64Encode(String.fromCharCode.apply(null, str.replace(/r|n/g, "").replace(/([da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" ")));
}
function base64ToHex(str) {
for (var i = 0, bin = base64Decode(str.replace(/[ rn]+$/, "")), hex = []; i < bin.length; ++i) {
var tmp = bin.charCodeAt(i).toString(16);
if (tmp.length === 1)
tmp = "0" + tmp;
hex[hex.length] = tmp;
}
return hex.join("");
}
function hexToBytes(str) {
var pos = 0;
var len = str.length;
if (len % 2 != 0) {
return null;
}
len /= 2;
var hexA = new Array();
for (var i = 0; i < len; i++) {
var s = str.substr(pos, 2);
var v = parseInt(s, 16);
hexA.push(v);
pos += 2;
}
return hexA;
}
function bytesToHex(arr) {
var str = '';
var k, j;
for (var i = 0; i < arr.length; i++) {
k = arr[i];
j = k;
if (k < 0) {
j = k + 256;
}
if (j < 16) {
str += "0";
}
str += j.toString(16);
}
return str;
}
function stringToHex(str) {
var val = "";
for (var i = 0; i < str.length; i++) {
if (val == "")
val = str.charCodeAt(i).toString(16);
else
val += str.charCodeAt(i).toString(16);
}
return val
}
function stringToBytes(str) {
var ch, st, re = [];
for (var i = 0; i < str.length; i++) {
ch = str.charCodeAt(i);
st = [];
do {
st.push(ch & 0xFF);
ch = ch >> 8;
}
while (ch);
re = re.concat(st.reverse());
}
return re;
}
//将byte[]转成String的方法
function bytesToString(arr) {
var str = '';
arr = new Uint8Array(arr);
for (var i in arr) {
str += String.fromCharCode(arr[i]);
}
return str;
}
function bytesToBase64(e) {
var r, a, c, h, o, t;
for (c = e.length, a = 0, r = ''; a < c;) {
if (h = 255 & e[a++], a == c) {
r += base64EncodeChars.charAt(h >> 2),
r += base64EncodeChars.charAt((3 & h) << 4),
r += '==';
break
}
if (o = e[a++], a == c) {
r += base64EncodeChars.charAt(h >> 2),
r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),
r += base64EncodeChars.charAt((15 & o) << 2),
r += '=';
break
}
t = e[a++],
r += base64EncodeChars.charAt(h >> 2),
r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),
r += base64EncodeChars.charAt((15 & o) << 2 | (192 & t) >> 6),
r += base64EncodeChars.charAt(63 & t)
}
return r
}
function base64ToBytes(e) {
var r, a, c, h, o, t, d;
for (t = e.length, o = 0, d = []; o < t;) {
do
r = base64DecodeChars[255 & e.charCodeAt(o++)];
while (o < t && r == -1);
if (r == -1)
break;
do
a = base64DecodeChars[255 & e.charCodeAt(o++)];
while (o < t && a == -1);
if (a == -1)
break;
d.push(r << 2 | (48 & a) >> 4);
do {
if (c = 255 & e.charCodeAt(o++), 61 == c)
return d;
c = base64DecodeChars[c]
} while (o < t && c == -1);
if (c == -1)
break;
d.push((15 & a) << 4 | (60 & c) >> 2);
do {
if (h = 255 & e.charCodeAt(o++), 61 == h)
return d;
h = base64DecodeChars[h]
} while (o < t && h == -1);
if (h == -1)
break;
d.push((3 & c) << 6 | h)
}
return d
}
//stringToBase64 stringToHex stringToBytes
//base64ToString base64ToHex base64ToBytes
// hexToBase64 hexToBytes
// bytesToBase64 bytesToHex bytesToString
Java.perform(function () {
var secretKeySpec = Java.use('javax.crypto.spec.SecretKeySpec');
secretKeySpec.$init.overload('[B', 'java.lang.String').implementation = function (a, b) {
showStacks();
var result = this.$init(a, b);
console.log("======================================");
console.log("算法名:" + b + "|str密钥:" + bytesToString(a));
console.log("算法名:" + b + "|Hex密钥:" + bytesToHex(a));
return result;
}
var DESKeySpec = Java.use('javax.crypto.spec.DESKeySpec');
DESKeySpec.$init.overload('[B').implementation = function (a) {
showStacks();
var result = this.$init(a);
console.log("======================================");
var bytes_key_des = this.getKey();
console.log("des密钥 |str " + bytesToString(bytes_key_des));
console.log("des密钥 |hex " + bytesToHex(bytes_key_des));
return result;
}
DESKeySpec.$init.overload('[B', 'int').implementation = function (a, b) {
showStacks();
var result = this.$init(a, b);
console.log("======================================");
var bytes_key_des = this.getKey();
console.log("des密钥 |str " + bytesToString(bytes_key_des));
console.log("des密钥 |hex " + bytesToHex(bytes_key_des));
return result;
}
var mac = Java.use('javax.crypto.Mac');
mac.getInstance.overload('java.lang.String').implementation = function (a) {
showStacks();
var result = this.getInstance(a);
console.log("======================================");
console.log("算法名:" + a);
return result;
}
mac.update.overload('[B').implementation = function (a) {
//showStacks();
this.update(a);
console.log("======================================");
console.log("update:" + bytesToString(a))
}
mac.update.overload('[B', 'int', 'int').implementation = function (a, b, c) {
//showStacks();
this.update(a, b, c)
console.log("======================================");
console.log("update:" + bytesToString(a) + "|" + b + "|" + c);
}
mac.doFinal.overload().implementation = function () {
//showStacks();
var result = this.doFinal();
console.log("======================================");
console.log("doFinal结果: |str :" + bytesToString(result));
console.log("doFinal结果: |hex :" + bytesToHex(result));
console.log("doFinal结果: |base64 :" + bytesToBase64(result));
return result;
}
mac.doFinal.overload('[B').implementation = function (a) {
//showStacks();
var result = this.doFinal(a);
console.log("======================================");
console.log("doFinal参数: |str :" + bytesToString(a));
console.log("doFinal结果: |str :" + bytesToString(result));
console.log("doFinal结果: |hex :" + bytesToHex(result));
console.log("doFinal结果: |base64 :" + bytesToBase64(result));
return result;
}
var md = Java.use('java.security.MessageDigest');
md.getInstance.overload('java.lang.String', 'java.lang.String').implementation = function (a, b) {
//showStacks();
console.log("======================================");
console.log("算法名:" + a);
return this.getInstance(a, b);
}
md.getInstance.overload('java.lang.String').implementation = function (a) {
//showStacks();
console.log("======================================");
console.log("算法名:" + a);
return this.getInstance(a);
}
md.update.overload('[B').implementation = function (a) {
//showStacks();
console.log("======================================");
console.log("update:" + bytesToString(a))
return this.update(a);
}
md.update.overload('[B', 'int', 'int').implementation = function (a, b, c) {
//showStacks();
console.log("======================================");
console.log("update:" + bytesToString(a) + "|" + b + "|" + c);
return this.update(a, b, c);
}
md.digest.overload().implementation = function () {
//showStacks();
console.log("======================================");
var result = this.digest();
console.log("digest结果:" + bytesToHex(result));
console.log("digest结果:" + bytesToBase64(result));
return result;
}
md.digest.overload('[B').implementation = function (a) {
//showStacks();
console.log("======================================");
console.log("digest参数:" + bytesToString(a));
var result = this.digest(a);
console.log("digest结果:" + bytesToHex(result));
console.log("digest结果:" + bytesToBase64(result));
return result;
}
var ivParameterSpec = Java.use('javax.crypto.spec.IvParameterSpec');
ivParameterSpec.$init.overload('[B').implementation = function (a) {
//showStacks();
var result = this.$init(a);
console.log("======================================");
console.log("iv向量: |str:" + bytesToString(a));
console.log("iv向量: |hex:" + bytesToHex(a));
return result;
}
var cipher = Java.use('javax.crypto.Cipher');
cipher.getInstance.overload('java.lang.String').implementation = function (a) {
//showStacks();
var result = this.getInstance(a);
console.log("======================================");
console.log("模式填充:" + a);
return result;
}
cipher.init.overload('int', 'java.security.Key').implementation = function (a, b) {
//showStacks();
var result = this.init(a, b);
console.log("======================================");
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
var bytes_key = b.getEncoded();
console.log("init key:" + "|str密钥:" + bytesToString(bytes_key));
console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key));
return result;
}
cipher.init.overload('int', 'java.security.cert.Certificate').implementation = function (a, b) {
//showStacks();
var result = this.init(a, b);
console.log("======================================");
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
return result;
}
cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function (a, b, c) {
//showStacks();
var result = this.init(a, b, c);
console.log("======================================");
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
var bytes_key = b.getEncoded();
console.log("init key:" + "|str密钥:" + bytesToString(bytes_key));
console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key));
return result;
}
cipher.init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom').implementation = function (a, b, c) {
//showStacks();
var result = this.init(a, b, c);
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
return result;
}
cipher.init.overload('int', 'java.security.Key', 'java.security.SecureRandom').implementation = function (a, b, c) {
//showStacks();
var result = this.init(a, b, c);
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
var bytes_key = b.getEncoded();
console.log("init key:" + "|str密钥:" + bytesToString(bytes_key));
console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key));
return result;
}
cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters').implementation = function (a, b, c) {
//showStacks();
var result = this.init(a, b, c);
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
var bytes_key = b.getEncoded();
console.log("init key:" + "|str密钥:" + bytesToString(bytes_key));
console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key));
return result;
}
cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function (a, b, c, d) {
//showStacks();
var result = this.init(a, b, c, d);
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
var bytes_key = b.getEncoded();
console.log("init key:" + "|str密钥:" + bytesToString(bytes_key));
console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key));
return result;
}
cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom').implementation = function (a, b, c, d) {
//showStacks();
var result = this.update(a, b, c, d);
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
var bytes_key = b.getEncoded();
console.log("init key:" + "|str密钥:" + bytesToString(bytes_key));
console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key));
return result;
}
cipher.update.overload('[B').implementation = function (a) {
//showStacks();
var result = this.update(a);
console.log("======================================");
console.log("update:" + bytesToString(a));
return result;
}
cipher.update.overload('[B', 'int', 'int').implementation = function (a, b, c) {
//showStacks();
var result = this.update(a, b, c);
console.log("======================================");
console.log("update:" + bytesToString(a) + "|" + b + "|" + c);
return result;
}
cipher.doFinal.overload().implementation = function () {
//showStacks();
var result = this.doFinal();
console.log("======================================");
console.log("doFinal结果: |str :" + bytesToString(result));
console.log("doFinal结果: |hex :" + bytesToHex(result));
console.log("doFinal结果: |base64 :" + bytesToBase64(result));
return result;
}
cipher.doFinal.overload('[B').implementation = function (a) {
//showStacks();
var result = this.doFinal(a);
console.log("======================================");
console.log("doFinal参数: |str :" + bytesToString(a));
console.log("doFinal结果: |str :" + bytesToString(result));
console.log("doFinal结果: |hex :" + bytesToHex(result));
console.log("doFinal结果: |base64 :" + bytesToBase64(result));
return result;
}
var x509EncodedKeySpec = Java.use('java.security.spec.X509EncodedKeySpec');
x509EncodedKeySpec.$init.overload('[B').implementation = function (a) {
//showStacks();
var result = this.$init(a);
console.log("======================================");
console.log("RSA密钥:" + bytesToBase64(a));
return result;
}
var rSAPublicKeySpec = Java.use('java.security.spec.RSAPublicKeySpec');
rSAPublicKeySpec.$init.overload('java.math.BigInteger', 'java.math.BigInteger').implementation = function (a, b) {
//showStacks();
var result = this.$init(a, b);
console.log("======================================");
//console.log("RSA密钥:" + bytesToBase64(a));
console.log("RSA密钥N:" + a.toString(16));
console.log("RSA密钥E:" + b.toString(16));
return result;
}
var KeyPairGenerator = Java.use('java.security.KeyPairGenerator');
KeyPairGenerator.generateKeyPair.implementation = function ()
{
//showStacks();
var result = this.generateKeyPair();
console.log("======================================");
var str_private = result.getPrivate().getEncoded();
var str_public = result.getPublic().getEncoded();
console.log("公钥 |hex" + bytesToHex(str_public));
console.log("私钥 |hex" + bytesToHex(str_private));
return result;
}
KeyPairGenerator.genKeyPair.implementation = function ()
{
//showStacks();
var result = this.genKeyPair();
console.log("======================================");
var str_private = result.getPrivate().getEncoded();
var str_public = result.getPublic().getEncoded();
console.log("公钥 |hex" + bytesToHex(str_public));
console.log("私钥 |hex" + bytesToHex(str_private));
return result;
}
});
```
- 开发环境
- 安装开发环境
- pip下载换源
- python 下载加速
- 安装多个版本的python
- 使用pypy解释器
- 使用pyston解释器
- 生成和安装requirements.txt依赖
- python 3.10.11
- 环境
- 资源
- python安装模块的几种方法
- 常用操作类
- py310_db_20231021
- 使用nuitka打包
- nuitka常用指令
- 请求封装
- 代理ip测试
- 使用pyjion加速
- 20240608环境
- 大牛资源复制
- 编译成so文件
- python基础
- 变量与基本数据类型
- 变量
- 基本数据类型
- 运算符
- 流程控制
- if 语句
- while 循环
- for循环
- break,continue,pass
- with...as 语句
- 列表与元组
- 列表的创建和访问
- 列表的运算
- 列表元素的操作
- 元组的创建和访问
- 列表和元组 推导式
- 字典与集合
- 字典的创建和访问
- 字典元素的操作
- 字典推导式
- 集合的创建,元素的操作
- 集合的运算
- 字典排序
- 字符串与编码
- 字符串编码
- 字符串操作
- 字符串格式化
- 面向对象编程
- 函数
- 类
- 类里面的常用的方法
- 反射
- 异常处理和调试
- 异常
- 异常处理
- 文件/IO 操作
- 创建和关闭文件
- 写入和读取
- IO操作图片
- HTTP网络编程
- requests请求封装模块(一)
- requests请求封装模块(二)
- requests请求封装模块(三)
- http请求表单 multipart/form-data
- httpbin
- http
- http请求模块
- 使用代理IP
- http 请求 单独cookie
- http请求模块 session cookies
- 数据库
- 安装mysql数据库
- 操作mysql数据库
- MySql数据库链接池操作类
- SQLite数据库操作
- SQLite查询元组转字典
- SQLite数据库操作类
- SQLite数据库操作类2
- SQLite数据库链接池操作类
- aiosqlite 异步数据库操作类
- sqlite 数据库操作类
- 使用DuckDB数据库
- DuckDB数据库操作类
- DuckDB插入重复数据替换
- apsw sqlite操作类
- peewee sqlite数据库操作类
- sqlite3 数据库操作类
- 字典模式 sqlite3 操作类
- 字典模式 peewee 操作类
- Berkeley DB数据库操作
- Firebird 数据库操作
- sqlite3 运算符
- sqlite的数据类型
- sqlite 语句分页
- sqlite数据库去重复
- 多协程
- 协程 Coroutine
- 生成器 yield
- 异步IO框架-asyncio
- 异步IO框架-asyncio(二)
- 异步IO框架-asyncio(三)
- 协程 greenlet
- 协程 gevent
- 协程池 gevent.Pool
- 多线程
- 使用多线程
- 多线程中常用的方法
- 线程同步(锁)和通信
- 线程同步(锁)和通信(二)
- 使用队列的线程通信
- 使用队列管理线程-线程池
- 线程池-threadpool
- 线程池-ThreadPoolExecutor
- 线程池-ThreadPoolExecutor(二)
- 线程池-ThreadPoolExecutor(三)
- 多线程获取
- 线程池kun
- multiprocessing 线程池
- 多进程
- 使用多进程
- 多进程中常用的方法
- 进程同步(锁)和通信
- 进程同步(锁)和通信(二)
- 进程池-multiprocessing.Pool
- 进程池-ProcessPoolExecutor
- Flask web开发
- 安装调试 flask 模块
- Flask的Http方法
- 宝塔部署 flask 项目
- 错误处理机制
- fastapi 开发
- 入门
- 路径和参数
- 请求体
- html模板渲染
- 静态文件设置
- html发起GET请求
- html发起POST请求
- 重写异常
- 设置公共部分
- Jinja2 教程
- 使用hypercorn服务器
- 使用uvicorn服务器
- 使用vue.js 渲染html
- fastapi 设置响应超时
- post请求接收表单数据
- fastapi 上传文件
- asyncio 防止堵塞
- 设置cookie鉴权
- swagger
- request 对象
- response 对象
- 提前创建 和 退出前关闭
- fastapi接口压力测试
- 中间件使用技巧
- 使用ssl证书变成https
- 加密解密
- Base64
- AES
- RSA
- DES
- 加密算法
- MD5 哈希算法加密
- RSA公钥解密[解密对应私钥的加密]
- HMAC-SHA1
- OCR图像识别
- muggle_ocr
- ddddocr
- easyocr
- cv2裁剪图片
- 处理url中常见的图片
- 使用cv2 匹配滑块缺口
- 安卓逆向
- adb 手机调试
- frida
- frida-server
- objection
- objection注入报错 双进程保护
- frida-dexdump 安卓app脱壳
- Android-apktool 脱壳
- frida注入hook脚本脱壳
- Jadx 反编译
- 在安卓模拟器上使用frida
- SimpleHook
- 应用伪装
- python frida
- 使用 hook 脚本
- 编写hook 脚本
- 枚举当前加载的模块及模块中方法
- 万能的hook Md5 脚本
- hook常用js函数封装
- frida工具-FridaInfoShow
- frida工具-fridaUiTools
- frida工具-appmon
- frida工具-ZenTracer-master
- frida工具-Dwarf
- frida工具-lamda
- frida抓包工具 r0capture
- 脱壳工具
- python调用浏览器
- 常用方法
- for while 循环显示进度
- 打印艺术字或者图案
- json.dumps()中文乱码
- 队列构造循环池
- 模糊匹配 in 关键词用法
- python中的编码声明
- 列表平均分割
- requests 不使用代理 防止抓包
- 递增矩阵算法
- 判断是否是中文
- 数组内的字典关键词排序
- 垃圾回收释放内存
- 打印异常程序不停止
- 判断json数据
- 判断url是否合法
- 字符串空格步长统一和数组转字符串
- 监控内存使用情况
- 监控cpu使用情况
- 获取机器码
- 取16个随机字符串加密
- parsel解析html
- 三元表达式
- py调用js函数
- js加密算法-护世界app
- 中国大学AES例子
- 字典转字符串
- 提取requests里面cookie
- MD5算法js还原
- 优学院app一个md5算法
- 字符串转字节和字节数组
- 池馆一个js-AES-CRT算法
- 屏蔽抓包工具
- request重定向
- 常用获取时间接口
- bs4解析html
- 递归例子
- bs4 查找匹配
- 使用socks5代理
- 检测代理ip
- json解析优化
- python代码可视化
- 读写文件操作技巧
- requests模块优化
- 模块优化
- bs4截取js里面字符串
- requests传递多个同名参数
- 压力测试
- gevent模块报错
- nuitka 查看所有插件
- nuitka
- nuitka打包指定插件位置
- 修改python中sqlite3版本
- 使用pyinstaller打包
- pyinstaller打包 exe 反编译逆向
- execjs执行js报错;UnicodeEncodeError: ‘gbk‘
- 截取html标签里面的字符串
- lxml解析网页
- lxml使用css选择器
- 常用排序
- 字典循环输出
- 模块包技巧
- 调用验证码接口
- bs4 技巧
- 查看对象大小
- 运行的时候不生成pyc
- requests慢 浏览器 postman正常
- 数组相同分配
- 常用的时间转换方法
- tcp网络调优
- 防止未知报错闪退
- bs4报错UnicodeEncodeError
- 多条件判断优化
- 判断字符串中是否包含中文
- 读取文件报错 UnicodeDecodeError: 'gbk' ...
- 常规数据正则匹配验证
- 题目字符串截取方案
- fastapi防止堵塞的方案分析
- 调试内存泄漏
- 判断字符串中英文
- 获取系统信息
- curl_cffi和request模块一样牛逼的模块
- js逆向
- 使用fiddler修改网页的js
- 浏览器hook算法