因一纸设计稿,我把竞品 APP 扒得裤衩不剩 (下),让人茅塞顿开
另外,个人感觉 AS 上看 smali 并不是很爽 !既然觉得不爽,那就换个体位,是吧?举几个例子:
男的觉得不够刺激,就用「推磨式」;
女的觉得不够刺激,就用「猫式」;
男的想快感加倍,就用「后入式」;
女的想自由把控,就用「传统女上位式」;
想丰富彼此情感交流,就用「传教士体位」;
想延长时间,就用「面对面侧卧」;
em…体位有很多,就不一一列举了,只是想告诉大家:哪种方式适合自己就用哪种~

如果你用「VS Code」的话,可以安装一个「Smalise」插件:Smali 语法高亮 支持变量或者方法名的定位:

除此之外,还可以直接看「Unicode 转换后的中文」、「变量信息」、「定位到定义处」

⑤ 动态调试 so
目前不会,以后有兴趣或者需要学再去学吧,学完了再来补全~
0x6、是时候表演真正的技术了 => 破解
学完调试定位技巧,我们已经能快速找到 G 点(核心代码),再来玩点「刺激」的吧:

看到,有人在上一篇《因一纸设计稿,我把竞品APP扒得裤衩不剩(中)》有人在评论区留言对「邻居的故事」感兴趣,我用简单的几句诗来概括下后续剧情吧:
男子加班回家晚,草草了事交公粮。
妹子觉得略失望,欲求不满暗自叹。
邻居首捷心暗爽,唯美画面反思量。
妹子软萌待开发,制服跳蛋震动棒。
觉得妹子过于乖巧,邻居想二次开发妹子(APK),于是用上了三个道具,这些道具怎么用等等再说。说回这一节,在使用别人 APP 的时候,你可能会想:如果是我的做的 APP,我要…!建议别想,直接动手吧!加点什么(自定义 UI) 或者 改点什么(付费变免费,开隐藏关卡),当然自己暗爽就好了,可别到处传播,「破坏计算机信息系统罪警告」。以竞品 APP 关卡付费为例,讲解一波:

问题描述如下:
1、首页课程有锁,点击:弹出需要开通完整课程的对话框;
2、点击下一关,无法切换到下一关,提示:敬请期待;
3、50-100 节的课程带锁,点击提示:努力建造中…;
4、课程等级除了 L1 外,其他级别带锁,点击提示:敬请期待;
① 制服——调试下断点直接改标志位

怎么动态调试 Smali 上面已经介绍过了,具体调试技巧可见《逮虾户!Android程序调试竟简单如斯》,来到 APP 中的如下页面:

点击 50-100 会出现「努力建造中」的提示语,打开开发者助手:

直接定位到 CourseChangeFragment:

看下 this.n 是啥,以及里面的 d 是什么:

行吧,这个 d 就是图片是否高亮,1 为高亮,接着看下 this.n 在哪里完成赋值:

而关卡选择,直接全局搜「选择等级对应的课程地图」定位到 ChangeLevelDialog,全局搜,定位回 CourseChangeFragment:

同样,看下 this.k 是啥,在哪里完成了赋值:

跟到 ChangeLevelDialog,可以看到,提取的是里面的 CourseLevelInfo

跟过去看看:

行吧,这个 c 就是关卡的状态,1 为可用状态,行吧,找下断点的时机,搜下控件:

控件 id 为 0x7f0f0363,回到 CourseChangeFragment.smali 搜:

直接定位到 sswitch_2:

这里圈住的地方,其实是中文的 Unicode 码,不信,转换下你就知道了:

定位到下面这段代码:

