来自黑洞的旅人(小小戰姬 / Mobile Goddess) Spine LayaAir引擎

dianliu

资源位置

热更新资源

/storage/emulated/0/Android/data/com.lzhddlrcs.yf/cache/gameRes/localRes/webp/res/crypto/

APK

image-20260629160850270

分析

加密逻辑在bundle1.js中,混淆过了,直接丢给llm分析吧。

分析结果显示gwcrypto是核心目标,需要找相关逻辑进行下一步分析。

随便找一个文本编辑器,Ctrl F搜索一番可以推断出处理逻辑:基于url(大概率是文件名称)来生成一个掩码,再用这个掩码进行特定的解码。

image-20260709123747596

相应的,应该能找到这个gwcrypto的声明位置

var gwcrypto,
  _0x38d07f = _0x43df;

不难猜到这里是一个混淆手段,所以后续应该围绕_0x38d07f 以及 _0x43df展开。

继续寻找_0x38d07f这个变量的引用,找到了疑似的函数

image-20260709124641765

看不懂怎么办?你懂的。

当然实际上自己处理的时候并没有这么顺利,不建议过度依赖llm,因为很容易被一个错误的方向误导,然后会一直陷入幻觉。

LayaAir是一个web引擎,不难猜到应该有个web版本

Play Online - Mobile Goddess

F12 开控制台

console.log(gwcrypto)
...
console.log(gwcrypto.getMaskCode.toString())
->
function(t,e){var n=_0x43df,s=t[n(207)]("/"),t=t[n(204)](s+1),r=(s=(t=-1<t[n(207)](n(217))?t[n(192)](n(217),""):-1<t[n(207)](n(216))?t[n(192)](n(216),""):(t=(t=t[n(192)](n(206),""))[n(192)](n(209),""))[n(192)](n(193),""))[n(223)]("-"))[1]?parseInt(s[1],16):i;for(r%=e[n(228)];3*r<i;)r*=3;return r}

console.log(gwcrypto.codec.toString())
->
function(t,i){for(var n=e,s=Math[n(205)](Math[n(200)](t[n(228)]/4)),r=new Uint32Array(t,0,s*s),a=s,o=s,h=48;s<2*h;)h=Math[n(205)](s/2);for(var l=0;l<o;l++)for(var c=0;c<a;c++){var u=c,_=l,d=!1;if(Math[n(205)](l/h)%2==0){if(l+h<o?_=l+h:d=!0,Math[n(205)](c/h)%2==0)c+h<a&&(u=c+h);else{if(d)continue;u=c-h}d=l*a+c,_=_*a+u,u=r[d],r[d]=r[_]^i,r[_]=u^i}}return t}
// console.log(gwcrypto.MaskUtil.toString())

挺奇怪,昨天测试的时候还能正常consolo输出,今天就显示异常了。 :tieba_15:

image-20260709123050362

数据处理

所有的.png都是webp格式的,需要把webp转png。skel/atlas/png都是同样的加密方式处理的。

APK里面还有个 gameres.zip 加密过了,不知道是什么,自行研究吧。

  1. decrypt.py
  2. Webp2Png.py

没了。 :tieba_01:

1 个赞

感谢大佬,Google版本以前也叫 来自黑洞的旅人,改名后叫小小戰姬。

1 个赞