〖无聊的白嫖〗某叶 游戏加速器 无限24小时 让软件获取随机设备ID

查看 193|回复 10
作者:芽衣   
本教程只是提供思路,并不是让你拿着软件照着改,特别是说想拿来练练手的,我都快要笑死了。所以
没有样品
提供!

准备工具:
1、反编译工具
2、java2smali
3、绿叶
本教程不适合小白。软件样品为当前最新版8.1.0,随时可能失效。软件有签名校验,就不再分析了,用工具一键hook即可。软件免费会员只有24小时,时间不算长,用来救急还是不错的选择。软件有广告,观看广告或者签到之后可以获取一定时长的会员。

像一些抓包或者事前准备就不说了,略过,直接讲重点。先看一下app界面。


1.png (60.49 KB, 下载次数: 4)
下载附件
2020-12-8 21:14 上传

这个加速器新用户送24小时的黄金会员,而且是自动注册的,安装注册后再卸载重装并没有重置会员状态,那么考虑是获取了设备id进行了一个验证。
我试过对vip进行赋值,即使显示绿金会员还是提示了“会员到期”,所以这款app是服务器验证的,那入手点就从免费送24小时会员那里切入。
首先我想到的思路是让这个app获取一个随机ID,以此来逃避用户检查。当然方法很多,比如用xp框架改、抓包或者在虚拟机里面运行都是可以办到的。但是这样只是改了和app无关的东西,有点差强人意。所以我直接硬杠app。
实际上大部分app进行设备封号基本上都会获取id,至于还获取了什么这就要看开发者了,但是设备id不会缺席,每次都有它。
反编译后直接搜索字符串【deviceId】,有几个结果,进入到SplashActivity。如下图:


1.png (78.19 KB, 下载次数: 6)
下载附件
2020-12-8 21:30 上传

public static String j(Context context) {
                        SharedPreferences a = e.a(context);
                        String string = a.getString("pref_local_device_id", "");
                        if (!string.equals("")) {
                                        return string;
                        }
                        String string2 = Settings.Secure.getString(context.getContentResolver(), "android_id");
                        if (f.j(string2) || "9774d56d682e549c".equals(string2)) {
                                        string2 = UUID.randomUUID().toString();
                        }
                        a.edit().putString("pref_local_device_id", string2).commit();
                        return string2;
        }
