Capstone、Unicorn、Keystone

出自同一个组织之手

三个框架的区别与特点
-w781

Capstone

在 2014 年黑帽大会上由新加坡南阳理工大学发布的

python 安装
pip install capstone

Unicorn

在 2015 年黑帽大会上由新加坡南阳理工大学发布的 CPU 模拟器
  • Unicorn CPU 模拟器 官方网站
  • 支持 Arm,Arm64,X86,等等
  • 语言支持 Haskell, Ruby, Python, Java, Go, .NET, Delphi/Pascal & MSVC available.等

python 安装
pip install unicorn

Keystone

在 2016 年黑帽大会上由新加坡南阳理工大学发布的, frida 源码中也有使用。
  • Keystone 新一代汇编框架 官方网站
  • 支持 Arm,Arm64,X86,等等
  • 支持多平台
  • 支持多语言

python 安装
pip install keystone-engine

实例篇

Keystone

需求:对指定的地址进行反汇编输出

FRIDA 中使用

// addr=地址, number 显示条数
function dis(addr, number){
    // 利用 Keystone 驱动读取 汇编指令
    for(var i=0; i<number;i++){
        var ins=Instruction.parse(addr);
        console.log('addr: '+ addr + " --dis: "+ins.toString()); // 指定地址反汇编
        addr = ins.next;

        // 例子
        if(ins.mnemonic.startsWith("bl")){
            console.log("this is a function call ins!!")
            //hook();
            //ins.operands
        }
    }
}

-w318


直接python使用:
官方示例

from capstone import *

CODE = b"\x55\x48\x8b\x05\xb8\x13\x00\x00"

md = Cs(CS_ARCH_X86, CS_MODE_64)
for i in md.disasm(CODE, 0x1000):
    print("0x%x:\t%s\t%s" %(i.address, i.mnemonic, i.op_str))

解锁反调试

解锁的方法很多,这里只是结合 Capstone 的一个例子

Frida 中有 Capstone 驱动的 ArmWriter, 可以利用其来解锁反调试 官方说明文档 其中可以用 putNop 来达到效果 -w351 对指定的地址写入 nop 指令。当然也可以用 断点指令 putBreakpoint() 等等

这里我们来实战一个,自动检测 Frida 的 bybass。(app附件下载)

  • 包名: com.example.test
  • 目标: frida 运行程序就会被关闭
  • So: libnative-lib.so

分析:
该种情况最常见的就是被kill掉了

导入表中可以看到这些关键词

找到 so 加载中较早的hook点 -w832

  • call_function 就是一个较早的点 稳当
  • call_function("DT_INIT", init_func_, get_realpath());
  • 参数1: 要执行的函数的类型, 参数2: 当前地址 参数3: so 路径
// 这是视频教程的 Demo,视频apk并不适用


// addr=地址, number 显示条数
function dis(address, number) {
    // 利用 Keystone 驱动读取 汇编指令
    for (var i = 0; i < number; i++) {
        var ins = Instruction.parse(address);
        console.log("address:" + address + "--dis:" + ins.toString()); // 指定地址反汇编
        address = ins.next;
    }
}

//libc->strstr()
function hook() {
//call_function("DT_INIT", init_func_, get_realpath());
    var linkermodule = Process.getModuleByName("linker");
    var call_function_addr = null;
    var symbols = linkermodule.enumerateSymbols();
    for (var i = 0; i < symbols.length; i++) {
        var symbol = symbols[i];
        //LogPrint(linkername + "->" + symbol.name + "---" + symbol.address);

        // 符号, 导出函数
        if (symbol.name.indexOf("__dl__ZL13call_functionPKcPFviPPcS2_ES0_") != -1) {
            call_function_addr = symbol.address;
            //LogPrint("linker->" + symbol.name + "---" + symbol.address)

        }
    }
    Interceptor.attach(call_function_addr, {
        onEnter: function (args) {
            var type = ptr(args[0]).readUtf8String();
            var address = args[1];
            var sopath = ptr(args[2]).readUtf8String();
            console.log("loadso:" + sopath + "--addr:" + address + "--type:" + type);
            if (sopath.indexOf("libnative-lib.so") != -1) {
                var libnativemodule = Process.getModuleByName("libnative-lib.so");
                var base = libnativemodule.base;
                dis(base.add(0x8D8E).add(1), 10);
                var patchaddr = base.add(0x8d96);

                // 方法1:
                Memory.patchCode(patchaddr, 4, patchaddr => {
                    var cw = new ThumbWriter(patchaddr);
                    cw.putNop();
                    cw = new ThumbWriter(patchaddr.add(0x2));
                    cw.putNop();
                    cw.flush();
                });
     

                // 方法2:
                // console.log("+++++++++++++++++++++++")
                // dis(base.add(0x8D8E).add(1), 10);
                // console.log("----------------------")

                // dis(base.add(0x8E6E).add(1), 10);
                // Memory.protect(base.add(0x8E78), 4, 'rwx');//4个字节可写权限
                // base.add(0x8E78).writeByteArray([0x00, 0xbf, 0x00, 0xbf]);
                // console.log("+++++++++++++++++++++++")
                // dis(base.add(0x8E6E).add(1), 10);


            }
        }
    })
}

function main() {
    hook();
}

setImmediate(main);

文章app下载:

此处内容需要评论回复后(审核通过)方可阅读。

Last modification:December 4, 2020
如果觉得我的文章对你有用,请随意赞赏