接着讲解一波这段代码:
iget-object?v0,?p0,?.../CourseChangeFragment;->n:.../$CourseLevelMapInfo;
#?引用对象,p0 为该变量所在类的实例,即 this,把 n 的值放到 v0 寄存器中
if-eqz?v0,?:cond_1
#?判断 v0 是否为 0(null),是的话跳到 cond_1
iget-object?v0,?p0,?.../CourseChangeFragment;->n:.../$CourseLevelMapInfo
#?同上上一行代码把 n 的值放到 v0 寄存器中
iget?v0,?v0,?...$CourseLevelMapInfo;->d:I
#?引用 v0 寄存器中保存的 n 对象,把 n.d 的值放到 v0 寄存器中
if-ne?v0,?v1,?:cond_1
#?判断 v0 寄存器和 v1 寄存器中的值是否相等,不等跳到 cond_1
如图下完断点,开始调试 smail,来到关切页面,点击后进入调试模式:

右键 d,选择 Set Value,把值设置为 1,接着往下执行断点,可以看到「隐藏关卡」开启成功:

啧啧,有点意思,其他几个破解也是「如法炮制」,不过每次都要这样调试显得太麻烦了,有没有一劳永逸的方法?当然有,写个 Xposed 插件耍耍吧~
② 跳蛋——编写 Xposed 插件

关于 Xposed,之前写过一个系列,就不再详细介绍了:
简单说通过它,你可以:
修改变量的值,Hook 方法(执行前后做一些修改),显式去执行一些方法等。
我们需要先定位到「标志位的源头处」(一般是方法),在方法执行前或后,进行一些修改,过程比较琐碎,直接给出插件代码吧!先是 3、破解课程选择的锁:

接着是:4、破解关卡选择对话框

再接着是:2、破解首页下一关切换

最后是:1、破解首页所有关卡

把写好的 Xposed 插件安装到手机上,Xposed Installer 勾选,重启,接着打开 APP,看下效果:

行吧,插件编写完毕,但是毕竟不是每个人的手机都会 Root 装 Xposed,索性破解后二次打包吧。
③ 振动棒——apktool 二次打包

使用 apktool 二次打包的流程很简单,难的是改 Samli 代码:
改 smali => apktool b 重打包 => jarsigner/apksigner 二次签名
行吧,动手撸 smali,定位到 CourseChangeFragment.smali 的 onClick 函数 的判断处代码:

前面这个数字是「十六进制的资源 id」,可以直接把 jadx 反编译出来的 id 转换下:

分别对应:7f0f0360 和 7f0f0363,对应跳=> sswitch_3 和 sswitch_2,先去 sswitch_2 处,可以看到源码中做了判断,如果不满足 return,满足的话继续走,这里可以钻个空子,「直接把判断相关的代码删掉」,只保留下图圈着的代码:

接着拖过如下命令把项目二次打包回 apk:
apktool?b?xxx?-o?xxx.apk
接着用「jadx-gui」打开 apk 看看代码:

啧啧,可以,接着需要对 APK 进行二次签名才能安装到手机上,可以通过「jarsigner」或「apksigner」完成签名。玩法如下:
#?如果你没有签名,可通过下述命令创建,回车后会让你输入密码,输完无脑回车即可
keytool?-genkey?-v?-keystore?文件名.jks?-keyalg?RSA?-keysize?2048?-validity?10000?-alias?签名别名
#?======?jarsigner 签名?======
#??1、输入下述指令,回车后输入密码
jarsigner?-verbose?-keystore?证书?-signedjar?签名后.apk?签名前.apk?证书别名
#?2、报错的话可能需要最在-keystore 前添加下述参数:
-digestalg?SHA1?-sigalg?MD5withRSA
#?3、Tips:可以使用下述命令查看 APK 是否已签名
jarsigner?-verify?xxx.apk
#?======?使用谷歌提供的签名及验证的专用工具:apksigner?======
#?位于:Android?SDK/build-tools/SDK 版本/apksigner.bat
#?1、对齐
zipalign?-v?-p?4?xxx.apk?xxx_aligned.apk????
#?2、签名
sign?--ks?证书?--out?release.apk?origin_aligned.apk
#?3、验证是否签名成功
apksigner?verify?release.apk
把签名后的 APK 安装到手机上,打开看下效果:

虽然还有锁的那个图标,但是却可以点击切换关卡了,可以,继续折腾,选择关卡部分:

点击时判断 courseLevelInfo.c == 1,那么我们找到初始化 courseLevelInfo 对象的地方,在这里直接把 c 设置为 1 即可,不难定位到:

