安卓逆向frida之so层hook分析关键函数定位探究

一、基础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));
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云霄IT

感谢感谢!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值