本文记录常用hook脚本的代码
hook so层打印堆栈
function dump_c(context, str_tag)
{
console.log('');
console.log("=============================" + str_tag + " Stack strat=======================");
console.log(Thread.backtrace(context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n'));
console.log("=============================" + str_tag + " Stack end =======================");
}
so层dump内存
function readPointerXX(pointer, len) {
var ret = ""
try {
ret = hexdump(pointer, {
offset: 0,
length: len,
header: false,
ansi: false
})
} catch (e) {
ret = pointer
}
return ret
}
hook动态加载的java层类方法
function hook_java(){
console.log("===== hook java =====");
Java.perform(function(){
console.log("---------------Java.enumerateClassLoaders");
Java.enumerateClassLoaders({
onMatch: function(cl){
fartwithClassloader(cl);
},
onComplete: function(){
}
});
});
}
function fartwithClassloader(cl){
Java.perform(function(){
var clstr = cl.$className.toString();
if(clstr.indexOf("java.lang.BootClassLoader") >= 0 ){
return
}
console.log(" |------------",cl.$className);
var class_BaseDexClassLoader = Java.use("dalvik.system.BaseDexClassLoader");
var pathcl = Java.cast(cl, class_BaseDexClassLoader);
console.log(".pathList" + pathcl.pathList.value);
//libsgmain.so需要修改为对应的动态库
if(pathcl.pathList.value.toString().search("libsgmain.so") !== -1){
console.log(" sgmain hooking ");
//获取到classloader之后就可以进行java层的hook了
Java.classFactory.loader = pathcl;
var initsmsdk = Java.classFactory.use('类名')
initsmsdk.方法名.implementation = function (参数) {
return res;
}
}
}
// 这里如果要打印参数,需要先获取相关java类,然后将参数强转成java类后再打印
// 例子:
const String = Java.use('java.lang.String')
const Map = Java.use('java.util.Map')
const JavaByte = Java.use("[B");
console.log(Java.cast(args[4],String).toString())
var buffer = Java.cast(args[9],JavaByte)
var res = Java.array('byte', buffer)
console.log(byteToString(res))
hook so层的memcopy
function hook_memcopy() {
// 通过函数名称获取 memcpy 地址并hook
var atol = Module.getExportByName('libc.so', 'memcpy');
console.log("===== memcopy hook start ");
Interceptor.attach(atol, {
onEnter: function (args) {
var length = args[2]
var text = args[1].readCString()
var addr = args[0]
console.log("===== memcopy : " + text)
console.log("===== memcopy from " + args[1] + " to : " + addr)
}, onLeave: function (retval) {
}
});
}
hook so层的malloc
function hook_malloc() {
var atol = Module.getExportByName('libc.so', 'malloc');
console.log(" malloc hooking... ")
Interceptor.attach(atol, {
onEnter: function (args) {
this.arg1 = args[0]
}, onLeave: function (retval) {
console.log("===== malloc retval : " + retval + " 长度 : " + this.arg1)
}
});
}
简单的so层hook libart 打印so层调用java层函数
function hook_art() {
var module_libart = Process.findModuleByName("libart.so");
var libart_addr = Module.findBaseAddress("libart.so")
console.log("libart_addr : " + libart_addr)
var symbols = module_libart.enumerateSymbols();
for (var i = 0; i < symbols.length; i++) {
var name = symbols[i].name;
// console.log("libart 函数名称及地址 : " + name + " " + symbols[i].address)
if (name.indexOf("CallSta") >= 0 || name.indexOf("CallObj") >= 0) {
console.log("=== name : " + name)
try {
Interceptor.attach(symbols[i].address, {
onEnter: function (args) {
console.log("=== get " + name)
try {
var java_class = args[1];
var mid = args[2];
var class_name = Java.vm.tryGetEnv().getObjectClassName(java_class);
var method_name = prettyMethod(mid, 1);
console.log("JAVA FUNCTION : ", DebugSymbol.fromAddress(this.returnAddress), class_name, method_name);
} catch (e) {
console.log("非调用")
}
}
})
} catch (e) {
console.log("无法hook : " + name)
}
}
}
}
打印当前进程pid
const gettid = new SystemFunction(Module.findExportByName(null, 'gettid'), 'int32', []);
console.log("=== pid : " + gettid().value)