关于付费 APP 加密方式的一些疑问

2022-07-01 08:56:34 +08:00
 equationl

可能因为我的水平有限,我所能想到的加密方式似乎都没有实际用处。

比如,某个业务场景是付费用户可以创建无限的素材,而非付费用户只能创建不高于某数量的素材。

虽然我已经用了各种方式来加密这个“某数量”的值,不过不管前面写的多绕,但是最终还是会回归到一个 if 逻辑判断。

比如,针对上述场景,我是这样写的:

    val a = "RWM="
    val b = a.decodeBase64()?.string(Charset.forName("utf8")) ?: "${Char(0)}${Char(0)}"

    val realNum = 10

    if (realNum <= b.toCharArray()[1].code - b.toCharArray()[0].code) {
        println("pass")
    }
    else {
        println("you need pay first")
    }

但是反编译下来是这样的:

(节选)

      if (realNum <= var8 - var3) {
         var4 = "pass";
         System.out.println(var4);
      } else {
         var4 = "you need pay first";
         System.out.println(var4);
      }

不管你前面写的有多复杂,最终还是会回归到简单的 if 逻辑判断,别人修改时只需要删除或者直接改一下这个判断就能轻松破解了。

判断是否付费同理,不管前面写的多复杂,最终会回归到简单的逻辑判断。

所以我现在加密完全依赖于加固,但是加固也只能防的住“脚本小子”一键破解,如果是有大牛专门破解的话,也很容易被脱壳。

虽然防住“脚本小子”已经满足我的需求了,但是我还是想知道,应该怎么在不加固的情况下避免被“一键”破解呢?

据我所知,某个业内有名的 APP ,就没有使用加固,但是就是至今没被破解,甚至作者还专门搞了个悬赏,让别人区破解它。据我了解的是,至今没人破解成功。

补充:

  1. APP 性质决定了没法将需要加密的逻辑放到服务器避免被本地破解
  2. 上述代码只是做了一个示例,实际使用比这个复杂,而且核心代码也是写在 c++ 中的,不过正如我上述说的,即使写在 c++ 中,最终也是回归到 java 调用 c++的代码,然后做一个简单的逻辑判断
  3. 我想到的是把加密和业务逻辑混合在一起,但是自己实际测试过,即使这样反编译后效果也不理想。
6320 次点击
所在节点    程序员
67 条回复
heguangyu5
2022-07-01 09:43:23 +08:00
分享一下我的思路,关键有两点:

1. 定位到 if 判断需要一定时间
2. 要有办法在代码中加入足够多的 if 判断
gaobing
2022-07-01 09:47:15 +08:00
单机版 APP 吗?可以结合服务端进行设置。
TOUJOURSER
2022-07-01 09:49:47 +08:00
某个业内有名的 APP 指的是?
kile
2022-07-01 09:51:17 +08:00
怎么可能才一个 if

多个不同的值共同做加解密,互相做校验,一旦发现校验不通过,直接崩,每句语句都单独写判断。不要整合到一个方法里面。能写多少写多少
equationl
2022-07-01 09:51:50 +08:00
@gaobing 正如我所说的,由于 APP 类型限制,没法把这部分内容放到服务器。

虽然我现在确实也做了利用服务器的在线校验,但是最终还是会回到我正文中说的问题,最后还是靠本地的简单逻辑判断。

但是我这个 APP 又没法把需要加密的代码放到服务端来执行,最终本地只负责接收服务端的计算结果...
lerp
2022-07-01 09:52:43 +08:00
把业务逻辑也写进 c++里,在 c++里再进行签名校验。还有就是更新频率快一点,让他破解的速度跟不上你更新的速度。
equationl
2022-07-01 09:53:41 +08:00
@heguangyu5 我现在就是这样做的,但是这样也只能做到增大“脚本小子”一键破解的难度,只要它稍微多捋一捋,还是能捋清
equationl
2022-07-01 09:54:57 +08:00
@kile
@lerp

这确实是一个好办法,我试试看
xiangyuecn
2022-07-01 09:55:03 +08:00
有没有那么一种可能,只要你代码写的足够复杂,别人就会懒得去破解😂

一个 if 不够,那就整一堆 if ,for 、while 都可以作为 if 的替代品

要是破解了一个地方进来了,里面发现校验不对,直接整点声音、震动、闪屏 物理攻击😂
equationl
2022-07-01 09:55:31 +08:00
@TOUJOURSER MT 管理器
Mitt
2022-07-01 09:57:08 +08:00
没有什么破解不了,只取决于你的价值,其实以前有很多反破解做的很好的外挂说自己不可破解甚至还悬赏,基本都是因为太嚣张第一天就被破解了然后卷着尾巴跑了的,还是应该把附加价值算进去,比如售后好一点之类的,别人愿意买正版那被破解了也无所谓,最怕的就是把防破解做到极致了,客户都跑了
equationl
2022-07-01 10:00:54 +08:00
@Mitt 这确实,我也没打算防这些大牛,我只想防“脚本小子”的一键破解,这些人太烦了,基本都是一些刚入门的学生,用别人写好的脚本破解了就沾沾自喜,到处发,真的大牛一般即使破解了也不会像他们这样到处发到处宣传
YouKnowIt
2022-07-01 10:31:57 +08:00
上定制版的 dex vmp 可以保护住,防防脚本小子没问题的
dearmymy
2022-07-01 10:40:09 +08:00
只能说有很多小技巧增加难度。针对你这种简单方法是。
两套校验逻辑
1 ,java 业务层判断,这种 if 比较容易被破解,而且需要提示给正常用户。
2 ,搞套 c++库逻辑,起个线程静默判断,发现 c++判断无效,但是前端逻判断有效,说明前端判断逻辑被爆破。c++线程里设置个变量,然其他 c++调用地方故意搞崩溃,不要给前端任何提示。
这样就符合你不需要太多加固,又比较简单拦住一帮新手了。
ZhiyuanLin
2022-07-01 10:43:19 +08:00
另一个思路是给个简单破解的口子,破解了会在生成素材加不可见水印+上传制作者信息到服务器。
然后律师函走起。
libook
2022-07-01 10:48:07 +08:00
加固通常对源代码没有侵入,个人认为能用加固解决的问题就尽量不要去污染源代码。
heguangyu5
2022-07-01 10:50:57 +08:00
@equationl 我没有实际做过破解,多问一句,如果在代码里加上几十万处 if 后,if 代码不完全一致,是有办法批量处理的吗?
yaocai321
2022-07-01 10:53:15 +08:00
曾经破解过一个 App ,他的反破解还挺有意思的。
先搞个类,里面的校验代码挺正常的,实际上是迷惑你的。 运行时,会利用双亲委派的机制,替换掉这个类。
这个用来替换的类,会将字节码加密成字符串存在某个地方。
是不是有点意思?
equationl
2022-07-01 11:07:12 +08:00
@heguangyu5 全自动不行,但是可以半自动,只要分析出你的逻辑,几十万,还是几十亿不都是批量替换的事嘛
equationl
2022-07-01 11:08:36 +08:00
@libook 这个确实也是,但是加固有个问题就是现在加固几乎没有支持加固 aab 的,但是 play 只允许上传 aab 了。只能二选一。

ps:我知道 360 支持加固 aab ,但是价格太高了,不是我能承受的起的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/863351

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX