上一篇介绍了防毕业机制素质相对高的养肝游戏,这次介绍个养肝工具,用于对付素质不那么高的刷刷刷游戏,比如魔灵召唤

Ankulua是一款lua脚本执行器,自带OpenCV识图库,普遍用于手机游戏自动化。相对于开源的Sikuli,Ankulua用起来更简单一些,还有免root使用方案:adb装个daemon。

免费版Ankulua有两个限制:

  • 只能试用30分钟
  • 试用完还有冷却时间

这就不是很肝了。

unzip没发现好玩的东西,用apktool解压:

mv ankulua_v7.2.0-trail.apk ankutrail.apk
apktool d ankutrail.apk

smali/com/appautomatic/ankulua/里,一眼看过去,代码还不少:

cd smali/com/appautomatic/ankulua
cat **/*.smali | wc -l
49301

一个个看不划算,这时想想程序给了什么提示——试用结束时会弹个窗,上面写了Trial version needs to cool down for …,悬浮窗也会换成无法播放的图标。

Android程序字符串一般位于res/values/strings.xml,搜索cooldown:

0x7f060050,仅有的两次调用都出现在OverlayShowingService

第二个用到该字符串的地方是onClick(),没有写操作,忽略。看第一个,grep -A 40 60050 OverlayShowingService.smali

.method private g()V 
    # ...
    :cond_a
    # ...
    const v6, 0x7f060050
    invoke-virtual {v5, v6}, Landroid/content/res/Resources;->getString(I)Ljava/lang/String;
    move-result-object v5
    invoke-virtual {v1, v5}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move-result-object v1
    invoke-virtual {v1, v3}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
    move-result-object v1
    const-string v3, ":"
    invoke-virtual {v1, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move-result-object v1
    invoke-virtual {v1, v4}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
    move-result-object v1
    const-string v3, ":"
    invoke-virtual {v1, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move-result-object v1
    invoke-virtual {v1, v0}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
    move-result-object v0
    invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
    move-result-object v0
    # 
    invoke-virtual {p0, v2, v0, v7}, Lcom/appautomatic/ankulua/OverlayShowingService;->a(Ljava/lang/String;Ljava/lang/String;Z)V
    goto/16 :goto_0

这是Dalvik Opcode,语法简洁清晰,大概长这样:op {args} class;->method(signature) L<return_type>。本篇总共就用到了两个文档,一个是简要版,一个是细致的官方文档

这段作用是,把0x7f060050指向的字符串和冷却时间的时、分、秒拼在一起,然后弹窗提示试用结束。往上翻找到触发条件:

.method private g()V
    # j()返回了转换成秒的android/os/SystemClock;->elapsedRealtime()
    invoke-static {}, Lcom/appautomatic/ankulua/OverlayShowingService;->j()J
    move-result-wide v4
    sget-wide v0, Lcom/appautomatic/ankulua/OverlayShowingService;->I:J
    sub-long/2addr v0, v4
    
    # 这里又用了v4,所以要重新获取一次
    invoke-static {}, Lcom/appautomatic/ankulua/OverlayShowingService;->j()J
    move-result-wide v4 
    
    # 也就是 if (this.I > this.j()) {jump :cond_a};
    const-wide/16 v4, 0x0
    cmp-long v3, v0, v4
    if-gtz v3, :cond_a

标签:cond_a是停止试用,所以this.I就是冷却结束时间了。看看哪里会修改它:

.method public onCreate()V
    # ... 
    # this.I = this.c + now()
    invoke-static {}, Lcom/appautomatic/ankulua/OverlayShowingService;->j()J
    move-result-wide v0
    iget-wide v2, p0, Lcom/appautomatic/ankulua/OverlayShowingService;->c:J
    add-long/2addr v0, v2
    sput-wide v0, Lcom/appautomatic/ankulua/OverlayShowingService;->I:J

this.c就是与运行时长正相关的冷却时长(一个增量),修改它的setter,就可以无限试用了。实践中先patch的是30分钟试用限制,结果跑了1个小时停倒是没停,停下来发现有CD……

.method private k()V
    # ...
    # 在(逻辑上)最后一个iput-wide之前patch
    # const v0, 0 #patch
    # const v1, 0 #patch
    const-side v0, 0
    iput-wide v0, p0, Lcom/appautomatic/ankulua/OverlayShowingService;->c:J
    new-instance v0, Ljava/lang/StringBuilder;
    const-string v1, "duration = "

测试用机是魅蓝Note6,欢快地跑了起来,把apk放模拟器里跑却出现了闪退,logcat错误信息是rejecting opcode。原因是部分dalvik VM类型要求更严格,需要把两个const改成一个const-wide,iput-wide才会接受。

去掉试用时长限制的步骤相对简单些。既然知道跑了一阵子会停,那肯定有个计时器,文件内搜索Timer/Thread/Runnable发现目标:

.method private h()Ljava/lang/String;
    # 相当于: new Handler().post(new Runnable() {check_running_period()};
    # 注释掉最后一行
    sget-object v2, Lcom/appautomatic/ankulua/Settings;->f:Landroid/os/Handler;
    new-instance v3, Lcom/appautomatic/ankulua/OverlayShowingService$3;
    invoke-virtual {v2, v3}, Landroid/os/Handler;->post(Ljava/lang/Runnable;)Z

大功告成,打包签名安装:

apktool b ankutrail -f -o ankutrail.apk
apksigner sign --ks test.jks ankutrail.apk
adb install -r ankutrail.apk

例行公事,虽然新版本加了个阿里的mobisecenhance防破解,售价也从15刀涨到了35刀……有条件还是请支持正版。