android逆向总结

首先项目里的java文件,以及项目引用到的第三方jar或aar包里面的class,统统都编译成classes.dex放在apk包的根目录,项目的资源目录和AndroidManifest.xml被处理生成资源目录和resource.arsc以及AndroidManifest.xml文件放到apk包根目录。

apk包安装到android后,apk包被复制到/data/app目录,应用程序每次启动后就会加载这个apk,访问里面的资源。而为了加快执行,apk包根目录的classes.dex会已经arch优化成odex,放在/data/dalvik_cache目录。应用程序加载的执行代码就是这个odex。apk包的lib目录下的所有文件(主要是so第三方c库)都会从apk包复制到/data/lib。

当我们对一个普通的apk包分析时,res目录下的xml和根目录下的AndroidManifest.xml都在打包时被处理过,不能直接阅读。这些xml文件都是可执行的脚本描述。而执行文件classes.dex则是我们希望反编译汇编代码进行分析的。apktool这个工具的主要逆向功能就是,将res目录下的xml和AndroidManifest.xml文件还原释放出来,以及将classes.dex反汇编成smali。

android系统自带有反汇编工具,/usr/xbin/dexdump。这个工具可以直接从odex反汇编出smali描述出来。

下面常用的反编译工具和各种文件之间的转换。

这里有4种工具,

oat2dex,将odex或oat转换出dex。

d2j工具套,虚拟机机器指令和可执行包之间的assemble和disassemble,以及Davlik虚拟机可执行文件dex和java虚拟机执行包之间的转换。dex可以反汇编出smali,而class可以反汇编出j。

代码逆向工具,smali2java就是将smali翻译出java文件,DJ JavaDecomplier就是将class或java虚拟机指令反向出java文件。这两个工具都不能很好地对控制逻辑(条件控制,循环控制,跳转)进行翻译。smali2java面对稍复杂一点的控制逻辑就不工作,它的翻译函数异常没有结果。而DJ JavaDecomplier面对稍复杂一点的控制逻辑,它的逆向代码与其它语言的逆向工具的逆向代码一样,天书一样多的跳标签,不是人类阅读的。

注,这里说Java有跳转,是指catch,熟悉c++,oc反汇编都明白,在异常处理代码就是在做跳转。而在java机器指令或smali指令中,异常也是有专门的跳转指令和标签。

下面是我对百度加固baiduprotect的StubApplication.smali进行人工逆向的java代码

  1 .method private static loadX86Library()V
  2     .locals 33
  3
  4     .prologue
  5     .line 128
  6     const/16 v24, 0x0
  7
  8     .line 129
  9     .local v24, "packageName":Ljava/lang/String;
 10     const/4 v4, 0x0
 11
 12     .line 131
 13     .local v4, "apkPath":Ljava/lang/String;
 14     invoke-static {}, Lcom/baidu/protect/StubApplication;->is64BitEnv()Z
 15
 16     move-result v15
 17
 18     .line 134
 19     .local v15, "is_x86_64":Z
 20     :try_start_0
 21     new-instance v5, Ljava/io/BufferedReader;
 22
 23     new-instance v30, Ljava/io/InputStreamReader;
 24
 25     .line 135
 26     new-instance v31, Ljava/io/FileInputStream;
 27
 28     const-string v32, "/proc/self/maps"
 29
 30     invoke-direct/range {v31 .. v32}, Ljava/io/FileInputStream;-><init>(Ljava/lang/String;)V
 31
 32     invoke-direct/range {v30 .. v31}, Ljava/io/InputStreamReader;-><init>(Ljava/io/InputStream;)V
 33
 34     .line 134
 35     move-object/from16 v0, v30
 36
 37     invoke-direct {v5, v0}, Ljava/io/BufferedReader;-><init>(Ljava/io/Reader;)V
 38
 39     .line 136
 40     .local v5, "br":Ljava/io/BufferedReader;
 41     invoke-virtual {v5}, Ljava/io/BufferedReader;->readLine()Ljava/lang/String;
 42
 43     move-result-object v19
 44
 45     .local v19, "line":Ljava/lang/String;
 46     :goto_0
 47     if-nez v19, :cond_3
 48
 49     .line 186
 50     :goto_1
 51     invoke-virtual {v5}, Ljava/io/BufferedReader;->close()V
 52     :try_end_0
 53     .catch Ljava/io/IOException; {:try_start_0 .. :try_end_0} :catch_0
 54
 55     .line 192
 56     .end local v5    # "br":Ljava/io/BufferedReader;
 57     .end local v19    # "line":Ljava/lang/String;
 58     :goto_2
 59     if-eqz v15, :cond_a
 60
 61     .line 193
 62     const-string v28, "libbaiduprotect_x86_64.so"
 63
 64     .line 200
 65     .local v28, "soname":Ljava/lang/String;
 66     :goto_3
 67     if-eqz v4, :cond_2
 68
 69     if-eqz v24, :cond_2
 70
 71     .line 201
 72     const-wide/16 v12, 0x0
 73
 74     .line 202
 75     .local v12, "fileModified":J
 76     const-wide/16 v22, 0x0
 77
 78     .line 203
 79     .local v22, "newFileModified":J
 80     invoke-static/range {v24 .. v24}, Lcom/baidu/protect/StubApplication;->getDataFolder(Ljava/lang/String;)Ljava/lang/String;
 81
 82     move-result-object v7
 83
 84     .line 205
 85     .local v7, "dataFolder":Ljava/lang/String;
 86     new-instance v30, Ljava/lang/StringBuilder;
 87
 88     invoke-static {v7}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String;
 89
 90     move-result-object v31
 91
 92     invoke-direct/range {v30 .. v31}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
 93
 94     move-object/from16 v0, v30
 95
 96     move-object/from16 v1, v24
 97
 98     invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
 99
