watchdoge 发表于 2017-5-15 20:54

【练手】阿里crackme的新解法-frida

本帖最后由 watchdoge 于 2017-5-15 20:58 编辑

最近在看Frida,又看坛子里PJ头狼的帖子http://www.52pojie.cn/thread-559205-1-1.html,于是顺手用frida来试试,对于这题frida有个很大的优势,就是不会触发反调试,这样就节省了很多功夫。
先简单介绍下frida,frida是一款代码插桩工具,它可以向windows,macOS,Linux,iOS,Android等平台的原生应用中注射自定义的JavaScript代码片段,它的主要作用有:

[*]Access process memory
[*]Overwrite functions while the application is running
[*]Call functions from imported classes
[*]Find object instances on the heap and use them
[*]Hook, trace and intercept functions etc.
0x01 简单地绕过验证
如果只是想绕过验证的话,那么非常简单,通常思路是反编译成smali文件然后编辑这里的代码,然后重新打包签名,不过这里我们用frida也很容易实现,用下面的代码在java层hook住这个securityCheck函数,直接重新编写其逻辑:
send("Running Script");
Java.perform(function(){
    MainActivity = Java.use("com.yaotong.crackme.MainActivity");
    MainActivity.securityCheck.implementation = function(v){
      send("securityCheck hooked");
      return true;
    }
});
0x02 获取密码
我们的主要目的当然还是获取到正确的密码,这个程序的具体情况不细说了,感兴趣的可以自己分析或者看头狼的那篇帖子,其验证逻辑如下:

最核心的就是将我们的输入与off_628c所指向的值做比较,而我们在这里用frida来获取程序运行时该处的值,frida提供了劫持native函数以及操作内存的一系列方法,首先我们需要通过导出函数表获取securityCheck这个函数的地址
var securityCheck = undefined;
    exports = Module.enumerateExportsSync("libcrackme.so");
    for(i=0; i<exports.length; i++){
      if(exports.name == "Java_com_yaotong_crackme_MainActivity_securityCheck"){
            securityCheck = exports.address;
            send("securityCheck is at " + securityCheck);
            break;
      }
    }
然后就是读取off_628C的值了,在ida的exports里可以看到该函数的偏移为0x11A8,因此可以通过函数当前地址减0x11A8再加0x628C,然后用Memory.readPointer获取该处所指向的地址,最后用Memory.readUtf8String读取最终的结果,所有的代码如下:
#!/usr/bin/env python
# coding=utf-8
from __future__ import print_function
import frida,sys

native_hook_code = """
Java.perform(function(){
    send("Running Script");

    var securityCheck = undefined;
    exports = Module.enumerateExportsSync("libcrackme.so");
    for(i=0; i<exports.length; i++){
      if(exports.name == "Java_com_yaotong_crackme_MainActivity_securityCheck"){
            securityCheck = exports.address;
            send("securityCheck is at " + securityCheck);
            break;
      }
    }

    Interceptor.attach(securityCheck,{
      onEnter: function(args){
            send("key is: " + Memory.readUtf8String(Memory.readPointer(securityCheck.sub(0x11a8).add(0x628c))));
      }
    });
});
"""

check_hook_code = """
    send("Running Script");
Java.perform(function(){
    MainActivity = Java.use("com.yaotong.crackme.MainActivity");
    MainActivity.securityCheck.implementation = function(v){
      send("securityCheck hooked");
      return true;
    }
});
"""

def on_message(message, data):
    if message['type'] == 'send':
      print(" {0}".format(message['payload']))
    else:
      print(message)

process = frida.get_device_manager().enumerate_devices()[-1].attach("com.yaotong.crackme")
script = process.create_script(native_hook_code)
script.on('message', on_message)
script.load()
sys.stdin.read()
结果如图:

Loopher 发表于 2017-5-24 09:56

楼主,你的frida是用的官方的还是自己编译的,我用官方编译的,在我的nexus5上不能跑,能给点思路吗,谢谢

Vetedu 发表于 2017-5-15 21:26

key is : aiyou bucuoo

MatrixOne 发表于 2017-5-15 21:31

好强大,有空学学这个。

ssa126971220 发表于 2017-5-16 08:04

表示看不懂

千里千寻 发表于 2017-5-16 08:09

看看,换可以

qtfreet00 发表于 2017-5-16 17:15

少有的frida教程,&#128077;

会飞的丑小鸭 发表于 2017-5-16 17:39

厉害啊 学学

daocao 发表于 2017-5-16 18:25

感谢分享~~~~~~~~~~~~~

冲洞男 发表于 2017-5-16 18:58

不错啊,同学

zhuzhuxia 发表于 2017-5-16 21:12


好强大,有空学学这个
页: [1] 2 3 4 5
查看完整版本: 【练手】阿里crackme的新解法-frida