安卓逆向—某APP会员代码分析总结

admin 2026-09-23 06:04:07 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详细分析了某安卓APP的会员验证逻辑逆向过程。作者通过去签、搜索常量定位支付接口,分析smali代码中VIP判断方法y0(),发现其通过getVip和getVip_forever返回值判断会员状态。最终通过修改这两个方法返回值实现破解会员功能,并提示新用户注册赠送会员可能影响修改效果。文章步骤清晰,包含完整代码分析。 综合评分: 62 文章分类: 逆向分析,移动安全,免杀


安卓逆向 — 某APP会员代码分析总结

anke1 anke1

逆向有你

2026年9月20日 10:20 河南

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

首先软件各大应用商店下载,此贴以vivo应用商店为例

软件去签后打开全部dex,常量搜索会员后只发现有两个支付接口

于是找到resources.arsc进行搜索资源值〔VIP〕,发现这段字对应了软件上的提示,

接下来复制ID打开dex,搜索后选第一个。

打开第一个方法名进行代码分析

thod&nbsp;private&nbsp;l0(I)V&nbsp; &nbsp; .registers&nbsp;6&nbsp; &nbsp; .line&nbsp;1&nbsp; &nbsp; invoke-static&nbsp;{},&nbsp;Lcom/yunshangxiezuo/apk/db/c;->d0()Lcom/yunshangxiezuo/apk/db/c;&nbsp; &nbsp; move-result-object v0&nbsp; &nbsp; invoke-virtual {v0},&nbsp;Lcom/yunshangxiezuo/apk/db/c;->y0()Z&nbsp; &nbsp; move-result v0&nbsp; &nbsp;&nbsp;if-nez v0, :cond_1f&nbsp; &nbsp; .line&nbsp;2&nbsp; &nbsp; invoke-static&nbsp;{},&nbsp;Lcom/yunshangxiezuo/apk/db/c;->d0()Lcom/yunshangxiezuo/apk/db/c;&nbsp; &nbsp; move-result-object p1&nbsp; &nbsp; invoke-virtual {p0},&nbsp;Landroidx/appcompat/app/AppCompatActivity;->getResources()Landroid/content/res/Resources;&nbsp; &nbsp; move-result-object p0&nbsp; &nbsp; const v0,&nbsp;0x7f10011e&nbsp; &nbsp; invoke-virtual {p0, v0},&nbsp;Landroid/content/res/Resources;->getString(I)Ljava/lang/String;&nbsp; &nbsp; move-result-object p0&nbsp; &nbsp; sget v0,&nbsp;Lcom/yunshangxiezuo/apk/db/c;->A:I&nbsp; &nbsp; invoke-virtual {p1, p0, v0},&nbsp;Lcom/yunshangxiezuo/apk/db/c;->u1(Ljava/lang/String;I)V&nbsp; &nbsp;&nbsp;return-void&nbsp; &nbsp; .line&nbsp;3&nbsp; &nbsp; :cond_1f&nbsp; &nbsp; iget-object v0, p0,&nbsp;Lcom/yunshangxiezuo/apk/MainActivity;->c:Ljava/util/List;&nbsp; &nbsp; invoke-interface {v0, p1},&nbsp;Ljava/util/List;->get(I)Ljava/lang/Object;&nbsp; &nbsp; move-result-object p1&nbsp; &nbsp; check-cast p1,&nbsp;Lcom/yunshangxiezuo/apk/model/sync/book_details;&nbsp; &nbsp; .line&nbsp;4&nbsp; &nbsp; invoke-virtual {p1},&nbsp;Lcom/yunshangxiezuo/apk/model/sync/book_details;->getUuid()Ljava/lang/String;&nbsp; &nbsp; move-result-object v0&nbsp; &nbsp; iput-object v0, p0,&nbsp;Lcom/yunshangxiezuo/apk/MainActivity;->h:Ljava/lang/String;&nbsp; &nbsp; .line&nbsp;5&nbsp; &nbsp; invoke-virtual {p1},&nbsp;Lcom/yunshangxiezuo/apk/model/sync/book_details;->getUSN()J&nbsp; &nbsp; move-result-wide v0&nbsp; &nbsp; const-wide/16&nbsp;v2,&nbsp;0x0&nbsp; &nbsp; cmp-long v0, v0, v2&nbsp; &nbsp;&nbsp;if-nez v0, :cond_43&nbsp; &nbsp; .line&nbsp;6&nbsp; &nbsp; invoke-static&nbsp;{},&nbsp;Lcom/yunshangxiezuo/apk/db/c;->d0()Lcom/yunshangxiezuo/apk/db/c;&nbsp; &nbsp; move-result-object p0&nbsp; &nbsp; sget p1,&nbsp;Lcom/yunshangxiezuo/apk/db/c;->A:I&nbsp; &nbsp; const-string v0,&nbsp;"请先同步数据"&nbsp; &nbsp; invoke-virtual {p0, v0, p1},&nbsp;Lcom/yunshangxiezuo/apk/db/c;->u1(Ljava/lang/String;I)V&nbsp; &nbsp; goto :goto_68&nbsp; &nbsp; .line&nbsp;7&nbsp; &nbsp; :cond_43&nbsp; &nbsp; new-instance v0,&nbsp;Lcom/yunshangxiezuo/apk/activity/view/w;&nbsp; &nbsp; new-instance v1,&nbsp;Lcom/yunshangxiezuo/apk/f;&nbsp; &nbsp; invoke-direct {v1, p0, p1},&nbsp;Lcom/yunshangxiezuo/apk/f;-><init>(Lcom/yunshangxiezuo/apk/MainActivity;Lcom/yunshangxiezuo/apk/model/sync/book_details;)V&nbsp; &nbsp; invoke-direct {v0, p0, v1},&nbsp;Lcom/yunshangxiezuo/apk/activity/view/w;-><init>(Landroid/app/Activity;Landroid/view/View$OnClickListener;)V&nbsp; &nbsp; iput-object v0, p0,&nbsp;Lcom/yunshangxiezuo/apk/MainActivity;->w:Lcom/yunshangxiezuo/apk/activity/view/w;&nbsp; &nbsp; .line&nbsp;8&nbsp; &nbsp; invoke-virtual {p0},&nbsp;Landroid/app/Activity;->getWindow()Landroid/view/Window;&nbsp; &nbsp; move-result-object p1&nbsp; &nbsp; invoke-virtual {p1},&nbsp;Landroid/view/Window;->getDecorView()Landroid/view/View;&nbsp; &nbsp; move-result-object p1&nbsp; &nbsp; check-cast p1,&nbsp;Landroid/view/ViewGroup;&nbsp; &nbsp; .line&nbsp;9&nbsp; &nbsp; iget-object v0, p0,&nbsp;Lcom/yunshangxiezuo/apk/MainActivity;->w:Lcom/yunshangxiezuo/apk/activity/view/w;&nbsp; &nbsp; const-string v1,&nbsp;"从相册中选择"&nbsp; &nbsp; invoke-virtual {v0, v1},&nbsp;Lcom/yunshangxiezuo/apk/activity/view/w;->e(Ljava/lang/String;)V&nbsp; &nbsp; .line&nbsp;10&nbsp; &nbsp; iget-object p0, p0,&nbsp;Lcom/yunshangxiezuo/apk/MainActivity;->w:Lcom/yunshangxiezuo/apk/activity/view/w;&nbsp; &nbsp; const/16&nbsp;v0,&nbsp;0x11&nbsp; &nbsp; const/4&nbsp;v1,&nbsp;0x0&nbsp; &nbsp; invoke-virtual {p0, p1, v0, v1, v1},&nbsp;Landroid/widget/PopupWindow;->showAtLocation(Landroid/view/View;III)V&nbsp; &nbsp; :goto_68&nbsp; &nbsp;&nbsp;return-void.end method
  1. 先判断你 是不是VIP(调用  y0() )
  • 不是VIP → 弹提示,不让用
  • 是VIP → 继续往下走
  1. 拿到你点的那本书/文档
  2. 判断这本书 有没有同步过(USN 是否为 0)
  • 没同步 → 提示: 请先同步数据
  • 同步过 → 正常执行
  1. 最后弹出一个选择框:从相册中选择

