Open CelestialCosmic opened 1 year ago
这一篇是 《dnspy 调试新版 unity》的后续
上一次弄的是 mono 的,但是很快就发现这些对 il2cpp 的不起作用,所以又有了这一篇
首先准备 cpp2il,写个脚本给它方便操作
chcp 65001 cls set /p gamepath="输入游戏路径" set /p exefile="输入主程序名字(如果有.exe请删除)" .\Cpp2IL-2022.0.7-Windows.exe --game-path="%gamepath%" --exe-name="%exefile%" pause
这样程序会把东西解压到 cpp2il_out 里面
cpp2il_out
代码被反编译出来的那一刻,直接收回想法:
// Token: 0x17000063 RID: 99 // (get) Token: 0x0600057B RID: 1403 RVA: 0x00002050 File Offset: 0x00000250 [Token(Token = "0x17000063")] public string Raw { [Token(Token = "0x600057B")] [Address(RVA = "0x5FC090", Offset = "0x5FB090", VA = "0x1805FC090")] get { return null; } }
加密过了,能看得到的只有函数名
去查,得到这个说法:
RVA: (Relative Virtual Address 简称 RVA),RVA 只是内存中的一个简单的相对于 PE 文件装入地址的偏移位置,或称为偏移量。 VA:在 PE 用语里,实际的内存地址被称作虚拟地址(Virtual Address)简称VA。 虚拟地址 VA =装入地址(Imagebase) + 相对虚拟地址(RVA)
想起前几天弄的一个 rpgmaker 的,用了什么六代 jsjiami ,然后被开源工具 0.7 秒解密,感慨攻防双方的无尽战争,顺带咒骂加私货还加密它的组织(原文件没有任何加密),这种东西只会拖延人十分钟的进度
尝试 de4dot ,但是它删除了所有的 release
ipwnosx/de4dot-All-Version-2021: GG
这里有之前的 release
一万个 error,没用
这种双重保护的时候就不要想着装插件改代码了,准备磕汇编吧
应该要开 IDA 和 cheatengine 试试看了,不过在此之前需要收集可疑函数
发现它做了自己的类:
using Cpp2IlInjected; using System; namespace OHD.Dungeons.Player { // Token: 0x02000751 RID: 1873 [Token(Token = "0x2000751")] public enum PlayerHPState { // Token: 0x04001C06 RID: 7174 [Token(Token = "0x4001C06")] Normal = 1, // Token: 0x04001C07 RID: 7175 [Token(Token = "0x4001C07")] Injury, // Token: 0x04001C08 RID: 7176 [Token(Token = "0x4001C08")] SeriousInjury } }
全局搜索 "0x4001C06",发现只是一个类成员变量
"0x4001C06"
所以我逐渐开始理解一切:
[Token(Token = "0x6002CBF")] 是类里面的变量
[Token(Token = "0x6002CBF")]
[Address(RVA = "0x80EC60", Offset = "0x80DC60", VA = "0x18080EC60", Slot = "4")] 则揭示了函数的地址与其使用的参数数量
[Address(RVA = "0x80EC60", Offset = "0x80DC60", VA = "0x18080EC60", Slot = "4")]
[FieldOffset(Offset = "0x0")] 应该是比特位移位
[FieldOffset(Offset = "0x0")]
DllImportAttribute_metadata.txt 则记录了引入的东西
DllImportAttribute_metadata.txt
于是我锁定了一段代码:
这是一段血量代码
// OHD.Dungeons.Player.BattleRoomPlayer // Token: 0x06002CF9 RID: 11513 RVA: 0x00002053 File Offset: 0x00000253 [Token(Token = "0x6002CF9")] [Address(RVA = "0x79C030", Offset = "0x79B030", VA = "0x18079C030", Slot = "34")] public override void RecoverHP(int recoverAmount) { }
根据我的猜测,这个地址是 18079B030
18079B030
丢进 IDA 里面,起始地址是 180001000
180001000
18079B030 得到 call sub_180B83830 18079C030 得到 mov [rsp+arg_0], rbx
call sub_180B83830
18079C030
mov [rsp+arg_0], rbx
因为它应该是个函数的首地址,所以我认为 18079B030 更合适
再看看游戏启动以后的表现
cheat engine 这时候开启 mono 也没用
跳转 gameassembly.dll,这次得到 7FFEF42F0000
7FFEF42F0000
再跳转 7FFEF4A8B030 (gameassembly.dll+offset) 得到操作码 cld
7FFEF4A8B030
cld
7FFEF4A8B030 - cld 7FFEF4A8B031 - xchg [rsi],edi 7FFEF4A8B033 - add [rax+rax*8-74B7EC8C],al 7FFEF4A8B03A - and al,38 7FFEF4A8B03D - test rcx,rcx 7FFEF4A8B040 - je 7FFEF4A8B084 ; 跳到段内 7FFEF4A8B042 - xor edx,edx 7FFEF4A8B044 - call 7FFEF4CB0F50 ; 去了别处 7FFEF4A8B049 - jmp 7FFEF4A8B023 ; 无用 7FFEF4A8B04B - mov rdx,[7FFEF7055608] 7FFEF4A8B052 - lea rcx,[rsp+28] 7FFEF4A8B057 - call 7FFEF46E8800 ; 跳转到一段空代码 7FFEF4A8B05C - jmp 7FFEF4A8B079 ; 跳到段内 7FFEF4A8B05E - mov rdx,[7FFEF7055608] 7FFEF4A8B065 - lea rcx,[rsp+28] 7FFEF4A8B06A - call 7FFEF46E8800 ; 跳转到一段空代码 7FFEF4A8B06F - mov rcx,[rsp+70] 7FFEF4A8B074 - test rcx,rcx 7FFEF4A8B077 - jne 7FFEF4A8B08A ; 跳转到下面的xor那里 7FFEF4A8B079 - mov rbx,[rsp+78] 7FFEF4A8B07E - add rsp,60 7FFEF4A8B082 - pop rdi 7FFEF4A8B083 - ret 7FFEF4A8B084 - call 7FFEF46B1F10 ; 另一段跳转 7FFEF4A8B089 - nop 7FFEF4A8B08A - xor edx,edx 7FFEF4A8B08C - call 7FFEF46B1EE0 ; 无用 7FFEF4A8B091 - int 3
还有一个值得注意的点:从这里开始,下面有九个跳转
即便打下断点,游戏中的操作也不会触发断点,说明这里只是前期处理的时候使用过,游戏启动以后就完全不被使用了。
我想找的函数大概就藏在里面...
所以寻址大概就是:
上一次弄的是 mono 的,但是很快就发现这些对 il2cpp 的不起作用,所以又有了这一篇
获得源代码
首先准备 cpp2il,写个脚本给它方便操作
这样程序会把东西解压到
cpp2il_out
里面代码被反编译出来的那一刻,直接收回想法:
加密过了,能看得到的只有函数名
去查,得到这个说法:
想起前几天弄的一个 rpgmaker 的,用了什么六代 jsjiami ,然后被开源工具 0.7 秒解密,感慨攻防双方的无尽战争,顺带咒骂加私货还加密它的组织(原文件没有任何加密),这种东西只会拖延人十分钟的进度
尝试解除混淆
尝试 de4dot ,但是它删除了所有的 release
ipwnosx/de4dot-All-Version-2021: GG
这里有之前的 release
一万个 error,没用
对齐地址
这种双重保护的时候就不要想着装插件改代码了,准备磕汇编吧
应该要开 IDA 和 cheatengine 试试看了,不过在此之前需要收集可疑函数
发现它做了自己的类:
全局搜索
"0x4001C06"
,发现只是一个类成员变量所以我逐渐开始理解一切:
[Token(Token = "0x6002CBF")]
是类里面的变量[Address(RVA = "0x80EC60", Offset = "0x80DC60", VA = "0x18080EC60", Slot = "4")]
则揭示了函数的地址与其使用的参数数量[FieldOffset(Offset = "0x0")]
应该是比特位移位DllImportAttribute_metadata.txt
则记录了引入的东西于是我锁定了一段代码:
这是一段血量代码
根据我的猜测,这个地址是
18079B030
丢进 IDA 里面,起始地址是
180001000
18079B030
得到call sub_180B83830
18079C030
得到mov [rsp+arg_0], rbx
因为它应该是个函数的首地址,所以我认为
18079B030
更合适再看看游戏启动以后的表现
cheat engine 这时候开启 mono 也没用
跳转 gameassembly.dll,这次得到
7FFEF42F0000
再跳转
7FFEF4A8B030
(gameassembly.dll+offset) 得到操作码cld
还有一个值得注意的点:从这里开始,下面有九个跳转
即便打下断点,游戏中的操作也不会触发断点,说明这里只是前期处理的时候使用过,游戏启动以后就完全不被使用了。
我想找的函数大概就藏在里面...
所以寻址大概就是: