本文不是讲解传统源码的阅读, 而是『别人的APK源码』该怎么阅读。
此前,由于工作的原因,反编译竞品SDK,通过逆向的手段修复其源码并编译运行。
前端之下,本无秘密。相对于前端源码,Android APK源码并不是那么容易获取。由于Android这样一个开发的系统和使用java编写应用使得源码的获取成为现实。本文不过多介绍如果脱壳dex,或者动态调试apk,着重聊一下如何阅读jadx APK/DEX/JAR之后的『源码』。
什么是反编译?Executable->Human Readable
:机器可执行转变为程序员可读。后面通过APK打包过程分析打包产物
和从打包产物到可读产物
。
注:apk反编译生成的一般为Smali或java decompiled(后简称jd)代码。
原官网较为完整的打包过程:
APK打包流程
打包资源文件,生成R.java文件
通过aapt打包res资源文件,生成R.java、resources.arsc和res文件(二进制 & 非二进制如res/raw和pic保持原样)
处理aidl文件,生成相应的Java文件
编译项目源代码,生成class文件
通过Java Compiler编译R.java、Java接口文件、Java源文件,生成.class文件,生成的class文件位于工程中的bin/classes目录下。
转换所有的class文件,生成classes.dex文件
dx工具生成可供Android系统Dalvik虚拟机执行的classes.dex文件,该工具位于android-sdk/platform-tools 目录下。
任何第三方的libraries和.class文件都会被转换成.dex文件。
dx工具的主要工作是将Java字节码转成成Dalvik字节码、压缩常量池、消除冗余信息等。
打包生成APK文件
通过apkbuilder工具,将aapt生成的resources.arsc和res文件、assets文件和classes.dex一起打包生成apk
对APK文件进行签名
一旦APK文件生成,它必须被签名才能被安装在设备上。
通过Jarsigner工具,对上面的apk进行debug或release签名
在开发过程中,主要用到的就是两种签名的keystore。一种是用于调试的debug.keystore,它主要用于调试,在Eclipse或者Android
Studio中直接run以后跑在手机上的就是使用的debug.keystore。另一种就是用于发布正式版本的keystore。
对签名后的APK文件进行对齐处理
通过zipalign工具,将签名后的apk进行对齐处理。
对齐的主要过程是将APK包中所有的资源文件距离文件起始偏移为4字节整数倍,这样通过内存映射访问apk文件时的速度会更快。对齐的作用就是减少运行时内存的使用。
考虑到Gradle作为主要构建工具,官方后来缩减版(可以看谷歌的变化之快):
典型 Android 应用模块的构建流程
APK文件结构(通过解压缩查看)
Apks are nothing more than a zip file containing resources and assembled java code
$ unzip testapp.apk
Archive: testapp.apk
inflating: AndroidManifest.xml
inflating: classes.dex
extracting: res/drawable-hdpi/ic_launcher.png
inflating: res/xml/literals.xml
inflating: res/xml/references.xml
extracting: resources.arsc
无法查看目录中资源文件
查看 AndroidManifest.xml、resource.arsc编译后的二进制文件,后面讲解怎么查看APK、dex和反编译后端资源文件。
AAR文件结构
注意:lib中jar文件依然存在,在APK打包时候会合入.dex中。
以下,介绍一些java decompiled
的工具。
Apktool
apktool工具官网的介绍 :
editing or viewing a compiled file is next to impossible. That is where Apktool >comes into play.
由于apktool实在太常用,甚至有许多人以为是官网给出的打包工具。
$ apktool d testapp.apk//apk 、jar
I: Using Apktool 2.0.0 on testapp.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: 1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Copying assets and libs...
$
很多APK通过apktool的bug加壳之后不能反编译。
$ apktool b foo.jar.out
# builds foo.jar.out folder into foo.jar.out/dist/foo.jar file
dex2jar
功能:将 dex 文件还原成为 jar 文件;d2j-dex2jar.sh dex文件名
,
将 dex 文件还原成为 smali 文件;d2j-dex2smali.bat dex文件名
功能:查看 dex 文件还原成为 jar 文件代码;将 jar 文件中所有的 class 文件转换成为 java 文件
2015 年开始就停止了维护
jadx
功能:可直接浏览 Apk、dex、jar
带全局搜索功能,很好用,通过保存全部可以获得所以反编译的java代码。
enjarify
Google 出品
环境:Python3
可直接将 apk 文件还原成为 jar 文件,也可以和 dex2jar 一样,直接操作某个dex
ClassyShark
Google 出品
功能:可直接浏览 Apk,支持对.dex, .aar, .so,.apk, .jar, .class等文件的操作,查看统计、依赖等
优点:轻量
感兴趣请阅读以下参考
http://www.jianshu.com/p/8e8b88ea2197
https://github.com/borisf/classyshark-user-guide
背景故事很有趣。
网络抓包分析工具
1.思路:
2.修复java代码过程(不同工具反编译字节码得到java文件不相同)
匿名内部类闭包、自引用(this)、匿名类嵌套匿名类(超难解)、引用父类成员或方法与当前所在类同名
运行时类型丢失、泛型类型被擦除、资源和字符串常量化等
局部变量声明丢失
反编译失败型(比较少,往往是第一个入口类)
位置错落型
太多不一一列举,感兴趣的可以试着反编译看一下。
上面介绍的主要是一些jd方面的技术。jd之后的代码可以简单理解混淆后的代码,因为JVM的代码优化和逆向的语法问题使得代码不能完全运行,只要修复还是可以还原的(针对非大型项目)。代码量太多(超过5W行)只能慢慢阅读逆向代码了。阅读代码代码时需要注意this指针,同包下不需要导入的特性,可以快速定位类和方法。
1 当前端传送密码到后端时候,需要进行两次MD5加密,登录和注册时的加解密流程是怎么样的?前端和后端加密都可以规定使用密码的某几位作为盐进行加解密操作,而这种约定俗成的盐选取操作只有程序员自己知道,所以安全性较高,不需要前后端传送盐。 或者是前端和后端开发人员在开发的时候商量好这个第一层加密的盐,分别在前端和后端存储起来,这样前端在每次发送密码的时候都使用md5配合盐进行加密,服务器因为知道盐,所以可以自然的解密出来。答:1 无论是注册还是登录,密码的第一次md5加密是在前端完成的,第二次加密都是在侯
传送门:poj 3080题意:给出一系列长度为60的字符串,让求出它们的最大的公共子序列题解:1、既然是公共子序列,那么在其中一个数据里面可能会有一个子串是满足条件的,那么我们可以将其中的一个串作为基底(这里我是把第一个串作为基底)进行个计算即可。实现这一步操作我用到了C++里面的substr()函数,这个函数的作用是将string中的从第一个变量位置开始的字符到长度为第二...
目录问题 A: 计算组合数问题 B: 求组合数问题 A: 计算组合数题目描述编制程序,输入m,n(M>=n>=0)后,计算下列表达式的值并输出: m! n! (m-n)!要求将计算阶乘运算的函数写为fact(n),函数返回值的类型为float输入m n输出对应表达式的值样例输入2 1样例输出...
文章由CSDN陈明于2015-04-09 23:19分享 创造历史之举在过去长达十多年的时间里,密歇根州大学电气与计算机科学系的David Blaauw团队一直在做一件事情,那就是打造体积只有1立方毫米的微型计算机Michigan Micro Mote(即M³),这是一次创造历史的壮举。这是M3与一枚硬币的对比:这可能是全球最小的自动化计算机设备
太激动了!在一天的不懈努力下终于找到了解决办法~哈哈哈啊哈哈~所以有必要记录一下!!!之前eclipse一切正常,今天装了某语言插件后运行一段语言也很正常,就是退出之后不知道误动了哪里,导致在进入Eclipse出现报错:看了很多关于eclipse报错13的问题,得到的答案大部分都是jdk和eclipse版本不一致导致的,又是删除环境变量了,又或是在Eclipse的安装目录中找到eclipse.ini文件,在-vm中增加正确的JDK安装目录,若没有则在plugins后第三行加入-vm。
明天正好就是正式接触ACM一年了vj:84codeforce:115洛谷:206CDOJ: 大概三四十道(不用了)UESTC OJ :58一年下来 就写了五百多道题....接触ACM的第一年打了很好的基础,只能说是编程和简单思维上吧。现在开始才是真正的训练了。正经脸:不埋怨过去,放眼未来。这两个月的暑期集训选拔。加油!...
直接上代码:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!--.hr0{ height:1px;border:none;border-top:1px dashed #1E
imageView的.setBackgroundResource 、setBackground设置图片,没有效果
如图示: 功能描述:在勾选了全选时,所有的商品都会勾选,在取消全选时,取消所有物品的勾选。如果点击批量删除,删除所勾选的商品。<td align="center" width="12%" > <input type="checkbox" id="allChecks" onclick="ckAll()" /> 全选/全不选</td>//全选 function ckAll(){
项目中,有些函数需要处理某个服务的返回结果,而在对函数单元测试的时候,又不能启动那些服务,这里就可以利用Mockito工具,其中有如下三种注解:@InjectMocks:创建一个实例,简单的说是这个Mock可以调用真实代码的方法,其余用@Mock(或@Spy)注解创建的mock将被注入到用该实例中。@Mock:对函数的调用均执行mock(即虚假函数),不执行真正部分。@Spy:对函数的调用均...
结构SCREEN有如下字段NAME 结构名称 GROUP1GROUP2GROUP3 元素属性GROUP4 同属性元素的先后次序REQUIREDINPUT 输入允许OUTPUT 输出允许INTENSIFIEDINVISIBLE 可视LENGTH 长度A
Ubuntu下安装boost库安装环境