function main() {
Java.perform(function () {
demo()
})
}
setImmediate(main)
静态方法
function demo() {
var Utils = Java.use(包名.类名);
// 应用 hook 函数到静态方法
Utils.方法名.implementation = function () {
// 调用原始方法
var result = this.方法名(方法参数);
return result;
}
}
重载方法
function demo() {
var Utils = Java.use(包名.类名);
Utils.getOver.overload('int').implementation = function (arg) {
console.log(arg)
var res = this.getOver(arg)
return res
}
}
构造方法
function demo() {
var money = Java.use(包名.类名);
money.$init.overload('java.lang.String', 'int').implementation =
function (str, num) {
console.log(str, num);
this.$init(str, num);
}
}
主动调用静态方法
function demo() {
var Utils = Java.use(包名.类名);
// 应用 hook 函数到静态方法
Utils.方法(参数)
}
主动调用实例方法
function demo() {
// 新建对象调用
var res = Java.use(包名.类名).$new(初始化参数).方法名称(参数);
console.log(res)
// 获取已有对象调用 一般在rpc会经常使用
Java.choose(包名.类名, {
onMatch: function (obj) {
console.log(obj.方法名称(参数))
},
onComplete: function () {
console.log('内存中Money操作完毕')
}
});
}
Java类-获取和修改类的字段
function demo() {
var money = Java.use(包名.类名);
money.字段名称.value = "111";
console.log(money.字段名称.value, '修改之后的结果');
//获取已有对象的方法,非静态字段的修改
Java.choose(包名.类名, {
onMatch: function (obj) {
obj._字段名称.value = "222"; // 字段名与方法名相同时 前面需要加个下划线
console.log(obj._字段名称.value)
},
onComplete: function () {
}
});
}
Java类-内部类
function demo() {
var InnerClass = Java.use('包名.类目$内部类名');
// 优化构造函数的 hook
InnerClass.$init.overload(初始化参数类型).implementation =
function (参数) {
// 调用原始构造函数
return this.$init(参数);
};
}
Java类-枚举类的方法
function demo() {
// 下面这行是枚举所有类
// console.log(Java.enumerateLoadedClassesSync().join('\n'))
var money = Java.use(包名.类名);
// 获取该类下所有的方法
var methods = money.class.getDeclaredMethods()
console.log(methods)
for (var i = 0; i < methods.length; i++) {
// 获取当前方法的名称
console.log(methods[i].getName())
}
// 获取该类下的构造函数
var contructors = money.class.getDeclaredConstructors();
console.log(contructors)
// 获取该类下的字段
var field = money.class.getDeclaredFields();
console.log(field)
// 后去内部类
var classes = money.class.getDeclaredClasses();
console.log(classes)
}
BufferMap
function demo() {
var BufferMap = Java.use("com.xxx.com.BufferMap");
BufferMap.show.implementation = function (map) {
console.log(map);
// map的遍历
var key = map.keySet(); // 返回所有建的集合
var it = key.iterator();
while (it.hasNext()) {
var keystr = it.next();
var valuestr = map.get(keystr);
console.log(keystr, valuestr)
}
// 添加数据返回
map.put("name", "xialuo");
map.put("age", "18");
var result = this.show(map);
// 在这里可以对原始方法的返回值进行修改或者额外的操作
return result;
}
}
HashMap
function demo() {
var hashMap = Java.use("java.util.HashMap");
hashMap.put.implementation = function (a, b) {
console.log('输出--》', a, b)
return this.put(a, b)
}
}
判断用户输入是否为空
function demo() {
var TextUtils = Java.use("android.text.TextUtils");
TextUtils.isEmpty.implementation = function (aa) {
console.log('TextUtils--》', aa)
return this.isEmpty(aa)
}
}
function demo() {
var JSONObject = Java.use('org.json.JSONObject');
// Hook JSONObject.getString() 方法
JSONObject.getString.overload('java.lang.String').implementation = function (key) {
console.log('Hooked JSONObject.getString()');
console.log('Key: ' + key.toString());
// 调用原始的getString()方法
var result = this.getString(key);
return result;
};
}
排序算法
function demo() {
var Collections = Java.use('java.util.Collections');
// Hook sort() 方法
Collections.sort.overload("java.util.List").implementation = function (list) {
console.log('Hooked Collections.sort()');
console.log('List: ' + list.toString());
// 使用 Java.cast 进行类型转换 将list转换成ArrayList类型
var res = Java.cast(list, Java.use("java.util.ArrayList"))
console.log('List list-->', res)
// 调用原始的 sort() 方法
return this.sort(list);
};
Collections.sort.overload("java.util.List", "java.util.Comparator").implementation = function (a, b) {
console.log('Hooked Collections.sort()');
var res = Java.cast(a, Java.use("java.util.ArrayList"))
console.log('Comparator list-->', res)
return this.sort(a, b);
};
}
字符串转换
function demo() {
var StringClass = Java.use('java.lang.String');
// Hook String 类的构造函数
StringClass.getBytes.overload().implementation = function () {
console.log('Original Value');
// 可在此处修改传入的字符串参数
var res = this.getBytes();
var newString = StringClass.$new(res)
// 输出修改后的值
console.log('Modified Value: ' + newString);
return res;
};
// Hook String 类的静态方法
StringClass.getBytes.overload('java.lang.String').implementation = function (obj) {
console.log('Hooked String.valueOf()');
// 可在此处修改传入的对象参数
var res = this.getBytes(obj);
var newString = StringClass.$new(res, obj)
// 输出修改后的结果
console.log('getBytes: ' + newString)
return res
}
}
StringBuilder的tostring
function demo() {
// 获取 StringBuilder 类并定义需要 Hook 的方法名
var stringBuilderClass = Java.use("java.lang.StringBuilder");
stringBuilderClass.toString.implementation = function () {
console.log(arguments)
var res = this.toString.apply(this, arguments)
return res
}
}
Arrays.toString()
Java.use("java.util.Arrays").toString.overload('[Ljava.lang.Object;').implementation = function (x) {
var result = this.toString(x);
console.log("params=", x);
console.log("result=", result)
return result
}
function demo() {
var btn_login_id = Java.use("com.dodonew.online.R$id").btn_login.value;
var View = Java.use('android.view.View');
View.setOnClickListener.implementation = function (listener) {
console.log(this.getId(), "22222222222")
// 调用原始的setOnClickListener方法
return this.setOnClickListener(listener);
};
}
算法hook-未完成
function bytesToHex(arr) {
var str = "";
for (var i = 0; i < arr.length; i++) {
var tmp = arr[i];
if (tmp < 0) {
tmp = (255 + tmp + 1).toString(16);
} else {
tmp = tmp.toString(16);
}
if (tmp.length == 1) {
tmp = "0" + tmp;
}
str += tmp;
}
return str;
}
function bytesToBase64(e) {
var base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
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 bytesToString(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);
}
str += String.fromCharCode(parseInt(store, 2));
i += bytesLength - 1;
} else {
str += String.fromCharCode(_arr[i]);
}
}
return str;
}
function bytesToUtf8(arr) {
const utf8Bytes = new Uint8Array(arr);
const decoder = new TextDecoder('utf-8');
const decodedString = decoder.decode(utf8Bytes);
return decodedString
}
function MD5() {
console.log("==============MD5==============")
var MessageDigest = Java.use("java.security.MessageDigest");
MessageDigest.getInstance.overload('java.lang.String').implementation = function (a) {
send("[*]算法是:" + a)
return this.getInstance(a)
}
MessageDigest.update.overload('byte').implementation = function (a) {
send("[*]update传入类型byte:" + a)
return this.update(a)
}
MessageDigest.update.overload('java.nio.ByteBuffer').implementation = function (a) {
send("[*]update传入类型ByteBuffer:" + a)
return this.update(a)
}
MessageDigest.update.overload('[B').implementation = function (a) {
send("[*]update传入类型Bytes:" + a)
send("update Bytes To String:" + bytesToString(a))
return this.update(a)
}
MessageDigest.update.overload('[B', 'int', 'int').implementation = function (a, b, c) {
send("[*]update传入类型Bytes,int,int:" + a + "|" + b + "|" + c)
send("update Bytes To String:" + bytesToString(a))
return this.update(a)
}
MessageDigest.digest.overload().implementation = function () {
var result = this.digest()
send("digest结果(hex):" + bytesToHex(result))
send("digest结果(base64):" + bytesToBase64(result))
send("digest结果(string):" + bytesToString(result))
return result;
}
MessageDigest.digest.overload('[B').implementation = function (arg) {
send("digest Bytes To String:" + bytesToString(arg))
var result = this.digest(arg)
send("digest结果(hex):" + bytesToHex(result))
send("digest结果(base64):" + bytesToBase64(result))
send("digest结果(string):" + bytesToString(result))
return result;
}
}
function DES() {
console.log("==============DES/AES==============")
var Cipher = Java.use("javax.crypto.Cipher")
Cipher.getInstance.overload('java.lang.String').implementation = function (a) {
var result = this.getInstance(a)
send("[*]算法是:" + a)
return result
}
Cipher.getInstance.overload('java.lang.String', 'java.lang.String').implementation = function (a, b) {
var result = this.getInstance(a, b)
send("[*]算法是:" + a + "|" + b)
return result
}
var SecretKeySpec = Java.use("javax.crypto.spec.SecretKeySpec");
SecretKeySpec.$init.overload('[B', 'java.lang.String').implementation = function (a, b) {
send("算法名:" + b + ",密钥文件(String):" + bytesToString(a))
send("算法名:" + b + ",密钥文件(Hex):" + bytesToHex(a))
send("算法名:" + b + ",密钥文件(Base64):" + bytesToBase64(a))
return this.$init(a, b)
}
// 操作 iv 偏移量
var IvParameterSpec = Java.use("javax.crypto.spec.IvParameterSpec")
IvParameterSpec.$init.overload('[B').implementation = function (arg) {
send("IV偏移量(String):" + bytesToString(arg))
send("IV偏移量(HEX):" + bytesToHex(arg))
send("IV偏移量(Base64):" + bytesToBase64(arg))
var result = this.$init(arg)
return result
}
Cipher.update.overload('[B').implementation = function (arg) {
send("update Bytes To String:" + bytesToString(arg))
var result = this.update(arg)
return result
}
Cipher.update.overload('[B', 'int', 'int').implementation = function (arg, b, c) {
send("[*]update传入类型Bytes,int,int:" + arg + "|" + b + "|" + c)
send("update Bytes To String:" + bytesToString(arg))
var result = this.update(arg, b, c)
return result
}
Cipher.doFinal.overload().implementation = function () {
var result = this.doFinal()
send("doFinal加密结果(String):" + result)
send("doFinal加密结果(hex):" + bytesToHex(result))
send("doFinal加密结果(base64):" + bytesToBase64(result))
return result
}
Cipher.doFinal.overload('[B').implementation = function (arg) {
send("doFinal入参:" + bytesToString(arg))
// 获取算法名称
// var alg = this.getAlgorithm();
// console.log(alg)
var result = this.doFinal(arg)
send("doFinal结果(hex):" + bytesToHex(result))
send("doFinal结果(base64):" + bytesToBase64(result))
return result
}
}
function HMAC() {
console.log("==============HMAC==============")
var mac = Java.use("javax.crypto.Mac")
mac.update.overload('[B').implementation = function (arg) {
send("[*]update传入类型ByteBuffer:" + arg)
send("update Bytes To String:" + bytesToString(arg))
var result = this.update(arg)
return result
}
mac.update.overload('[B', 'int', 'int').implementation = function (arg, b, c) {
send("[*]update传入类型ByteBuffer,int,int:" + arg + "|" + b + "|" + c)
send("update Bytes To String:" + bytesToString(arg))
var result = this.update(arg, b, c)
return result
}
mac.doFinal.overload().implementation = function () {
var alg = this.getAlgorithm();
var result = this.doFinal()
send(alg + "-doFinal加密结果(hex):" + bytesToHex(result))
send(alg + "-doFinal加密结果(base64):" + bytesToBase64(result))
return result
}
mac.doFinal.overload('[B').implementation = function (arg) {
var alg = this.getAlgorithm();
send("doFinal入参:" + bytesToString(arg))
var result = this.doFinal(arg)
send(alg + "-doFinal结果(hex):" + bytesToHex(result))
send(alg + "-doFinal结果(base64):" + bytesToBase64(result))
return result
}
}
function BASE64() {
var b64 = Java.use("android.util.Base64")
b64.decode.overload('java.lang.String', 'int').implementation = function (a, b) {
send("b64接受入参:" + a + "|" + b)
return this.decode(a, b)
}
var X509EncodedKeySpec = Java.use("java.security.spec.X509EncodedKeySpec")
X509EncodedKeySpec.$init.overload('[B').implementation = function (a) {
var res = this.$init(a)
send("RSA密钥:" + bytesToBase64(a))
return res
}
}
function main() {
Java.perform(function () {
MD5()
DES()
HMAC()
BASE64()
})
}
setImmediate(main)