逆向思路

CE工具

https://www.cheatengine.org/downloads.php

Cheat Engine

基本概念

进程的基址

CE中静态地址(或者说基址)以绿色字体显示,静态地址可以理解为全局变量或静态变量在内存空间中的地址,在一个程序编译时,就已经确定其在进程的内存中空间地址了,除非更改代码,静态地址在每次加载程序中都不会改变

学过PE结构的应该都知道,其值大多数都放在data段中。 12A473A0 这个字体是黑色的,在CE中代表动态地址,可以理解成局部变量,是在栈里面的,每次加载程序地址是会改变,是不确定的

通过值找基址

“值” 则是指存储在特定地址中的数据内容, 扫描出来都是值 **in short 类似要找到 ‘GC的root 对象’ **

  1. 底层地址: 查找的是写入操作, 找到对应的寄存器地址(通常有偏移的, 需记录偏移)
  2. 底层-1指针:查找的是访问操作, 勾上HEX(16进制) 搜索

5大排除法:碰到如下相符的5种情况,无需跟踪, 那么剩下的就是正确的了 排除1:值变动不跟 排除2:空白代码不跟 排除3:直接传址(大概率假的) 排除4:相似地址不跟 排除5:地址不等不跟

手动定位

实例

  1. 找到对的地址 19FBCE21CEC

  2. 查找写入 WeChatWin.dll+13094AC - mov [rax+rbx*2],bp

翻译一下是: 将寄存器 bp 的值移动到内存地址 [rax+rbx*2] 处;

[rax+rbx2] MD这里是动态偏移!? 偏移 rbx2 rax = 19FBCE21CE0

  1. 二级 新搜索 19FBCE21CE0 勾上HEX 搜索; 查找 访问 WeChatWin.dll+1309C1B - mov rax,[rcx]

… 直至找到绿色基址

指针扫描?

右键这个地址选(对这个基址进行指针扫描) > 注意指针级别参数 > 确定后会需要保存一个文件

重开游戏或者重上游戏让 指针刷新 再次找出指针(之前扫的界面再次扫描)

一直重复上面操作,当数据数据变成几十的时候里面的数据基本都是可以用的随便拿一个都可以用

指令地址 转 x64dbg地址

WeChatWin.dll+2C4577F - 48 2B D1 - sub rdx,rcx

  • 在CE中是 WeChatWin.dll+2C4577F

  • 在 x64dbg 中需要 符号找到该模块的基址复制基址 00007FFC89D90000+2C4577F = 7FFC 8C9D 577F

监控内存修改与访问 F5 & F6

Find out what accesses this assress Find out what writes to this assress

将会监控到修改此内存的汇编指令 gtutorial-x86_64.exe+400E3: 1000400DE - 00 00 - add [rax],al 1000400E0 - 48 89 C8 - mov rax,rcx 1000400E3 - 29 50 60 - sub [rax+60],edx << //操作的指令: 减法(sub) 地址([rax+60]), edx(寄存器) 1000400E6 - C3 - ret 1000400E7 - 00 00 - add [rax],al

Replace with code that does noting 可以将该指令替换为(NOP) 啥也不做

指令逻辑注入

Find out what writes to this address (定位到汇编指令后) Show disassembler Tools Auto Assemble Template Code injection

代码注入的原理就是把原来那个位置的指令换成 jmp,跳转到我们新申请的一块内存中,程序正常运行到这里就会跳转到我们新申请的那块内存中,然后执行我们的指令,我们自己写的指令的最后一条指令是跳转回原来的位置,这样程序中间就会多执行一段我们的指令了。

内存结构分析 Dissect data/structures

在Memory Viewer窗口,然后点击 Tools——Dissect data/structures,或者使用快捷键Ctrl+D,进入结构浏览器,将地址 添到文本框里,然后点击菜单Structure——Define new structure,或使用快捷键Ctrl+N,一路回车之后,我们就可以结构

可以将几个不同的内存地址作为起始地址, 按顺序对比内存值列表 (红色为不同值, 绿色为相同值), new structure 的 size 为对比内存大小, 不要重叠就行了

调试

Find out what writes to this address (定位到汇编指令后) Show disassembler 右键 set breakporint (可以设置断点, 调试汇编指令) 此操作将会附加进程调试

无法附加进程?

CE (Cheat Engine) 调试器无法附加进程是一个常见问题。可能有以下几种原因导致这个问题:

操作系统安全设置:某些操作系统(特别是 Windows 10)会禁止 CE 调试器附加进程,你需要更改你的安全设置以允许 CE 调试器附加进程。 进程权限:CE 调试器需要以管理员身份运行,否则无法附加进程。 进程保护:某些进程可能会有保护机制,防止 CE 调试器附加。 防护软件:如果你在使用防护软件(例如反病毒软件),它可能会阻止 CE 调试器附加进程。

DBVM

官方解释:https://www.cheatengine.org/aboutdbvm.php

关于DBVM DBVM是一个虚拟机,可以运行操作系统并扩展指令集,使用户模式应用程序能够访问内核模式。它允许程序将系统事件的流重定向到不同的位置并改变其结果。(例如,将中断重定向到不同的中断处理程序,而无需编辑中断表)

