Frida-Labs

0x1

截图

截图

获取了100以内的随机数

截图

只需要确保输入的数为随机数的2倍+4即可

截图

hook该方法,返回值随意,只要自己输入符合对该值的要求即可

Java.perform(function () {
    let MainActivity = Java.use("com.ad2001.frida0x1.MainActivity");
    MainActivity["get_random"].implementation = function () {
        this["get_random"]();
        console.log('get_random() return 0');
        return 0;
    };
})

返回0,输入4即可

截图

0x2

截图

很显然,需要主动调用get_flag方法,将显示的textview修改掉

截图

Java.perform(function () {
    Java.choose('com.ad2001.frida0x2.MainActivity',{
        onMatch: function(instance){
            instance.get_flag(4919)
        },
        onComplete: function(){

        }
    })
})

采用attach方式进行hook,避免找到实例时,值修改后又被该回去

或者spawn的话用下面的脚本(因为get_flag是静态方法)

Java.perform(function () {
    let MainActivity = Java.use("com.ad2001.frida0x2.MainActivity");
    MainActivity["onCreate"].implementation = function (savedInstanceState) {
        this["onCreate"](savedInstanceState);
        MainActivity.get_flag(4919)
    }

截图

0x3

截图

需要修改Checker的code属性的值为512

截图

截图

Java.perform(function () {
    let MainActivity = Java.use("com.ad2001.frida0x3.MainActivity$1");
    MainActivity["onClick"].implementation = function (view) {
        let Checker = Java.use("com.ad2001.frida0x3.Checker")
        Checker.code.value = 512
        this["onClick"](view);
    };
})

在onclick下面hookCheck类,可以最大程度上避免其他类或方法对其产生干扰

截图


0x4

截图

这里应该是考察主动调用,新建一个Check类的实例,调用get_flag,并把值送给textview

截图

截图

Java.perform(function () {
    let MainActivity = Java.use("com.ad2001.frida0x4.MainActivity");
    MainActivity["onCreate"].implementation = function (savedInstanceState) {
        this["onCreate"](savedInstanceState);
        let Check = Java.use("com.ad2001.frida0x4.Check").$new()
        let c = Check.get_flag(1337)
        console.log(c)
    };
})

直接打印结果即可(我想试着修改textview,结果出现了不知名错误=-=)

截图

0x5

截图

与0x2不同的是,这里的方法不再是静态方法

截图

Java.perform(function () {
    Java.choose('com.ad2001.frida0x5.MainActivity',{
        onMatch: function(instance){
            instance.flag(1337)
        },
        onComplete: function(){

        }
    })
})

还是attach

截图

0x6

截图

在0x5的基础上,构造Checker即可

截图

截图

Java.perform(function () {
    Java.choose('com.ad2001.frida0x6.MainActivity',{
        onMatch: function(instance){
            let Checker = Java.use('com.ad2001.frida0x6.Checker').$new()
            Checker.num1.value = 1234
            Checker.num2.value = 4321
            instance.get_flag(Checker)
        },
        onComplete: function(){

        }
    })
})

依旧是attach

截图

0x7

截图

hookChecker的构造方法即可

截图

Java.perform(function () {
    let Checker = Java.use("com.ad2001.frida0x7.Checker");
    Checker["$init"].implementation = function (a, b) {
        console.log('hook $init()')
        this["$init"](520,520);
    };
})

截图

0x8

截图

这里就要去看so了,直接hook返回值肯定拿不到正确的flag

截图

每位的ascii码减一就是flag了,但是这里用到了strcmp进行比较

截图

直接hook strcmp

截图

同时看到有打印日志,因此也可以hook日志

截图

0x9

截图

修改native的返回值即可

截图

Java.perform(function () {
    let MainActivity = Java.use("com.ad2001.a0x9.MainActivity");
    MainActivity["check_flag"].implementation = function () {
        this["check_flag"]();
        console.log(`hook check_flag() return 1337`);
        return 1337;
    };
})

截图

0xA

截图

这里就是正常的调用

截图

但是在so里,存在一个导出函数get_flag

截图

可以一眼看出如何解密,但是还是采用hook的方式来做

截图

主动调用一下get_flag,同时还要注意其真正的导出名,不然找不到地址,解密后通过日志输出了

Java.perform(function () {
    var addr = Module.findExportByName("libfrida0xa.so", "_Z8get_flagii");
    console.log(addr)
    let get_flag_pointer = new NativePointer(addr)
    let get_flag = new NativeFunction(get_flag_pointer,'int',['int','int'])
    get_flag(1,2)
})

截图

0xB

截图

截图

在so中,由于永假的判断,导致代码不执行,所以可以把jnz给nop掉,一共6个字节

截图

Java.perform(function () {
    var funAddr = Module.findExportByName("libfrida0xb.so", "Java_com_ad2001_frida0xb_MainActivity_getFlag");
    var opAddr = funAddr.add(0x1E)
    console.log(opAddr)
    var writer = new X86Writer(opAddr)
    Memory.protect(opAddr,0x1000,'rwx')
    try{
        writer.putNop()
        writer.putNop()
        writer.putNop()
        writer.putNop()
        writer.putNop()
        writer.putNop()
        writer.flush()
    }finally{
        writer.dispose()
    }
})

或者是将jnz改成jz,我这里64位的模拟器,jnz的字节码是0f85d2000000,85改成84就是jz

Java.perform(function () {
    var funAddr = Module.findExportByName("libfrida0xb.so", "Java_com_ad2001_frida0xb_MainActivity_getFlag");
    var opAddr = funAddr.add(0x1E)
    console.log(opAddr)
    var writer = new X86Writer(opAddr)
    Memory.protect(opAddr,0x1000,'rwx')
    try{
        writer.putU8(0x0f)
        writer.putU8(0x84)
        writer.putU8(0xd2)
        writer.putU8(0x0)
        writer.putU8(0x0)
        writer.putU8(0x0)
        writer.flush()
    }finally{
        writer.dispose()
    }
})

截图

这里附上在ida中将jnz改为jz后的伪代码

截图

posted @ 2024-06-04 19:01  WXjzc  阅读(35)  评论(0编辑  收藏  举报