所以我们选中y0进行转跳

.method&nbsp;public&nbsp;y0()Z&nbsp; &nbsp; .registers 7&nbsp; &nbsp; .line 1&nbsp; &nbsp; invoke-virtual&nbsp;{p0}, Lcom/yunshangxiezuo/apk/db/c;->p0()Lcom/yunshangxiezuo/apk/model/users;&nbsp; &nbsp; move-result-object&nbsp;p0&nbsp; &nbsp; .line&nbsp;2&nbsp; &nbsp; invoke-virtual&nbsp;{p0}, Lcom/yunshangxiezuo/apk/model/users;->getVip_forever()J&nbsp; &nbsp; move-result-wide v0&nbsp; &nbsp;&nbsp;const-wide/16&nbsp;v2,&nbsp;0x1&nbsp; &nbsp; cmp-long&nbsp;v0, v0, v2&nbsp; &nbsp;&nbsp;const/4&nbsp;v1,&nbsp;0x1&nbsp; &nbsp;&nbsp;if-nez v0, :cond_10&nbsp; &nbsp;&nbsp;return&nbsp;v1&nbsp; &nbsp; .line&nbsp;3&nbsp; &nbsp; :cond_10&nbsp; &nbsp; invoke-virtual&nbsp;{p0}, Lcom/yunshangxiezuo/apk/model/users;->getVip()J&nbsp; &nbsp; move-result-wide v4&nbsp; &nbsp; cmp-long&nbsp;p0, v4, v2&nbsp; &nbsp;&nbsp;if-nez p0, :cond_19&nbsp; &nbsp;&nbsp;return&nbsp;v1&nbsp; &nbsp; :cond_19&nbsp; &nbsp;&nbsp;const/4&nbsp;p0,&nbsp;0x0&nbsp; &nbsp;&nbsp;return&nbsp;p0.end method
  1. 先拿到当前登录的用户信息
  2. 查用户的 永久VIP 状态( getVip_forever )
  • 如果等于 1 → 直接判定:你是VIP,返回  true
  1. 如果不是永久VIP,再查 普通VIP 状态( getVip )
  • 如果等于 1 → 也判定:你是VIP,返回  true
  1. 两个都不是 → 判定:你不是VIP,返回  false

转跳getVip_forever后进入了com.yunshangxiezuo.apk.model.users类

  1. getUpdated_at() 返回: updated_at  字符串 意思:用户信息最后更新时间
  2. getUuid() 返回: uuid 意思:用户唯一Id
  3. getVip()J 返回: vip  长整型 意思:普通VIP 的状态 / 到期时间戳
  4. getVip_forever()J 返回: vip_forever  长整型 意思:永久VIP 通常: = 0 → 不是永久 = 1 → 永久VIP
  5. getVip_last() 返回: vip_last  字符串 意思:VIP最后一次更新时间 所以我们修改getvip和getVip_forever就可以了 因为getvip和getVip_forever的返回值都是J型 所以我们这里插入const-wide/16 v0, 0x1而不是const/4 v0, 0x1 我们这里顺便把VIP到期时间改成终身会员,更美观些

会员功能都能用,免责声明:新用户注册有送的会员,不知道代码修改是否有效,等到明天会员过期了再更新教程

·今 日 推 荐·

| | | | — | — | | | |


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:逆向有你 anke1 anke1《安卓逆向 — 某APP会员代码分析总结》

评论:0   参与:  0