吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 31410|回复: 232
收起左侧

[原创] steam某塔防游戏破解

    [复制链接]
yellowtail 发表于 2023-2-11 17:14
本帖最后由 yellowtail 于 2023-2-11 17:34 编辑

概述

最近在玩Steam某款塔防游戏,玩了1000多小时,难度低的地图都过去了,点击模式过不去,竞速模式因为手残成绩不太理想,所以萌生了破解、逆向的念头,研究一下

省流

部分功能破解成功,但是被官方抓住了,封号了,无法联机(也就是长草,但是本地模式还是可以玩的

所以大家练习的时候,记得开小号尝试,大号被封了就很emo

游戏版本是 34.3.6116

长草

长草
Snipaste_2023-02-11_15-25-29.png

unity游戏破解思路

打开游戏安装目录,发现是 unity 游戏
unity游戏破解思路比较固定

运行时有两种: mono 或者il2cpp

mono步骤简单点,就是 dnspy 分析代码+修改il字节码(步骤较少,难度不一定)
il2cpp 步骤多点,如下所示

  1. Il2CppDumper 提取c#代码结构,得到 Assembly-CSharp.dllscript.jsonstringliteral.json和其他文件
  2. dnspy 分析Assembly-CSharp.dll找到关键方法(函数)
  3. ida 分析 libil2cpp.so(安卓)GameAssembly.dll(Windows)
  4. ida 加载script.jsonstringliteral.json
  5. 找到关键修改点,用汇编转16进制网站,得到修改后的16进制,用010修改、保存(记得备份)

分析

步骤1、2、3、4,我之前的帖子已经描述过了,这里就不再赘述
某unity游戏逆向破解

这里直接进入第五步

首先玩一下游戏,得到一些概念

概念 关键字
防御塔 Tower  Hero
生命值 Hp
伤害 Damage
buff buff
技能 skill
攻击范围 Range Distance
升级 Upgrade
金币 gold``cost gain(获得金币)
飞艇 ddt moab
折扣 discount(猴村的折扣)

找了很多地方,尝试了一些修改,但是效果不太理想,这里放1个有效果的

升级折扣

dnspy 搜索 GetTowerUpgradeCost

(为什么搜索这个?因为我用关键字找了很多的地方,其它地方没有效果,只有这里有效果,所以才贴出来:keai )
GetTowerUpgradeCost.png

看到签名如下

public float GetTowerUpgradeCost(Tower tower, int path, int tier, float overrideBaseCost = -1f, bool isParagonUpgrade = false)
{
return default(float);
}

可知:方法返回一个 float浮点数,表示当前防御塔升级所需要消耗的金币

用ida看一下实现
GetTowerUpgradeCost-ida.png

看红色区域

LABEL_45:
  v41 = *(_QWORD *)(a1 + 24);
  if ( !v41 )
    goto LABEL_50;
  LOBYTE(v16) = FreeUpgrade == 0;
  if ( (float)((float)((float)v16 * v14)
             * (float)(1.0
                     - Assets_Scripts_Simulation_Simulation__GetSimulationBehaviorDiscount(// 得到折扣值
                         v41,
                         a2,
                         a3,
                         a4,
                         LODWORD(v34)).m128_f32[0])) < 0.0 )
    return 0.0;
  else
    return (float)(int)Assets_Scripts_Simulation_SMath_Math__RoundToNearestInt(v42, 5);// 得到浮点数临近的int(floor)

大概的意思是:

  1. 得到折扣系数
  2. 如果折扣小于0(我实在想不到怎样可以小于0,那只能是程序员防御编程了,避免出bug,严谨!),那么就返回0.0
  3. 否则用cost*discount, 再floor一下返回(RoundToNearestInt的作用)

其实,这一个方法里面有很多的修改点

  1. 最后一行的v42就是折扣系数,5应该是原始价格(这里可能是ida识别错误,毕竟找不到v42的来演),那么可以修改v42或5
  2. 如果折扣值小于0,就返回0,可以修改为去掉判断,直接返回0(jmp)
  3. GetAreaDiscount得到折扣区域,我们可以加大这个返回值
  4. GetDiscountMultiplier得到折扣系数,我们可以加大这个返回值

修改返回值,还比较费劲,如果代码返回立即数还好说,汇编也能改,如果返回寄存器或者需要寻址,就费劲了,所以我选择了最简单的,修改跳转逻辑,也就是2

可以看到,ida里的if语句,在汇编里是

il2cpp:0000000180B5A0AE 0F 5B D2                      cvtdq2ps xmm2, xmm2
il2cpp:0000000180B5A0B1 F3 41 0F 59 D0                mulss   xmm2, xmm8
il2cpp:0000000180B5A0B6 F3 0F 10 05 82 9C A1 01       movss   xmm0, cs:Y
il2cpp:0000000180B5A0BE F3 0F 5C C1                   subss   xmm0, xmm1
il2cpp:0000000180B5A0C2 F3 0F 59 D0                   mulss   xmm2, xmm0
il2cpp:0000000180B5A0C6 0F 2F F2                      comiss  xmm6, xmm2
il2cpp:0000000180B5A0C9 77 3F                         ja      short loc_180B5A10A

看到ja就应该能想到jmp
ja是满足某种条件之后才跳转,跳到返回0的地方,我们改为无脑跳转jmp就好了
if.png

首先看一下调整偏移量
77 3fja 0x41
我们改为jmp 0x41就好
可以看到,77改为eb就行
jmp.png

转换网站是 Online-Assembler-and-Disassembler

ida改完看一下效果
change-after.png

看起来是有效果的,那么上 010 修改一下

010偏移和ida有所差异(不知道为啥),我是通过搜索16进制找到的
搜索 F3 0F 59 D0 0F 2F F2 77 3F 找到了唯一的一个地方(如果出现多个,那么就继续多复制几个字节,直到只有一个为止)

修改77eb
010.png

直接进游戏吧
start.png

有效果的

效果是:塔的升级都是免费的;放置塔要花钱,无法免费升级到模范塔

作弊和反作弊

玩了几局,效果可以的

当天也没有封号
但是第二天再登录游戏,就长草、封号了

猜测是游戏的时候,上传的那些数据,游戏服务器会做离线计算,发现不对,就封号

后面再开了一个小号,等封号之前赶紧进行竞速比赛,发现最后无法提交成绩
无法提交成绩.png

看来提交成绩的时候,还会再做一次数据校验,于是抓包分析了一下

以下是步骤和分析结果,结论就是:本人太菜,反作弊失败

抓包

安卓上抓包,很简单,wifi 设置代{过}{滤}理,或者用  potsern 把流量导到电脑上,或者骚气的,直接用 eCapture 抓包

电脑上,需要一定的思路和技巧

第一招: hosts

  1. wireshark 抓dns包,得到域名
  2. 修改hosts为本地 https服务
  3. https服务流量转到charles上
  4. charles通过设置 dns解析服务器,把流量发到正确的服务器上

比较费劲的是第三步,需要自己写代码实现,费了好大劲才搞出来

第二招,v2clash
这个也是偶然想到的,之前破解 羊了个羊小程序的时候,就是用这招抓电脑版微信小程序的流量,这次试了一下,对电脑版游戏也适用

v2clash可以安装虚拟网卡,通过设置规则,让指定进程流量发到抓包软件上,就可以抓到游戏的包了(仅限http/https类型的包,如果游戏是tcp的,那得想别的办法)

以下贴几个请求和样例吧,因为有签名和加密,加密逻辑没有逆向出来,就不多写了

DNS 查询

A static-api.nkstatic.com A 104.18.16.97 A 104.18.17.97        

A api.ninjakiwi.com A 104.19.235.38 A 104.19.234.38        

A bfb.ninjakiwi.com A 104.19.234.38 A 104.19.235.38        

A analytics.ninjakiwi.com A 104.19.234.38 A 104.19.235.38        

A fast-static-api.nkstatic.com A 104.18.16.97 A 104.18.17.97        

可以发现ip都是 104.19 或者 104.18

这些都是 cloudflare 的地址

/unity/time

得到服务器时间

{
    "error": null,
    "data": "{\"date\":{\"time\":1675178987230}}",
    "sig": "392ae763cc5171fd893a2ef1640d6a26373120e5"
}

杰哥买东西

每在商店买一次东西,都会发起请求一次

连续买两次,那么在延迟几秒之后,只会发起一个请求,数量是2

比如下面买了三个辣椒

兔子是 PetRabbit

POST /btd6/mobile/geraldoshopdata HTTP/1.1
Host: bfb.ninjakiwi.com
Accept: */*
Accept-Encoding: deflate, gzip
Cookie: xxxx
user-agent: btd6-windowsplayer-34.3.6116
donottrack: 0
Content-Type: application/json
signature: 01f261aa3a490fbe4b5a385a5fcc6ad2
X-Unity-Version: 2021.3.12f1
Content-Length: 745

{
        "game_id": "5158",
        "attempt_id": "0",
        "round_id": "78",
        "geraldoshopitem_ShootyTurret": "0",
        "geraldoshopitem_StackOfOldNails": "0",
        "geraldoshopitem_CreepyIdol": "0",
        "geraldoshopitem_JarOfPickles": "0",
        "geraldoshopitem_RareQuincyActionFigure": "0",
        "geraldoshopitem_SeeInvisibilityPotion": "0",
        "geraldoshopitem_TubeOfAmazoGlue": "0",
        "geraldoshopitem_SharpeningStone": "0",
        "geraldoshopitem_WornHerosCape": "0",
        "geraldoshopitem_BladeTrap": "0",
        "geraldoshopitem_BottleHotSauce": "3", //辣椒
        "geraldoshopitem_Fertilizer": "0",
        "geraldoshopitem_PetRabbit": "0",  // 兔子
        "geraldoshopitem_RejuvPotion": "0",
        "geraldoshopitem_GenieBottle": "2",
        "geraldoshopitem_ParagonPowerTotem": "0",
        "userId": "xxx",
        "created_at": "2023-02-01 12:21:21",
        "session_id": "1675252467",
        "_delta": "5"
}

换英雄 selectHero

POST /btd6/mobile/selectHero HTTP/1.1
Host: bfb.ninjakiwi.com
Accept: */*
Accept-Encoding: deflate, gzip
Cookie: xxx
user-agent: btd6-windowsplayer-34.3.6116
donottrack: 0
Content-Type: application/json
signature: f05362162af86562455edee0cae4081d
X-Unity-Version: 2021.3.12f1
Content-Length: 133

{
        "hero_name": "Geraldo",
        "userId": "zzz",
        "created_at": "2023-02-01 12:02:32",
        "session_id": "1675252467",
        "_delta": "6"
}

响应

{
        "send": true,
        "error": ""
}

开始游戏 startTrack

POST /btd6/mobile/startTrack HTTP/1.1
Host: bfb.ninjakiwi.com
Accept: */*
Accept-Encoding: deflate, gzip
Cookie: xxxx
user-agent: btd6-windowsplayer-34.3.6116
donottrack: 0
Content-Type: application/json
signature: 5f4397120971317beb34496ee198f965
X-Unity-Version: 2021.3.12f1
Content-Length: 409

{
        "game_mode": "MagicOnly",       //仅魔法
        "resumed_game": "no",
        "coop_mode": "no",
        "map_name": "Carved",           // 地图
        "difficulty": "Hard",          // 困难模式
        "overwrote_save": "1",
        "monkey_money": "52204",       // 猴钞数量
        "knowledge_points": "0",
        "game_id": "5158",
        "attempt_id": "0",
        "hero_selected": "Geraldo",    // 英雄
        "hero_skin": "Geraldo",        // 英雄皮肤
        "event_id": "",
        "rank": "155",
        "is_restart": "false",
        "userId": "xxxx",
        "created_at": "2023-02-01 12:03:00",
        "session_id": "1675252467",
        "_delta": "1"
}

响应

{
        "send": true,
        "error": ""
}

改变目标 changeTargetingPrio

POST /btd6/mobile/changeTargetingPrio HTTP/1.1
Host: bfb.ninjakiwi.com
Accept: */*
Accept-Encoding: deflate, gzip
Cookie: xxx
user-agent: btd6-windowsplayer-34.3.6116
donottrack: 0
Content-Type: application/json
signature: 001c45a0dc7437980986af166483205c
X-Unity-Version: 2021.3.12f1
Content-Length: 159

{
        "towerName": "Alchemist-220",           // 炼金220
        "prevOrNext": "Prev",
        "userId": "xxx",
        "created_at": "2023-02-01 12:14:14",
        "session_id": "1675252467",
        "_delta": "3"
}
{
        "send": false,
        "error": "disabled"
}

游戏结束之后 新增猴钞

POST /bank/balances HTTP/1.1
Host: api.ninjakiwi.com
Accept-Encoding: deflate, gzip
Cookie: xxx
User-Agent: btd6-windowsplayer-34.3
Content-Type: application/json
Accept: application/json
X-Unity-Version: 2021.3.12f1
Content-Length: 294

{
        "data": "{\"accountHolder\":\"xxx\",\"wallets\":[\"NK_ACCDATA\"]}",
        "auth": {
                "session": "xxx",
                "appID": 11,
                "skuID": 35,
                "device": "no_linkxxxx"
        },
        "sig": "95ae9e69bfbea2b049df7261a51e4328",
        "nonce": "2998913795344284556"
}

可以看到这里的响应体里出现了 sig ,说明这个响应体被签名了, 直接进行中间人攻击是没有用的,得找到验签逻辑,破解掉才行

特殊 /storage/static/multi

游戏启动的时候,会触发这个请求,猜测是 获取每日活动之类的,竞速、boss等

但是结果是加密的,无法直接阅读
charles.png

这个请求会一直发到服务器,猜测官方也是通过这个请求来实现反作弊的,但是因为不知道怎么解密,所以看不到明文,进行不下去了

免费评分

参与人数 68威望 +2 吾爱币 +168 热心值 +61 收起 理由
xinshengyue + 1 + 1 谢谢@Thanks!谢谢作者!
PawnSaruto + 1 热心回复!
liujun2000114 + 1 + 1 感谢发布教程!!!
Element777 + 1 + 1 谢谢@Thanks!
onlywey + 1 + 1 谢谢@Thanks!
vieing727360 + 1 + 1 我很赞同!
xiguadandan + 1 + 1 谢谢@Thanks!
rnundiw + 1 谢谢@Thanks!
soyadokio + 1 用心讨论,共获提升!
Zz4794zZ + 1 + 1 谢谢@Thanks!
hkq666 + 1 + 1 谢谢@Thanks!
AlphaGo + 1 + 1 热心回复!
mis落为 + 1 NeweBeer!!!!
aabbcc123123 + 1 + 1 谢谢@Thanks!
柑桔 + 1 + 1 用心讨论,共获提升!
Yanglen + 1 + 1 用心讨论,共获提升!
jiangrui98 + 1 + 1 我很赞同!
iceSleeping + 1 + 1 谢谢@Thanks!
wdraemv + 1 + 1 我很赞同!
RiiiickSandes + 1 我很赞同!
tianjianggouxia + 1 + 1 热心回复!
viewing727360 + 1 + 1 我很赞同!
lookerJ + 1 + 1 用心讨论,共获提升!
shili180 + 1 + 1 我很赞同!
hututu739 + 1 + 1 热心回复!
笙若 + 1 + 1 谢谢@Thanks!
Bluesky10 + 1 + 1 我很赞同!
维C糖果 + 1 我很赞同!
CrazyNut + 3 + 1 用心讨论,共获提升!
fengbolee + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
xwmowzvi + 1 + 1 热心回复!
gunxsword + 1 + 1 热心回复!
indobe + 1 谢谢@Thanks!
Bin2450 + 1 + 1 我很赞同!
gaosld + 1 + 1 热心回复!
Flytom + 1 + 1 我很赞同!
Minesa + 1 + 1 用心讨论,共获提升!
dyanst + 1 + 1 我很赞同!
yvhkchao + 1 + 1 谢谢@Thanks!
baopushouzhuo + 1 + 1 我很赞同!
mkami + 1 我很赞同!
pp67868450 + 1 + 1 用心讨论,共获提升!
不喝酒的陈小熊 + 1 + 1 我很赞同!
s20211111 + 1 + 1 热心回复!
H19990807 + 1 + 1 用心讨论,共获提升!
maddock + 1 厉害啊
threeleaves + 1 + 1 用心讨论,共获提升!
cn211211 + 1 热心回复!
plasd + 1 + 1 谢谢@Thanks!
daoye9988 + 1 + 1 热心回复!
兴趣使然 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
道冲渊风 + 1 + 1 谢谢@Thanks!
yxpp + 1 用心讨论,共获提升!
dongmie + 1 + 1 用心讨论,共获提升!
Bob5230 + 1 + 1 谢谢@Thanks!
guiwuzhe + 1 + 1 热心回复!
LM14233 + 1 + 1 热心回复!
yinya0473 + 1 + 1 用心讨论,共获提升!
heimaojingzhang + 1 + 1 谢谢@Thanks!
萌新与小白 + 1 + 1 热心回复!
Lightstarx + 1 + 1 我很赞同!
KFCcrazyThurs + 1 我很赞同!
xiaosu28 + 1 + 1 热心回复!
侃遍天下无二人 + 4 + 1 用心讨论,共获提升!
正己 + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
维多利加 + 1 + 1 热心回复!
RickSanchez + 1 + 1 热心回复!
youranata + 1 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| yellowtail 发表于 2023-2-12 11:01
Arcticlyc 发表于 2023-2-12 10:24
想请问一下,v2clash是什么,具体怎么操作的

说错了,软件名是 Clash for Windows


1. 安装虚拟网卡
2. 开启 Tun Mode
3. 编写配置文件

Fiddler 或者 charles 就可以抓包了。

配置文件如下

[Plain Text] 纯文本查看 复制代码
proxies:
  - name: charles
    type: socks5
    server: 127.0.0.1
    port: 8889
rules:
  - PROCESS-NAME,BloonsTD6.exe,charles
  - MATCH,DIRECT
Arcticlyc 发表于 2023-2-12 10:17
Arcticlyc 发表于 2023-2-12 10:24
a3284595 发表于 2023-2-12 10:27
厉害  感谢分享学习
liushuaijie123 发表于 2023-2-12 10:41
金钱和血量是加密的,分析那个比较有意思。我去年玩这个游戏还用CE脚本写过解密过程,不知道后来加解密方式改变了没有。
chen1860906 发表于 2023-2-12 11:11
感谢分享,
不搭落俗笑忘书 发表于 2023-2-12 11:20
学习一下,感觉不错
wxxbc 发表于 2023-2-12 11:54
感谢分享
 楼主| yellowtail 发表于 2023-2-12 11:56
liushuaijie123 发表于 2023-2-12 10:41
金钱和血量是加密的,分析那个比较有意思。我去年玩这个游戏还用CE脚本写过解密过程,不知道后来加解密方式 ...

大佬还记得加密大概的思路么?

我分析的结果是 循环字节加减,不知道方向对不对
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-22 11:06

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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