转载地址:http://mp.weixin.qq.com/s?__biz=MjM5NzAxMzk4NA==&mid=209300616&idx=1&sn=bcc440640f68e9355fcb20842a1ddaef&scene=0#rd
环境及工具
系统版本: Android 2.3.5
工具 : IDA pro 6.6 、010Editor
1.对加壳后的so进行反编译,代码不能正常显示,被加密了,如下图所示:
查看so的"INIT_ARRAY",指向了壳的入口, 如下图所示:
2.用IDA反编译加壳后的so文件,到0Xfd30去(壳的入口函数),如下图所示
3.通过上面分析知道了入口在"INIT_ARRAY",接下来动态调试,(如果不知道如何到该入口的可以参考 0n1y3nd's 大神写的文章http://0nly3nd.sinaapp.com/?p=649)到达壳入口后如下图所示:
与静态分析时是一样的。
4.壳反调试 检查是否有如下调试器 gdb strace ltrace android_server,如下图所:
5.接下来解密第二层的壳代码,算法为RC4,如下图所示:
6.知道密钥和算法及要解密的数据与大小,我们来写程序静态解密so中的数据,解密后生成so文件然后反编译该文件,以前不能正常显示的代码现在都能正常显示了(第二层壳),如下图所示:
7.第二层的壳代码解密完后,INIT_ARRAY处的壳代码功能算是走完了,接着在JNI_OnLoad处下好断点,F9运行,如下图所示:
8.断在JNI_OnLoad后继续分析,在Unk_8050303C函数会解密原始so RC4算法,如下图所示:
解密后的数据以".lfx"开头, 如下图所示:
9.将解密后的数据全部dump出来保存为lfx.Dump,与原始的so比较,看发生了什么变化,如下图所示:
10.将上面dump出来的文件lfx.Dump与没加壳前的so文件比较,发现不同的地方很多,说明还没有完全解密,继续分析,如下图所示:
开头4字节不一样
中间N多字节不一样
11.继分析后发现会对该文件的代码节进解压缩,这时候dump出来就会是原始的代码了,如下图所示:
解密原始so并解压代码的流程如下:
[Asm] 纯文本查看 复制代码
?
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
libjuan.so:8050303C loc_8050303C
; CODE XREF: libjuan.so:JNI_OnLoad+34p
libjuan.so:8050303C F0 4F 2D E9 STMFD
SP
!, {R4-R11,LR}
libjuan.so:80503040 D0 B2 9F E5 LDR R11, =(unk_8050FEE0 - 0x80503054)
libjuan.so:80503044 D0 32 9F E5 LDR R3, =0xFFFFFF68
libjuan.so:80503048 D0 52 9F E5 LDR R5, =(unk_8050D940 - 0x80503060)
libjuan.so:8050304C 0B B0 8F E0
ADD
R11, PC, R11
; unk_8050FEE0
libjuan.so:80503050 03 30 9B E7 LDR R3, [R11,R3]
libjuan.so:80503054 5B
DF
4D E2
SUB
SP
,
SP
, #0x16C
libjuan.so:80503058 05 50 8F E0
ADD
R5, PC, R5
; unk_8050D940
libjuan.so:8050305C 0C 30 8D E5
STR
R3, [
SP
,#0xC]
libjuan.so:80503060 00 30 93 E5 LDR R3, [R3]
libjuan.so:80503064 05 10 A0 E1
MOV
R1, R5
libjuan.so:80503068 0A 20 A0 E3
MOV
R2, #0xA
libjuan.so:8050306C 1C 00 8D E2
ADD
R0,
SP
, #0x1C
libjuan.so:80503070 64 31 8D E5
STR
R3, [
SP
,#0x164]
libjuan.so:80503074 11 FE FF EB
BL
memcpy_0
; 拷贝密钥0XA字节
libjuan.so:80503074
; 46 45 88 89 98 99 87 87 65 87
libjuan.so:80503078 1C 00 8D E2
ADD
R0,
SP
, #0x1C
libjuan.so:8050307C 0A 10 A0 E3
MOV
R1, #0xA
libjuan.so:80503080 60 20 8D E2
ADD
R2,
SP
, #0x60
libjuan.so:80503084 7E 0B 00 EB
BL
init_Key
libjuan.so:80503088 94 32 9F E5 LDR R3, =0xFFFFFF94
libjuan.so:8050308C 45 1C A0 E3+
MOV
R1, #0x451C
; 要解密的大小 0000451C
libjuan.so:80503094 03 90 9B E7 LDR R9, [R11,R3]
libjuan.so:80503098 60 20 8D E2
ADD
R2,
SP
, #0x60
; R2初始化的的密钥
libjuan.so:8050309C 00 60 A0 E3
MOV
R6, #0
libjuan.so:805030A0 09 00 A0 E1
MOV
R0, R9
; R0要解密的数据 地址805104CC
libjuan.so:805030A4 97 0C 00 EB
BL
rc4_crypt
; 解密原始的so文件
libjuan.so:805030A8 01 2C A0 E3
MOV
R2, #0x100
libjuan.so:805030AC 00 10 A0 E3
MOV
R1, #0
libjuan.so:805030B0 02 20 82 E2
ADD
R2, R2, #2
libjuan.so:805030B4 60 00 8D E2
ADD
R0,
SP
, #0x60
libjuan.so:805030B8 03 FE FF EB
BL
memset_0
libjuan.so:805030BC 04 00 A0 E3
MOV
R0, #4
libjuan.so:805030C0 12 12 00 EB
BL
AnitDbg_0
libjuan.so:805030C4 20 40 99 E5 LDR R4, [R9,#0x20]
libjuan.so:805030C8 B2 33 D9 E1 LDRH R3, [R9,#0x32]
libjuan.so:805030CC 28 20 A0 E3
MOV
R2, #0x28
libjuan.so:805030D0 04 40 89 E0
ADD
R4, R9, R4
libjuan.so:805030D4 92 43 23 E0 MLA R3, R2, R3, R4
libjuan.so:805030D8 10 30 93 E5 LDR R3, [R3,#0x10]
libjuan.so:805030DC 03 30 89 E0
ADD
R3, R9, R3
libjuan.so:805030E0 04 30 8D E5
STR
R3, [
SP
,#4]
libjuan.so:805030E4 76 10 00 EB
BL
__gnu_armfini_11
libjuan.so:805030E8 0D 20 A0 E3
MOV
R2, #0xD
libjuan.so:805030EC 0C 10 85 E2
ADD
R1, R5, #0xC
libjuan.so:805030F0 28 00 8D E2
ADD
R0,
SP
, #0x28
libjuan.so:805030F4 F1 FD FF EB
BL
memcpy_0
libjuan.so:805030F8 28 00 8D E2
ADD
R0,
SP
, #0x28
libjuan.so:805030FC D3 14 00 EB
BL
GetBase64String
libjuan.so:80503100 38 10 8D E2
ADD
R1,
SP
, #0x38
libjuan.so:80503104 28 00 8D E2
ADD
R0,
SP
, #0x28
libjuan.so:80503108 38 60 8D E5
STR
R6, [
SP
,#0x38]
libjuan.so:8050310C 3C 60 8D E5
STR
R6, [
SP
,#0x3C]
libjuan.so:80503110 40 60 8D E5
STR
R6, [
SP
,#0x40]
libjuan.so:80503114 44 60 8D E5
STR
R6, [
SP
,#0x44]
libjuan.so:80503118 48 60 8D E5
STR
R6, [
SP
,#0x48]
libjuan.so:8050311C 4C 60 8D E5
STR
R6, [
SP
,#0x4C]
libjuan.so:80503120 50 60 8D E5
STR
R6, [
SP
,#0x50]
libjuan.so:80503124 54 60 8D E5
STR
R6, [
SP
,#0x54]
libjuan.so:80503128 58 60 8D E5
STR
R6, [
SP
,#0x58]
libjuan.so:8050312C 5C 60 8D E5
STR
R6, [
SP
,#0x5C]
libjuan.so:80503130 4D 13 00 EB
BL
DecBase64String
libjuan.so:80503134 1C 10 85 E2
ADD
R1, R5, #0x1C
libjuan.so:80503138 06 20 A0 E3
MOV
R2, #6
libjuan.so:8050313C 14 00 8D E2
ADD
R0,
SP
, #0x14
libjuan.so:80503140 DE FD FF EB
BL
memcpy_0
libjuan.so:80503144 14 00 8D E2
ADD
R0,
SP
, #0x14
libjuan.so:80503148 06 10 A0 E3
MOV
R1, #6
libjuan.so:8050314C 8A FF FF EB
BL
DecString_0
libjuan.so:80503150 B0 33 D9 E1 LDRH R3, [R9,#0x30]
libjuan.so:80503154 06 00 53 E1
CMP
R3, R6
libjuan.so:80503158 03 60 A0 01 MOVEQ R6, R3
libjuan.so:8050315C 39 00 00 0A BEQ loc_80503248
libjuan.so:80503160 C0 71 9F E5 LDR R7, =(dword_805149E8 - 0x80503170)
libjuan.so:80503164 06 80 A0 E1
MOV
R8, R6
libjuan.so:80503168 07 70 8F E0
ADD
R7, PC, R7
; dword_805149E8
libjuan.so:8050316C
libjuan.so:8050316C loc_8050316C
; CODE XREF: libjuan.so:__gnu_arm_flush+350j
libjuan.so:8050316C 04 C0 9D E5 LDR R12, [
SP
,#4]
libjuan.so:80503170 00 00 94 E5 LDR R0, [R4]
libjuan.so:80503174 14 10 8D E2
ADD
R1,
SP
, #0x14
libjuan.so:80503178 00 00 8C E0
ADD
R0, R12, R0
libjuan.so:8050317C DE FD FF EB
BL
strcmp
; 与.text比较
libjuan.so:80503180 00 30 50 E2 SUBS R3, R0, #0
libjuan.so:80503184 3D 00 00 1A BNE loc_80503280
libjuan.so:80503188 10 50 94 E5 LDR R5, [R4,#0x10]
libjuan.so:8050318C 14 C0 94 E5 LDR R12, [R4,#0x14]
libjuan.so:80503190 05 A0 99 E7 LDR R10, [R9,R5]
libjuan.so:80503194 08 C0 8D E5
STR
R12, [
SP
,#8]
libjuan.so:80503198 00 30 8D E5
STR
R3, [
SP
]
libjuan.so:8050319C 0A 00 A0 E1
MOV
R0, R10
libjuan.so:805031A0 C3 FD FF EB
BL
malloc
libjuan.so:805031A4 00 60 50 E2 SUBS R6, R0, #0
libjuan.so:805031A8 05 50 89 E0
ADD
R5, R9, R5
libjuan.so:805031AC 00 30 9D E5 LDR R3, [
SP
]
libjuan.so:805031B0 51 00 00 0A BEQ loc_805032FC
libjuan.so:805031B4 00 00 5A E3
CMP
R10, #0
libjuan.so:805031B8 14 00 00 DA BLE loc_80503210
libjuan.so:805031BC 68 11 9F E5 LDR R1, =0xFFFFFF70
libjuan.so:805031C0 04 20 A0 E3
MOV
R2, #4
libjuan.so:805031C4 01 E0 9B E7 LDR LR, [R11,R1]
libjuan.so:805031C8 00 10 9E E5 LDR R1, [LR]
libjuan.so:805031CC
libjuan.so:805031CC loc_805031CC
; CODE XREF: libjuan.so:__gnu_arm_flush+28Cj
libjuan.so:805031CC 03 00 13 E3 TST R3, #3
libjuan.so:805031D0 07 00 00 1A BNE loc_805031F4
libjuan.so:805031D4 FE 00 51 E3
CMP
R1, #0xFE
libjuan.so:805031D8 05 00 00 8A BHI loc_805031F4
libjuan.so:805031DC 4C 01 9F E5 LDR R0, =0xFFFFFF6C
libjuan.so:805031E0 02 C0 D5 E7 LDRB R12, [R5,R2]
libjuan.so:805031E4 01 10 81 E2
ADD
R1, R1, #1
libjuan.so:805031E8 00 00 9B E7 LDR R0, [R11,R0]
libjuan.so:805031EC 01 20 82 E2
ADD
R2, R2, #1
libjuan.so:805031F0 43 C1 C0 E7 STRB R12, [R0,R3,ASR
#
2]
libjuan.so:805031F4
libjuan.so:805031F4 loc_805031F4
; CODE XREF: libjuan.so:__gnu_arm_flush+254j
libjuan.so:805031F4
; libjuan.so:__gnu_arm_flush+25Cj
libjuan.so:805031F4 02 00 D5 E7 LDRB R0, [R5,R2]
libjuan.so:805031F8 01 20 82 E2
ADD
R2, R2, #1
libjuan.so:805031FC 03 00 C6 E7 STRB R0, [R6,R3]
libjuan.so:80503200 01 30 83 E2
ADD
R3, R3, #1
libjuan.so:80503204 03 00 5A E1
CMP
R10, R3
libjuan.so:80503208 EF FF FF 1A BNE loc_805031CC
libjuan.so:8050320C 00 10 8E E5
STR
R1, [LR]
libjuan.so:80503210
libjuan.so:80503210 loc_80503210
; CODE XREF: libjuan.so:__gnu_arm_flush+23Cj
libjuan.so:80503210 08 C0 9D E5 LDR R12, [
SP
,#8]
libjuan.so:80503214 05 00 A0 E1
MOV
R0, R5
libjuan.so:80503218 10 10 8D E2
ADD
R1,
SP
, #0x10
libjuan.so:8050321C 06 20 A0 E1
MOV
R2, R6
libjuan.so:80503220 0A 30 A0 E1
MOV
R3, R10
libjuan.so:80503224 10 C0 8D E5
STR
R12, [
SP
,#0x10]
libjuan.so:80503228 C2 FD FF EB
BL
uncompress_0
; 解压代码(.text)
libjuan.so:8050322C 00 00 50 E3
CMP
R0, #0
; 这时候dump可以得到原始的so了
libjuan.so:80503230 27 00 00 0A BEQ loc_805032D4
libjuan.so:80503234 F8 30 9F E5 LDR R3, =0xFFFFFF60
libjuan.so:80503238 BF 2E A0 E3
MOV
R2, #0xBF0
libjuan.so:8050323C 00 60 A0 E3
MOV
R6, #0
libjuan.so:80503240 03 30 9B E7 LDR R3, [R11,R3]
libjuan.so:80503244 00 20 83 E5
STR
R2, [R3]
libjuan.so:80503248
libjuan.so:80503248 loc_80503248
; CODE XREF: libjuan.so:__gnu_arm_flush+1E0j
libjuan.so:80503248
; libjuan.so:__gnu_arm_flush+354j ...
libjuan.so:80503248 0C C0 9D E5 LDR R12, [
SP
,#0xC]
libjuan.so:8050324C 64 21 9D E5 LDR R2, [
SP
,#0x164]
libjuan.so:80503250 06 00 A0 E1
MOV
R0, R6
libjuan.so:80503254 00 30 9C E5 LDR R3, [R12]
libjuan.so:80503258 03 00 52 E1
CMP
R2, R3
libjuan.so:8050325C 2C 00 00 1A BNE loc_80503314
libjuan.so:80503260 5B
DF
8D E2
ADD
SP
,
SP
, #0x16C
libjuan.so:80503264 F0 8F BD E8 LDMFD
SP
!, {R4-R11,PC}
libjuan.so:80503268
; ---------------------------------------------------------------------------
libjuan.so:80503268
libjuan.so:80503268 loc_80503268
; CODE XREF: libjuan.so:__gnu_arm_flush+364j
libjuan.so:80503268 05 00 A0 E1
MOV
R0, R5
libjuan.so:8050326C 0C 10 85 E0
ADD
R1, R5, R12
libjuan.so:80503270 69 FE FF EB
BL
sub_80502C1C
libjuan.so:80503274 06 00 A0 E1
MOV
R0, R6
libjuan.so:80503278 96 FD FF EB
BL
unk_805028D8
libjuan.so:8050327C 01 60 A0 E3
MOV
R6, #1
libjuan.so:80503280
libjuan.so:80503280 loc_80503280
; CODE XREF: libjuan.so:__gnu_arm_flush+208j
libjuan.so:80503280 05 00 A0 E3
MOV
R0, #5
libjuan.so:80503284 A1 11 00 EB
BL
AnitDbg_0
; 反调试,查看是否有
libjuan.so:80503284
; gdb strace ltrace android_server程序
libjuan.so:80503288 04 C0 9D E5 LDR R12, [
SP
,#4]
libjuan.so:8050328C 00 00 94 E5 LDR R0, [R4]
libjuan.so:80503290 38 10 8D E2
ADD
R1,
SP
, #0x38
libjuan.so:80503294 00 00 8C E0
ADD
R0, R12, R0
libjuan.so:80503298 94 FD FF EB
BL
strstr
libjuan.so:8050329C 00 00 50 E3
CMP
R0, #0
libjuan.so:805032A0 05 00 00 0A BEQ loc_805032BC
libjuan.so:805032A4 00 30 97 E5 LDR R3, [R7]
libjuan.so:805032A8 0C 00 84 E2
ADD
R0, R4, #0xC
libjuan.so:805032AC 07 00 90 E8 LDMIA R0, {R0-R2}
libjuan.so:805032B0 03 10 81 E0
ADD
R1, R1, R3
libjuan.so:805032B4 03 30 80 E0
ADD
R3, R0, R3
libjuan.so:805032B8 0E 00 87 E9 STMIB R7, {R1-R3}
libjuan.so:805032BC
libjuan.so:805032BC loc_805032BC
; CODE XREF: libjuan.so:__gnu_arm_flush+324j
libjuan.so:805032BC B0 33 D9 E1 LDRH R3, [R9,#0x30]
libjuan.so:805032C0 01 80 88 E2
ADD
R8, R8, #1
libjuan.so:805032C4 28 40 84 E2
ADD
R4, R4, #0x28
libjuan.so:805032C8 08 00 53 E1
CMP
R3, R8
libjuan.so:805032CC A6 FF FF CA
BGT
loc_8050316C
libjuan.so:805032D0 DC FF FF EA B loc_80503248
libjuan.so:805032D4
; ---------------------------------------------------------------------------
libjuan.so:805032D4
libjuan.so:805032D4 loc_805032D4
; CODE XREF: libjuan.so:__gnu_arm_flush+2B4j
libjuan.so:805032D4 10 30 9D E5 LDR R3, [
SP
,#0x10]
libjuan.so:805032D8 08 C0 9D E5 LDR R12, [
SP
,#8]
libjuan.so:805032DC 03 00 5C E1
CMP
R12, R3
libjuan.so:805032E0 E0 FF FF 0A BEQ loc_80503268
libjuan.so:805032E4 48 30 9F E5 LDR R3, =0xFFFFFF60
libjuan.so:805032E8 BF 2E A0 E3
MOV
R2, #0xBF0
libjuan.so:805032EC 00 60 A0 E1
MOV
R6, R0
libjuan.so:805032F0 03 30 9B E7 LDR R3, [R11,R3]
libjuan.so:805032F4 00 20 83 E5
STR
R2, [R3]
libjuan.so:805032F8 D2 FF FF EA B loc_80503248
libjuan.so:805032FC
; ---------------------------------------------------------------------------
libjuan.so:805032FC
libjuan.so:805032FC loc_805032FC
; CODE XREF: libjuan.so:__gnu_arm_flush+234j
libjuan.so:805032FC 30 20 9F E5 LDR R2, =0xFFFFFF60
libjuan.so:80503300 BE 3E A0 E3+
MOV
R3, #0xBEF
libjuan.so:80503308 02 20 9B E7 LDR R2, [R11,R2]
|
12.解压缩后再次dump出来保存为lfx1.Dump与原始的so比较,发现只有前4字节不一样了,如下图所示:
13.将第二次dump出来的lfx1.Dump文件的头4字节.lfx改成.ELF就成了,脱壳完毕。
14.总结: 壳入口 --> INIT_ARRAY--->解密第二层壳(JNI_OnLoad)---->解密原始so文件--->解压缩原始so的代码节。
样本 http://yunpan.cn/cVCApjnJvJue6 (提取码:85fc)