android自动化脱壳,[原创] FART:ART环境下基于主动调用的自动化脱壳方案 [android脱壳源码公开,基于android-9.0.0_r36]...

一、背景

hanbingle在看雪论坛上分享了[原创]FART:ART环境下基于主动调用的自动化脱壳方案,思路非常棒;可惜并没有公开修改android源码部分,这让深入理解脱壳方案或者定制化自己的脱壳方案存在困难,本文通过逆向FART所提供的system.img镜像得到思路,同时修改源码适配android-9.0.0_r36,并公开脱壳源码。

二、如何逆向system.img呢?

1、simg2img system.img system.img.ext4

2、sudo mkdir sysmain

3、sudo mount -t ext4 -o loop system.img.ext4 sysmain

进入到sysmain中,找到framework.jar、core-libart.jar、libart.so,主要涉及修改的是

framework.jar中的ActivityThread.java、core-libart.jar中的DexFile.java、libart.so中的libdexfile/dex/standard_dex_file.h、runtime/art_method-inl.h、runtime/art_method.h、runtime/native/dalvik_system_DexFile.cc。

将framework.jar改为

framework.zip解压后得到classes.dex,使用dex2jar,jd-gui转换为java代码查看,但jd-guid无法将核心的smali代码转为java代码。

所以只能通过阅读smali来了解脱壳思路,使用dex2smali将dex转换为smali,我们主要看ActivityThread.smali;

同理core-libart.jar也是同样的思路,最终我们得到DexFile.java,在这里只是加了一个函数,这个函数时个native方法,我们会在libart.so里面实现,在

ActivityThread.smali 里面调用,如何调用呢,我们看接下来的分析。

public classs DexFile {

+private static native void dumpMethodCode(Object methodid);

}

三、分析Java层脱壳代码

我们先看

ActivityThread.smali里面核心的脱壳代码:

.method public static fart()V

.catch Ljava/lang/Exception; { :L0 .. :L1 } :L11

.catch Ljava/lang/Exception; { :L3 .. :L4 } :L12

.catch Ljava/lang/IllegalAccessException; { :L15 .. :L16 } :L19

.catch Ljava/lang/IllegalAccessException; { :L21 .. :L22 } :L25

.catch Ljava/lang/reflect/InvocationTargetException; { :L21 .. :L22 } :L24

.registers 30

.prologue

.line 701

invoke-static { }, Landroid/app/ActivityThread;->getClassloader()Ljava/lang/ClassLoader;

move-result-object v5

.line 702

.local v5, appClassloader:Ljava/lang/ClassLoader;

new-instance v9, Ljava/util/ArrayList;

invoke-direct { v9 }, Ljava/util/ArrayList;->()V

.line 703

.local v9, dexFilesArray:Ljava/util/List;, "Ljava/util/List;"

const-string/jumbo v25, "dalvik.system.BaseDexClassLoader"

const-string/jumbo v26, "pathList"

move-object/from16 v0, v25

move-object/from16 v1, v26

