本文正在参与「金石计划」

前言

frida-unpack是一个根据frida的脱壳东西,项目地址:github.com/chzphoenix/…

可是作者阐明的不够详细,运用的时分遇到了种种问题,所以整理了一下。

留意我的android版别是8.1.0

装置frida

因为是根据frida结构,所以需求装置frida,这个可以参阅frida官方文档,或许参阅我之前的一篇文章:装置运用Frida在Android上进行hook

获取libart.so(libdexfile.so)

在低版别(应该是android10以下)上应该运用:

  • 32位运用:/system/lib/libart.so
  • 64位运用:/system/lib64/libart.so

在android10上应该运用,作者说应该运用/apex/com.android.runtime/lib/libdexfile.so,可是应该也有一个64版别/apex/com.android.runtime/lib64/libdexfile.so,这个我没有验证。

经过adb将so文件拷贝到电脑上

获取OpenMemory

然后需求在libart.so中获取OpenMemory办法的签名,在终端中输入指令:

nm libart.so |grep OpenMemory

作者说在libdexfile.so中则是OpenCommon办法。可是留意,在android8.1.0中提取出来的libart.so中现已没有OpenMemory办法了,取而代之的是OpenCommon办法,所以大家假如经过指令发现获取OpenMemory没有任何信息,就可以试试OpenCommon

nm libart.so |grep OpenCommon

得到的信息是办法的签名,如下:

$ nm libart.so |grep OpenCommon
0000000000193560 T _ZN3art7DexFile10OpenCommonEPKhmRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPKNS_10OatDexFileEbbPS9_PNS0_12VerifyResultE

这个后边会用到,记录下来。

修正OpenMemory.js

然后咱们需求修正项目中的OpenMemory.js,原代码如下:

Interceptor.attach(Module.findExportByName("libart.so", "_ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapEPKNS_10OatDexFileEPS9_"), {
    onEnter: function (args) {
        //dex起始方位
        var begin = args[1]
        //打印magic
        console.log("magic : " + Memory.readUtf8String(begin))
        //dex fileSize 地址
        var address = parseInt(begin,16) + 0x20
        //dex 大小
        var dex_size = Memory.readInt(ptr(address))
        console.log("dex_size :" + dex_size)
        //dump dex 到/data/data/pkg/目录下
        var file = new File("/data/data/xxx.xxx.xxx/" + dex_size + ".dex", "wb")
        file.write(Memory.readByteArray(begin, dex_size))
        file.flush()
        file.close()
    },
    onLeave: function (retval) {
        if (retval.toInt32() > 0) {
            /* do something */
        }
    }
});

首要需求将findExportByName的第二个参数换成咱们获取到的办法签名,即
_ZN3art7DexFile10OpenCommonEPKhmRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPKNS_10OatDexFileEbbPS9_PNS0_12VerifyResultE

然后更改一下保存的地址,作者这里坚持到/data/data/pkg/目录下没必要,可以直接放到/sdcard/下随便新建一个目录,这样获取也便利。

最终还要修正一下dex起始方位var begin = this.context.x0,这个后边细说。

运转

然后在终端进入项目目录,输入指令:

./inject.sh 要脱壳的运用的包名 OpenMemory.js

即可,等待脱壳完结就可以得到dex文件了。

问题

Error: expected a pointer

假如报错:

Error: expected a pointer
  at value (frida/runtime/core.js:367)
  at <eval> (/OpenMemory.js:32)

阐明OpenMemory(或OpenCommon)的办法签名不对,检查签名。比如是32位so文件中的签名,可是应该是64位的。

Error: access violation accessing

假如报错:

Error: access violation accessing 0x4e067c
  at onEnter (/OpenMemory.js:14)
Error: access violation accessing 0x526304
  at onEnter (/OpenMemory.js:14)
Error: access violation accessing 0xae330
  at onEnter (/OpenMemory.js:14)
Error: access violation accessing 0x19ee4
  at onEnter (/OpenMemory.js:14)

可以是dex起始方位代码有问题,上面提到过,要修正成var begin = this.context.x0

根据网上大神的说法,假如是64位的so文件,应该运用var begin = this.context.x0;假如是32位的,则坚持原代码不变。