首先项目里的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
  3.  
  4. .prologue
  5. .line
  6. const/ v24, 0x0
  7.  
  8. .line
  9. .local v24, "packageName":Ljava/lang/String;
  10. const/ v4, 0x0
  11.  
  12. .line
  13. .local v4, "apkPath":Ljava/lang/String;
  14. invoke-static {}, Lcom/baidu/protect/StubApplication;->is64BitEnv()Z
  15.  
  16. move-result v15
  17.  
  18. .line
  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
  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
  35. move-object/from16 v0, v30
  36.  
  37. invoke-direct {v5, v0}, Ljava/io/BufferedReader;-><init>(Ljava/io/Reader;)V
  38.  
  39. .line
  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
  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
  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
  62. const-string v28, "libbaiduprotect_x86_64.so"
  63.  
  64. .line
  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
  72. const-wide/ v12, 0x0
  73.  
  74. .line
  75. .local v12, "fileModified":J
  76. const-wide/ v22, 0x0
  77.  
  78. .line
  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
  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
  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
  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
  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
  151. invoke-virtual {v9}, Ljava/io/File;->mkdir()Z
  152.  
  153. .line
  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
  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
  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
  198. .local v20, "localZipEntry":Ljava/util/zip/ZipEntry;
  199. if-nez v20, :cond_b
  200.  
  201. .line
  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
  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
  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
  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
  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
  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
  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
  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
  316. :cond_4
  317. const/ 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
  328. .local v3, "apkName":Ljava/lang/String;
  329. :goto_7
  330. const/ 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
  339. .local v16, "lastIndex":I
  340. const/ 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
  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/ :goto_0
  359.  
  360. .line
  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
  377. const/ 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
  388. .restart local v3 # "apkName":Ljava/lang/String;
  389. goto :goto_7
  390.  
  391. .line
  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
  407. const/ 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
  421. .restart local v16 # "lastIndex":I
  422. :cond_8
  423. const/ 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
  434. .local v29, "tmpPackageName":Ljava/lang/String;
  435. move-object/from16 v24, v29
  436.  
  437. .line
  438. if-eqz v15, :cond_9
  439.  
  440. .line
  441. const/ 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
  450. const/ 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
  459. const/ 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
  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
  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
  508. move-object/from16 v24, v29
  509.  
  510. .line
  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
  528. goto/ :goto_1
  529.  
  530. .line
  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
  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
  575. move-object/from16 v24, v29
  576.  
  577. .line
  578. move-object/from16 v4, v25
  579.  
  580. .line
  581. goto/ :goto_1
  582.  
  583. .line
  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
  596. .local v8, "e":Ljava/io/IOException;
  597. invoke-virtual {v8}, Ljava/io/IOException;->printStackTrace()V
  598.  
  599. goto/ :goto_2
  600.  
  601. .line
  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/ :goto_3
  608.  
  609. .line
  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
  636. invoke-virtual/range {v20 .. v20}, Ljava/util/zip/ZipEntry;->getTime()J
  637.  
  638. move-result-wide v22
  639.  
  640. .line
  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
  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
  660. invoke-virtual {v10}, Ljava/io/File;->lastModified()J
  661.  
  662. move-result-wide v12
  663.  
  664. .line
  665. cmp-long v30, v12, v22
  666.  
  667. if-nez v30, :cond_c
  668.  
  669. .line
  670. invoke-virtual/range {v21 .. v21}, Ljava/util/zip/ZipInputStream;->closeEntry()V
  671.  
  672. move-object v9, v10
  673.  
  674. .line
  675. .end local v10 # "f":Ljava/io/File;
  676. .restart local v9 # "f":Ljava/io/File;
  677. goto/ :goto_5
  678.  
  679. .line
  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
  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
  694. .local v11, "fo":Ljava/io/FileOutputStream;
  695. const/ v30, 0x400
  696.  
  697. move/from16 v0, v30
  698.  
  699. new-array v6, v0, [B
  700.  
  701. .line
  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
  711. .local v14, "i":I
  712. const/ v30, -0x1
  713.  
  714. move/from16 v0, v30
  715.  
  716. if-ne v14, v0, :cond_e
  717.  
  718. .line
  719. invoke-virtual {v11}, Ljava/io/FileOutputStream;->flush()V
  720.  
  721. .line
  722. invoke-virtual {v11}, Ljava/io/FileOutputStream;->close()V
  723.  
  724. .line
  725. invoke-virtual/range {v21 .. v21}, Ljava/util/zip/ZipInputStream;->closeEntry()V
  726.  
  727. .line
  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
  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
  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/ :goto_5
  754.  
  755. .line
  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
  766. .restart local v8 # "e":Ljava/io/IOException;
  767. :goto_9
  768. invoke-virtual {v8}, Ljava/io/IOException;->printStackTrace()V
  769.  
  770. goto/ :goto_6
  771.  
  772. .line
  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/ 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
  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
  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/ :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。

android逆向总结的更多相关文章

  1. [转]Android逆向之动态调试总结

    一.在SO中关键函数上下断点 刚学逆向调试时.大多都满足于在SO中某关键函数上下断点.然后通过操作应用程序,去触发这个断点,然后进行调试 详细的步骤可以参见非虫大大的<Android软件安全与逆 ...

  2. android逆向学习小结--CrackMe_1

    断断续续的总算的把android开发和逆向的这两本书看完了,虽然没有java,和android开发的基础,但总体感觉起来还是比较能接收的,毕竟都是触类旁通的.当然要深入的话还需要对这门语言的细节特性和 ...

  3. Android逆向之so的半自动化逆向

    因为工作需要,转型干android逆向,有几个月了.不过对于so的逆向,任然停留在,难难难的阶段,虽然上次自己还是逆向了一个15k左右的小so文件,但是,那个基本是靠,一步一步跟代码,查看堆栈信息来自 ...

  4. Android逆向破解表单注册程序

    Android逆向破解表单注册程序 Android开发 ADT: android studio(as) 程序界面如下,注册码为6位随机数字,注册成功时弹出通知注册成功,注册失败时弹出通知注册失败. 布 ...

  5. Android逆向破解表单登录程序

    Android逆向破解表单登录程序 Android开发 ADT: android studio(as) 程序界面如下,登录成功时弹出通知登录成功,登录失败时弹出通知登录失败. 布局代码 <?xm ...

  6. Android逆向之静态分析

    想必打过CTF的小伙伴多多少少都触过Android逆向,所以斗哥将给大家整一期关于Android逆向的静态分析与动态分析.本期先带来Android逆向的静态分析,包括逆向工具使用.文件说明.例题解析等 ...

  7. Android 逆向实战篇(加密数据包破解)

    1. 实战背景由于工作需要,要爬取某款App的数据,App的具体名称此处不便透露,避免他们发现并修改加密逻辑我就得重新破解了. 爬取这款App时发现,抓包抓到的数据是加密过的,如图1所示(原数据较长, ...

  8. 【转】Android逆向入门流程

    原文:https://www.jianshu.com/p/71fb7ccc05ff 0.写在前面 本文是笔者自学笔记,以破解某目标apk的方式进行学习,中间辅以原理性知识,方便面试需求. 参考文章的原 ...

  9. Android逆向之smali

    Android逆向之smali 头信息 smail文件前三行 .class <访问权限> [关键修饰字] <类名>; .super <父类名>; .source & ...

  10. Android逆向学习资料

    Android逆向基础之Dalvik虚拟机: https://lyxw.github.io/archivers/Android%E9%80%86%E5%90%91%E5%9F%BA%E7%A1%80% ...

随机推荐

  1. std::multimap

    标准库还定义了一个 multimap 容器,它与 map 类似,所不同的是它允许重复键. 成员函数 insert() make_pair() 辅助函数来完成此任务. find(k) 返回指向第一个与键 ...

  2. PowerShell渗透--Empire(二)

    权限提升 Bypass UAC usemodule powershell/privesc/bypassuac 设置listener execute list查看 usemodule powershel ...

  3. echarts折线图动态改变数据时的一个bug

    echarts折线图中当增加dataZoom,修改start大于0的时候,会出现折线混乱,变成竖直的线,绘制有问题. 解决方法,在dataZoom中增加filterMode: 'empty' http ...

  4. Sentinel Getting Started And Integration of Spring Cloud Alibaba Tutorials

    原文链接:Sentinel Getting Started And Integration of Spring Cloud Alibaba Tutorials Sentinel Getting Sta ...

  5. vue-cli3 搭建 vue 项目

    vue-cli3 搭建 vue 项目 项目是在mac的环境下配置的 win的同学请移步[https://www.cnblogs.com/zhaomeizi/p/8483597.html] 安装 nod ...

  6. 百万年薪python之路 -- 面向对象之:类空间问题以及类之间的关系

    面向对象之:类空间问题以及类之间的关系 1.从空间角度研究类 1.何处添加对象属性 class A: def __init__(self,name): self.name = name def fun ...

  7. Veins(车载通信仿真框架)入门教程

    Veins入门教程——教你如何下手研究 目录 Veins入门教程——教你如何下手研究 目录 废话少说! 讲解omnetpp.ini!(挑关键的) 讲解RSUExampleScnario.ned! 注意 ...

  8. APP打包设置程序版本号

    正确设置方式是: 注意,以下修改不会起作用<manifestxmlns:android="http://schemas.android.com/apk/res/android" ...

  9. 怎样通过excel录入来批量造数据

    背景: 自动化测试除了验证系统功能外,还能够为测试人员根据测试要求造数据实现测试需要!但是一般的自动化测试,都是在编写脚本的时候,写死在程序里的.所以本文是为了在满足系统操作流程的基础上,根据测试的要 ...

  10. Scrapy 之settings配置

    BOT_NAME 默认: 'scrapybot' 当您使用 startproject 命令创建项目时其也被自动赋值. ROBOTSTXT_OBEY = False 是否遵守rebotes.txt协议 ...