返回列表 发新帖

颜色软件《游咔》flutter框架应用逆向思路

  [复制链接]

27

主题

990

回帖

5915

积分

硕士生

Rank: 6Rank: 6

金币
2372
好评
70
信誉
100

考神MT论坛新人MT论坛帅哥MT论坛最佳新人

QQ
发表于 2025-8-7 14:08:47 | 显示全部楼层 | 阅读模式  来自 广东–江门–恩平
本帖最后由 蛀牙の小蓝 于 2025-8-11 08:52 编辑

我有一个朋友,真是一个朋友,他想玩的小黄油在这个app上,新注册用户可以免费下载一次,如果开会员可以免费下载以及看奇怪的漫画和动漫。

我正经人怎么可能用这种app,不过刚好最近在学习逆向,想着能不能搞一下,试试就逝世!

先把app要过来,看下有没有加固,啥框架

没有加固很好,但是居然是flutter,之前没有接触过,听说不好处理,来去翻翻论坛有无大佬提供点思路。

这里找了Sunika大佬的flutter教程贴:https://bbs.binmt.cc/thread-138529-1-1.html,那就拿这个软件来试手当学习了!

开始破解
破解思路 一:
    改会员状态,通过应用ui和部分会员弹窗提示文案,最终定位到 VipStatusManager --》isVip --》vip_status_manager.dart --》isVipEffective() --》user_vip_status.dart ,疑似判断会员状态。
    修改了状态后,本地虽然显示解锁了会员,但是游戏、漫画和动漫都无法正常观看还是非会员,目测是服务器验证了(调了会员到期时间也一样)!
    纯粹的本地自慰破解了(残念

本来到这里都已经准备放弃了,但是突然想到这个app注册的新用户会有半天的会员体验时间,而且一台新设备首次注册账号都是自动生成的系统账号,不需要手机号和邮箱注册,只有二次注册才需要手机号和邮箱注册。那这里是不是有漏洞可以钻?只要我保证每次注册的时候都让app识别为新设备,那么是不是可以达到伪开通会员,说干就干!


破解思路 二:
    1.从pp.txt全局搜索注册文本【继续注册】,定位到卡注册的文本位置,可以发现该文案关联的文件为【funbox/page/account/logic/login_logic.dart】
    2.全局搜索文件【login_logic.dart】分析下注册逻辑
        a.发现【继续注册】的拦截弹窗在 getDeviceRegisterList() 方法中,注册的代码在 _checkRegister
        b.观察 _checkRegister 代码可以发现,在请求到 getDeviceRegisterList() 拦截弹窗前,有调用 getDeviceNo()和判断 ,那么这里很有可能就是获取设备id唯一标识的地方
        c.getDeviceNo() 方法关联的文件为【package:bus_common/utils/device_utils.dart】
    3.全局搜索文件【device_utils.dart】分析代码逻辑
        a.从getDeviceNo()汇编脚本语言可以观察出,其中是先尝试读取缓存是否有设备id,没有则重新生成一个唯一的设备id标识
        b.那是不是说明我们找对地方了,只要强制代码逻辑不读取缓存,每次注册都直接生成新设备id就可以了,有希望
这里把完整的getDeviceNo() 代码发出来,有几处判断懒得一个个看,直接暴力全改了:
static String getDeviceNo() {
    // ** addr: 0x96a21c, size: 0xf0
    // 0x96a21c: EnterFrame
    //     0x96a21c: stp             fp, lr, [SP, #-0x10]!
    //     0x96a220: mov             fp, SP
    // 0x96a224: AllocStack(0x18)
    //     0x96a224: sub             SP, SP, #0x18
    // 0x96a228: CheckStackOverflow
    //     0x96a228: ldr             x16, [THR, #0x38]  ; THR::stack_limit
    //     0x96a22c: cmp             SP, x16
    //     0x96a230: b.ls            #0x96a2f8
    // 0x96a234: r0 = LoadStaticField(0xcd0)
    //     0x96a234: ldr             x0, [THR, #0x68]  ; THR::field_table_values
    //     0x96a238: ldr             x0, [x0, #0x19a0]
    // 0x96a23c: cmp             w0, NULL       【改为  nop 直接忽略】
    // 0x96a240: b.eq            #0x96a24c    【强制修改为  b #0x96a284】使其强制跳转到生成新设备id的代码位置
    // 0x96a244: LoadField: r1 = r0->field_7
    //     0x96a244: ldur            w1, [x0, #7]
    // 0x96a248: cbnz            w1, #0x96a2ec   【强制修改为  b #0x96a284】使其强制跳转到生成新设备id的代码位置
    // 0x96a24c: r0 = LoadStaticField(0xccc)
    //     0x96a24c: ldr             x0, [THR, #0x68]  ; THR::field_table_values
    //     0x96a250: ldr             x0, [x0, #0x1998]
    //     0x96a254: ldr             x16, [PP, #0x40]  ; [pp+0x40] Sentinel
    // 0x96a258: cmp             w0, w16
    // 0x96a25c: b.eq            #0x96a300
    // 0x96a260: LoadField: r1 = r0->field_13
    //     0x96a260: ldur            w1, [x0, #0x13]
    // 0x96a264: DecompressPointer r1
    //     0x96a264: add             x1, x1, HEAP, lsl #32
    // 0x96a268: LoadField: r0 = r1->field_7
    //     0x96a268: ldur            w0, [x1, #7]
    // 0x96a26c: cbnz            w0, #0x96a2e8   【强制修改为  b #0x96a284】使其强制跳转到生成新设备id的代码位置
    // 0x96a270: r1 = "custom_device_no"
    //     0x96a270: add             x1, PP, #0x14, lsl #12  ; [pp+0x14bf0] "custom_device_no"
    //     0x96a274: ldr             x1, [x1, #0xbf0]
    // 0x96a278: r0 = getString()
    //     0x96a278: bl              #0x67b5e4  ; [package:sp_util/sp_util.dart] SpUtil::getString
    // 0x96a27c: LoadField: r1 = r0->field_7
    //     0x96a27c: ldur            w1, [x0, #7]
    // 0x96a280: cbnz            w1, #0x96a2e4   【强制修改为  b #0x96a284】使其强制跳转到生成新设备id的代码位置
    // 0x96a284: r1 = Null
    //     0x96a284: mov             x1, NULL
    // 0x96a288: r2 = 4
    //     0x96a288: mov             x2, #4
    // 0x96a28c: r0 = AllocateArray()
    //     0x96a28c: bl              #0xc076fc  ; AllocateArrayStub
    // 0x96a290: r16 = "type"
    //     0x96a290: ldr             x16, [PP, #0x27a0]  ; [pp+0x27a0] "type"
    // 0x96a294: StoreField: r0->field_f = r16
    //     0x96a294: stur            w16, [x0, #0xf]
    // 0x96a298: r16 = "deviceType"
    //     0x96a298: add             x16, PP, #0x14, lsl #12  ; [pp+0x14bf8] "deviceType"
    //     0x96a29c: ldr             x16, [x16, #0xbf8]
    // 0x96a2a0: StoreField: r0->field_13 = r16
    //     0x96a2a0: stur            w16, [x0, #0x13]
    // 0x96a2a4: r16 = <String, dynamic>
    //     0x96a2a4: ldr             x16, [PP, #0x1da8]  ; [pp+0x1da8] TypeArguments: <String, dynamic>
    // 0x96a2a8: stp             x0, x16, [SP]
    // 0x96a2ac: r0 = Map._fromLiteral()
    //     0x96a2ac: bl              #0x48a200  ; [dart:core] Map::Map._fromLiteral
    // 0x96a2b0: str             x0, [SP]
    // 0x96a2b4: r1 = Instance_Uuid
    //     0x96a2b4: add             x1, PP, #0x12, lsl #12  ; [pp+0x12f58] Obj!Uuid@b184f1
    //     0x96a2b8: ldr             x1, [x1, #0xf58]
    // 0x96a2bc: r4 = const [0, 0x2, 0x1, 0x1, options, 0x1, null]
    //     0x96a2bc: add             x4, PP, #0x14, lsl #12  ; [pp+0x14c00] List(7) [0, 0x2, 0x1, 0x1, "options", 0x1, Null]
    //     0x96a2c0: ldr             x4, [x4, #0xc00]
    // 0x96a2c4: r0 = v4()
    //     0x96a2c4: bl              #0x7e6140  ; [package:uuid/uuid.dart] Uuid::v4
    // 0x96a2c8: mov             x2, x0
    // 0x96a2cc: r1 = "custom_device_no"
    //     0x96a2cc: add             x1, PP, #0x14, lsl #12  ; [pp+0x14bf0] "custom_device_no"
    //     0x96a2d0: ldr             x1, [x1, #0xbf0]
    // 0x96a2d4: stur            x0, [fp, #-8]
    // 0x96a2d8: r0 = putString()
    //     0x96a2d8: bl              #0x84f664  ; [package:sp_util/sp_util.dart] SpUtil::putString
    // 0x96a2dc: ldur            x1, [fp, #-8]
    // 0x96a2e0: b               #0x96a2e8
    // 0x96a2e4: mov             x1, x0
    // 0x96a2e8: mov             x0, x1
    // 0x96a2ec: LeaveFrame
    //     0x96a2ec: mov             SP, fp
    //     0x96a2f0: ldp             fp, lr, [SP], #0x10
    // 0x96a2f4: ret
    //     0x96a2f4: ret            
    // 0x96a2f8: r0 = StackOverflowSharedWithoutFPURegs()
    //     0x96a2f8: bl              #0xc07804  ; StackOverflowSharedWithoutFPURegsStub
    // 0x96a2fc: b               #0x96a234
    // 0x96a300: r9 = _androidInfo
    //     0x96a300: add             x9, PP, #0x14, lsl #12  ; [pp+0x14c08] Field <Device._androidInfo@716315110>: static late (offset: 0xccc)
    //     0x96a304: ldr             x9, [x9, #0xc08]
    // 0x96a308: r0 = LateInitializationErrorSharedWithoutFPURegs()
    //     0x96a308: bl              #0xc08034  ; LateInitializationErrorSharedWithoutFPURegsStub
  }


使用 DisElf2 打开【libapp.so】库文件,按照上述思路修改逻辑后保存文件,将 libapp.so 替换进apk后重新打包签名,至此大功告成!!!!
就可以正常使用会员功能拉,如果会员到期直接清空缓存后又双叒叕是一条好汉!

原包和破解包就不发了,怕被查水表
补充个改后的4.0.5版本的libapp.so文件,有需自取:
https://www.123684.com/s/DSEnTd-ZZl0v 提取码:WN9u


叠个甲,免责声明,本教程仅供技术交流,无不良影响,无引流推广,仅提供逆向思路
再次感谢Sunika大佬提供的教程,真的学到东西了!





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

12

主题

1705

回帖

5429

积分

硕士生

Rank: 6Rank: 6

金币
712
好评
2
信誉
90

MT论坛最佳新人

发表于 2025-8-7 19:09:46 来自手机  | 显示全部楼层  来自 四川
有IP验证,不过已经很完美了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0

主题

82

回帖

324

积分

初中生

Rank: 3Rank: 3

金币
248
好评
0
信誉
100
发表于 2025-8-7 14:11:04 来自手机  | 显示全部楼层  来自 重庆
学习
回复

使用道具 举报

14

主题

1721

回帖

5272

积分

硕士生

春日野穹

Rank: 6Rank: 6

金币
3164
好评
4
信誉
103

MT论坛新人考神MT论坛帅哥MT论坛最佳新人

发表于 2025-8-7 14:12:56 来自手机  | 显示全部楼层  来自 广西
看看
回复

使用道具 举报

134

主题

3460

回帖

1万

积分

博士生

无敌最俊朗

Rank: 7Rank: 7Rank: 7

金币
3010
好评
49
信誉
105
发表于 2025-8-7 14:13:47 来自手机  | 显示全部楼层  来自 四川
学习一下思路
回复

使用道具 举报

123

主题

3512

回帖

1万

积分

博士生

●一只菜鸡●

Rank: 7Rank: 7Rank: 7

金币
3509
好评
85
信誉
122

考神MT论坛新人MT论坛最佳新人MT论坛帅哥MT论坛活跃会员

发表于 2025-8-7 14:17:05 来自手机  | 显示全部楼层  来自 江苏
感谢分享,论坛有你更精彩!
回复

使用道具 举报

217

主题

1486

回帖

9407

积分

硕士生

Rank: 6Rank: 6

金币
159
好评
26
信誉
102

考神MT论坛灌水老大MT论坛帅哥MT论坛活跃会员

发表于 2025-8-7 14:17:08 来自手机  | 显示全部楼层  来自 河南
看看
回复

使用道具 举报

39

主题

575

回帖

2705

积分

大学生

Rank: 5Rank: 5

金币
601
好评
10
信誉
93
QQ
发表于 2025-8-7 14:18:02 来自手机  | 显示全部楼层  来自 四川
这啥
回复

使用道具 举报

0

主题

417

回帖

2123

积分

大学生

Rank: 5Rank: 5

金币
324
好评
0
信誉
100
发表于 2025-8-7 14:22:57 来自手机  | 显示全部楼层  来自 广东
看看
回复

使用道具 举报

9

主题

2676

回帖

6798

积分

硕士生

Rank: 6Rank: 6

金币
6398
好评
2
信誉
100

MT论坛最佳新人考神

发表于 2025-8-7 14:23:20 来自手机  | 显示全部楼层  来自 北京
感谢分享
回复

使用道具 举报

0

主题

1589

回帖

7558

积分

硕士生

Rank: 6Rank: 6

金币
3377
好评
0
信誉
100
发表于 2025-8-7 14:23:50 | 显示全部楼层  来自 四川
感谢分享
回复

使用道具 举报

9

主题

772

回帖

2692

积分

大学生

Rank: 5Rank: 5

金币
348
好评
1
信誉
102

考神MT论坛新人

发表于 2025-8-7 14:25:17 来自手机  | 显示全部楼层  来自 浙江
学习
回复

使用道具 举报

30

主题

1104

回帖

4028

积分

大学生

Rank: 5Rank: 5

金币
792
好评
10
信誉
83
QQ
发表于 2025-8-7 14:26:12 来自手机  | 显示全部楼层  来自 福建
看看
回复

使用道具 举报

2

主题

2759

回帖

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
1432
好评
0
信誉
100
发表于 2025-8-7 14:26:30 来自手机  | 显示全部楼层  来自 广东
看看隐藏
回复

使用道具 举报

162

主题

8064

回帖

2万

积分

博士后

滑稽

Rank: 8Rank: 8

金币
953
好评
474
信誉
210

MT论坛新人MT论坛最佳新人MT论坛活跃会员考神MT论坛帅哥MT论坛灌水老大

QQ
发表于 2025-8-7 14:26:39 来自手机  | 显示全部楼层  来自 福建
路过看看
回复

使用道具 举报

0

主题

776

回帖

2351

积分

大学生

Rank: 5Rank: 5

金币
1589
好评
0
信誉
101
发表于 2025-8-7 14:27:48 来自手机  | 显示全部楼层  来自 山东
探探
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表