在箭头所指的代码后,添加一句:courseLevelInfo.c = 1;,就好了,但是你需要把这个 java 语句转换成 smali!这个转换可没你想象中那么简单哦!打开 ChangeLevelDialog.smali,定位 a 方法:

不难定位到如下位置,我们需要在.line 添加赋值代码:

赋值操作需要用一个寄存器保存 1(0x1),然后用 iput 进行赋值:

接着 apktool b 打包,用 jadx-gui 打开看看:

行吧,转换后除了行号,没问题,直接 jarsigner 二次签名,adb 安装到手机上验证下:

可以,nice,把剩下的首页下一关和所有关卡也折腾下吧:

删除赋值语句,对应 Smali 中:

重打包,jadx-gui 打开查看:

每个关卡锁定位到:MainHomeworkAdapter$CommonViewHolder 类 (美元符号代表内部类)

在如图所示的地方插入赋值语句,

重打包,jadx-gui 打开查看:

运行下看下效果,结果和 xposed 大同小异,但是没装 Xposed 的手机也能直接使用~

然后说一点:
不是所有的 APK 都能直接二次打包签名!有些会做签名校验,打开签名不对,直接闪退,Java 层可以 Hook 掉检验的方法,Native 层的只能去改 So;还有些加固的 APK,尽管可以导出 dex,但是二次打包的话还需要修复 onCreate 函数(如 360 加固宝)。所以大部分时候,我们都只是能看看代码而已~所以 Xposed 还是香,Smali 写起来是真的繁琐,复杂逻辑的代码会写到想哭,每次看效果都要重打包…
④ 移动端逆向利器——MT 管理器 2
PC 端逆向,需要下载一堆反编译工具(apktool, jadx 等),一些更好用的工具(AndroidKiller,smali2java)等还不支持 mac,
所以它来了—— MT 管理器 2:移动端「双窗口文件管理」和「强大的 APK 编辑功能」,可在手机上高效地修改安卓软件,界面如下:

官方文档中已有详细的讲解,就不哔哔了,读者自行查看文档把:MT管理器,另外还有个相关的逆向论坛:MT论坛

「Tips:基本上可以说是付费的,部分功能需要会员才能使用~」
笔者有「记账」的习惯,用的是「X 记账」,界面粉粉的,挺 Gay 的,就是每次打开弹出的「广告闪屏页」令我很是反感。行吧,就拿它来开刀吧,顺带给大家演示下「MT 管理器 2」怎么耍。

点击左侧菜单栏的「跟踪 Activity」,开始跟踪,接着打开软件,然后回到 MT 管理器,可以看到 Activity 的启动记录:

先进 LogoActivity,再进 MainActivity,点击左侧菜单「安装包提取」:

提取后定位到**/MT2/apks 目录下**,点 apk,「查看」,打开 AndroidManifest.xml 也看到:

行吧,入口是就是 LogoActivity,点击 classex.dex 打开,两个 dex 都选择:

接着按照包名,打开 LogoActivity,点击右上角,「转成 Java」

转换后的 Java 代码和 Jadx 的一样:

见名知意,圈着的就是显示广告的 View(@BindView 祖传黄油刀),想把广告禁掉,把相关加载的代码都删掉就好啦:

和 PC 一样改 smali,不过比起 PC,改完,直接就可以转 Java,方便好多,修改完后保存,返回会弹出如下对话框:

但是,打开二次打包后的 APP:「广告内容没了,但是却卡在了图标页,要点击右上角才能关闭」
我擦,估计是 AdsView 里还有什么逻辑(比如广告加载完才跳转),一不做二不休,直接把这个 AdsView 给去掉吧,
删布局文件里的,再删 LogoActivity 相关的代码,正当我准备开始这样做的时候,我看到了这些:

2333,为了避免「空指针异常」,调用 adsView 相关方法前都做了「判空」可以,很好的开发习惯!

但也方便了我(心里乐开了花)
我直接在页面初始化的地方把这个「adsView 设置为 null」不就好了!
定位到如图所示位置,在初始化 View 的地方把 View 置空,没毛病

