安卓逆向案例之全局负一屏高级版绕过原创

admin 2022年10月30日19:39:09安卓逆向案例之全局负一屏高级版绕过原创已关闭评论109 views字数 2242阅读7分28秒阅读模式

此为何物?#

这是一个可以在任何应用界面打开的负一屏工具,你可以添加常用的应用,快捷方式,网址,图片,联系人以及小工具,当然你也可以从你的系统小部件中选择你想要的任何部件添加上去,只需轻轻一滑,一切尽在眼前!

何为绕过?#

解锁全局负一屏的高级版功能。

高级版功能几何?#

  1. 支持自由布局 ⭐
  2. 显示为高级版

正餐甜点#

  1. ARM 架构的汇编指令集
  2. 使用 IDA 直接给 so 文件打补丁
  3. 安卓 Apk 的回编译和签名验证绕过
  4. 使用 AndroidStudio 来动态调试 apk
  5. 使用 AndroidStudio 来查看 App 的运行日志
  6. MT 工具的使用
  7. smali 语法

以上为一些需要了解的知识,磨刀不误砍柴工,多学学总归没有坏处。

风味佳肴#

我们假设,正餐甜点部分你已经完全了解。不了解就放弃吧,你学不会的。

这个 App 没有进行加壳,估计也是对安全不是非常重视,整个过程还是比较顺利的,适合新手练手。

Part 1 显示成高级版#

至少样子上是骗过系统了~

这个 app 的代码采用了 0o 混淆方案,不适合直接阅读,下面截图的代码中,部分代码做了反混淆优化(你问我怎么优化?当然是读懂了再改名字啊!)

  • 打开 app,在关于里面,可以看到高级版字样是红色,购买成功的应该是绿色(别问我怎么知道....我买过...)

    image-20220330111541750

  • 用 MT 管理器,查看当前页面的 Activity~

    image-20220330112657559

  • 这就找到了这个页面的 Activity,com.example.xf.negativeonescreen.pro.activity.about.AboutActivity

  • 有的小伙伴可能遇到过这种情况,不管你划到哪个页面,都只能捕获到同一个 Activity。这是因为这个应用采用的 单一Activiy 架构,内容部分是由 Fragment 来渲染实现。这个问题不在本次讨论范畴之内,了解即可。

  • 我们找到了这个 Activity,那么 高级版 的字体的设置想必就在这里了

  • 我们使用 jeb 打开这个 apk,找到这个 Activity 的实现

    image-20220330150827879

  • 没有找到高级版字样,想来是写死到布局文件里面了,我们可以跟一下对应的布局文件

  • 一个 Activity 的布局文件渲染正常会在 onCreate 阶段,主要去跟一下这一块

image-20220330162327580

  • 当然,这种布局渲染方案正在逐渐被 Google 放弃,改用 databing 的方式,这里暂且不表。

  • 查看布局文件,不出意外的就能发现 高级版,不过这种写法不符合安卓多语言规范,按照规范,这边应该是 @string/advance 之类的来指代高级版;

    image-20220330162553248

  • 我们记一下这个 id,资源 id 在安卓中是唯一标记组件的办法。

  • 回到 AboutActivity 页面,我们可以看到,这个组件对应了 textview2

image-20220330162940933

  • 此时再去跟这个 textview2,会发现整个 class 中没有任何调用,可以推测,这个 Activity 被作为一个对象传入了其他地方调用。即便不推测,继续往下看代码,也能发现端倪。ActivationPresenter,单词拆分一下,就是 激活演示 的意思,很容易就能跟到这里。

    image-20220330164104590

  • 为了便于理解,我对这里混淆的字符做了语义化修改

image-20220330165238353

  • 这边就能看到我们熟悉的 textview2,很显然我们所需显示成高级版的功能就在这里。

  • 那么只要让 Ooo00OO0.isActived() 返回 true,就能达成显示高级版的目的~

  • 我们继续跟这个函数~

    image-20220330165749788

  • 这边居然只判断存储于 SharedPreferences 的 sign 是不是 null 就判定是否激活,有那么简单?试试不就知道了~

  • 这里的验证不使用 frida 或者 xp 来实现,通过直接修改 smail 的方式搞定~

  • 由于 class 混淆过,直接去找这个类比较麻烦,用搜索功能搜索其中的字符串找到这个类;

image-20220330174624464

  • 对比转换过的 java,分析一下 smali 代码

image-20220331131705269

  • 由于 AndroidKiller 用着不顺手,下面都换成 MT 管理器
  • MT 中修改了这部分之后,返回,选择自动签名。

image-20220331134348178

  • 我们安装看看直接就能打开了看来没有做应用完整性校验....问题不大~
  • 我们的 Part1 目标达成

image-20220331134727152

Part 2 解锁自由布局功能#

image-20220331135355288

  • 老办法,先定位 Activity 发现 Activity 是空的,这是因为,它的负一屏采用的是悬浮窗方案实现,没有 activity 这一说

image-20220331135840284

  • 我们先用 jadx 找一下(jeb 的查找太烂了),这个页面会在哪个文件中出现。使用 Jadx 搜索自由布局,找到 name,根据 name 查找引用~

image-20220331144144815

image-20220331144652969

  • 直接就定位到了要找的部分,我们回到 jeb 找到这个类 com.example.xf.negativeonescreen.pro.Oo00O0oo ,jeb 中没有将 array 解密,所以看到的就是这种....

image-20220331151222802

  • 这是 OnClick 事件中的一块,我们往上找一找,v0 是一个 Tag,标记当前点击的是第几个选项,我们跟一下这个函数

image-20220331152806174

  • 因为这个弹出的列表触发的事件全是点击,只要关注 onClick 即可~

image-20220331154723130

  • 从而反推优化下代码~

image-20220331154612392

  • 这个接口类的方法,在刚在的类中,必须要有对应的实现,我们找一下~

image-20220331155227555

  • 找到可疑之处:

    image-20220331155936718

  • 跟一下这个 native 函数

image-20220331160119500

  • 在 libbase.so 文件里面,先看看他的导出表,很明显有两个函数,checkSignisActivated,不过这个 checkSign 似乎并没有发挥作用~

image-20220331160213627

  • 我们反编译这个函数看下~

image-20220331161037118

  • 他的校验返回,放在最后,这种最好搞定了~只要整个函数中,v3 返回 1 就是已激活状态。

image-20220331173357250

  • 在所有给 R7 赋值前的 R0 全部赋值为#1,即可让最终 R7 的值为 1
  • 我们用 MT,把修改后的文件合并进来

image-20220331173750409

  • 简单测试下,Part2 目标达成

image-20220331174100061

饭后甜品#

这个 apk 有几个问题:

  1. 对高级版的授权校验太简单;
  2. 对 so 层的加密保护不严格,很容易找到关键的校验函数;
  3. 作者已经跑路了~不然我也懒得搞它....

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年10月30日19:39:09
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   安卓逆向案例之全局负一屏高级版绕过原创http://cn-sec.com/archives/1379919.html