invoke-static { v5, v0, v1 }, Landroid/app/ActivityThread;->getClassField(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/reflect/Field;

move-result-object v23

.line 705

.local v23, pathList_Field:Ljava/lang/reflect/Field;

const-string/jumbo v25, "dalvik.system.BaseDexClassLoader"

const-string/jumbo v26, "pathList"

move-object/from16 v0, v25

move-object/from16 v1, v26

invoke-static { v0, v5, v1 }, Landroid/app/ActivityThread;->getFieldOjbect(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;

move-result-object v24

.line 706

.local v24, pathList_object:Ljava/lang/Object;

const-string/jumbo v25, "dalvik.system.DexPathList"

const-string/jumbo v26, "dexElements"

move-object/from16 v0, v25

move-object/from16 v1, v24

move-object/from16 v2, v26

invoke-static { v0, v1, v2 }, Landroid/app/ActivityThread;->getFieldOjbect(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;

move-result-object v4

check-cast v4, [Ljava/lang/Object;

.line 707

.local v4, ElementsArray:[Ljava/lang/Object;

const/4 v8, 0

:L0

.line 709

.local v8, dexFile_fileField:Ljava/lang/reflect/Field;

const-string/jumbo v25, "dalvik.system.DexPathList$Element"

const-string/jumbo v26, "dexFile"

move-object/from16 v0, v25

move-object/from16 v1, v26

invoke-static { v5, v0, v1 }, Landroid/app/ActivityThread;->getClassField(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/reflect/Field;

:L1

move-result-object v8

:L2

.line 713

.end local v8

const/4 v3, 0

:L3

.line 715

.local v3, DexFileClazz:Ljava/lang/Class;

const-string/jumbo v25, "dalvik.system.DexFile"

move-object/from16 v0, v25

invoke-virtual { v5, v0 }, Ljava/lang/ClassLoader;->loadClass(Ljava/lang/String;)Ljava/lang/Class;

:L4

move-result-object v3

:L5

.line 719

.end local v3

const/16 v19, 0

.line 720

.local v19, getClassNameList_method:Ljava/lang/reflect/Method;

const/4 v7, 0

.line 721

.local v7, defineClass_method:Ljava/lang/reflect/Method;

const/4 v11, 0

.line 722

.local v11, dumpDexFile_method:Ljava/lang/reflect/Method;

const/4 v12, 0

.line 724

.local v12, dumpMethodCode_method:Ljava/lang/reflect/Method;

invoke-virtual { v3 }, Ljava/lang/Class;->getDeclaredMethods()[Ljava/lang/reflect/Method;

move-result-object v26

const/16 v25, 0

move-object/from16 v0, v26

array-length v0, v0

move/from16 v27, v0

:L6

.end local v7

.end local v11

.end local v12

.end local v19

move/from16 v0, v25

move/from16 v1, v27

if-ge v0, v1, :L13

aget-object v18, v26, v25

.line 725

.local v18, field:Ljava/lang/reflect/Method;

invoke-virtual/range { v18 .. v18 }, Ljava/lang/reflect/Method;->getName()Ljava/lang/String;

move-result-object v28

const-string/jumbo v29, "getClassNameList"

invoke-virtual/range { v28 .. v29 }, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result v28

if-eqz v28, :L7

.line 726

move-object/from16 v19, v18

.line 727

.local v19, getClassNameList_method:Ljava/lang/reflect/Method;

const/16 v28, 1

move-object/from16 v0, v19

move/from16 v1, v28

invoke-virtual { v0, v1 }, Ljava/lang/reflect/Method;->setAccessible(Z)V

:L7

.line 729

.end local v19

invoke-virtual/range { v18 .. v18 }, Ljava/lang/reflect/Method;->getName()Ljava/lang/String;

move-result-object v28

const-string/jumbo v29, "defineClassNative"

invoke-virtual/range { v28 .. v29 }, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result v28

if-eqz v28, :L8

.line 730

move-object/from16 v7, v18

.line 731

.local v7, defineClass_method:Ljava/lang/reflect/Method;

const/16 v28, 1

move/from16 v0, v28

invoke-virtual { v7, v0 }, Ljava/lang/reflect/Method;->setAccessible(Z)V

:L8

.line 733

.end local v7

invoke-virtual/range { v18 .. v18 }, Ljava/lang/reflect/Method;->getName()Ljava/lang/String;

move-result-object v28

const-string/jumbo v29, "dumpDexFile"

invoke-virtual/range { v28 .. v29 }, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result v28

if-eqz v28, :L9

.line 734

move-object/from16 v11, v18

.line 735

.local v11, dumpDexFile_method:Ljava/lang/reflect/Method;

const/16 v28, 1

move/from16 v0, v28

invoke-virtual { v11, v0 }, Ljava/lang/reflect/Method;->setAccessible(Z)V

:L9

.line 737

.end local v11

invoke-virtual/range { v18 .. v18 }, Ljava/lang/reflect/Method;->getName()Ljava/lang/String;

move-result-object v28

const-string/jumbo v29, "dumpMethodCode"

invoke-virtual/range { v28 .. v29 }, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result v28

if-eqz v28, :L10

.line 738

move-object/from16 v12, v18

.line 739

.local v12, dumpMethodCode_method:Ljava/lang/reflect/Method;

const/16 v28, 1

move/from16 v0, v28

invoke-virtual { v12, v0 }, Ljava/lang/reflect/Method;->setAccessible(Z)V

:L10

.line 724

.end local v12

add-int/lit8 v25, v25, 1

goto :L6

:L11

.line 710

.end local v18

.restart local v8

move-exception v13

.line 711

.local v13, e:Ljava/lang/Exception;

const-string/jumbo v25, "ActivityThread->err"

invoke-static { v1

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值