Cheat Engine可以利用这些新增指令来简化游戏修改和调试。特别是在Vista 64位系统中。要使用它,只需启动DBVM,它将启动您的操作系统(通常是Windows),Cheat Engine将自动检测到DBVM已加载,并利用新增功能。

安全性:DBVM可以被恶意软件使用。因此,它需要一个160位长的密钥来使用这些指令。其中一个指令是将默认密钥更改为其他密钥,以防止其他程序在没有正确密钥的情况下使用它。

一个简单的方法来确定您的系统是否支持dbvm是 在 help about 它会告诉您系统是否支持以及您是否实际上已加载了dbvm,并且还会告诉您运行的dbvm修订版。

Ultimap

Ultimap是 cheatengine 官网出的搜索汇编调用计次工具,使用这个工具可以迅速定位到程序指定内存地址。

常用的寻基址方法就是字节搜索,变量加减搜索,指针扫描大法…但是如果遇到加密程序按这些方法可能就无法找到了,

所以还有个方法就是用ultimap寻找,直接冲汇编调用次数来寻找。

它是一个可以 过滤 执行汇编指令的强大工具, 需要开启DBVM

Ultimap这玩意可以快速定位找到call位置,是个神器,但是吃内存 开启该功能相当于开启个小型的虚拟机,会将程序所以代码挂入虚拟机,当程序代码执行后,会记录汇编代码是否经过位置,记录次数 ,每条代码都记录和计次,属实有点吃内存

  1. Memory View > Tools Ultimap Code did not get executed //代码没有执行 Code has been executed //代码已执行 Filter out routine(s) that where not CALL’ed//代码没有调用CALL

Banch目标为0?
解决方案: 编辑设置调试器选项 user kernelmodel debugger [Make possible]

利用CheatEngine工具Ultimap功能对抗游戏数据加密以及拓展

x64dbg 工具

约等于64的OD

官方网站 加壳原理笔记06:反调试技术入门 x64dbg使用技巧与实用插件合集

技巧帮助

流程图 在反汇编窗口按下G键切换到流程图

高亮模式 按H键, 此时单击需要高亮显示的内容即可高亮显示,再次按下H,点击空白处可以取消。

内存断点 x64dbg可以内存区域,设置 内存访问断点或内存写入断点,原理是对所设的地址赋予不可访问/不可写属性,这样当访问/写入的时候就会产生异常。x64dbg捕获异常后,比较异常地址是不是断点地址,如果是就中断,接着用户就可以调试了。

事件断点 选项 > 选项 > 事件; 可以设置断点, 默认的断点就是这里来的

汇编特征搜索

和 OD 不同,x64dbg没有提供 find sequence of commands 功能,要想搜索多条指令,可以用特征码匹配来代替。

mov [rax+rbx*2],bp 可以右键选择搜索–当前区域–匹配特征,把指令的字节码填入十六进制搜索即可;

注意是汇编的二进制, 在x64dbg是 右键汇编指令二进制复制, 在CE是 右键 copy to clipboardBytes 其实就是 byte 部分的内容

WeChatWin.dll+2C4577F - 48 2B D1 - sub rdx,rcx //rcx 即当前 WeChatWin.dll+2C45782 - 0FB7 04 3A - movzx eax,word ptr [rdx+rdi] WeChatWin.dll+2C45786 - 66 89 07 - mov [rdi],ax //微信 写会话wxid; 48 2B D1 0F B7 04 3A 66 89 07

断点

断点原理

(1)软件断点 内存断点的实现方式是将你欲下断地址所在的内存页增加一个名为PAGE_NOACCESS的属性,这个属性会把当前内存页设为禁止任何形式的访问,如果进行访问会触发一个内存访问异常。在这同时,od开始捕获目标程序中出现的这个异常,并判断触发这个异常的位置是否跟你下断的地址相同,如果相同则内存断点触发,暂停被调试程序的运行,否则放行。有极大的性能问题

(2)硬件断点 与软件断点不同,硬件断点是通过修改特定的处理器寄存器来实现的,这些寄存器用于跟踪指令地址和数据访问地址。硬件断点通常比软件断点更快,但是受到硬件限制,可以在某些情况下设置的数量有限。

条件断点

暂停条件: 1 永真, 0永假; 可以读取寄存器表达式

防检测

替换驱动保护文件

找出游戏驱动保护文件(火绒剑)

运行程序,打开火绒剑,寻找可疑驱动文件,点击文件属性查看数字签名进一步确认。 将其替换空白文件

设置高级防护,防止原驱动保护文件再生(https://blog.csdn.net/qq_43082315/article/details/127173648?spm=1001.2014.3001.5502)

重新编译CE

https://www.52hb.com/thread-56936-1-1.html

反调试

一般监测被调试的函数 checkdebug IsDebuggerPresent CheckRemoteDebuggerPresent BeingDebugged

https://www.wenjiangs.com/doc/rh2g3fgey8