时间:2018-07-31
地点:长沙
人物:lieyunye
起因:
经常逛某网站,但是它不提供在线观看或者下载功能,而且发现它只有Android版本的APP,体验也非常的糟糕,于是就想做一个iOS版本的,既可以看又可以下载,不过需要知道获取数据的API。。通过charles抓取请求发现其参数带有加密数据。。但是也是有规律可循,想了想觉得还是可以破解的
经过:
一、反编译和编译
1、材料:apk文件、Android studio、apktool、dex2jar、JD-GUI、Mac OS
2、步骤:
a、准备好apk文件、下载安装好AS、AS的版本是
b、安装apktool环境,下载命令脚本
$ wget https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/osx/apktool
$ chmod +x apktool
$ mv apktool /usr/local/bin复制代码
下载最新apktoolJar包
$ mv apktool_x.x.x.jar apktool.jar
$ chmod +x apktool.jar
$ mv apktool.jar /usr/local/bin
$ apktool --version
2.3.3
复制代码
此时即可反编译(apktool d test.apk)和编译(apktool b test),编译后会在test目录下生成build,dist文件夹,编译出来的apk在dist文件夹
3、接下来需要查看反编译后的代码
下载dex2jar和JD-GUI这两个工具,dex2jar 将 apk 转为 jar 文件,以供JD-GUI打开查看源码
$ cd dex2jar
$ chmod +x d2j_invoke.sh
$ chmod +x d2j-dex2jar.sh
$ ./d2j-dex2jar.sh ~/test.apk复制代码
打开JD-GUI客户端,将生成的test-dex2jar.jar拖进去即可查看
此时我们已经可以获取到apk的res目录、AndroidManifest、还有看不懂的混淆后的源码,如何在源码中找到需要的api和请求参数呢
二、抓取网络请求
1、材料:charles
2、获取电脑IP地址
下载安装charles,打开后设置Proxy-->proxy-setting端口号8888
打开手机网络设置网络代理,输入代理IP和端口号
通过adb安装apk至手机
adb install test.apk
打开app,即可在charles中看到网络请求
分析找一下规律后,发现其参数和时间戳有关,猜测可能是使用了md5加密算法,但并不是简单的将时间戳md5后当作请求参数
在源码中搜索md5、imei、timestamp等关键词后发现
新建一个Android kotlin的测试工程
嗯,加密数据似乎和时间戳有点关系...如果将项目运行起来,然后打断点到md5这个方法,观察其传入的参数就好了
三、动态调试smali代码
1、材料:smalidea、baksmali、adb
下载smalidea插件到本地,然后如下图安装
一般正式发布的apk中的AndroidManifest.xml中的debug属性都是false,所以需要反编译apk讲这个属性修改为true,然后才可以动态调试
修改完之后再编译为apk,进行签名,可以参考这个官方文档签署您的应用,我这里这个apk本身就是true。。所以跳过签名步骤直接安装到手机
2、下载baksmali插件到本地
java -jar baksmali-2.2.4.jar disassemble test.apk -o ./smali
复制代码
将test.apk反编译到smali目录,得到smali源码,导入至AS
配置远程调试的选项,选择Run–>Edit Configurations:增加一个Remote调试的调试选项,端口选择:8100
接下来,我们在源码中搜索md5Hex字符串,找到md5Hex方法,打一个断点
接下来找到apk的包名,在AndroidManifest.xml这个文件中
接下来以调试状态启动app
adb shell am start -D -n com.movies/com.movies.activity.GuideActivity
复制代码
然后在AS中点击Run---Debug
如果此时遇到这些错误:
Error running 'debug': Unable to open debugger port (localhost:8100): java.net.SocketException "Connection reset"复制代码
Error running 'debug': Unable to open debugger port (localhost:8100): java.net.ConnectException "Connection refused (Connection refused)"
复制代码
Unable to open debugger port (localhost:8100): java.io.IOException "handshake failed - connection prematurally closed"复制代码
尝试重启AS或者进行端口转发
在终端输入
adb shell
ps | grep com.movies
u0_a122 25827 324 1047708 72340 ffffffff 00000000 S com.movies
其中25827就是需要转发端口到的进程PID
adb forward tcp:8100 jdwp:25827
复制代码
最后,当程序运行起来后触发了断点,我们开始调试找出其中的参数
四、smali语法
简单举几个例子:
1、方法代码以.method指令开始,以.end method指令结束
2、return-object表示返回的对象
3、p1表示传入的参数
通过观察,发现p1内可能就是传入的参数,展开value,得到一个字符串,尝试对其md5加密
得到的结果与v0一致
结果:
零零总总花了几个周末时间,让996变成了997,不过还是挺有意思!接下来的任务还是挺多,希望有时间能完成自己想要做的。
P.S.以上过程仅供非Android工程师参考233333
参考文章:
https://blog.csdn.net/hp910315/article/details/52790740
https://blog.csdn.net/daide2012/article/details/75332798
https://www.jianshu.com/p/730c6e3e21f6
https://blog.csdn.net/linchaolong/article/details/51146492
https://wxnacy.com/2018/03/09/apk-decompile/