吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6797|回复: 17
收起左侧

[Android 脱壳] 修复FART dump下来的dex

  [复制链接]
luoyesiqiu 发表于 2020-10-20 10:18

1. 情景

在使用脱壳机对Android App脱壳的时候,我们常常会得到有nop指令填充的函数的dex,nop是No Operation的缩写,意为无操作。

nop.jpg

上面是一个函数的smali代码,可以清晰的看到函数被多个nop指令填充,如果这个函数解析成Java代码,则得到一个空的函数:

unfix.jpg

某些壳在加固的时候会把dex文件中的函数的真正函数体给抽掉,用nop指令来填充,nop指令在这个过程中只用作占位,当函数执行的时候再把真正的代码给还原回去,加固壳用这种方式来保护函数中真正的代码。我们修复的过程就是把函数的真正代码写回dex文件的过程。函数修复后:

fixed.jpg

2. 修复

FART在dump dex的同时,还把dex的CodeItem给dump了下来,这给我们修复dex提供了极大的便利,CodeItem中存着函数中真正代码,CodeItem dump下来后存在.bin文件中。所以我们修复的时候,读取.bin文件,把CodeItem填入Dex文件的相应的位置即可。

我们打开.bin文件,可以看到它由多项形如以下格式的文本组成,每一项代表一个函数

{name:void junit.textui.ResultPrinter.printFailures(junit.framework.TestResult),method_idx:1565,offset:52440,code_item_len:46,ins:BQACAAQAAADpYAIADwAAAG4QpwUEAAwAbhCmBQQACgEbAhYFAABuQBsGAyEOAA==};

我们来看这些数据都是什么:

  • name 指示函数的全名,包括完整的参数类型和返回值类型
  • method_idx 是函数在method_ids中的索引
  • offset 指示函数的insns相对于dex文件的偏移
  • code_item_len CodeItem的长度
  • ins base64字符串,解码后是dex结构中的insns,即函数的真正的代码

在dex修复过程中,对我们有用的是offset和ins,可以编写代码将它们从.bin文件中提取出来:

public static List<CodeItem> convertToCodeItems(byte[] bytes){
    String input = new String(bytes);

    List<CodeItem> codeItems = new ArrayList<>();
    Pattern pattern = Pattern.compile("\\{name:(.+?),method_idx:(\\d+),offset:(\\d+),code_item_len:(\\d+),ins:(.+?)\\}");
    Matcher matcher = pattern.matcher(input);
    while(matcher.find()){
        int offset = Integer.parseInt(matcher.group(3));
        String insBase64 = matcher.group(5);
        byte[] ins = Base64.getDecoder().decode(insBase64);
        CodeItem codeItem = new CodeItem(offset,ins);
        codeItems.add(codeItem);
    }

    return codeItems;
}

CodeItem类:

public  class CodeItem{
    public CodeItem(long offset, byte[] byteCode) {
        this.offset = offset;
        this.byteCode = byteCode;
    }

    public long getOffset() {
        return offset;
    }

    public void setOffset(long offset) {
        this.offset = offset;
    }

    public byte[] getByteCode() {
        return byteCode;
    }

    public void setByteCode(byte[] byteCode) {
        this.byteCode = byteCode;
    }

    @Override
    public String toString() {
        return "CodeItem{" +
                "offset=" + offset +
                ", byteCode=" + Arrays.toString(byteCode) +
                '}';
    }

    private long offset;
    private byte[] byteCode;
}

接着将需要的修复dex复制一份,把insns填充到被复制出来的dex的相应位置,即修复过程:

public static void repair(String dexFile, List<CodeItem> codeItems){
    RandomAccessFile randomAccessFile = null;
    String outFile = dexFile.endsWith(".dex") ? dexFile.replaceAll("\\.dex","_repair.dex") : dexFile + "_repair.dex";
    //copy dex
    byte[] dexData = IoUtils.readFile(dexFile);
    IoUtils.writeFile(outFile,dexData);
    try{
        randomAccessFile = new RandomAccessFile(outFile,"rw");
        for(int i = 0 ; i < codeItems.size();i++){
            CodeItem codeItem = codeItems.get(i);
            randomAccessFile.seek(codeItem.getOffset());
            randomAccessFile.write(codeItem.getByteCode());
        }
    }
    catch (Exception e){
        e.printStackTrace();
    }
    finally {
        IoUtils.close(randomAccessFile);
    }
}

是不是很简单,本文完。

3. 完整代码

https://github.com/luoyesiqiu/DexRepair

免费评分

参与人数 3威望 +1 吾爱币 +22 热心值 +3 收起 理由
superbase + 1 + 1 热心回复!管用,好用!!!
fcguo800 + 1 + 1 感谢大佬,能提供下相应的脱壳及修复工具就更完美了。
qtfreet00 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| luoyesiqiu 发表于 2020-10-20 11:53
byh3025 发表于 2020-10-20 11:40
如何把bin文件中的代码写到dex中的

大体流程是把bin文件中的ins字段读出来,把它base64解码,这时候会得到对应函数的字节码,然后利用RandomAccessFile的seek方法定位到dex文件中函数insns的offset,因为函数体是nop填充的,我们可以直接把读到字节码写入到insns的offset,这样就是对函数代码填充(修复)
ZYZZMD 发表于 2021-3-31 01:28
大牛。你这个工具我把脱下来的dex和bin文件放在jar下边提示不能找到dexjar有时候还会提示不能找到dex和bin   是哪里出错了吗
byh3025 发表于 2020-10-20 10:30
没看明白怎么操作的,能详细点吗大神?可以方便下我们这样的小白
那年夏天52 发表于 2020-10-20 10:46
学到了,谢
 楼主| luoyesiqiu 发表于 2020-10-20 11:34
byh3025 发表于 2020-10-20 10:30
没看明白怎么操作的,能详细点吗大神?可以方便下我们这样的小白

哪里不清楚呢
byh3025 发表于 2020-10-20 11:40

如何把bin文件中的代码写到dex中的
baxtax 发表于 2020-10-20 16:27
谢谢楼主的分享
深蓝海琼 发表于 2020-10-20 19:18
过来看看,感谢
xixicoco 发表于 2020-10-20 20:43
好的,牛逼
gadegao 发表于 2020-10-21 13:39
不知道管用不
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-1-10 21:17

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表