zoukankan      html  css  js  c++  java
  • APK加固之类抽取分析与修复

    0x00 简单介绍

      目前我己知的APK加固主要有以下两种方式(或有其它的方式有待发现)

    隐藏dex文件:通过对目标DEX文件进行整体加密或压缩方式把整个dex转换为另外一个文件存放在assets文件夹中或者其它地方,然后利用类加载器技术进行内存解密并加载运行。

    修改dex结构:抽取DexCode中的字节码指令后用零去填充,或者修改方法属性等操作,运行时在内存中做修正、修复等处理工作。

    0x01 APK加固前后对比

      整体来看一下原始APK包和加固后的APK包结构相关变化

             图1

    图1所示加固后的APK包变化如下:

    新增2个文件夹:

    assets文件夹中增加3个文件

    data

    dx

    pk

    lib文件夹中增加了2个so文件

    libedog.so

    libfdog.so

    被修改的文件:

    AndroidManifest.xml

    classes.dex

    0x02 壳流程分析

        我们用AndroidKiller反编译加固后的APK, 反编译出错,错误日志如下:

             图2

    从图2可以看出反编译时出现了很多错误,我们用IDA对DEX进行反编译查看代码,发现方法指令都被零填充了,反编译后代码显示为nop样式,如图3所示。

             图3

    我们再来看看APK中的AndroidManifest.xml文件被修改了什么地方?

             图4

    从图4看到AndroidManifest.xml中的application新增了如下项做为壳的入口

    android:name="com.edog.AppWrapper"该类为壳的入口,继续分析AppWrapper都做了些什么?

             图5

             图6

             图7

    从图5-7可以看出最终会调用到libedog.so中的dl函数,下面就开始动态调试分析该so的功能流程(如何动态调试就不说了,网上己经有很多的教程了)。

    通过动态分析libedog.so中的dl函数主要功能是: 获得系统版本号->验证加固前后的签名是否一致->反调试->将抽走的指令映射到内存中还原指令时用到->HOOK函数dvmResolveClass->结束

    代码流程如下:

     1 libedog.so:5D692C18             Java_com_edog_ELibrary_d1
     2 libedog.so:5D692C18
     3 libedog.so:5D692C18             var_F0= -0xF0
     4 libedog.so:5D692C18             var_EC= -0xEC
     5 libedog.so:5D692C18             var_E4= -0xE4
     6 libedog.so:5D692C18             var_1C= -0x1C
     7 libedog.so:5D692C18             arg_0=  0
     8 libedog.so:5D692C18
     9 libedog.so:5D692C18 F0 B5       PUSH            {R4-R7,LR}
    10 libedog.so:5D692C1A 28 4F       LDR             R7, =(dword_5D6A5E60 - 0x5D692C24)
    11 libedog.so:5D692C1C B7 B0       SUB             SP, SP, #0xDC
    12 libedog.so:5D692C1E 00 93       STR             R3, [SP,#0xF0+var_F0]
    13 libedog.so:5D692C20 7F 44       ADD             R7, PC ; dword_5D6A5E60
    14 libedog.so:5D692C22 3F 68       LDR             R7, [R7]
    15 libedog.so:5D692C24 3C 99       LDR             R1, [SP,#0xF0+arg_0]
    16 libedog.so:5D692C26 04 1C       MOVS            R4, R0
    17 libedog.so:5D692C28 3B 68       LDR             R3, [R7]
    18 libedog.so:5D692C2A 01 91       STR             R1, [SP,#0xF0+var_EC]
    19 libedog.so:5D692C2C A9 21       MOVS            R1, #0xA9
    20 libedog.so:5D692C2E 35 93       STR             R3, [SP,#0xF0+var_1C]
    21 libedog.so:5D692C30 03 68       LDR             R3, [R0]
    22 libedog.so:5D692C32 89 00       LSLS            R1, R1, #2
    23 libedog.so:5D692C34 22 4D       LDR             R5, =(aFjFj0fjFjFj4fj - 0x5D692C42)
    24 libedog.so:5D692C36 5B 58       LDR             R3, [R3,R1]
    25 libedog.so:5D692C38 11 1C       MOVS            R1, R2
    26 libedog.so:5D692C3A 00 22       MOVS            R2, #0
    27 libedog.so:5D692C3C 98 47       BLX             R3
    28 libedog.so:5D692C3E 7D 44       ADD             R5, PC                  ; "$fj] fj]0fj](fj],fj]4fj]i]"
    29 libedog.so:5D692C40 2D 68       LDR             R5, [R5]                ; "$fj] fj]0fj](fj],fj]4fj]i]"
    30 libedog.so:5D692C42 20 4E       LDR             R6, =(aFjFj0fjFjFj4fj+4 - 0x5D692C50)
    31 libedog.so:5D692C44 28 60       STR             R0, [R5]
    32 libedog.so:5D692C46 20 1C       MOVS            R0, R4
    33 libedog.so:5D692C48 00 F0 5C F8 BL              _Z17ANDROID_API_LEVELP7_JNIEnv
    34 libedog.so:5D692C4C 7E 44       ADD             R6, PC                  ; " fj]0fj](fj],fj]4fj]i]"
    35 libedog.so:5D692C4E 36 68       LDR             R6, [R6]                ; " fj]0fj](fj],fj]4fj]i]"
    36 libedog.so:5D692C50 30 60       STR             R0, [R6]
    37 libedog.so:5D692C52 20 1C       MOVS            R0, R4
    38 libedog.so:5D692C54 00 F0 82 F8 BL              _Z24ANDROID_PLATFORM_VERSIONP7_JNIEnv
    39 libedog.so:5D692C58 20 1C       MOVS            R0, R4
    40 libedog.so:5D692C5A 00 F0 A9 F8 BL              _Z22ANDROID_PLATFORM_MODELP7_JNIEnv
    41 libedog.so:5D692C5E 20 1C       MOVS            R0, R4
    42 libedog.so:5D692C60 00 F0 D0 F8 BL              _Z22ANDROID_PLATFORM_BRANDP7_JNIEnv
    43 libedog.so:5D692C64 20 1C       MOVS            R0, R4
    44 libedog.so:5D692C66 01 99       LDR             R1, [SP,#0xF0+var_EC]
    45 libedog.so:5D692C68 00 F0 8A FC BL              _Z6verifyP7_JNIEnvP8_jobject ; 比较加固前后的签名是否一致
    46 libedog.so:5D692C6C 16 49       LDR             R1, =(aDataDataSLibLi - 0x5D692C76)
    47 libedog.so:5D692C6E 2A 68       LDR             R2, [R5]
    48 libedog.so:5D692C70 03 A8       ADD             R0, SP, #0xF0+var_E4
    49 libedog.so:5D692C72 79 44       ADD             R1, PC                  ; "/data/data/%s/lib/libfdog.so"
    50 libedog.so:5D692C74 FF F7 B0 EE BLX             sprintf
    51 libedog.so:5D692C78 03 A8       ADD             R0, SP, #0xF0+var_E4
    52 libedog.so:5D692C7A 01 1C       MOVS            R1, R0
    53 libedog.so:5D692C7C 00 F0 02 FD BL              _Z4antiPKcS0_           ; 反调试
    54 libedog.so:5D692C80 00 F0 3E F9 BL              _Z10openMemoryv         ; 将抽走的指令映射到内存中来
    55 libedog.so:5D692C80                                                     ; assets中的data文件
    56 libedog.so:5D692C84 23 68       LDR             R3, [R4]
    57 libedog.so:5D692C86 A9 22 92 00 MOVS            R2, #0x2A4
    58 libedog.so:5D692C8A 9B 58       LDR             R3, [R3,R2]
    59 libedog.so:5D692C8C 00 99       LDR             R1, [SP,#0xF0+var_F0]
    60 libedog.so:5D692C8E 20 1C       MOVS            R0, R4
    61 libedog.so:5D692C90 00 22       MOVS            R2, #0
    62 libedog.so:5D692C92 98 47       BLX             R3
    63 libedog.so:5D692C94 0D 49       LDR             R1, =(unk_5D6A2A0D - 0x5D692C9A)
    64 libedog.so:5D692C96 79 44       ADD             R1, PC
    65 libedog.so:5D692C98 FF F7 A4 EE BLX             strstr
    66 libedog.so:5D692C9C 00 28       CMP             R0, #0
    67 libedog.so:5D692C9E 02 D1       BNE             loc_5D692CA6
    68 libedog.so:5D692CA0 33 68       LDR             R3, [R6]
    69 libedog.so:5D692CA2 14 2B       CMP             R3, #0x14               ; 判断版本
    70 libedog.so:5D692CA4 00 DD       BLE             loc_5D692CA8            ; 根据操作系统的版本
    71 libedog.so:5D692CA4                                                     ; hook对应的dvmResolveClass函数
    72 libedog.so:5D692CA6
    73 libedog.so:5D692CA6             loc_5D692CA6                            ; CODE XREF: Java_com_edog_ELibrary_d1+86j
    74 libedog.so:5D692CA6 01 20       MOVS            R0, #1
    75 libedog.so:5D692CA8
    76 libedog.so:5D692CA8             loc_5D692CA8                            ; CODE XREF: Java_com_edog_ELibrary_d1+8Cj
    77 libedog.so:5D692CA8 00 F0 E8 FB BL              _Z7restorei             ; 根据操作系统的版本
    78 libedog.so:5D692CA8                                                     ; hook对应的dvmResolveClass函数
    79 libedog.so:5D692CAC 35 9A       LDR             R2, [SP,#0xF0+var_1C]
    80 libedog.so:5D692CAE 3B 68       LDR             R3, [R7]
    81 libedog.so:5D692CB0 9A 42       CMP             R2, R3
    82 libedog.so:5D692CB2 01 D0       BEQ             loc_5D692CB8
    83 libedog.so:5D692CB4 FF F7 9C EE BLX             sub_5D6929F0
    84 libedog.so:5D692CB8             ; ---------------------------------------------------------------------------
    85 libedog.so:5D692CB8
    86 libedog.so:5D692CB8             loc_5D692CB8                            ; CODE XREF: Java_com_edog_ELibrary_d1+9Aj
    87 libedog.so:5D692CB8 37 B0       ADD             SP, SP, #0xDC
    88 libedog.so:5D692CBA F0 BD       POP             {R4-R7,PC}
    89 libedog.so:5D692CBA             ; End of function Java_com_edog_ELibrary_d1
    90 libedog.so:5D692CBA
    91 libedog.so:5D692CBA             ; -------------------------------------

    0x03 指令还原算法分析

    原始指令还原时机就是在dvmResolveClass的hook函数中对对指令进行解密还原,以下结构的中的几个值会用到,因为被保护后的方法中的 debugInfoOff的值被修改成从0x20000000开始的一个值,该值在指令还原时起到重要作用。

    1 struct DexCode {
    2     u2  registersSize;
    3     u2  insSize;
    4     u2  outsSize;
    5     u2  triesSize;
    6     u4  debugInfoOff;      /* file offset to debug info stream */
    7     u4  insnsSize;        /* size of the insns array, in u2 units */
    8     u2  insns[1];
    9 };

    指令还原大致流程如下:

    判断是否为保护的类->判断debuginfo值大于0x1FFFFFFF->将debuginfo值左移8位再右移6位->将移位后的值加上加密指令在内存中的开始址取4字节做为偏移->将偏移加上加密指令在内存中的开始地址定位到对应方法的指令->解密指令并还原->清零debuginfo值->结束。

    解密指令算法流程如下:(每4字节进行xor)

    XorArray函数中进行解密操作->将方法debuginfo值进行crc32计算得到一个值->crc32计算得到的值与指令每4字节进行xor->4字节结束后再将crc32值用PolyXorKey函数生成一个新的4字节数做为密钥,一直循环到解密完成。

    代码流程如下

      1 libedog.so:5D693144
      2 libedog.so:5D693144             _Z13restoreMethodP11ClassObjectP6Method ; CODE XREF: _Z10replaceFunP11ClassObjectjb+22p
      3 libedog.so:5D693144                                                     ; _Z10replaceFunP11ClassObjectjb+3Ap
      4 libedog.so:5D693144
      5 libedog.so:5D693144             var_34= -0x34
      6 libedog.so:5D693144             Debug_info= -0x30
      7 libedog.so:5D693144             var_2C= -0x2C
      8 libedog.so:5D693144             codeSize= -0x28
      9 libedog.so:5D693144             data= -0x24
     10 libedog.so:5D693144             codeoffset= -0x1C
     11 libedog.so:5D693144
     12 libedog.so:5D693144 F0 B5       PUSH            {R4-R7,LR}
     13 libedog.so:5D693146 89 B0       SUB             SP, SP, #0x24
     14 libedog.so:5D693148 0F 1E       SUBS            R7, R1, #0
     15 libedog.so:5D69314A 5C D0       BEQ             loc_5D693206
     16 libedog.so:5D69314C 84 69       LDR             R4, [R0,#0x18]
     17 libedog.so:5D69314E 00 2C       CMP             R4, #0
     18 libedog.so:5D693150 59 D0       BEQ             loc_5D693206
     19 libedog.so:5D693152 20 1C       MOVS            R0, R4
     20 libedog.so:5D693154 4C 21       MOVS            R1, #'L'
     21 libedog.so:5D693156 FF F7 A0 EC BLX             strchr
     22 libedog.so:5D69315A 00 28       CMP             R0, #0
     23 libedog.so:5D69315C 53 D0       BEQ             loc_5D693206
     24 libedog.so:5D69315E 3E 6A       LDR             R6, [R7,#0x20]
     25 libedog.so:5D693160 00 2E       CMP             R6, #0
     26 libedog.so:5D693162 50 D0       BEQ             loc_5D693206
     27 libedog.so:5D693164 35 1C       MOVS            R5, R6
     28 libedog.so:5D693166 10 3D       SUBS            R5, #0x10
     29 libedog.so:5D693168 AA 68       LDR             R2, [R5,#8]
     30 libedog.so:5D69316A 02 92       STR             R2, [SP,#0x38+Debug_info]
     31 libedog.so:5D69316C EB 88       LDRH            R3, [R5,#6]
     32 libedog.so:5D69316E EA 68       LDR             R2, [R5,#0xC]
     33 libedog.so:5D693170 03 93       STR             R3, [SP,#0x38+var_2C]
     34 libedog.so:5D693172 04 92       STR             R2, [SP,#0x38+codeSize]
     35 libedog.so:5D693174 25 4B       LDR             R3, =0x1FFFFFFF
     36 libedog.so:5D693176 02 9A       LDR             R2, [SP,#0x38+Debug_info]
     37 libedog.so:5D693178 9A 42       CMP             R2, R3                  ; 判断debuginfo值大于 0x1FFFFFFF (因为被保护的方法debuginfo从0X20000000开始)
     38 libedog.so:5D69317A 44 D9       BLS             loc_5D693206
     39 libedog.so:5D69317C 24 49       LDR             R1, =(aLandroid - 0x5D693184)
     40 libedog.so:5D69317E 20 1C       MOVS            R0, R4
     41 libedog.so:5D693180 79 44       ADD             R1, PC                  ; "Landroid/"
     42 libedog.so:5D693182 FF F7 30 EC BLX             strstr                  ; 是系统的类就跳过
     43 libedog.so:5D693186 00 28       CMP             R0, #0
     44 libedog.so:5D693188 3D D1       BNE             loc_5D693206
     45 libedog.so:5D69318A 36 78       LDRB            R6, [R6]
     46 libedog.so:5D69318C 01 96       STR             R6, [SP,#0x38+var_34]
     47 libedog.so:5D69318E 00 2E       CMP             R6, #0
     48 libedog.so:5D693190 39 D1       BNE             loc_5D693206
     49 libedog.so:5D693192 20 4B       LDR             R3, =(aFjFj0fjFjFj4fj+0xC - 0x5D69319C)
     50 libedog.so:5D693194 07 A8       ADD             R0, SP, #0x38+codeoffset
     51 libedog.so:5D693196 07 96       STR             R6, [SP,#0x38+codeoffset]
     52 libedog.so:5D693198 7B 44       ADD             R3, PC                  ; "(fj],fj]4fj]i]"
     53 libedog.so:5D69319A 1B 68       LDR             R3, [R3]                ; "(fj],fj]4fj]i]"
     54 libedog.so:5D69319C 1B 68       LDR             R3, [R3]                ; data数据
     55 libedog.so:5D69319E 05 93       STR             R3, [SP,#0x38+data]
     56 libedog.so:5D6931A0 02 9B       LDR             R3, [SP,#0x38+Debug_info]
     57 libedog.so:5D6931A2 05 9A       LDR             R2, [SP,#0x38+data]
     58 libedog.so:5D6931A4 19 02       LSLS            R1, R3, #8
     59 libedog.so:5D6931A6 89 09       LSRS            R1, R1, #6
     60 libedog.so:5D6931A8 89 18       ADDS            R1, R1, R2
     61 libedog.so:5D6931AA 04 22       MOVS            R2, #4
     62 libedog.so:5D6931AC FF F7 68 EC BLX             memcpy_0
     63 libedog.so:5D6931B0 03 9A       LDR             R2, [SP,#0x38+var_2C]
     64 libedog.so:5D6931B2 04 9C       LDR             R4, [SP,#0x38+codeSize]
     65 libedog.so:5D6931B4 93 00       LSLS            R3, R2, #2
     66 libedog.so:5D6931B6 08 34       ADDS            R4, #8
     67 libedog.so:5D6931B8 E4 18       ADDS            R4, R4, R3
     68 libedog.so:5D6931BA 13 1C       MOVS            R3, R2
     69 libedog.so:5D6931BC 01 33       ADDS            R3, #1
     70 libedog.so:5D6931BE 9B 00       LSLS            R3, R3, #2
     71 libedog.so:5D6931C0 E4 18       ADDS            R4, R4, R3
     72 libedog.so:5D6931C2 64 00       LSLS            R4, R4, #1
     73 libedog.so:5D6931C4 20 1C       MOVS            R0, R4
     74 libedog.so:5D6931C6 FF F7 26 EC BLX             malloc
     75 libedog.so:5D6931CA 22 1C       MOVS            R2, R4
     76 libedog.so:5D6931CC 06 1C       MOVS            R6, R0
     77 libedog.so:5D6931CE 01 99       LDR             R1, [SP,#0x38+var_34]
     78 libedog.so:5D6931D0 FF F7 5C EC BLX             memset_0
     79 libedog.so:5D6931D4 29 1C       MOVS            R1, R5
     80 libedog.so:5D6931D6 22 1C       MOVS            R2, R4
     81 libedog.so:5D6931D8 30 1C       MOVS            R0, R6
     82 libedog.so:5D6931DA FF F7 52 EC BLX             memcpy_0
     83 libedog.so:5D6931DE 04 9B       LDR             R3, [SP,#0x38+codeSize]
     84 libedog.so:5D6931E0 05 9A       LDR             R2, [SP,#0x38+data]
     85 libedog.so:5D6931E2 07 99       LDR             R1, [SP,#0x38+codeoffset]
     86 libedog.so:5D6931E4 5D 00       LSLS            R5, R3, #1
     87 libedog.so:5D6931E6 02 98       LDR             R0, [SP,#0x38+Debug_info]
     88 libedog.so:5D6931E8 51 18       ADDS            R1, R2, R1
     89 libedog.so:5D6931EA 01 23       MOVS            R3, #1
     90 libedog.so:5D6931EC 2A 1C       MOVS            R2, R5
     91 libedog.so:5D6931EE 01 F0 1E EF BLX             dbone_crypt_ins         ; 解密指令
     92 libedog.so:5D6931F2 01 9B       LDR             R3, [SP,#0x38+var_34]
     93 libedog.so:5D6931F4 34 1C       MOVS            R4, R6
     94 libedog.so:5D6931F6 10 34       ADDS            R4, #0x10
     95 libedog.so:5D6931F8 01 1C       MOVS            R1, R0
     96 libedog.so:5D6931FA B3 60       STR             R3, [R6,#8]             ; 清空Debug_info
     97 libedog.so:5D6931FC 20 1C       MOVS            R0, R4
     98 libedog.so:5D6931FE 2A 1C       MOVS            R2, R5
     99 libedog.so:5D693200 FF F7 3E EC BLX             memcpy_0                ; 还原指令
    100 libedog.so:5D693204 3C 62       STR             R4, [R7,#0x20]
    101 libedog.so:5D693206
    102 libedog.so:5D693206             loc_5D693206                            ; CODE XREF: _Z13restoreMethodP11ClassObjectP6Method+6j
    103 libedog.so:5D693206                                                     ; _Z13restoreMethodP11ClassObjectP6Method+Cj ...
    104 libedog.so:5D693206 09 B0       ADD             SP, SP, #0x24
    105 libedog.so:5D693208 F0 BD       POP             {R4-R7,PC}
    106 libedog.so:5D693208             ; End of function _Z13restoreMethodP1
    107 解密指令
    108 libedog.so:5D69502C
    109 libedog.so:5D69502C             dbone_crypt_ins                         ; CODE XREF: _Z13restoreMethodP11ClassObjectP6Method+AAp
    110 libedog.so:5D69502C
    111 libedog.so:5D69502C             DecMode= -0x1C
    112 libedog.so:5D69502C             codeSize= -0x18
    113 libedog.so:5D69502C             codedata= -0x14
    114 libedog.so:5D69502C             key= -0x10
    115 libedog.so:5D69502C             crckey= -8
    116 libedog.so:5D69502C
    117 libedog.so:5D69502C 00 48 2D E9 STMFD           SP!, {R11,LR}
    118 libedog.so:5D695030 04 B0 8D E2 ADD             R11, SP, #4
    119 libedog.so:5D695034 18 D0 4D E2 SUB             SP, SP, #0x18
    120 libedog.so:5D695038 10 00 0B E5 STR             R0, [R11,#key]
    121 libedog.so:5D69503C 14 10 0B E5 STR             R1, [R11,#codedata]
    122 libedog.so:5D695040 18 20 0B E5 STR             R2, [R11,#codeSize]
    123 libedog.so:5D695044 1C 30 0B E5 STR             R3, [R11,#DecMode]      ; 1
    124 libedog.so:5D695048 10 30 4B E2 SUB             R3, R11, #-key
    125 libedog.so:5D69504C 03 00 A0 E1 MOV             R0, R3
    126 libedog.so:5D695050 04 10 A0 E3 MOV             R1, #4
    127 libedog.so:5D695054 47 01 00 EB BL              _Z5crc32Phj
    128 libedog.so:5D695058 00 30 A0 E1 MOV             R3, R0
    129 libedog.so:5D69505C 08 30 0B E5 STR             R3, [R11,#crckey]
    130 libedog.so:5D695060 1C 30 1B E5 LDR             R3, [R11,#DecMode]
    131 libedog.so:5D695064 01 00 53 E3 CMP             R3, #1
    132 libedog.so:5D695068 06 00 00 1A BNE             loc_5D695088
    133 libedog.so:5D69506C 08 20 1B E5 LDR             R2, [R11,#crckey]
    134 libedog.so:5D695070 18 30 1B E5 LDR             R3, [R11,#codeSize]
    135 libedog.so:5D695074 02 00 A0 E1 MOV             R0, R2
    136 libedog.so:5D695078 14 10 1B E5 LDR             R1, [R11,#codedata]
    137 libedog.so:5D69507C 14 20 1B E5 LDR             R2, [R11,#codedata]
    138 libedog.so:5D695080 80 00 00 EB BL              _Z8XorArrayjPhS_j
    139 libedog.so:5D695084 0D 00 00 EA B               loc_5D6950C0
    140 libedog.so:5D695088             ; ---------------------------------------------------------------------------
    141 libedog.so:5D695088
    142 libedog.so:5D695088             loc_5D695088                            ; CODE XREF: dbone_crypt_ins+3Cj
    143 libedog.so:5D695088 1C 30 1B E5 LDR             R3, [R11,#DecMode]
    144 libedog.so:5D69508C 00 00 53 E3 CMP             R3, #0
    145 libedog.so:5D695090 06 00 00 1A BNE             loc_5D6950B0
    146 libedog.so:5D695094 10 20 1B E5 LDR             R2, [R11,#key]
    147 libedog.so:5D695098 18 30 1B E5 LDR             R3, [R11,#codeSize]
    148 libedog.so:5D69509C 02 00 A0 E1 MOV             R0, R2
    149 libedog.so:5D6950A0 14 10 1B E5 LDR             R1, [R11,#codedata]
    150 libedog.so:5D6950A4 14 20 1B E5 LDR             R2, [R11,#codedata]
    151 libedog.so:5D6950A8 B1 00 00 EB BL              _Z13XorArray_0x99jPhS_j
    152 libedog.so:5D6950AC 03 00 00 EA B               loc_5D6950C0
    153 libedog.so:5D6950B0             ; ---------------------------------------------------------------------------
    154 libedog.so:5D6950B0
    155 libedog.so:5D6950B0             loc_5D6950B0                            ; CODE XREF: dbone_crypt_ins+64j
    156 libedog.so:5D6950B0 18 30 9F E5 LDR             R3, =(aUsageDbone_cry - 0x5D6950BC)
    157 libedog.so:5D6950B4 03 30 8F E0 ADD             R3, PC, R3              ; "USAGE:dbone_crypt_ins(key,ins,ins_lenth"...
    158 libedog.so:5D6950B8 03 00 A0 E1 MOV             R0, R3
    159 libedog.so:5D6950BC 99 F6 FF EB BL              puts
    160 libedog.so:5D6950C0
    161 libedog.so:5D6950C0             loc_5D6950C0                            ; CODE XREF: dbone_crypt_ins+58j
    162 libedog.so:5D6950C0                                                     ; dbone_crypt_ins+80j
    163 libedog.so:5D6950C0 14 30 1B E5 LDR             R3, [R11,#codedata]
    164 libedog.so:5D6950C4 03 00 A0 E1 MOV             R0, R3
    165 libedog.so:5D6950C8 04 D0 4B E2 SUB             SP, R11, #4
    166 libedog.so:5D6950CC 00 88 BD E8 LDMFD           SP!, {R11,PC}
    167 libedog.so:5D6950CC             ; End of function dbone_crypt_ins
    168 libedog.so:5D6950CC
    169 libedog.so:5D6950CC             ; -------------
    170 
    171 //循环解密
    172 
    173 libedog.so:5D695288             _Z8XorArrayjPhS_j                       ; CODE XREF: dbone_crypt_file+180p
    174 libedog.so:5D695288                                                     ; dbone_crypt_ins+54p
    175 libedog.so:5D695288
    176 libedog.so:5D695288             codeSize= -0x24
    177 libedog.so:5D695288             codedata1= -0x20
    178 libedog.so:5D695288             codedata= -0x1C
    179 libedog.so:5D695288             crckey= -0x18
    180 libedog.so:5D695288             crckey1= -0x14
    181 libedog.so:5D695288             crckeyaddr= -0x10
    182 libedog.so:5D695288             crckeyindex= -0xC
    183 libedog.so:5D695288             index= -8
    184 libedog.so:5D695288
    185 libedog.so:5D695288 00 48 2D E9 STMFD           SP!, {R11,LR}
    186 libedog.so:5D69528C 04 B0 8D E2 ADD             R11, SP, #4
    187 libedog.so:5D695290 20 D0 4D E2 SUB             SP, SP, #0x20
    188 libedog.so:5D695294 18 00 0B E5 STR             R0, [R11,#crckey]
    189 libedog.so:5D695298 1C 10 0B E5 STR             R1, [R11,#codedata]
    190 libedog.so:5D69529C 20 20 0B E5 STR             R2, [R11,#codedata1]
    191 libedog.so:5D6952A0 24 30 0B E5 STR             R3, [R11,#codeSize]
    192 libedog.so:5D6952A4 18 30 1B E5 LDR             R3, [R11,#crckey]
    193 libedog.so:5D6952A8 14 30 0B E5 STR             R3, [R11,#crckey1]
    194 libedog.so:5D6952AC 14 30 4B E2 SUB             R3, R11, #-crckey1
    195 libedog.so:5D6952B0 10 30 0B E5 STR             R3, [R11,#crckeyaddr]
    196 libedog.so:5D6952B4 00 30 A0 E3 MOV             R3, #0
    197 libedog.so:5D6952B8 08 30 0B E5 STR             R3, [R11,#index]
    198 libedog.so:5D6952BC 00 30 A0 E3 MOV             R3, #0
    199 libedog.so:5D6952C0 0C 30 0B E5 STR             R3, [R11,#crckeyindex]
    200 libedog.so:5D6952C4 00 30 A0 E3 MOV             R3, #0
    201 libedog.so:5D6952C8 08 30 0B E5 STR             R3, [R11,#index]
    202 libedog.so:5D6952CC 1E 00 00 EA B               loc_5D69534C
    203 libedog.so:5D6952D0             ; ---------------------------------------------------------------------------
    204 libedog.so:5D6952D0
    205 libedog.so:5D6952D0             loc_5D6952D0                            ; CODE XREF: _Z8XorArrayjPhS_j+E0j
    206 libedog.so:5D6952D0 08 30 1B E5 LDR             R3, [R11,#index]
    207 libedog.so:5D6952D4 20 20 1B E5 LDR             R2, [R11,#codedata1]
    208 libedog.so:5D6952D8 03 30 82 E0 ADD             R3, R2, R3
    209 libedog.so:5D6952DC 08 20 1B E5 LDR             R2, [R11,#index]
    210 libedog.so:5D6952E0 1C 10 1B E5 LDR             R1, [R11,#codedata]
    211 libedog.so:5D6952E4 02 20 81 E0 ADD             R2, R1, R2
    212 libedog.so:5D6952E8 00 10 D2 E5 LDRB            R1, [R2]
    213 libedog.so:5D6952EC 0C 20 1B E5 LDR             R2, [R11,#crckeyindex]
    214 libedog.so:5D6952F0 10 00 1B E5 LDR             R0, [R11,#crckeyaddr]
    215 libedog.so:5D6952F4 02 20 80 E0 ADD             R2, R0, R2
    216 libedog.so:5D6952F8 00 20 D2 E5 LDRB            R2, [R2]
    217 libedog.so:5D6952FC 02 20 21 E0 EOR             R2, R1, R2
    218 libedog.so:5D695300 FF 20 02 E2 AND             R2, R2, #0xFF
    219 libedog.so:5D695304 00 20 C3 E5 STRB            R2, [R3]
    220 libedog.so:5D695308 0C 30 1B E5 LDR             R3, [R11,#crckeyindex]
    221 libedog.so:5D69530C 03 00 53 E3 CMP             R3, #3                  ; 比较key是否结束
    222 libedog.so:5D695310 07 00 00 1A BNE             loc_5D695334
    223 libedog.so:5D695314 14 30 1B E5 LDR             R3, [R11,#crckey1]
    224 libedog.so:5D695318 03 00 A0 E1 MOV             R0, R3
    225 libedog.so:5D69531C 6C FF FF EB BL              _Z10PolyXorKeyj
    226 libedog.so:5D695320 00 30 A0 E1 MOV             R3, R0
    227 libedog.so:5D695324 14 30 0B E5 STR             R3, [R11,#crckey1]
    228 libedog.so:5D695328 00 30 A0 E3 MOV             R3, #0
    229 libedog.so:5D69532C 0C 30 0B E5 STR             R3, [R11,#crckeyindex]
    230 libedog.so:5D695330 02 00 00 EA B               loc_5D695340
    231 libedog.so:5D695334             ; ---------------------------------------------------------------------------
    232 libedog.so:5D695334
    233 libedog.so:5D695334             loc_5D695334                            ; CODE XREF: _Z8XorArrayjPhS_j+88j
    234 libedog.so:5D695334 0C 30 1B E5 LDR             R3, [R11,#crckeyindex]
    235 libedog.so:5D695338 01 30 83 E2 ADD             R3, R3, #1
    236 libedog.so:5D69533C 0C 30 0B E5 STR             R3, [R11,#crckeyindex]
    237 libedog.so:5D695340
    238 libedog.so:5D695340             loc_5D695340                            ; CODE XREF: _Z8XorArrayjPhS_j+A8j
    239 libedog.so:5D695340 08 30 1B E5 LDR             R3, [R11,#index]
    240 libedog.so:5D695344 01 30 83 E2 ADD             R3, R3, #1
    241 libedog.so:5D695348 08 30 0B E5 STR             R3, [R11,#index]
    242 libedog.so:5D69534C
    243 libedog.so:5D69534C             loc_5D69534C                            ; CODE XREF: _Z8XorArrayjPhS_j+44j
    244 libedog.so:5D69534C 24 20 1B E5 LDR             R2, [R11,#codeSize]
    245 libedog.so:5D695350 08 30 1B E5 LDR             R3, [R11,#index]
    246 libedog.so:5D695354 03 00 52 E1 CMP             R2, R3
    247 libedog.so:5D695358 00 30 A0 D3 MOVLE           R3, #0
    248 libedog.so:5D69535C 01 30 A0 C3 MOVGT           R3, #1
    249 libedog.so:5D695360 FF 30 03 E2 AND             R3, R3, #0xFF
    250 libedog.so:5D695364 00 00 53 E3 CMP             R3, #0
    251 libedog.so:5D695368 D8 FF FF 1A BNE             loc_5D6952D0
    252 libedog.so:5D69536C 04 D0 4B E2 SUB             SP, R11, #4
    253 libedog.so:5D695370 00 88 BD E8 LDMFD           SP!, {R11,PC}
    254 libedog.so:5D695370             ; End of function _Z8XorArrayjPhS_j
    255 libedog.so:5D695370
    256 libedog.so:5D695374
    257 libedog.so:5D695374             ; =============== S U B R O U T

    0x04 编写修复程序

             修复程序主要分为解析dex与解密两个步骤来完成,这里只贴出部分代码详细的请看工程,代码写得比较粗操,看下思路就行了,有性趣的就慢慢撸吧!

      1 void fixdexClassData()
      2 {
      3 
      4     DexFile *dexFile = &gDexFile;
      5 
      6     char * Tag = "L";
      7     char * ClassTag = "Landroid/";
      8 
      9     const DexClassDef* classdef;
     10     u4 count = dexFile->pHeader->classDefsSize;
     11 
     12     printf("该DEX共有%d 个类
    ", count);
     13 
     14     const u1* pEncodedData = NULL;
     15     DexClassData* pClassData = NULL;
     16     const char *descriptor = NULL;
     17 
     18 
     19     int FileSize = file_size();
     20 
     21     gCodeData = (u1*)malloc(FileSize);
     22     if (NULL == gCodeData)
     23     {
     24         printf("分配内存失败!
    ");
     25         return;
     26     }
     27     memset(gCodeData, 0, FileSize);
     28 
     29     //获得加密指令数据
     30     GetCodeData(gCodeData, FileSize);
     31 
     32     if (NULL == gCodeData)
     33     {
     34         printf("获取加密指令数据出错!
    ");
     35         return;
     36     }
     37 
     38     for(u4 i=0; i<count; i++){
     39         classdef = dexGetClassDef(dexFile, i);
     40 
     41         descriptor = getTpyeIdString(dexFile, classdef->classIdx);
     42 
     43         if (strstr(descriptor,Tag) == NULL)
     44         {
     45             continue;
     46         }
     47 
     48         //跳过一些系统的类
     49         if (strstr(descriptor, ClassTag) != NULL)
     50         {
     51             continue;
     52         }
     53 
     54         pEncodedData = dexFile->baseAddr + classdef->classDataOff;
     55         pClassData = dexReadAndVerifyClassData(&pEncodedData, NULL);
     56 
     57         if (pClassData == NULL) {
     58             continue;
     59         }
     60 
     61       FixdexMethodInsns(dexFile, pClassData, descriptor);
     62 
     63     }
     64 
     65 }
     66 
     67 void FixdexMethodInsns(DexFile *dexFile, const DexClassData*classData ,const char* className)
     68 {
     69     int idx = 0;
     70     DexMethod *method = NULL;
     71     const DexMethodId* methodId = NULL;
     72     DexCode* code = NULL;
     73     const char* methodName;
     74     method = classData->directMethods;
     75     methodId = dexFile->pMethodIds;
     76     unsigned int CodeDataOffset = 0;
     77     u1 * tempCode = NULL;
     78     for (int i = 0; i < (int) classData->header.directMethodsSize; i++) {
     79         idx = classData->directMethods[i].methodIdx;
     80 
     81         methodId = dexGetMethodId(dexFile, idx);
     82         methodName = dexStringById(dexFile, methodId->nameIdx);
     83 
     84         DexCode* pCode = dexGetCode(dexFile, &classData->directMethods[i]);
     85         if (NULL == pCode)
     86         {
     87             continue;
     88         }
     89         //判断是否为保护后的方法,如果是就修复指令
     90         if ( (pCode->debugInfoOff > 0x1FFFFFFF) && (pCode->insns[0] == 0X00))
     91         {
     92             //求加密指令的偏移
     93             CodeDataOffset = pCode->debugInfoOff << 0x8;
     94             CodeDataOffset >>= 0x6;
     95             //解密指令
     96             tempCode = DecCode(gCodeData+CodeDataOffset, pCode->insnsSize*sizeof(u2), pCode->debugInfoOff, gCodeData);
     97             //修复指令
     98             memcpy(pCode->insns, tempCode, (pCode->insnsSize)*sizeof(u2));
     99             pCode->debugInfoOff = 0x00;
    100             printf("修复%s 类中的%s 方法成功! 大小%X
    ",className, methodName,pCode->insnsSize);
    101             if (NULL != tempCode)
    102             {
    103                 free(tempCode);
    104                 tempCode = NULL;
    105             }
    106         }
    107     }
    108 
    109     for (int i = 0; i < (int) classData->header.virtualMethodsSize; i++) {
    110         idx = classData->virtualMethods[i].methodIdx;
    111 
    112         methodId = dexGetMethodId(dexFile, idx);
    113         methodName = dexStringById(dexFile, methodId->nameIdx);
    114 
    115         DexCode* pCode = dexGetCode(dexFile, &classData->virtualMethods[i]);
    116         if (NULL == pCode)
    117         {
    118             continue;
    119         }
    120         //判断是否为保护后的方法,如果是就修复指令
    121         if ( (pCode->debugInfoOff > 0x1FFFFFFF) && (pCode->insns[0] == 0X00))
    122         {
    123             //求加密指令的偏移
    124             CodeDataOffset = pCode->debugInfoOff << 0x8;
    125             CodeDataOffset >>= 0x6;
    126             //解密指令
    127             tempCode = DecCode(gCodeData+CodeDataOffset, pCode->insnsSize*sizeof(u2), pCode->debugInfoOff, gCodeData);
    128             //修复指令
    129             memcpy(pCode->insns, tempCode, (pCode->insnsSize)*sizeof(u2));
    130             pCode->debugInfoOff = 0x00;
    131             printf("修复%s 类中的%s 方法成功! 大小%X
    ",className, methodName,pCode->insnsSize);
    132             if (NULL != tempCode)
    133             {
    134                 free(tempCode);
    135                 tempCode = NULL;
    136             }
    137         }
    138     }
    139     return;
    140 }
    141 unsigned int PolyXorKey(DWORD crckey)
    142 {
    143     unsigned int dwKey;
    144     char temp;
    145     unsigned __int8 temp1;
    146     unsigned __int8 temp2;
    147     char *pKey;
    148     int temp3;
    149     int j;
    150     int i;
    151 
    152     j = 0;
    153     temp3 = 0;
    154     pKey = (char *)&dwKey;
    155     temp2 = 0;
    156     temp1 = 0;
    157     temp = 0;
    158     dwKey = crckey ^ 0xDF138530;
    159     i = 0;
    160     while ( i <= 3 )
    161     {
    162         temp2 = *pKey;
    163         j = 128;
    164         temp3 = 7;
    165         while ( j > 1 )
    166         {
    167             temp = (temp2 & j / 2) >> (temp3 - 1);
    168             temp1 = ((signed int)(unsigned __int8)(temp2 & j) >> temp3) ^ temp;
    169             temp1 <<= temp3;
    170             temp2 |= temp1;
    171             j /= 2;
    172             --temp3;
    173         }
    174         temp = temp2 & 1;
    175         temp1 = temp2 & 1 ^ temp2 & 1;
    176         *pKey = temp2;
    177         ++i;
    178         ++pKey;
    179     }
    180     return dwKey;
    181 }

    0x05 测试与总结

             将加固后的 APK中assets文件夹中的data文件与classes.dex放在修复程序同一个目录中,然后运行修复程序。

             图8

    去掉AndroidManifest.xml中的壳入口,将修复后的classes.dex重新打包反编译,成功运行,如图9所示能正常反编译源码,至此,分析完毕。

             图9

    壳流程总结:

    AndroidManifest.xml中的壳入口->com.edog.AppWrapper->

    so中Java_com_edog_ELibrary_d1->hook dvmResolveClass函数->在dvmResolveClass hook函数中修复指令->结束。

    语言表达不行,说的很杂,自己都觉得文章没有任何逻辑可言,如果大家能从中获得一些思路那也是好的, 不过这次分析让自己学到了很多,感谢APK加固作者。

    样本及pdf文档下载

    http://yunpan.cn/cmApFwTesyPGk (提取码:b37f)

  • 相关阅读:
    有趣的F-String
    停止使用非版本控制的可执行代码
    Django ORM中,如何使用Count来关联对象的子集数量
    Django Tastypie: 贴士,技巧和故障排除
    我实在不懂Python的Asyncio
    使用Let's Encrypt为网站加入SSL证书
    [debug]记一次竞态更新bug的解决
    我的web聊天之---序章
    我的音乐盒子(nodejs7 + koa2 + vue + vuex + vue-router)
    装饰器 生成器 进阶
  • 原文地址:https://www.cnblogs.com/2014asm/p/4757633.html
Copyright © 2011-2022 走看看