先上python的调用代码,实际上js代码也可以写在里面,但是在pycharm下面不感知颜色,还是分开写好
import frida
import sys
import time
import io
#代码可以直接写入下面,但是可读性不好
# jscode = """
#
# """
def printMessage(message,data):
if message['type'] == 'send':
print('[*] {0}'.format(message['payload']))
# file_object = open("e:\\log.txt", 'ab+')
# file_object.write(message['payload'].encode())
# file_object.write('\n'.encode())
# file_object.close()
else:
print(message)
# device = frida.get_usb_device()
# pid = device.spawn(["com.rom.testso"])
# device.resume(pid)
# time.sleep(8)
# process = device.attach(pid)
process = frida.get_usb_device().attach('testSo')
#直接读入sotest.js,在pycharm中代码有颜色感知,易于编辑
with open('./sotest.js',encoding='utf-8') as f:
jscode = f.read()
script = process.create_script(jscode)
#script = process.create_script(jscode)
script.on('message',printMessage)
script.load()
sys.stdin.read()
.js代码,实现hook so函数,打印字串,拦截类中类等
function hook_myJNI_check() {
Java.perform(function () {
//hook so 中的函数
Interceptor.attach(Module.findExportByName("libJniLib.so", "Java_com_rom_testso_JniDemo_add"), {
onEnter: function (args) {
send("Hook add start");
send("args[0]=" + args[0]);
send("args[1]=" + args[1]);
send("args[2]=" + args[2]);
send("args[3]=" + args[3]);
},
onLeave: function (retval) {
send("ori add return:" + retval);
retval.replace(10);
send("changed add return:" + retval);
}
});
//获取加载的所有模块
// Process.enumerateModules({
// onMatch: function (exp) {
// if (exp.name == 'libJniLib.so') {
// //send(exp.name + "|" + exp.base + "|" + exp.size + "|" + exp.path);
// console.log(exp.name + " : " + exp.base + "\t" + exp.size + "\t" + exp.path);
// //send(exp);
// //return 'stop';
// }
// },
// onComplete: function () {
// send('stop');
// }
// });
var resultPtr = null;
Interceptor.attach(Module.findExportByName("libJniLib.so", "Java_com_rom_testso_JniDemo_getString"), {
onEnter: function (args) {
send("Hook getString start");
send("args[0]=" + args[0]);
send("args[1]=" + args[1]);
resultPtr = args[1];
printstack()
},
onLeave: function (retval) {
var string_to_send = retval.toString();
send("retval value :" + retval.toString());
send("getString return:" + string_to_send);
//上面已经写了怎么Hook修改native层函数返回值为int类型的情况,使用replace()函数直接修改即可,
// 但是返回情况为字符串则不一样,在c语言中,返回值为字符串其实是返回了一个char *(字符串指针),
// 所以简单的替换是无法取效果的,具体怎么修改返回值,接着看下面
var env = Java.vm.getEnv(); //获取env对象,即第一个参数
var jstrings = env.newStringUtf("abc"); //返回的是字符串指针,构造一个newStringUtf对象用来代替这个指针
send("函数返回new值:" + jstring2Str(retval));
send("改变jstrings:" + jstring2Str(jstrings));
//var my_string = Java.use("java.lang.String").overload('java.lang.String').$new(jstrings);
//send("my_string my_string:" + my_string );
//retval.replace(jstrings); //替换返回值
var buffer = Memory.readByteArray(resultPtr, 64);
console.log(hexdump(buffer, {
offset: 0,
length: 64,
header: true,
ansi: false
}));
}
});
Java.choose('com.rom.testso.MainActivity$2', {
onMatch: function (instance) {
console.log('button found', instance)
},
onComplete: function () {
console.log('search Complete')
}
})
var MainAcitivity = Java.use('com.rom.testso.MainActivity')
console.log("Java.Use.Successfully!") //定位类成功!
// 静态函数主动调用
MainAcitivity.add_log("helloworld");
Java.choose('com.rom.testso.MainActivity', {
onMatch: function (instance) {
console.log('MainActivity instance found', instance)
console.log("static helloworld: " + instance.add_log("helloworld"));
console.log("static helloworld: " + instance.add_non_static_log("add_non_static_log"));
//instance.secret()
//instance.staticSecret();
},
onComplete: function () {
console.log('search Complete')
}
})
//因为生成类的实例是在按钮之后,所以一启动应用并没有生成实例,会报错
Java.choose('com.rom.testso.MainActivity$cinc', {
onMatch: function (instance) {
console.log('cinc instance found', instance)
console.log("Result of cinc add func: " + instance.add(7, 3));
//instance.secret()
//instance.staticSecret();
},
onComplete: function () {
console.log('search Complete')
}
})
Interceptor.attach(Module.findExportByName("libc.so", "open"), {
onEnter: function (args) {
send("open called! args[0]:", Memory.readByteArray(args[0], 256));
},
onLeave: function (retval) {
}
});
});
//把javascripts中的string 转成可以输出的string用于观察变量
function jstring2Str(jstring) { //从frida_common_funs.js中copy出来
var ret;
Java.perform(function () {
var String = Java.use("java.lang.String");
ret = Java.cast(jstring, String);//jstring->String
});
return ret;
}
function printstack() {
//方式1 ,直接抛
//send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
//方式2 ,逐行打印
var stack = Java.use("java.lang.Thread").$new().currentThread().getStackTrace();
for (var i = 2; i < stack.length; i++) {
send("getStackTrace[" + (i - 2) + "] : " + stack[i].toString());
}
}
}
function main() {
hook_myJNI_check();
}
setImmediate(main);