平时常用的frida函数
//**********************************************************************************************
function log_print(info){
var Log = Java.use("android.util.Log");
Log.i("yooha-testjs", info);
}
//**********************************************************************************************
function ArrayTotString(dexarray, offset){
var string = new Array();
var flag = 1;
while(flag != 0){
flag = dexarray[offset];
offset += 1;
if(flag != 0){
string.push(flag);
}
}
var str = "";
for(var i=0;i<string.length;i++){
str += String.fromCharCode(string[i])
}
return str;
}
//**********************************************************************************************
function hook_JSONOBJ(){
Java.perform(function() {
var ClassName = "org.json.JSONObject";
var Platform = Java.use(ClassName);
var targetMethod = "$init";
var len = Platform[targetMethod].overloads.length; //重载个数
console.log(len);
for(var i = 0; i < len; ++i) {
Platform[targetMethod].overloads[i].implementation = function () { //hook所有的重载
console.log("**********************************************")
for (var j = 0; j < arguments.length; j++) {
console.log(" param --> ", j + 1, " param = ", arguments[j])
}
var stack = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new());
console.log(stack);
this[targetMethod].apply(this, arguments);
}
}
});
}
function hook_JSONPUT(){
Java.perform(function() {
Java.use("org.json.JSONObject").put.overload('java.lang.String', 'java.lang.Object').implementation=function(a,b){
var ret = this.put(a,b);
if(a == "userprofile"){
console.log("a:",a);
console.log("b ", b);
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
console.log("ret ", ret);
}
return ret;
}
});
}
//**********************************************************************************************
function load_dex(){
var dexPath = "/data/local/tmp/yooha.dex";
Java.openClassFile(dexPath).load();
log_print("inject " + dexPath + " successfully!")
}
//**********************************************************************************************
/**
* 打印类的全部字段值
* @param {*} obj 对象
* @returns
*/
function printClass(obj){
var str = "-------------------------------\n";
str += "|" + JSON.stringify(obj) + "\n";
var fields = obj.getClass().getFields();
for(var index in fields){
var field = fields[index];
var fieldName = "";
var value = "";
try{
fieldName = field.getName();
value = field.get(obj);
}catch(e){
}
if(fieldName == ""){
continue;
}
str += "|" + fieldName + ":" + printValue(value) + "\n";
}
str += "------------------------------\n\n\n";
return str;
}
function printValue(value){
try{
var newValue = Java.cast(value, Java.use("java.lang.Object"))
switch(newValue.getClass().getName()){
case "[B":
return printBytes(value)
}
return value;
}catch(e){
return value;
}
}
function printBytes(result){
try{
var ByteArrayOutputStreamClass = Java.use("java.io.ByteArrayOutputStream");
var out = ByteArrayOutputStreamClass.$new()
var ObjectOutputStreamClass = Java.use("java.io.ObjectOutputStream");
var sOut = ObjectOutputStreamClass.$new(out);
sOut.writeObject(result);
sOut.flush();
var bytes = out.toByteArray();
var argsArray = [];
for(var i = 0; i < bytes.length; i++) {
argsArray.push(bytes[i]);
}
return "["+argsArray.join(",")+"]";
}catch(e){
console.log(e);
return result;
}
}
//**********************************************************************************************
function get_interface(){
Java.perform(function () {
Java.enumerateLoadedClasses({
onMatch: function (name, handle){
var hookCls = Java.use(name);
var interFaces = hookCls.class.getInterfaces();
if(interFaces.length > 0){
for(var i in interFaces){
console.log(name);
console.log("interface = ", interFaces[i].toString());
}
}
},
onComplete: function () {
console.log("end")
}
})
})
}
//**********************************************************************************************
function hook_Load(){
Java.perform(function(){
const System = Java.use('java.lang.System');
const Runtime = Java.use('java.lang.Runtime');
const VMStack = Java.use('dalvik.system.VMStack');
System.loadLibrary.implementation = function (library) {
try {
console.log('System.loadLibrary("' + library + '")');
var ret;
ret = Runtime.getRuntime().loadLibrary0(VMStack.getCallingClassLoader(), library);
return ret;
} catch (ex) {
console.log(ex);
}
};
System.load.implementation = function (library) {
try {
console.log('System.load("' + library + '")');
var ret;
ret = Runtime.getRuntime().load0(VMStack.getCallingClassLoader(), library);
return ret;
} catch (ex) {
console.log(ex);
}
};
});
}
//**********************************************************************************************
function class_cast(obj, dest_class){
return Java.cast(obj, Java.use(dest_class));
}
//**********************************************************************************************
var jclazz = null;
var jobj = null;
function getObjClassName(obj) {
if (!jclazz) {
var jclazz = Java.use("java.lang.Class");
}
if (!jobj) {
var jobj = Java.use("java.lang.Object");
}
return jclazz.getName.call(jobj.getClass.call(obj));
}
function watch(obj, mtdName) {
var listener_name = getObjClassName(obj);
var target = Java.use(listener_name);
if (!target || !mtdName in target) {
return;
}
// send("[WatchEvent] hooking " + mtdName + ": " + listener_name);
target[mtdName].overloads.forEach(function (overload) {
overload.implementation = function () {
//send("[WatchEvent] " + mtdName + ": " + getObjClassName(this));
console.log("[WatchEvent] " + mtdName + ": " + getObjClassName(this))
return this[mtdName].apply(this, arguments);
};
})
}
function hook_click(){
Java.perform(function(){
console.log("**********************************************")
//以spawn启动进程的模式来attach的话
// Java.enumerateClassLoaders({
// onMatch:function(loader){
// try{
// if (loader.findClass("com.qq.e.comm.plugin.nativeadunified.f")){
// console.log("Succefully found loader:", loader);
// Java.classFactory.loader = loader;
// }
// }
// catch(error){
// console.log("found error:" + error);
// }
// },onComplete:function(){"enum completed"}
// })
Java.use("android.view.View").setOnClickListener.implementation = function (listener) {
if (listener != null) {
watch(listener, 'onClick');
}
return this.setOnClickListener(listener);
};
// Java.use("android.view.View").setOnTouchListener.implementation = function (listener) {
// if (listener != null) {
// watch(listener, 'onTouch');
// }
// return this.setOnTouchListener(listener);
// };
//如果frida以attach的模式进行attch的话
// Java.choose("android.view.View$ListenerInfo", {
// onMatch: function (instance) {
// instance = instance.mOnClickListener.value;
// if (instance) {
// console.log("mOnClickListener name is :" + getObjClassName(instance));
// watch(instance, 'onClick');
// }
// },
// onComplete: function () {
// }
// })
});
}
function print_list(lists){
if (lists != null){
for(var i = 0; i < lists.size(); i++){
console.log("list:", lists.get(i).toString());
}
}
}
function hook_plugin_dex(classname, funcname, paramsLog){
Java.perform(function(){
Java.enumerateClassLoaders({
onMatch:function(loader){
try{
if (loader.findClass("com.qq.e.comm.plugin.t.b$1")){
console.log("Succefully found loader:", loader);
Java.classFactory.loader = loader;
hook_func(classname, funcname, paramsLog);
}
}
catch(error){
//console.log("found error:" + error);
}
},onComplete:function(){"enum completed"}
})
});
}
function getJson(jsStr){
return JSON.parse(jsStr);
}
function hook_recv_msg(){
Java.use("c.c.d.n").c.overload('java.util.List').implementation=function(a1){
console.log("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ recv msg ");
get_time();
for(var i = 0; i < a1.size(); i++){
console.log("********************************** msg -> ", i)
var im = a1.get(i);
var imobj = Java.cast(im, Java.use("com.netease.nimlib.sdk.msg.model.IMMessage"));
console.log("msg getUuid = ", imobj.getUuid());
console.log("msg getSessionId = ", imobj.getSessionId());
console.log("msg getSubtype = ", imobj.getSubtype());
console.log("msg getStatus = ", imobj.getStatus());
console.log("msg getDirect = ", imobj.getDirect());
console.log("msg getAttachment = ", imobj.getAttachment());
console.log("msg getAttachStatus = ", imobj.getAttachStatus());
console.log("msg getCallbackExtension = ", imobj.getCallbackExtension());
console.log("msg getPushPayload = ", imobj.getPushPayload()); //推送标题
var lo = imobj.getPushPayload();
if (lo != null){
var gelo = Java.cast(lo, Java.use('java.util.HashMap'));
console.log("msg getPushPayload HashMap -> ", gelo);
}
var cfg = imobj.getConfig();
console.log("msg getConfig = ", cfg); //推送配置
if (cfg != null){
var getcfg = Java.cast(cfg, Java.use("com.netease.nimlib.sdk.msg.model.CustomMessageConfig"));
var enablePush = getcfg.getClass().getDeclaredField("enablePush");
enablePush.setAccessible(true);
console.log("msg getConfig CustomMessageConfig - enablePush -> ", enablePush.get(getcfg));
var enablePushNick = getcfg.getClass().getDeclaredField("enablePushNick");
enablePushNick.setAccessible(true);
console.log("msg getConfig CustomMessageConfig - enablePushNick -> ", enablePushNick.get(getcfg));
}
console.log("msg getServerId = ", imobj.getServerId());
console.log("msg getFromAccount = ", imobj.getFromAccount());
console.log("msg getFromNick = ", imobj.getFromNick());//消息发送者的昵称
console.log("msg getMsgType = ", imobj.getMsgType()); //消息类型
console.log("msg getContent = ", imobj.getContent()); //消息内容
console.log("msg getSessionType = ", imobj.getSessionType());
console.log("msg getFromClientType = ", imobj.getFromClientType());
console.log("msg getRemoteExtension = ", JSON.stringify(imobj.getRemoteExtension()));
var ex = imobj.getRemoteExtension();
if (ex != null){
var eemoteExtension = Java.cast(ex, Java.use('java.util.HashMap'));
console.log("msg getRemoteExtension HashMap -> ", eemoteExtension);
}
console.log("msg getLocalExtension = ", imobj.getLocalExtension());
console.log("msg getPushContent = ", imobj.getPushContent()); //推送文案
console.log("msg getMemberPushOption = ", imobj.getMemberPushOption());
}
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
this.c(a1);
}
Java.use("cn.weli.im.ChatService").a.overload('com.netease.nimlib.sdk.msg.model.CustomNotification').implementation=function(a1){
console.log("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ recv customNotification 自定义系统通知") //展示请求视频
get_time();
console.log("customNotification getApnsText = ", a1.getApnsText());
var cfg = a1.getConfig();
var imobj = Java.cast(cfg, Java.use("com.netease.nimlib.sdk.msg.model.CustomNotificationConfig"));
var enablePushNick = imobj.getClass().getDeclaredField("enablePushNick"); //获取字段
enablePushNick.setAccessible(true);
console.log("customNotification getConfig -> enablePushNick -> ", enablePushNick.get(imobj)); //打印字段的值
var enablePush = imobj.getClass().getDeclaredField("enablePush"); //获取字段
enablePush.setAccessible(true);
console.log("customNotification getConfig -> enablePush -> ", enablePush.get(imobj)); //打印字段的值
console.log("customNotification getContent = ", a1.getContent());
console.log("customNotification getFromAccount = ", a1.getFromAccount());
console.log("customNotification getSessionId = ", a1.getSessionId());
console.log("customNotification getSessionType = ", a1.getSessionType());
console.log("customNotification getEnv = ", a1.getEnv());
console.log("customNotification getFromAccount = ", a1.getFromAccount());
console.log("customNotification getPushPayload = ", a1.getPushPayload());
var lo = a1.getPushPayload();
if (lo != null){
var gelo = Java.cast(lo, Java.use('java.util.HashMap'));
console.log("customNotification getPushPayload HashMap -> ", gelo);
}
console.log("customNotification getNIMAntiSpamOption = ", a1.getNIMAntiSpamOption());
var cfg = a1.getNIMAntiSpamOption();
if (cfg != null){
var getcfg = Java.cast(cfg, Java.use("com.netease.nimlib.sdk.msg.model.NIMAntiSpamOption"));
var antiSpamConfigId = getcfg.getClass().getDeclaredField("antiSpamConfigId");
antiSpamConfigId.setAccessible(true);
console.log("customNotification getNIMAntiSpamOption antiSpamConfigId -> ", antiSpamConfigId.get(getcfg));
var content = getcfg.getClass().getDeclaredField("content");
content.setAccessible(true);
console.log("customNotification getNIMAntiSpamOption content -> ", content.get(getcfg));
var enable = getcfg.getClass().getDeclaredField("enable");
enable.setAccessible(true);
console.log("customNotification getNIMAntiSpamOption enable -> ", enable.get(getcfg));
}
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
this.a(a1);
}
Java.use("cn.weli.im.ChatService$b").a.implementation=function(a1){
console.log("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ recv broadcast 广播消息");
get_time();
var imobj = Java.cast(a1, Java.use("com.netease.nimlib.sdk.msg.model.BroadcastMessage"));
console.log("broadcast getContent = ", imobj.getContent());
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
this.a(a1);
}
Java.use("cn.weli.im.ChatService").a.overload('boolean').implementation=function(a1){
console.log("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ register observer 注册各种消息的观察者");
get_time();
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
this.a(a1);
}
Java.use("com.netease.nimlib.c.e.f").sendCustomNotification.implementation=function(a1){
console.log("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ send CustomNotification");
get_time();
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
this.sendCustomNotification(a1);
}
Java.use("c.c.d.o$d").getAvatarForMessageNotifier.implementation=function(a1,a2){
console.log("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ getAvatarForMessageNotifier 获取通知栏头像");
get_time();
// var info = Java.use("c.c.d.c0.a").b(a2);
// var infoobj = Java.cast(info, Java.use("com.netease.nimlib.sdk.uinfo.model.UserInfo"));
// console.log("UserInfo getAvatar = ", infoobj.getAvatar())
console.log("getAvatarForMessageNotifier str = ", a2);
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
return this.getAvatarForMessageNotifier(a1, a2);
}
Java.use("c.c.d.n").a.overload('java.util.List').implementation=function(a1){
console.log("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ recv chatroom ")
get_time();
try{
for(var i = 0; i < a1.size(); i++){
console.log("********************************** msg -> ", i)
var im = a1.get(i);
var imobj = Java.cast(im, Java.use("com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage"));
console.log("ChatRoomMessage getChatRoomConfig = ", imobj.getChatRoomConfig());
console.log("ChatRoomMessage getChatRoomMessageExtension = ", imobj.getChatRoomMessageExtension());
imobj = Java.cast(im, Java.use("com.netease.nimlib.sdk.msg.model.IMMessage"));
console.log("ChatRoomMessage getUuid = ", imobj.getUuid());
console.log("ChatRoomMessage getSessionId = ", imobj.getSessionId());
console.log("ChatRoomMessage getSubtype = ", imobj.getSubtype());
console.log("ChatRoomMessage getStatus = ", imobj.getStatus());
console.log("ChatRoomMessage getDirect = ", imobj.getDirect());
console.log("ChatRoomMessage getAttachment = ", imobj.getAttachment());
console.log("ChatRoomMessage getAttachStatus = ", imobj.getAttachStatus());
console.log("ChatRoomMessage getCallbackExtension = ", imobj.getCallbackExtension());
console.log("ChatRoomMessage getPushPayload = ", imobj.getPushPayload()); //推送标题
var lo = imobj.getPushPayload();
if (lo != null){
var gelo = Java.cast(lo, Java.use('java.util.HashMap'));
console.log("ChatRoomMessage getPushPayload HashMap -> ", gelo);
}
var cfg = imobj.getConfig();
console.log("ChatRoomMessage getConfig = ", cfg); //推送配置
if (cfg != null){
var getcfg = Java.cast(cfg, Java.use("com.netease.nimlib.sdk.msg.model.CustomMessageConfig"));
var enablePush = getcfg.getClass().getDeclaredField("enablePush");
enablePush.setAccessible(true);
console.log("ChatRoomMessage getConfig CustomMessageConfig - enablePush -> ", enablePush.get(getcfg));
var enablePushNick = getcfg.getClass().getDeclaredField("enablePushNick");
enablePushNick.setAccessible(true);
console.log("ChatRoomMessage getConfig CustomMessageConfig - enablePushNick -> ", enablePushNick.get(getcfg));
}
console.log("ChatRoomMessage getServerId = ", imobj.getServerId());
console.log("ChatRoomMessage getFromAccount = ", imobj.getFromAccount());
console.log("ChatRoomMessage getFromNick = ", imobj.getFromNick());//消息发送者的昵称
console.log("ChatRoomMessage getMsgType = ", imobj.getMsgType()); //消息类型
console.log("ChatRoomMessage getContent = ", imobj.getContent()); //消息内容
console.log("ChatRoomMessage getSessionType = ", imobj.getSessionType());
console.log("ChatRoomMessage getFromClientType = ", imobj.getFromClientType());
console.log("ChatRoomMessage getRemoteExtension = ", JSON.stringify(imobj.getRemoteExtension()));
var ex = imobj.getRemoteExtension();
if (ex != null){
var eemoteExtension = Java.cast(ex, Java.use('java.util.HashMap'));
console.log("ChatRoomMessage getRemoteExtension HashMap -> ", eemoteExtension);
}
console.log("ChatRoomMessage getLocalExtension = ", imobj.getLocalExtension());
console.log("ChatRoomMessage getPushContent = ", imobj.getPushContent()); //推送文案
console.log("ChatRoomMessage getMemberPushOption = ", imobj.getMemberPushOption());
}
}catch(e){
console.log("ChatRoomMessage error ", e);
}
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
this.a(a1);
}
}
function hook_func(classname, funcname, isReturn, isParam){
try{
var Platform = Java.use(classname);
var overloads = Platform[funcname].overloads;
var len = overloads.length;
for(var i = 0; i < len; ++i) {
overloads[i].implementation = function () {
if (isParam){
for (var i = 0; i < arguments.length; i ++){
console.log("param[" + (i+1) + "] => " + arguments[i]);
}
}
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
if (isReturn){
return this[funcname].apply(this, arguments);
}
else{
this[funcname].apply(this, arguments);
}
}
console.log("*************************************************************************************");
console.log("正在hook " + classname + " -> " + funcname);
for(var j = 0; j < overloads[i].argumentTypes.length; ++j) {
console.log("param[" + (j+1) + "]: " + getJson(JSON.stringify(overloads[i].argumentTypes[j]))["name"]);
}
console.log('\n');
}
}catch(error){
console.log("hook_func error:" + error);
}
}
function dump_so(so_name){
Java.perform(function () {
var currentApplication = Java.use("android.app.ActivityThread").currentApplication();
var dir = currentApplication.getApplicationContext().getFilesDir().getPath();
var libso = Process.getModuleByName(so_name);
console.log("[name]:", libso.name);
console.log("[base]:", libso.base);
console.log("[size]:", ptr(libso.size));
console.log("[path]:", libso.path);
var file_path = dir + "/" + libso.name + "_" + libso.base + "_" + ptr(libso.size) + ".so";
var file_handle = new File(file_path, "wb");
if (file_handle && file_handle != null) {
Memory.protect(ptr(libso.base), libso.size, 'rwx');
var libso_buffer = ptr(libso.base).readByteArray(libso.size);
file_handle.write(libso_buffer);
file_handle.flush();
file_handle.close();
console.log("[dump]:", file_path);
}
});
}
function hook_popen(){
let fgets_ptr = Module.findExportByName('libc.so', 'fgets');
let fgets = new NativeFunction(fgets_ptr, 'pointer', ['pointer', 'int', 'pointer']);
let popen_addr = Module.findExportByName('libc.so', 'popen');
console.log("popen addr =>", popen_addr);
Interceptor.attach(popen_addr, {
onEnter:function(args){
let command = args[0].readUtf8String();
let mode = args[1].readUtf8String();
console.log("[popen] command=", command);
console.log("[popen] mode=", mode);
},
onLeave:function(fp){
let output = '';
let buffer = Memory.alloc(1024);
while (fgets(buffer, 1024, fp) > 0){
output += buffer.readUtf8String();
}
console.log("[popen] fp=", fp);
console.log("[popen] output=", output);
}
})
}
function hook_call_function() {
// if (Process.pointerSize == 4) {
// var linker = Process.findModuleByName("linker");
// } else {
// var linker = Process.findModuleByName("linker64");
// }
var linker = Process.findModuleByName("linker");
var addr_call_function =null;
var addr_g_ld_debug_verbosity = null;
var addr_async_safe_format_log = null;
if (linker) {
var symbols = linker.enumerateSymbols();
for (var i = 0; i < symbols.length; i++) {
var name = symbols[i].name;
if (name.indexOf("call_function") >= 0){
addr_call_function = symbols[i].address;
}
else if(name.indexOf("g_ld_debug_verbosity") >=0){
addr_g_ld_debug_verbosity = symbols[i].address;
ptr(addr_g_ld_debug_verbosity).writeInt(2);
} else if(name.indexOf("async_safe_format_log") >=0 && name.indexOf('va_list') < 0){
addr_async_safe_format_log = symbols[i].address;
}
}
}
if(addr_async_safe_format_log){
Interceptor.attach(addr_async_safe_format_log,{
onEnter: function(args){
this.log_level = args[0];
this.tag = ptr(args[1]).readCString(); // "linker"
this.fmt = ptr(args[2]).readCString(); // [ Calling d-tor %s @ %p for '%s' ]
if(this.fmt.indexOf("c-tor") >= 0 && this.fmt.indexOf('Done') < 0){
this.function_type = ptr(args[3]).readCString(), // func_type
this.so_path = ptr(args[5]).readCString();
var strs = new Array(); //定义一数组
strs = this.so_path.split("/"); //字符分割
this.so_name = strs.pop();
this.func_offset = ptr(args[4]).sub(Module.findBaseAddress(this.so_name))
console.log("func_type:", this.function_type,
'\nso_name:',this.so_name,
'\nso_path:',this.so_path,
'\nfunc_offset:',this.func_offset
);
}
},
onLeave: function(retval){
}
})
}
}
function find_interface(classname, interfacename){
var hookCls = Java.use(classname);
var interFaces = hookCls.class.getInterfaces();
if(interFaces.length > 0){
if (interFaces[0].toString().indexOf(interfacename) != -1){
var srevar = interFaces[0].toString();
if (srevar == "interface " + interfacename){
if(Java.use(classname).class.isInterface() == false){
console.log("--> 实现类", classname);
console.log("--> 接口类", interFaces[0].toString());
return;
}
else{
console.log("--> 上层接口", classname);
console.log("--> 接口类", interFaces[0].toString());
enumerateClass_toFindInterface(classname);
}
}
}
}
}
function enumerateClass_toFindInterface(interfacename){ //找某接口的实现类
Java.enumerateLoadedClasses({
onMatch: function (name, handle){
if (name.indexOf("com.analytics") != -1){
find_interface(name, interfacename);
}
},
onComplete: function () {
}
})
}
function hookNoAscII(){
var targetClass = "com.jy.xposed.skip.ᐝ";
var hookCls = Java.use(targetClass);
// var methods = hookCls.class.getDeclaredMethods();
// for (var i in methods) {
// console.log("1:" + methods[i].toString());
// console.log("2:" + encodeURIComponent(methods[i].toString().replace(/^.*?\.([^\s\.\(\)]+)\(.*?$/, "$1")));
// }
hookCls[decodeURIComponent("%CB%8F")].implementation = function (x) {
console.log("DQ4JQBsMBwkRQAAKChMLBwU= -> " + this[decodeURIComponent("%D6%8F")]("DQ4JQBsMBwkRQAAKChMLBwU="));
console.log("DQ4JQBsMBwkRQAAKChMLBwU= -> " + this[decodeURIComponent("%D6%8F")]("DQ4JQBsMBwkRQAAKChMLBwU="));
return this[decodeURIComponent("%D6%8F")](x);;
}
}
function hookNoAscIIStatic(){
var targetClass = "com.jy.xposed.skip.ᐝ";
var hookCls = Java.use(targetClass);
console.log(" DQ4JQBsMBwkRQAAKChMLBwU= -> " + hookCls.ˏ("DQ4JQBsMBwkRQAAKChMLBwU="));
}
//写文件
function file_createdir(pkgname) {
var mkdirPtr = Module.getExportByName('libc.so', 'mkdir');
var mkdir = new NativeFunction(mkdirPtr, 'int', ['pointer', 'int']);
mkdir(Memory.allocUtf8String("/data/data/" + pkgname + "/dump"), 0x0FFF)
console.log("[+] 初始化dump目录:/data/data/" + pkgname + "/dump");
}
function dump_file_write(file_str, pkgname) {
var file_path = "/data/data/" + pkgname + "/dump/stack.txt";
var fd = new File(file_path, "a");
if (fd && fd != null) {
fd.write(file_str + "\r\n");
fd.flush();
fd.close();
}
}
function writeFileNative(){
var addr_fopen = Module.findExportByName("libc.so", "fopen");
var addr_fputs = Module.findExportByName("libc.so", "fputs");
var addr_fclose = Module.findExportByName("libc.so", "fclose");
// 将 libc 的系统方法注册到 js 层
var fopen = new NativeFunction(addr_fopen, "pointer", ["pointer", "pointer"]);
var fputs = new NativeFunction(addr_fputs, "int", ["pointer", "pointer"]);
var fclose = new NativeFunction(addr_fclose, "int", ["pointer"]);
// 在 js 层主动调用 libc 的方法
// 不能直接将 js 的字符串传给 libc中的方法, 需要进行转换
var filename = Memory.allocUtf8String("/sdcard/reg.dat");
var open_mode = Memory.allocUtf8String("w");
var file = fopen(filename, open_mode);
var buffer = Memory.allocUtf8String("content from frida");
var result = fputs(buffer, file);
console.log("fputs ret: ", result);
// 关闭文件
fclose(file);
}
//获取当前时间
function get_time(){
var date = Java.use("java.util.Date").$new()
return date.toLocaleString();
}
function monitor(){
Java.perform(function(){
enumerateClass_toFindInterface("com.analytics.sdk.view.interface");
});
}
function call_static(){
var targetClass = "com.rong.xposed.fakelocation.x.d.a.e" + "$" + "i";
var hookCls = Java.use(targetClass);
console.log(" a -> " + hookCls.a());
}
function hook_class_methods(classname){
try{
var clz = Java.use(classname);
var methods = clz.class.getDeclaredMethods()
for (var i = 0; i < methods.length; i++){
var methodname = methods[i].getName();
console.log(classname + " -> " + methodname);
}
}catch(error){
console.log("hook_class_methods error:" + error);
}
}
function hook_class_fields(classname){
try{
var clz = Java.use(classname);
var fields = clz.class.getDeclaredFields()
for (var i = 0; i < fields.length; i++){
var fieldname = fields[i].getName();
console.log(classname + " -> " + fieldname);
}
}catch(error){
console.log("hook_class_methods error:" + error);
}
}
function hook_methods(classname, methodname){
try{
console.log("hook -----> " + classname + " : " + methodname);
var Platform = Java.use(classname);
var overloads = Platform[methodname].overloads;
var len = overloads.length;
for(var i = 0; i < len; ++i) {
overloads[i].implementation = function () {
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
return this[methodname].apply(this, arguments);
}
}
}catch(error){
console.log("hook_methods error:" + error);
}
}
function hook_class(classname, isall, func){ // hook类的函数 全部函数或者包含某些关键字的函数
try{
var clz = Java.use(classname);
var methods = clz.class.getDeclaredMethods()
for (var i = 0; i < methods.length; i++){
var methodname = methods[i].getName();
if (isall){
hook_methods(classname, methodname);
}else{
if (methodname.indexOf(func) != -1){
hook_methods(classname, methodname);
}
}
}
}catch(error){
console.log("hook_class error:" + error);
}
}
function dump_maps(){
var ranges = Process.enumerateRanges("r--")
ranges = ranges.filter((range) => {
if(range.file && range.file.path && range.file.path.indexOf(".so") != -1){
console.log(range.protection + " begin:" + range.base + " size:" + range.size + " " + range.file.path);
}
return true;
})
}
function replace_kill(){ //置空函数
var kill_addr = Module.findExportByName("libc.so", "kill");
console.log("kill=>",kill_addr)
var pkill_addr = new NativeFunction(kill_addr,"void",["int","int"])
Interceptor.replace(pkill_addr,
new NativeCallback(function(parg1,parg2){
console.log("in kill ...");
console.log(parg1);
console.log(parg2);
console.log('kill called from:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
},"void",["int","int"]))
}
function replace_exit(){ //置空函数
var exit_addr = Module.findExportByName("libc.so", "exit");
console.log("exit=>",exit_addr)
var pexit_addr = new NativeFunction(exit_addr,"void",["int"])
Interceptor.replace(pexit_addr,
new NativeCallback(function(parg1){
console.log("in exit ...");
console.log(parg1);
console.log('kill called from:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
},"void",["int"]))
}
function hook_libart() {
var symbols = Module.enumerateSymbolsSync("libart.so");
var addrFindClass = null;
var addrGetMethodID = null;
var addrGetStaticMethodID = null;
for (var i = 0; i < symbols.length; i++) {
var symbol = symbols[i];
if (symbol.name.indexOf("art") >= 0 &&
symbol.name.indexOf("JNI") >= 0 &&
symbol.name.indexOf("CheckJNI") < 0
) {
if (symbol.name.indexOf("FindClass") >= 0) {
addrFindClass = symbol.address;
console.log("FindClass is at ", symbol.address, symbol.name);
} else if (symbol.name.indexOf("GetMethodID") >= 0) {
addrGetMethodID = symbol.address;
console.log("GetMethodID is at ", symbol.address, symbol.name);
}else if (symbol.name.indexOf("GetStaticMethodID") >= 0) {
addrGetStaticMethodID = symbol.address;
console.log("GetStaticMethodID is at ", symbol.address, symbol.name);
}
}
}
if (addrFindClass != null) {
Interceptor.attach(addrFindClass, {
onEnter: function (args) {
if (args[1] != null) {
var name = Memory.readCString(args[1]);
if (name.indexOf("[B") == -1){
console.log("[FindClass] name:" + name);
}
}
},
onLeave: function (retval) {}
});
}
if (addrGetMethodID != null) {
Interceptor.attach(addrGetMethodID, {
onEnter: function (args) {
if (args[2] != null) {
var name = Memory.readCString(args[2]);
if (args[3] != null) {
var sig = Memory.readCString(args[3]);
console.log("[GetMethodID] name:" + name + ", sig:" + sig);
} else {
console.log("[GetMethodID] name:" + name);
}
}
},
onLeave: function (retval) {}
});
}
if (addrGetStaticMethodID != null) {
Interceptor.attach(addrGetStaticMethodID, {
onEnter: function (args) {
if (args[2] != null) {
var name = Memory.readCString(args[2]);
if (args[3] != null) {
var sig = Memory.readCString(args[3]);
console.log("[GetStaticMethodID] name:" + name + ", sig:" + sig);
} else {
console.log("[GetStaticMethodID] name:" + name);
}
}
},
onLeave: function (retval) {}
});
}
}
function hook_open(){
var open_addr = Module.findExportByName("libc.so", "open");
console.log("open_addr => ",open_addr)
Interceptor.attach(open_addr,{
onEnter:function(args){
var stack_accurate = Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n';
var path = args[0].readUtf8String();
console.log("path -> ", path);
console.log('open called from ACCURATE:\n' + stack_accurate);
var stack_fuzzy = Thread.backtrace(this.context, Backtracer.FUZZY).map(DebugSymbol.fromAddress).join('\n') + '\n';
console.log('open called from FUZZY:\n' + stack_fuzzy);
},onLeave:function(retval){
//console.log("retval is =>",retval)
}
})
}
function print_Map(param){
var maps = Java.cast(param, Java.use('java.util.HashMap'));
console.log("Map = ", maps);
}
function hook_socket_func(){
//libsocket send recv
var socket_send = Module.findExportByName("libsocket.so","send");
if(socket_send!=null){
Interceptor.attach(socket_send,{
onEnter: function(args){
var sendinfo = args[1].readCString();
console.log("send:", sendinfo);
console.log('libsocket call send from:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
},
onLeave:function(retval){
}
});
}
var socket_recv = Module.findExportByName("libsocket.so","recv");
if(socket_recv!=null){
Interceptor.attach(socket_recv,{
onEnter: function(args){
this.buff = args[1];
console.log('libsocket call recv from:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
},
onLeave:function(retval){
var sendinfo = this.buff.readCString();
console.log("recv:", sendinfo);
}
});
}
}
function get_class(){
Java.perform(function () {
Java.enumerateLoadedClasses({
onMatch: function (name, handle){
console.log(name);
},
onComplete: function () {
console.log("end")
}
})
})
}
function hook_so(){
var android_dlopen_ext = Module.findExportByName(null,"android_dlopen_ext");
if(android_dlopen_ext!=null){
Interceptor.attach(android_dlopen_ext,{
onEnter: function(args){
var soName = args[0].readUtf8String();
console.log(soName);
if(soName.indexOf("libc.so") != -1){
console.log("find libc.so");
this.jshook = true;
}
},
onLeave:function(retval){
if(this.jshook){
hook_libc();
}
}
});
}
}
function hook_pthread_create(){
var pt_create_func = Module.findExportByName(null,'pthread_create');
var detect_frida_loop_addr = null;
console.log('pt_create_func:',pt_create_func);
Interceptor.attach(pt_create_func,{
onEnter:function(){
if(detect_frida_loop_addr == null)
{
var base_addr = Module.findBaseAddress('libmsaoaidsec.so');
if(base_addr != null){
detect_frida_loop_addr = base_addr.add(0x0000000000018C88)
console.log('this.context.x2: ', detect_frida_loop_addr , this.context.x2);
if(this.context.x2.compare(detect_frida_loop_addr) == 0) {
hook_anti_frida_replace(this.context.x2);
}
}
}
},
onLeave : function(retval){
// console.log('retval',retval);
}
})
}
function hook_anti_frida_replace(addr){
console.log('replace anti_addr :',addr);
Interceptor.replace(addr,new NativeCallback(function(a1){
console.log('replace success');
return;
},'pointer',[]));
}
function main(){
Java.perform(function(){
Java.use("com.pano.rtc.api.RtcEngine").create.implementation = function (a1) {
console.log("RtcEngine - init");
this.create(a1);
};
});
//setInterval(() => {monitor()}, 10000);
}
setImmediate(main)
//setTimeout(main, 10000)
封装一个快速hook函数,免去了overload的烦恼
//参数打印的回调
var callback = {
printDexClassLoader : function(args){
console.log("dexpath = ", args[0]);
console.log("optimizedDirectory = ", args[1]);
console.log("librarySearchPath = ", args[2]);
console.log("parent = ", args[3]);
},
printCipher : function(args){
var param1 = args[0];
var mode;
switch(param1){
case 1:
mode = "ENCRYPT_MODE";
break;
case 2:
mode = "DECRYPT_MODE";
break;
case 3:
mode = "WRAP_MODE";
break;
case 3:
mode = " UNWRAP_MODE";
break;
}
console.log("Mode -> " + mode);
}
};
function getJson(jsStr){
return JSON.parse(jsStr);
}
/**
*
* @param {*} classname 类名
* @param {*} funcname 函数名
* @param {*} isReturn 当前函数是否有返回值
* @param {*} paramCallback 参数打印的回调函数
* @param {*} detail 当前hook的函数的说明
*/
function hook_func(classname, funcname, returnCallback, paramCallback, detail){
try{
var Platform = Java.use(classname);
var overloads = Platform[funcname].overloads;
var len = overloads.length;
var returnType = getJson(JSON.stringify(overloads[0].returnType))["name"];
for(var i = 0; i < len; ++i) {
overloads[i].implementation = function () {
var stack = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new());
console.log("---------------------------> ", detail);
if (paramCallback == null){
for (var i = 0; i < arguments.length; i ++){
console.log("param[" + (i+1) + "] => " + arguments[i]);
}
}else{
paramCallback(arguments);
}
if (returnType != "V"){
var ret = this[funcname].apply(this, arguments);
if (returnCallback == null){
console.log("return -> ", ret);
}else{
returnCallback(ret);
}
var stack = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new());
console.log(stack);
return ret;
}
else{
var stack = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new());
console.log(stack);
this[funcname].apply(this, arguments);
}
}
console.log("************************************************************************************* ", detail);
console.log("正在hook " + classname + " -> " + funcname);
for(var j = 0; j < overloads[i].argumentTypes.length; ++j) {
console.log("param[" + (j+1) + "]: " + getJson(JSON.stringify(overloads[i].argumentTypes[j]))["name"]);
}
console.log("return: " + returnType);
console.log('\n');
}
}catch(error){
console.log("hook_func error:" + error);
}
}
//动态加载
function dynamic_loader(){
hook_func('dalvik.system.DexClassLoader', '$init', null, callback.printDexClassLoader, "动态加载");
}