Frida Hook可变参数

Frida Hook可变参数

0x00 前言:

可变参数Hook原理可以参考下我的这篇文章:C++逆向 可变参数Hook

我在网上搜了好久,都没找到有人写过Frida Hook可变参数.........

0x01 Frida Hook可变参数

args

OK 回归正题,Frida 如何Hook可变参数。

首先可变参数意味着,他的参数个数不确定,参数类型不确定。

在frida中,函数的参数都在args上。我看了官网资料,他说args是一个NativeObject的Array。

可是当我用JS去遍历这个Array的时候,总是会报错。。。。(如果有大神知道,请告诉我如何去遍历。谢谢!)

image-20220421174825412

而且我就这样直接输出args,他也会报一个array index 无效的错误。

格式控制字符串

我目前也只能做到那种格式控制字符串可变参数的函数,比如像printf("%s,%d-%d-%d","hello",1,2,3)这样的。

#include <stdio.h>
int main()
{
    printf("Hello,World!");
    printf("I love %s,test %d-%d-%d %f","C++",1,2,3,6.6);
}

我的思路是编写js代码,然后根据判断%来决定有多少个参数,并且截取%后面字符。

根据字符来进行不同类型的输出,比如字符串、整形、指针数据等。

image-20220421180450266

自己处理格式控制符

/*
/*用来模仿C语言中的 vsprintf 格式化,可变参数输出和函数
*/
function vspritf(format_str,args)
{
    

    //没有%,没有必要去格式化他.
    if (format_str.indexOf("%") === -1) {
        console.log("字符串:",format_str);
        return;
    }

    console.log("format:",format_str);

    //根据字符串长度来循环
    var pos = 0;
    var count = 0;
    console.log("--参数内容:--")
    for (let index = 0; index < format_str.length; index++) {
        pos = format_str.indexOf("%",pos);
        if(pos == -1)
            break;
        
        var format_ch = format_str.substr(pos+1, 1);
        switch (format_ch) {
            case "s":
                var ret = Memory.readUtf8String(args[(count+1)])
                console.log(ret);
                count++;
                break;
            case "d":
                //console.log("整型");
                console.log(args[(count+1)]);
                count++;
                break;
            case "p":
                //console.log("指针型")
                //var ret = Memory.readPointer(args[(count+2)])
                console.log(hexdump(ret,0x30));
                count++;
                break;
            case "f":
                console.log(args[(count+1)]);
        
            default:
                //console.log("其他格式");
                console.log(args[(count+1)]);
                count++;
                break;
        }
        pos+=index+2;
        
    }
    //console.log("一共出现%d次",count);
}

 function hook_printf()
 {
    var baseAddress = Module.getBaseAddress("va_arg.exe");
    var offset      = 0x1410;
    var funcAddress = baseAddress.add(offset);

    console.log("BaseAddress = ",baseAddress);
    console.log("Offset = ",offset);
    console.log("Offset in Module Address = ",funcAddress);

    //var argsp = null;
    Interceptor.attach(funcAddress,
    {
        onEnter: function(args)
        {
            //argsp = ptr(args[0]);
            console.log("")
            console.log("====frida Hook===");
            vspritf(args[0].readUtf8String(),args);
            console.log("=================");
        },
        onLeave: function(retval)
        {
            //console.log("返回字符串:",argsp.readUtf8String());
        }

    });
 }
 hook_printf();

目前我只能想出这种低端的做法,文章有纰漏请及时指出谢谢! 或者大佬么用更好的方法,请在评论区回复。

posted @ 2022-04-21 18:13  VxerLee昵称已被使用  阅读(1435)  评论(0编辑  收藏  举报