打开 initView 函数对应的 smali 代码,编写把 adsView 置空的 smali 代码:

二次打包,覆盖安装看看效果:

对比下没去广告的效果:

当真是日了狗,点击跳过的按钮很小很容易误触,而且点了还不是立马关闭!改完后瞬间舒服了~
对了,学完这里你可以出去吹牛逼了:《两行代码去掉 APP 闪屏广告页》
0x7 、死亡如风,常伴吾身 => 爬取 APP 数据
其实,本来没有这一节的,毕竟,APP 源码都被你扒得裤衩不剩「任意蹂躏」了,但是有一点:
她并不属于你!
如果哪一天,这个 APP 下架了,服务器撤掉了,你所做的一切就「付之东流」了。

与其在以后的某一天说暗自感叹
「祝你岁月无波澜,敬我余生不悲欢」
不如想办法让她真的属于你:
说到底:APP 只是一个资源展示工具,而后台则是一个资源调度工具,关键的还是「资源」!
把资源搞到手,APP 和后台随便你折腾,接着抓包分析一波,然后写个爬虫把每一关的数据保存起来~
直接通过 Fiddler,Charles 等 抓包工具抓取一波数据,移动端如何抓包,可参见我之前写过的文章:《忘了他吧!我偷别人APP的代码养你》,此处就不再复述了,直接开抓:

好几个接口,筛选出我们需要的接口:

规则比较简单,接口没做用户校验,付费资源链接也有返回,只是在 APP 端做了限制。
直接顶一个一个存储数据的类,把爬取到的数据塞到 MongoDB 中:

出于反爬虫的习惯,使用「代理 ip」访问,关于代理 IP 如何获取,以前说过,就不哔哔了,这里用阿布云的代理隧道,1 块钱 1 小时,美滋滋,相关配置如下:

除了使用代理 ip,「设备名,设备 id,版本」都随机生成:

接着编写请求和解析数据的方法:

最后开启一波多进程访问:

多进程+可用性比较高的代理,一分钟不到就爬完,美滋滋:


lessonDay 的顺序有些不对,排序查询一波:

行吧,数据爬取完毕,剩下的接口就不一一演示了,对了,你还可以写个脚本把所有的音视频资源,图片爬到自己电脑,或者同步到七牛云等 CDN 站点,接着遍历替换一波基地址。另外,如果抓包分析不出规律,你也可以从 APP 入手~

0x8、小结
历经坎坷,终于把最后一章给肝出来了,写这个系列的初衷是想扒一些竞品 APP 的好看效果,结果活生生写成了逆向,也算是自己一个阶段性学习的总结了,逆向的水挺深的,有机会和闲情再耍耍把,就这样,接下来,准备写个「面试准备周报」系列,以督查自己好好准备面试,敬请期待。
本系列最后一次送书,意思意思送「一本自己写的 Python 爬虫入门书」,评论区留言抽,包邮,下周五抽~ (可能延迟,但一定抽,无暗箱~)

谢谢各位一直以来的支持和厚爱,爱你们~

Tips:本你想系列用到的工具,都有给出比较官方的下载链接!!!你也可以到公号
最后为了帮助大家深刻理解 Android 相关知识点的原理以及面试相关知识,这里放上我搜集整理的 2019-2021BATJ 面试真题解析,我把大厂面试中常被问到的技术点整理成了 PDF,包知识脉络 + 诸多细节。
节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
《960 全网最全 Android 开发笔记》

《379 页 Android 开发面试宝典》
历时半年,我们整理了这份市面上最全面的安卓面试题解析大全包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。
如何使用它?
1.可以通过目录索引直接翻看需要的知识点,查漏补缺。2.五角星数表示面试问到的频率,代表重要推荐指数

《507 页 Android 开发相关源码解析》
只要是程序员,不管是 Java 还是 Android,如果不去阅读源码,只看 API 文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。
真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

腾讯、字节跳动、阿里、百度等 BAT 大厂 2019-2021 面试真题解析

资料太多,全部展示会影响篇幅,暂时就先列举这些部分截图
评论