100     move-result-object v30
101
102     const-string v31, "/.x86lib/"
103
104     invoke-virtual/range {v30 .. v31}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
105
106     move-result-object v30
107
108     invoke-virtual/range {v30 .. v30}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
109
110     move-result-object v18
111
112     .line 206
113     .local v18, "libTargetFolder":Ljava/lang/String;
114     new-instance v30, Ljava/lang/StringBuilder;
115
116     invoke-static/range {v18 .. v18}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String;
117
118     move-result-object v31
119
120     invoke-direct/range {v30 .. v31}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
121
122     move-object/from16 v0, v30
123
124     move-object/from16 v1, v28
125
126     invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
127
128     move-result-object v30
129
130     invoke-virtual/range {v30 .. v30}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
131
132     move-result-object v17
133
134     .line 207
135     .local v17, "libPath":Ljava/lang/String;
136     new-instance v9, Ljava/io/File;
137
138     move-object/from16 v0, v18
139
140     invoke-direct {v9, v0}, Ljava/io/File;-><init>(Ljava/lang/String;)V
141
142     .line 208
143     .local v9, "f":Ljava/io/File;
144     invoke-virtual {v9}, Ljava/io/File;->exists()Z
145
146     move-result v30
147
148     if-nez v30, :cond_0
149
150     .line 209
151     invoke-virtual {v9}, Ljava/io/File;->mkdir()Z
152
153     .line 212
154     :cond_0
155     :try_start_1
156     new-instance v30, Ljava/lang/StringBuilder;
157
158     const-string v31, "assets/"
159
160     invoke-direct/range {v30 .. v31}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
161
162     move-object/from16 v0, v30
163
164     move-object/from16 v1, v28
165
166     invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
167
168     move-result-object v30
169
170     invoke-virtual/range {v30 .. v30}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
171
172     move-result-object v27
173
174     .line 213
175     .local v27, "soEntryName":Ljava/lang/String;
176     new-instance v21, Ljava/util/zip/ZipInputStream;
177
178     new-instance v30, Ljava/io/FileInputStream;
179
180     move-object/from16 v0, v30
181
182     invoke-direct {v0, v4}, Ljava/io/FileInputStream;-><init>(Ljava/lang/String;)V
183
184     move-object/from16 v0, v21
185
186     move-object/from16 v1, v30
187
188     invoke-direct {v0, v1}, Ljava/util/zip/ZipInputStream;-><init>(Ljava/io/InputStream;)V
189
190     .line 215
191     .local v21, "localZipInputStream":Ljava/util/zip/ZipInputStream;
192     :goto_4
193     invoke-virtual/range {v21 .. v21}, Ljava/util/zip/ZipInputStream;->getNextEntry()Ljava/util/zip/ZipEntry;
194
195     move-result-object v20
196
197     .line 216
198     .local v20, "localZipEntry":Ljava/util/zip/ZipEntry;
199     if-nez v20, :cond_b
200
201     .line 258
202     :cond_1
203     :goto_5
204     invoke-virtual/range {v21 .. v21}, Ljava/util/zip/ZipInputStream;->close()V
205     :try_end_1
206     .catch Ljava/io/IOException; {:try_start_1 .. :try_end_1} :catch_1
207
208     .line 264
209     .end local v20    # "localZipEntry":Ljava/util/zip/ZipEntry;
210     .end local v21    # "localZipInputStream":Ljava/util/zip/ZipInputStream;
211     .end local v27    # "soEntryName":Ljava/lang/String;
212     :goto_6
213     invoke-static/range {v17 .. v17}, Ljava/lang/System;->load(Ljava/lang/String;)V
214
215     .line 266
216     .end local v7    # "dataFolder":Ljava/lang/String;
217     .end local v9    # "f":Ljava/io/File;
218     .end local v12    # "fileModified":J
219     .end local v17    # "libPath":Ljava/lang/String;
220     .end local v18    # "libTargetFolder":Ljava/lang/String;
221     .end local v22    # "newFileModified":J
222     :cond_2
223     return-void
224
225     .line 138
226     .end local v28    # "soname":Ljava/lang/String;
227     .restart local v5    # "br":Ljava/io/BufferedReader;
228     .restart local v19    # "line":Ljava/lang/String;
229     :cond_3
230     :try_start_2
231     const-string v30, ".apk"
232
233     move-object/from16 v0, v19
234
235     move-object/from16 v1, v30
236
237     invoke-virtual {v0, v1}, Ljava/lang/String;->endsWith(Ljava/lang/String;)Z
238
239     move-result v30
240
241     if-eqz v30, :cond_5
242
243     .line 139
244     sget-object v30, Ljava/lang/System;->out:Ljava/io/PrintStream;
245
246     new-instance v31, Ljava/lang/StringBuilder;
247
248     const-string v32, "Wigan:line="
249
250     invoke-direct/range {v31 .. v32}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
251
252     move-object/from16 v0, v31
253
254     move-object/from16 v1, v19
255
256     invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
257
258     move-result-object v31
259
260     invoke-virtual/range {v31 .. v31}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
261
262     move-result-object v31
263
264     invoke-virtual/range {v30 .. v31}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
265
266     .line 140
267     const-string v30, " "
268
269     move-object/from16 v0, v19
270
271     move-object/from16 v1, v30
272
273     invoke-virtual {v0, v1}, Ljava/lang/String;->split(Ljava/lang/String;)[Ljava/lang/String;
274
275     move-result-object v26
276
277     .line 141
278     .local v26, "s":[Ljava/lang/String;
279     move-object/from16 v0, v26
280
281     array-length v0, v0
282
283     move/from16 v30, v0
284
285     add-int/lit8 v30, v30, -0x1
286
287     aget-object v25, v26, v30
288
289     .line 144
290     .local v25, "path":Ljava/lang/String;
291     const-string v30, "/mnt/asec/"
292
293     move-object/from16 v0, v25
294
295     move-object/from16 v1, v30
296
297     invoke-virtual {v0, v1}, Ljava/lang/String;->startsWith(Ljava/lang/String;)Z
298
299     move-result v30
300
301     if-nez v30, :cond_4
302
303     const-string v30, "/data/app/"
304
305     move-object/from16 v0, v25
306
307     move-object/from16 v1, v30
308
309     invoke-virtual {v0, v1}, Ljava/lang/String;->startsWith(Ljava/lang/String;)Z
310
311     move-result v30
312
313     if-eqz v30, :cond_6
314
315     .line 145
316     :cond_4
317     const/16 v30, 0xa
318
319     move-object/from16 v0, v25
320
321     move/from16 v1, v30
322
323     invoke-virtual {v0, v1}, Ljava/lang/String;->substring(I)Ljava/lang/String;
324
325     move-result-object v3
326
327     .line 156
328     .local v3, "apkName":Ljava/lang/String;
329     :goto_7
330     const/16 v30, 0x2d
331
332     move/from16 v0, v30
333
334     invoke-virtual {v3, v0}, Ljava/lang/String;->lastIndexOf(I)I
335
336     move-result v16
337
338     .line 157
339     .local v16, "lastIndex":I
340     const/16 v30, -0x1
341
342     move/from16 v0, v16
343
344     move/from16 v1, v30
345
346     if-ne v0, v1, :cond_8
347
348     .line 136
349     .end local v3    # "apkName":Ljava/lang/String;
350     .end local v16    # "lastIndex":I
351     .end local v25    # "path":Ljava/lang/String;
352     .end local v26    # "s":[Ljava/lang/String;
353     :cond_5
354     invoke-virtual {v5}, Ljava/io/BufferedReader;->readLine()Ljava/lang/String;
355
356     move-result-object v19
357
358     goto/16 :goto_0
359
360     .line 147
361     .restart local v25    # "path":Ljava/lang/String;
362     .restart local v26    # "s":[Ljava/lang/String;
363     :cond_6
364     const-string v30, "/app/"
365
366     move-object/from16 v0, v25
367
368     move-object/from16 v1, v30
369
370     invoke-virtual {v0, v1}, Ljava/lang/String;->startsWith(Ljava/lang/String;)Z
371
372     move-result v30
373
374     if-eqz v30, :cond_7
375
376     .line 148
377     const/16 v30, 0x5
378
379     move-object/from16 v0, v25
380
381     move/from16 v1, v30
382
383     invoke-virtual {v0, v1}, Ljava/lang/String;->substring(I)Ljava/lang/String;
384
385     move-result-object v3
386
387     .line 149
388     .restart local v3    # "apkName":Ljava/lang/String;
389     goto :goto_7
390
391     .line 150
392     .end local v3    # "apkName":Ljava/lang/String;
393     :cond_7
394     const-string v30, "/mnt/asec2/[2]"
395
396     move-object/from16 v0, v25
397
398     move-object/from16 v1, v30
399
400     invoke-virtual {v0, v1}, Ljava/lang/String;->startsWith(Ljava/lang/String;)Z
401
402     move-result v30
403
404     if-eqz v30, :cond_5
405
406     .line 151
407     const/16 v30, 0xe
408
409     move-object/from16 v0, v25
410
411     move/from16 v1, v30
412
413     invoke-virtual {v0, v1}, Ljava/lang/String;->substring(I)Ljava/lang/String;
414
415     move-result-object v3
416
417     .restart local v3    # "apkName":Ljava/lang/String;
418     goto :goto_7
419
420     .line 160
421     .restart local v16    # "lastIndex":I
422     :cond_8
423     const/16 v30, 0x0
424
425     move/from16 v0, v30
426
427     move/from16 v1, v16
428
429     invoke-virtual {v3, v0, v1}, Ljava/lang/String;->substring(II)Ljava/lang/String;
430
431     move-result-object v29
432
433     .line 161
434     .local v29, "tmpPackageName":Ljava/lang/String;
435     move-object/from16 v24, v29
436
437     .line 162
438     if-eqz v15, :cond_9
439
440     .line 163
441     const/16 v30, 0x2f
442
443     move/from16 v0, v30
444
445     invoke-virtual {v3, v0}, Ljava/lang/String;->lastIndexOf(I)I
446
447     move-result v16
448
449     .line 164
450     const/16 v30, -0x1
451
452     move/from16 v0, v16
453
454     move/from16 v1, v30
455
456     if-eq v0, v1, :cond_5
457
458     .line 167
459     const/16 v30, 0x0
460
461     move/from16 v0, v30
462
463     move/from16 v1, v16
464
465     invoke-virtual {v3, v0, v1}, Ljava/lang/String;->substring(II)Ljava/lang/String;
466
467     move-result-object v2
468
469     .line 169
470     .local v2, "apkInstallName":Ljava/lang/String;
471     new-instance v9, Ljava/io/File;
472
473     new-instance v30, Ljava/lang/StringBuilder;
474
475     const-string v31, "/data/app/"
476
477     invoke-direct/range {v30 .. v31}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
478
479     move-object/from16 v0, v30
480
481     invoke-virtual {v0, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
482
483     move-result-object v30
484
485     const-string v31, "/lib/x86_64/libbaiduprotect.so"
486
487     invoke-virtual/range {v30 .. v31}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
488
489     move-result-object v30
490
491     invoke-virtual/range {v30 .. v30}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
492
493     move-result-object v30
494
495     move-object/from16 v0, v30
496
497     invoke-direct {v9, v0}, Ljava/io/File;-><init>(Ljava/lang/String;)V
498
499     .line 170
500     .restart local v9    # "f":Ljava/io/File;
501     invoke-virtual {v9}, Ljava/io/File;->exists()Z
502
503     move-result v30
504
505     if-eqz v30, :cond_5
506
507     .line 171
508     move-object/from16 v24, v29
509
510     .line 172
511     new-instance v30, Ljava/lang/StringBuilder;
512
513     const-string v31, "/data/app/"
514
515     invoke-direct/range {v30 .. v31}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
516
517     move-object/from16 v0, v30
518
519     invoke-virtual {v0, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
520
521     move-result-object v30
522
523     invoke-virtual/range {v30 .. v30}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
524
525     move-result-object v4
526
527     .line 173
528     goto/16 :goto_1
529
530     .line 177
531     .end local v2    # "apkInstallName":Ljava/lang/String;
532     .end local v9    # "f":Ljava/io/File;
533     :cond_9
534     new-instance v9, Ljava/io/File;
535
536     new-instance v30, Ljava/lang/StringBuilder;
537
538     const-string v31, "/data/data/"
539
540     invoke-direct/range {v30 .. v31}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
541
542     move-object/from16 v0, v30
543
544     move-object/from16 v1, v29
545
546     invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
547
548     move-result-object v30
549
550     const-string v31, "/lib/libbaiduprotect.so"
551
552     invoke-virtual/range {v30 .. v31}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
553
554     move-result-object v30
555
556     invoke-virtual/range {v30 .. v30}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
557
558     move-result-object v30
559
560     move-object/from16 v0, v30
561
562     invoke-direct {v9, v0}, Ljava/io/File;-><init>(Ljava/lang/String;)V
563
564     .line 178
565     .restart local v9    # "f":Ljava/io/File;
566     invoke-virtual {v9}, Ljava/io/File;->exists()Z
567     :try_end_2
568     .catch Ljava/io/IOException; {:try_start_2 .. :try_end_2} :catch_0
569
570     move-result v30
571
572     if-eqz v30, :cond_5
573
574     .line 179
575     move-object/from16 v24, v29
576
577     .line 180
578     move-object/from16 v4, v25
579
580     .line 181
581     goto/16 :goto_1
582
583     .line 187
584     .end local v3    # "apkName":Ljava/lang/String;
585     .end local v5    # "br":Ljava/io/BufferedReader;
586     .end local v9    # "f":Ljava/io/File;
587     .end local v16    # "lastIndex":I
588     .end local v19    # "line":Ljava/lang/String;
589     .end local v25    # "path":Ljava/lang/String;
590     .end local v26    # "s":[Ljava/lang/String;
591     .end local v29    # "tmpPackageName":Ljava/lang/String;
592     :catch_0
593     move-exception v8
594
595     .line 188
596     .local v8, "e":Ljava/io/IOException;
597     invoke-virtual {v8}, Ljava/io/IOException;->printStackTrace()V
598
599     goto/16 :goto_2
600
601     .line 196
602     .end local v8    # "e":Ljava/io/IOException;
603     :cond_a
604     const-string v28, "libbaiduprotect_x86.so"
605
606     .restart local v28    # "soname":Ljava/lang/String;
607     goto/16 :goto_3
608
609     .line 219
610     .restart local v7    # "dataFolder":Ljava/lang/String;
611     .restart local v9    # "f":Ljava/io/File;
612     .restart local v12    # "fileModified":J
613     .restart local v17    # "libPath":Ljava/lang/String;
614     .restart local v18    # "libTargetFolder":Ljava/lang/String;
615     .restart local v20    # "localZipEntry":Ljava/util/zip/ZipEntry;
616     .restart local v21    # "localZipInputStream":Ljava/util/zip/ZipInputStream;
617     .restart local v22    # "newFileModified":J
618     .restart local v27    # "soEntryName":Ljava/lang/String;
619     :cond_b
620     :try_start_3
621     invoke-virtual/range {v20 .. v20}, Ljava/util/zip/ZipEntry;->getName()Ljava/lang/String;
622
623     move-result-object v30
624
625     move-object/from16 v0, v30
626
627     move-object/from16 v1, v27
628
629     invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
630
631     move-result v30
632
633     if-eqz v30, :cond_f
634
635     .line 220
636     invoke-virtual/range {v20 .. v20}, Ljava/util/zip/ZipEntry;->getTime()J
637
638     move-result-wide v22
639
640     .line 221
641     new-instance v10, Ljava/io/File;
642
643     move-object/from16 v0, v17
644
645     invoke-direct {v10, v0}, Ljava/io/File;-><init>(Ljava/lang/String;)V
646     :try_end_3
647     .catch Ljava/io/IOException; {:try_start_3 .. :try_end_3} :catch_1
648
649     .line 222
650     .end local v9    # "f":Ljava/io/File;
651     .local v10, "f":Ljava/io/File;
652     :try_start_4
653     invoke-virtual {v10}, Ljava/io/File;->exists()Z
654
655     move-result v30
656
657     if-eqz v30, :cond_d
658
659     .line 223
660     invoke-virtual {v10}, Ljava/io/File;->lastModified()J
661
662     move-result-wide v12
663
664     .line 224
665     cmp-long v30, v12, v22
666
667     if-nez v30, :cond_c
668
669     .line 226
670     invoke-virtual/range {v21 .. v21}, Ljava/util/zip/ZipInputStream;->closeEntry()V
671
672     move-object v9, v10
673
674     .line 227
675     .end local v10    # "f":Ljava/io/File;
676     .restart local v9    # "f":Ljava/io/File;
677     goto/16 :goto_5
678
679     .line 229
680     .end local v9    # "f":Ljava/io/File;
681     .restart local v10    # "f":Ljava/io/File;
682     :cond_c
683     invoke-virtual {v10}, Ljava/io/File;->delete()Z
684
685     .line 233
686     :cond_d
687     new-instance v11, Ljava/io/FileOutputStream;
688
689     move-object/from16 v0, v17
690
691     invoke-direct {v11, v0}, Ljava/io/FileOutputStream;-><init>(Ljava/lang/String;)V
692
693     .line 234
694     .local v11, "fo":Ljava/io/FileOutputStream;
695     const/16 v30, 0x400
696
697     move/from16 v0, v30
698
699     new-array v6, v0, [B
700
701     .line 236
702     .local v6, "buffer":[B
703     :goto_8
704     move-object/from16 v0, v21
705
706     invoke-virtual {v0, v6}, Ljava/util/zip/ZipInputStream;->read([B)I
707
708     move-result v14
709
710     .line 237
711     .local v14, "i":I
712     const/16 v30, -0x1
713
714     move/from16 v0, v30
715
716     if-ne v14, v0, :cond_e
717
718     .line 242
719     invoke-virtual {v11}, Ljava/io/FileOutputStream;->flush()V
720
721     .line 243
722     invoke-virtual {v11}, Ljava/io/FileOutputStream;->close()V
723
724     .line 244
725     invoke-virtual/range {v21 .. v21}, Ljava/util/zip/ZipInputStream;->closeEntry()V
726
727     .line 247
728     new-instance v9, Ljava/io/File;
729
730     move-object/from16 v0, v17
731
732     invoke-direct {v9, v0}, Ljava/io/File;-><init>(Ljava/lang/String;)V
733     :try_end_4
734     .catch Ljava/io/IOException; {:try_start_4 .. :try_end_4} :catch_2
735
736     .line 248
737     .end local v10    # "f":Ljava/io/File;
738     .restart local v9    # "f":Ljava/io/File;
739     :try_start_5
740     invoke-virtual {v9}, Ljava/io/File;->exists()Z
741
742     move-result v30
743
744     if-eqz v30, :cond_1
745
746     .line 249
747     move-wide/from16 v0, v22
748
749     invoke-virtual {v9, v0, v1}, Ljava/io/File;->setLastModified(J)Z
750     :try_end_5
751     .catch Ljava/io/IOException; {:try_start_5 .. :try_end_5} :catch_1
752
753     goto/16 :goto_5
754
755     .line 259
756     .end local v6    # "buffer":[B
757     .end local v11    # "fo":Ljava/io/FileOutputStream;
758     .end local v14    # "i":I
759     .end local v20    # "localZipEntry":Ljava/util/zip/ZipEntry;
760     .end local v21    # "localZipInputStream":Ljava/util/zip/ZipInputStream;
761     .end local v27    # "soEntryName":Ljava/lang/String;
762     :catch_1
763     move-exception v8
764
765     .line 260
766     .restart local v8    # "e":Ljava/io/IOException;
767     :goto_9
768     invoke-virtual {v8}, Ljava/io/IOException;->printStackTrace()V
769
770     goto/16 :goto_6
771
772     .line 240
773     .end local v8    # "e":Ljava/io/IOException;
774     .end local v9    # "f":Ljava/io/File;
775     .restart local v6    # "buffer":[B
776     .restart local v10    # "f":Ljava/io/File;
777     .restart local v11    # "fo":Ljava/io/FileOutputStream;
778     .restart local v14    # "i":I
779     .restart local v20    # "localZipEntry":Ljava/util/zip/ZipEntry;
780     .restart local v21    # "localZipInputStream":Ljava/util/zip/ZipInputStream;
781     .restart local v27    # "soEntryName":Ljava/lang/String;
782     :cond_e
783     const/16 v30, 0x0
784
785     :try_start_6
786     move/from16 v0, v30
787
788     invoke-virtual {v11, v6, v0, v14}, Ljava/io/FileOutputStream;->write([BII)V
789     :try_end_6
790     .catch Ljava/io/IOException; {:try_start_6 .. :try_end_6} :catch_2
791
792     goto :goto_8
793
794     .line 259
795     .end local v6    # "buffer":[B
796     .end local v11    # "fo":Ljava/io/FileOutputStream;
797     .end local v14    # "i":I
798     :catch_2
799     move-exception v8
800
801     move-object v9, v10
802
803     .end local v10    # "f":Ljava/io/File;
804     .restart local v9    # "f":Ljava/io/File;
805     goto :goto_9
806
807     .line 255
808     :cond_f
809     :try_start_7
810     invoke-virtual/range {v21 .. v21}, Ljava/util/zip/ZipInputStream;->closeEntry()V
811     :try_end_7
812     .catch Ljava/io/IOException; {:try_start_7 .. :try_end_7} :catch_1
813
814     goto/16 :goto_4
815 .end method

smali指令文件

1     private static void loadX86Library() {
2         // :( Parsing error. Please contact me.
3     }

smali2java逆向出的结果

  1 private static void loadX86Library()
  2     {
  3         boolean flag;
  4         Object obj;
  5         Object obj1;
  6         Object obj2;
  7         Object obj3;
  8         Object obj5;
  9         Object obj6;
 10         obj2 = null;
 11         obj1 = null;
 12         obj5 = null;
 13         obj6 = null;
 14         flag = is64BitEnv();
 15         obj3 = obj5;
 16         obj = obj1;
 17         BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/self/maps")));
 18         obj3 = obj5;
 19         obj = obj1;
 20         String s = bufferedreader.readLine();
 21           goto _L1
 22 _L29:
 23         obj3 = obj1;
 24         obj = obj2;
 25         bufferedreader.close();
 26         obj = obj2;
 27 _L17:
 28         int i;
 29         Object obj4;
 30         String s1;
 31         if(flag)
 32             obj2 = "libbaiduprotect_x86_64.so";
 33         else
 34             obj2 = "libbaiduprotect_x86.so";
 35         if(obj1 == null || obj == null) goto _L3; else goto _L2
 36 _L2:
 37         obj = (new StringBuilder(String.valueOf(getDataFolder(((String) (obj)))))).append(((String) (obj))).append("/.x86lib/").toString();
 38         obj3 = (new StringBuilder(String.valueOf(obj))).append(((String) (obj2))).toString();
 39         obj = new File(((String) (obj)));
 40         if(!((File) (obj)).exists())
 41             ((File) (obj)).mkdir();
 42         obj2 = (new StringBuilder("assets/")).append(((String) (obj2))).toString();
 43         obj = new ZipInputStream(new FileInputStream(((String) (obj1))));
 44 _L25:
 45         obj1 = ((ZipInputStream) (obj)).getNextEntry();
 46         if(obj1 != null) goto _L5; else goto _L4
 47 _L4:
 48         ((ZipInputStream) (obj)).close();
 49 _L22:
 50         System.load(((String) (obj3)));
 51 _L3:
 52         return;
 53 _L27:
 54         obj1 = obj2;
 55         obj3 = obj5;
 56         obj = obj2;
 57         if(!s.endsWith(".apk")) goto _L7; else goto _L6
 58 _L6:
 59         obj3 = obj5;
 60         obj = obj2;
 61         System.out.println((new StringBuilder("Wigan:line=")).append(s).toString());
 62         obj3 = obj5;
 63         obj = obj2;
 64         obj1 = s.split(" ");
 65         obj3 = obj5;
 66         obj = obj2;
 67         s1 = obj1[obj1.length - 1];
 68         obj3 = obj5;
 69         obj = obj2;
 70         if(s1.startsWith("/mnt/asec/")) goto _L9; else goto _L8
 71 _L8:
 72         obj3 = obj5;
 73         obj = obj2;
 74         if(!s1.startsWith("/data/app/")) goto _L10; else goto _L9
 75 _L9:
 76         obj3 = obj5;
 77         obj = obj2;
 78         s = s1.substring(10);
 79 _L13:
 80         obj3 = obj5;
 81         obj = obj2;
 82         i = s.lastIndexOf(‘-‘);
 83         if(i != -1) goto _L12; else goto _L11
 84 _L11:
 85         obj1 = obj2;
 86 _L7:
 87         obj3 = obj5;
 88         obj = obj1;
 89         s = bufferedreader.readLine();
 90         obj2 = obj1;
 91         continue; /* Loop/switch isn‘t completed */
 92 _L10:
 93         obj3 = obj5;
 94         obj = obj2;
 95         if(!s1.startsWith("/app/"))
 96             break MISSING_BLOCK_LABEL_464;
 97         obj3 = obj5;
 98         obj = obj2;
 99         s = s1.substring(5);
100           goto _L13
101         obj1 = obj2;
102         obj3 = obj5;
103         obj = obj2;
104         if(!s1.startsWith("/mnt/asec2/[2]")) goto _L7; else goto _L14
105 _L14:
106         obj3 = obj5;
107         obj = obj2;
108         s = s1.substring(14);
109           goto _L13
110 _L12:
111         obj3 = obj5;
112         obj = obj2;
113         obj2 = s.substring(0, i);
114         obj4 = obj2;
115         if(!flag)
116             break MISSING_BLOCK_LABEL_650;
117         obj3 = obj5;
118         obj = obj4;
119         i = s.lastIndexOf(‘/‘);
120         obj1 = obj4;
121         if(i == -1) goto _L7; else goto _L15
122 _L15:
123         obj3 = obj5;
124         obj = obj4;
125         s1 = s.substring(0, i);
126         obj1 = obj4;
127         obj3 = obj5;
128         obj = obj4;
129         if(!(new File((new StringBuilder("/data/app/")).append(s1).append("/lib/x86_64/libbaiduprotect.so").toString())).exists()) goto _L7; else goto _L16
130 _L16:
131         obj3 = obj5;
132         obj = obj2;
133         boolean flag1;
134         try
135         {
136             obj1 = (new StringBuilder("/data/app/")).append(s).toString();
137             continue; /* Loop/switch isn‘t completed */
138         }
139         // Misplaced declaration of an exception variable
140         catch(Object obj1)
141         {
142             ((IOException) (obj1)).printStackTrace();
143             obj1 = obj3;
144         }
145           goto _L17
146         obj3 = obj5;
147         obj = obj4;
148         flag1 = (new File((new StringBuilder("/data/data/")).append(((String) (obj2))).append("/lib/libbaiduprotect.so").toString())).exists();
149         obj1 = obj4;
150         if(!flag1) goto _L7; else goto _L18
151 _L18:
152         obj1 = s1;
153         continue; /* Loop/switch isn‘t completed */
154 _L5:
155         long l;
156         if(!((ZipEntry) (obj1)).getName().equals(obj2))
157             break MISSING_BLOCK_LABEL_891;
158         l = ((ZipEntry) (obj1)).getTime();
159         obj1 = new File(((String) (obj3)));
160 label0:
161         {
162             if(!((File) (obj1)).exists())
163                 break MISSING_BLOCK_LABEL_789;
164             if(((File) (obj1)).lastModified() != l)
165                 break label0;
166             ((ZipInputStream) (obj)).closeEntry();
167         }
168           goto _L4
169         ((File) (obj1)).delete();
170         byte abyte0[];
171         obj1 = new FileOutputStream(((String) (obj3)));
172         abyte0 = new byte[1024];
173 _L23:
174         i = ((ZipInputStream) (obj)).read(abyte0);
175         if(i != -1) goto _L20; else goto _L19
176 _L19:
177         ((FileOutputStream) (obj1)).flush();
178         ((FileOutputStream) (obj1)).close();
179         ((ZipInputStream) (obj)).closeEntry();
180         obj1 = new File(((String) (obj3)));
181         if(!((File) (obj1)).exists()) goto _L4; else goto _L21
182 _L21:
183         ((File) (obj1)).setLastModified(l);
184           goto _L4
185         obj;
186 _L24:
187         ((IOException) (obj)).printStackTrace();
188           goto _L22
189 _L20:
190         ((FileOutputStream) (obj1)).write(abyte0, 0, i);
191           goto _L23
192         obj;
193           goto _L24
194         ((ZipInputStream) (obj)).closeEntry();
195           goto _L25
196 _L1:
197         if(s != null) goto _L27; else goto _L26
198 _L26:
199         obj1 = obj6;
200         if(true) goto _L29; else goto _L28
201 _L28:
202     }

DJ Java Decomplier逆向出来的结果

baiduprotect`StubApplication.loadX86Library 手工逆向的结果

这个函数逻辑是:

1. 描述内存映射区间,找出加载的apk包名。

2. 在/data/app,/mnt/asec,或/mnt/asec2[2]目录下找出安装的apk,(所谓的安装就是将apk复制到固定目录下)。

3. 用压缩包方式打开apk包,找里面的assets/libbaiduprotect_${arch}.so库文件。

4. 将找到的so库文件释放到/data/data/${appname}/.${arch}目录下。

5. 更新这个so库文件的修改时间。

6. 加载这个so库文件。

虽然在/data/lib/${appname}目录已经有一个libbaiduprotect.so,但那只是个晃。加载完真正的so后,就会将apk包内的assest/baiduprotect1.jar释放到/data/data/${appname}/.1/1.jar,再将其转换成classes.dex。这两个文件都是以加密的方式,放在存储设备上的。这才是被保护的app的正体,并且baiduprotect不会直接去加载这个dex,而是在内存中解密后,用libdvm.so的jni去进行内存加载。所以你不能通过映射区间找出其映射的位置,如果你想dump它的内存映像,就会被baiduprotect发现终止app。

时间: 2025-01-14 15:01:09

android逆向总结的相关文章

android逆向入门及工具下载

本文所用到的工具下载: 链接:http://pan.baidu.com/s/1i3uw4NN 密码:8hz5 最近在研究如何逆向android的app,于是就有了这篇android逆向入门的总结回馈互联网. 由于Android的.apk文件实际上就是一个zip文件,修改文件后缀后直接可以打开,效果如下图所示: 里面包含了的文件有: META-INF:这个文件夹是用于保存签名文件,确保包的完整性的 res:apk所要用的资源文件,都是原封不动地保存,我们可以直接提取出来,做汉化时就可以直接阅读st

Android逆向从未如此简单

哈,又标题党了..不过我一定竭尽所能,写一篇最亲民的入门文章. 本文仅供学习交流之用,切勿用于非法用途,读者若运用所学知识,进行非法任何商业目的或者非法牟利,一切责任由操作者自行承担,与本人无关.希望读者仅仅从了解原理,保护自身APP尽量减少危害出发来阅读本文. 本文发布自wing的地方酒馆,转载请注明出处. 本文以一个最简单的例子,来教给大家Android逆向入门的一些知识.所以首先我们需要准备一个APK,做的简单一些,就是一个EditText,已经一个按钮,模拟验证注册码. 当验证码填写正确

Android 逆向初探(一)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Helvetica; color: #000000 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Helvetica; color: #000000; min-height: 13.0px } span.s1 { } span.Apple-tab-span { white-space: pre } 逆向分析是一门技术,也是一门艺

Android逆向之动态调试so库JNI_Onload函数-----基于IDA实现

之前看过吾爱破解论坛一个关于Android'逆向动态调试的经验总结帖,那个帖子写的很好,对Android的脱壳和破解很有帮助,之前我们老师在上课的时候也讲过集中调试的方法,但是现在不太实用.对吾爱破解论坛的该贴,我也是看了很多遍,自己也查了不少资料,但是自己动手的时候总觉比较繁琐,并且很多细节的地方没有注意到,按照那个帖子尝试了几遍但是却出现了错误(后面会提到),今天周末重新拾起来试了试,终于把遇到的问题给解决了,顺便做个记录以免忘记了,其中的一些细节我也不是太明白,忘知道的人给指出. 第一步.

Android逆向分析初体验

一.    准备知识 1.             懂Java Android开发. 2.             懂NDK ,C 语言 Android 动态链接库.SO开发. 3.             懂Android反编译Smali 语法. 4.             懂adb 和 jdb 等等工具使用. 5.             懂IDA 调试(远程动态调试APK和本地静态调试.SO文件) 6.             懂Arm汇编语法(因为移动设备芯片是Arm架构的,不是Int

Android逆向-Android基础逆向(2-2)

[toc] #0x00 前言##不知所以然,请看Android逆向-Android基础逆向(1)Android逆向-Android基础逆向(2)##以及java系列:Android逆向-java代码基础(1)Android逆向-java代码基础(2)Android逆向-java代码基础(3)Android逆向-java代码基础(4)Android逆向-java代码基础(5)Android逆向-java代码基础(6)Android逆向-java代码基础(7)Android逆向-java代码基础(8

Android逆向系列文章— Android基础逆向(6)

本文作者:HAI_ 0×00 前言 不知所以然,请看 Android逆向-Android基础逆向(1) Android逆向-Android基础逆向(2) Android逆向-Android基础逆向(2-2) Android逆向-Android基础逆向(2-3补充篇) Android逆向-Android基础逆向(3) Android逆向-Android基础逆向(4) Android逆向-Android基础逆向(4-2) Android逆向-Android基础逆向(5) 以及java系列: Andr

Android逆向之Java常用类

Android逆向之Java常用类 包装类 byte ­> Byte int ­> Integer short ­> Short long ­> Long float ­> Float double ­> Double boolean ­> Boolean char ­> Character   public static void test0(){        int n =123456;      // 整型转字符串         String nu

Android逆向之旅---反编译利器Apktool和Jadx源码分析以及错误纠正

一.前言 在之前的破解过程中可以看到我们唯一离不开的一个神器那就是apktool了,这个工具多强大就不多说了,但是如果没有他我们没法涉及到后面的破解工作了,这个工具是开源的,也是使用Java语言开发的,代码相对简单,我们今天就来分析一下他的大体逻辑,注意是大体逻辑哦,因为如果要一行一行代码分析,首先觉得没必要,其次浪费时间,有了源码,谁看不懂呢.至于为什么要分析这个工具其实原因只有一个,就是我们在之前的反编译过程中会发现,总是有那么几个apk应用不让我们那么容易的反编译,他们就利用apktool

Android逆向之旅---动态方式破解apk进阶篇(IDA调试so源码)

一.前言 今天我们继续来看破解apk的相关知识,在前一篇:Eclipse动态调试smali源码破解apk 我们今天主要来看如何使用IDA来调试Android中的native源码,因为现在一些app,为了安全或者效率问题,会把一些重要的功能放到native层,那么这样一来,我们前篇说到的Eclipse调试smali源码就显得很无力了,因为核心的都在native层,Android中一般native层使用的是so库文件,所以我们这篇就来介绍如何调试so文件的内容,从而让我们破解成功率达到更高的一层.