然后跳转跟进j,原本的Java如上。这个方法有个明显的randomUUID,还有一个字符串9774d56d682e549c,这个字符串是什么可以百度看一下。所以的话它的老巢就是这里,启动的时候app从这个方法获取了设备id,然后上传到服务器进行注册,如果是新id就是新用户了,所以你卸载重装是没有用的。
根据它的id格式9774d56d682e549c,我现在要让这个方法产生一个随机16位的字符串,并包含小写字母和数字,看看能不能欺骗服务器。
先写一段Java给他安排上:
public class Utils {
public static String j(int length) {
    int a = 16;
    String KeyString = "123456789abcdef";
    int len = KeyString.length();
    StringBuffer sb = new StringBuffer();
    for(int i=0;i
因为这个写法是万用的,所以在一些场景中是非常有效的改法。
其中代码中的16是字符串的长度,可以根据需求随便改,如果你想产生8位随机数就写8。然后123456789abcdef就是字库,从里面抽取进行排列,你想抽什么就放什么。因为16进制没有那么多的字母,所以只保留到f,又因为开头我感觉应该不会是0,所以0也去掉了。
然后把这段Java转换成smali,就得到了下面这个:
.class public LUtils;
.super Ljava/lang/Object;
.source "Utils.java"
# direct methods
.method public constructor ()V
    .registers 1
    .prologue
    .line 1
    invoke-direct {p0}, Ljava/lang/Object;->()V
    return-void
.end method
.method public static j(I)Ljava/lang/String;
    .registers 11
    .prologue
    .line 5
    const/16 v1, 0x10
    .line 6
    const-string v2, "123456789abcdef"
    .line 7
    invoke-virtual {v2}, Ljava/lang/String;->length()I
    move-result v3
    .line 8
    new-instance v4, Ljava/lang/StringBuffer;
    invoke-direct {v4}, Ljava/lang/StringBuffer;->()V
    .line 9
    const/4 v0, 0x0
    :goto_e
    if-ge v0, v1, :cond_27
    .line 10
    invoke-static {}, Ljava/lang/Math;->random()D
    move-result-wide v6
    add-int/lit8 v5, v3, -0x1
    int-to-double v8, v5
    mul-double/2addr v6, v8
    invoke-static {v6, v7}, Ljava/lang/Math;->round(D)J
    move-result-wide v6
    long-to-int v5, v6
    invoke-virtual {v2, v5}, Ljava/lang/String;->charAt(I)C
    move-result v5
    invoke-virtual {v4, v5}, Ljava/lang/StringBuffer;->append(C)Ljava/lang/StringBuffer;
    .line 9
    add-int/lit8 v0, v0, 0x1
    goto :goto_e
    .line 12
    :cond_27
    invoke-virtual {v4}, Ljava/lang/StringBuffer;->toString()Ljava/lang/String;
    move-result-object v0
    return-object v0
.end method
我们只需要提取方法中的代码就可以了,其它不用理。
把这段代码覆盖到原来的方法里面去,然后回编译试一下。


1.png (81.38 KB, 下载次数: 3)
下载附件
2020-12-8 21:58 上传

结果还是……
好吧这样行不通。虽然产生了一个随机的设备id,但还是无法进行新用户注册。观察到这个app多次获取了id,开发者可能也想到了这个,如果出现变动那么肯定有问题。
那现在继续换另一种思路,直接写死id。


1.png (57.5 KB, 下载次数: 0)
下载附件
2020-12-8 22:04 上传

这个随便填,然后回编译测试一下。启动时先清除app所有数据,防止本地数据不一致,然后再打开。


1.png (97.96 KB, 下载次数: 0)
下载附件
2020-12-8 22:08 上传

成功!


1.jpg (5.11 KB, 下载次数: 0)
下载附件
2020-12-9 10:20 上传

过期的时候改一下id无限续命。

当然,如果你想随机抽取固定字符串的话,还可以这样设计,举例:
public class Test
{
    public Test()
    {
    }
    public static String num(String s)
    {
        int i = (int)(Math.random() * 5D);
        return (new String[] {
            "3452788", "8689967857", "8765785", "885755", "879785475"
        });
    }
}
代码中的数字就是要抽取的字符串,5D就是在5个之中抽取。
转换成smali代码就是:
.class public LTest;
.super Ljava/lang/Object;
.source "Test.java"
# direct methods
.method public constructor ()V
    .registers 1
    .prologue
    .line 6
    invoke-direct {p0}, Ljava/lang/Object;->()V
    .line 7
    return-void
.end method
.method public static num(Ljava/lang/String;)Ljava/lang/String;
    .registers 5
    .prologue
    .line 11
    invoke-static {}, Ljava/lang/Math;->random()D
    move-result-wide v0
    const-wide/high16 v2, 0x4014000000000000L    # 5.0
    mul-double/2addr v0, v2
    double-to-int v0, v0
    .line 12
    const/4 v1, 0x5
    new-array v1, v1, [Ljava/lang/String;
    const/4 v2, 0x0
    const-string v3, "3452788"
    aput-object v3, v1, v2
    const/4 v2, 0x1
    const-string v3, "8689967857"
    aput-object v3, v1, v2
    const/4 v2, 0x2
    const-string v3, "8765785"
    aput-object v3, v1, v2
    const/4 v2, 0x3
    const-string v3, "885755"
    aput-object v3, v1, v2
    const/4 v2, 0x4
    const-string v3, "879785475"
    aput-object v3, v1, v2
    aget-object v0, v1, v0
    return-object v0
.end method

下载次数, 字符串

shenhuen10   

理论上可以添加一个按钮然后写一个随机生成id的方法实现点击按钮续期。
或是每次打开自动获取剩余时间,如果过期了就自动生成随机的id再重试
AniMe1235   

你好请问gg修改怎么给他套层皮来达到防检测呢
枯坐万年   

谢谢分享
longling   

好用好用!谢谢楼主
jinhuiyi521   

这是个好东西,不用再烦网络延迟了
清风入梦   

感谢分享
我在B站撸猫   

这妹妹图上哪找的?
doge888   

非常满意
枯坐万年   

感谢发布原创作品,吾爱破解论坛因你更精彩!
您需要登录后才可以回帖 登录 | 立即注册