想明白工具怎么用,真的需要自己多加摸索,首先准备一个小的apk留着分析用,我这里将我们用的那个发到云盘供大家下载使用
链接: https://pan.baidu.com/s/1KmyNXHRv-aiSAfnnPXBNRQ 提取码: 2fns 一个40+k的apk
关于工具可能不同版本的使用方法稍微不同,看情况是否打包发上来
apktool 工具
Apktool是专为安卓软件DIY爱好者们设计的一款apk编译软件,用户们可以通过这款软件实现对各种各样安卓软件的编译、反编译、签名等操作。
一般是配合使用 但是比较麻烦......这里也不多接收 用它主要就是直接解压apk文件,后续再说
apktool
作用:主要查看res文件下xml文件、AndroidManifest.xml和图片。(注意:如果直接解压.apk文件,xml文件打开全部是乱码)
https://ibotpeaches.github.io/Apktool/
dex2jar
作用:将apk反编译成Java源码(classes.dex转化成jar文件)
jd-gui
作用:查看APK中classes.dex转化成出的jar文件,即源码文件
jadx反编译
优点是方便 缺点是不可以修改,一般反汇编完毕后需要手动记事本等的进行更改 然后在重新编译
https://github.com/skylot/jadx
可以下这个版本:
java -jar jadx-gui-0.7.1.jar 运行
SignApk签名
在安卓工具箱中,下载SignApk.jar。用于签名,这样才能安装apk,我们使用手机的时候也会经常注意到签名,签名用于防止恶意更改等。
signapk.jar是Android源码包中的一个签名工具。
代码位于:Android源码目录下,signapk.jar 可以编译build/tools/signapk/ 得到。
使用signapk.jar签名时需要提供签名文件,我们可以使用安卓源码中提供的testkey.pk8与testkey.x509.pem,他们位于Android源码build/target/product/security目录。
使用android自带的签名工具signapk.jar 以及源码中的testkey.x509.pem,testkey.pk8 对apk进行重新签名。
执行:java -jar signapk.jar testkey.x509.pem testkey.pk8 old.apk new.apk 执行后new.apk即为签名后的文件。
(注:执行命令时所有文件这里放在同一目录下,如果不在同一目录请修改路径)。
含义:通过signapk.jar这个可执行jar包,以testkey.x509.pem这个公钥文件和testkey.pk8这个私钥文件对old.apk进行签名,签名后的文件保存为old.apk。
测试使用
需要注意的是 如果我们不把工具放在windows目录下,那么我们需要设置系统环境才可以随心所欲的用
计算机-属性-高级属性-系统变量-path 添加我们的工具目录
当前目录结构
apktool 使用
解包命令:
apktool d xxxxxx.apk ABC
这里“d”表示要解码。Xxxxx.apk是要解包的APK文件。ABC是子目录名。解包的文件会放在这个子目录内。
打包命令:
apktool b ABC yyyyy.apk
使用d filename命令解压apk文件到当前目录
windows下暂时没有显示解压过程,linux下是可以的,大概是这个样子(示意)
得到文件的解压目录
打包的方法请接着往下看
signapk使用
使用目标系统的platform密钥来重新给apk文件签名。
1.首先在我的Android源码目录中的位置是"build argetproductsecurity",下面的platform.pk8和platform.x509.pem两个文件。
然后使用系统提供的签名工具signapk.jar,使用步骤是将自己的apk还有上述三个文件放入一个文件夹如图:
2、然后用压缩软件打开自己的apk文件,删掉META-INF目录下的CERT.SF和CERT.RSA两个文件。
命令使用方法 signapk pen文件路径 pk8文件路径 原始apk文件 新的签名之后的输出路径
jadx使用
选择文件进行反汇编
这是一个显示的界面
输入框 计算的按钮
查看源码可知 隐藏看了一个按钮
有两个按钮btn和一个输入框,但是btn2使用了setVisibility(4) 被隐藏了
android view setVisibility():
有三个参数:Parameters:visibility One of VISIBLE, INVISIBLE, or GONE,想对应的三个常量值:0、4、8
我们需要更改这个变量 但是jadx是无法更改的 找到解压的源码更改就可以
更改为我们需要的0 然后保存。我们更改完事源码之后重新压缩为apk打包 使用apk命令
.\apktool-cli-all.jar b 22 正常这样就是可以的 输出为22.apk 但是可能windows有问题 使用 -o参数才能输出apk文件
得到了新的apk文件,这里还需要签名
将那些需要的文件放在一起 然后签名
.\signapk.jar .\testkey.x509.pem .\testkey.pk8 .\new.apk new-sign.apk
下面使用adb安装apk文件
adb install apk文件路径
JEB的安装和使用方法前面已经说过了 不在赘述。
xposed hook 进程
Method分为两种,dalvik虚拟机在处理的时候有区别,一种是directMethod,即Java世界里面实现的方法,一种是nativeMethod,即在c/c++里面实现的方法。
ClassObject里面有两个集合,分别存放了这个Class下定义的directMethods和nativeMethods。
Method中,有两个非常重要的指针:
-
const u2* insns;
-
DalvikBridgeFunc nativeFunc;
对于directMethod,insns存放了该方法的字节码指针(还记得odex被mmap到内存中了么,这个指针就是这段内存里面指向code区域的开始处的指针)。
虚拟机在调用directMethod时,在构建好方法栈以后,pc指针指向了insns,于是可以从内存中取得字节码,然后解释执行。
那么大概的意思就是我们方法的调用是使用指针保存的位置,而这些指针是存储在内存中的
虚拟机在处理native方法时,走的是另外一套逻辑。
我们在使用native方法时,首先得使用System.loadLibrary对so进行加载,其最终是使用dlopen函数加载了指定的so文件。
之后在我们调用nativeMehtod的时候,会根据方法描述符,通过特定的映射关系(是否主动进行了注册会有不同)得到一个native层的函数名,再从之前dlopen获得的句柄中使用dlsys去查找对应的函数,得到了函数指针后,将这个指针赋值给 insns。在nativeFunc这个桥接函数中,将insns解析为函数指针,然后进行调用。
有前面这些知识后,再理解Xposed的hook原理就不难了。
前面已经知道,一个java方法在虚拟机里面对应的Method为directMethod,其insns指向了字节码位置。
Xposed在对java方法进行hook时,先将虚拟机里面这个方法的Method改为nativeMethod(其实就是一个标识字段),然后将该方法的nativeFunc指向自己实现的一个native方法,这样方法在调用时,就会调用到这个native方法,接管了控制权。
在这个native方法中,xposed直接调用了一个java方法,这个java方法里面对原方法进行了调用,并在调用前后插入了钩子,于是就hook住了这个方法。