一、基础hook
(1)获取指定 so 文件的基地址
function hook_module() {
var baseAddr = Module.findBaseAddress("libxxx-lib.so");
console.log("baseAddr", baseAddr);
}
二、通过函数偏移hook函数
(1)标准hook
function main() {
Java.perform(function () {
var str_name_so = "libxxx.so"; //要hook的so名
var n_addr_func_offset = 0x162C4; //要hook的函数在函数里面的偏移
var n_addr_so = Module.findBaseAddress(str_name_so);
var n_addr_func = parseInt(n_addr_so, 16) + n_addr_func_offset;
var Func = new NativePointer(n_addr_func);
console.log("找到函数地址:",Func);
Interceptor.attach(Func, {
onEnter: function(args) {
console.log('输出调用栈:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
console.log("============================= 输入 ===============================","\n")
for(let i = 0; i < 8; i++) {
console.log("arg",i,": ", "\n");
try {
console.log(hexdump(args[i],{length: 0x200}), "\r\n");
console.log("arg",i,": ",ptr(args[i]).readCString());
} catch (error) {
console.log((args[i]), "\r\n");
}
}
},
onLeave: function(retval) {
console.log('输出调用栈:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
console.log("============================= 结果 ===============================","\n")
try {
console.log(hexdump(retval,{length: 0x130}), "\r\n");
console.log("result:",ptr(retval).readCString());
} catch (error) {
console.log((retval), "\r\n");
}
}
});
});
}
setTimeout(main,20);
(2)无返回,指针取值hook
function main() {
Java.perform(function () {
var str_name_so = "libxxx.so"; //要hook的so名
var n_addr_func_offset = 0x2C90; //关键位置 0x168C4
var n_addr_so = Module.findBaseAddress(str_name_so);
var n_addr_func = parseInt(n_addr_so, 16) + n_addr_func_offset;
var Func = new NativePointer(n_addr_func);
console.log("找到函数地址:",Func);
Interceptor.attach(Func, {
onEnter: function(args) {
console.log('输出调用栈:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
console.log("============================= 输入 ===============================","\n")
for(let i = 0; i < 8; i++) {
console.log("arg",i,": ", "\n");
try {
console.log(hexdump(args[i],{length: 0x200}), "\r\n");
console.log("arg",i,": ",ptr(args[i]).readCString());
} catch (error) {
console.log((args[i]), "\r\n");
}
}
this.result = args[8]; // 取入参指针
},
onLeave: function(retval) {
console.log('输出调用栈:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
console.log("============================= 结果 ===============================","\n")
try {
console.log(hexdump(this.result,{length: 0x130}), "\r\n");
console.log("result:",Memory.readCString(this.result));
} catch (error) {
console.log((this.result), "\r\n");
}
}
});
});
}
setTimeout(main,20);
三、参数类型输出
(一)输出字符串
console.log(ptr(args[0]).readCString());
console.log(Memory.readCString(args[0]));
(二)输出byte数组
var data = Memory.readByteArray(args[0], args[1].toInt32());
console.log('args[0] byte[]:',new Uint8Array(data));
(三)输出base64
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
}
var data = Memory.readByteArray(args[0], 0x520); // 0x520为长度,或通过 args[1].toInt32() 获取
console.log('args[0] byte[]:',bytesToBase64(new Uint8Array(data)))
(四)输出缓冲区的hex
function print_hex(retval,length) { // retval为缓冲区,length字节长度
var buffer = Memory.readByteArray(retval,length);
const byteArray = new Uint8Array(buffer);
const hexParts = [];
for(let i = 0; i < byteArray.length; i++) {
const hex = byteArray[i].toString(16);
const paddedHex = ('00' + hex).slice(-2);
hexParts.push(paddedHex);
}
return hexParts.join('');
}
console.log('args[0] hex:',print_hex(args[0],64));