debug - 只要在内存中有显示相关的数据, 就会被CE找到

文章目录

    • debug - 只要在内存中有显示相关的实际数据, 就会被CE找到
    • 概述
    • 笔记
    • demo实现
    • demo运行效果
    • 用CE查找实际数据地址
    • 找到自己的调试点 - 方法1
    • 找到自己的调试点 - 方法2
    • 打补丁
    • 备注
    • END

debug - 只要在内存中有显示相关的实际数据, 就会被CE找到

概述

自己写了一个demo, 想验证一下, 如果不让显示值和实际值是一个地址(不直接使用结构, 而是用函数从结构中取值, 然后通过函数返回值给显示值用, 是否可以给CE增加一些麻烦? 发现不好使:P 因为实际值也是有地址的, 一样会被CE找到…

CE在查找/定位数据方面, 真是利器.

我在demo中, 还做了显示值和实际值的比对, 如果显示值被改了, 就退出程序.
结果, 程序直接跑. 用CE冻结找到的内存值时, 居然检测不到显示值和实际值不一样. 只有在用CE调试后, 才能检测到显示值和实际值不一样…, 可能是自己写的有bug.

也有可能被锁定的是实际数据, 已经过了作弊检查那个函数.
也有可能, 找到的都不是显示值的地址. 所以能通过作弊检查的函数. 因为每次都只激活一个CE表项.

笔记

demo实现

/*!
* \file Defence_CE_FindData.cpp
* \brief 防止CheatEngine查找数据的方法
*   CE擅长查找数据, 试试能不能给CE找点麻烦(用函数来取显示数据的地址/用函数取要显示的值, 而不是直接用结构指针).
* 
* \note 编程环境: vs2019 x64 debug console
*/#include <Windows.h>#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <cstdint>// 游戏UI中元素的显示用地址(e.g. 先使用控件的对象指针)
class game_addr_for_display
{
public:game_addr_for_display() { m_addr = NULL; }void set(float* addr) { m_addr = addr; }float* get() { return m_addr; }private:float* m_addr;
};class game_real_data
{
public:game_real_data() { m_data = .0f; }void set(float data) { m_data = data; }float get() { return m_data; }void res_inc() { m_data++; }private:float m_data;
};class game
{
public:void init(float* _addr_to_disp){m_disp.set(_addr_to_disp);}void run(){printf("please use CE modify real data, not display data, if APP exit(), means failed\n");do {Sleep(1000);m_data.res_inc(); // game resouce inc by some reasonshow_data();if (check_CE_modify()){printf("maybe memory was modify by some tools\n");break;}} while (true);}void show_data(){*m_disp.get() = m_data.get();printf("res disp data = %f\n", *m_disp.get());}bool check_CE_modify(){float f_disp = *m_disp.get();float f_real = m_data.get();return (((f_disp - f_real) < 0.001) ? false : true);}private:game_addr_for_display m_disp;game_real_data m_data;
};int main()
{float val_to_disp;game _game;_game.init(&val_to_disp);_game.run(); // entry game loopsystem("pause");return 0;
}

demo运行效果

在这里插入图片描述

用CE查找实际数据地址

运行程序
用CE附加程序
CE高级选项暂停目标程序.
在这里插入图片描述

查找(浮点数 + 精确值), 填入的值为UI上显示的值为进程暂停后最后的UI值. e.g. 35
用CE恢复目标进程, 让程序接着跑. 等UI显示的值变化了, 再次暂停目标进程, 再Next查找
如果找到的比较多, 就重复上步, 直到找到的值较少.
我这里最后最少只能找到4个, 将这4个都加入CE表.
恢复进程, 让程序正常跑起来.
逐个激活找到的单条CE表项, 每次只激活一条CE表项.
观察是否会使UI上显示的值不变.
最后确定可以使UI值不变的那条CE表项
在这里插入图片描述
现在锁定的那条CE表项, 锁定的值为179, UI值是180. 综合自己写的demo逻辑, 可知, 现在锁定的CE表项是实际值.
用函数返回实际值, 再赋值给UI, 根本对CE没用:)

确定了影响UI显示的确定CE表项后, 将该项的激活选择去掉, 让程序正常跑.
查找该表项对应的写入指令, 如果查到了写入这个地址的指令, 就看反汇编, 应该使用实际数据的逻辑就在附近.
我这里只查到一条指令, 且看到这条指令在不断的更新这个地址(CNT = 12, 不断的再更新UI的值, 使变化的实际数据更新到UI).
如果查找到多条指令, 都逐条看看反汇编, 看看哪条是使用实际数据来更新UI值的实现.
如果找到多条指令, 可以用指令写入次数来判断, 哪条指令是干活的实际指令.
在这里插入图片描述
在这里插入图片描述
进入反汇编窗口, 惊讶. 因为程序是自己写的, 可以很清楚的看懂逻辑, 这里正是更新实际数据的实现
逻辑如下

从保存实际数据的结构中取得实际值(这个数据结构是类的指针, 类数据地址针对类指针有个偏移)
将取到的实际数据放入浮点寄存器.
将浮点寄存器的值 + 1
将更新后的实际数据(在浮点寄存器xmm0中), 更新(回写)到类成员变量中给.

可知, 实际数据(类成员变量)的地址就是 [rbp + 0xE0].

在此处反汇编处上面找一处合适的语句(开始取实际数据的值, 还没开始执行更新实际值的逻辑), 下断点, 手工记录推算一下.
在这里插入图片描述
RBP = B083EFF890
RBP + 0xE0 = B083EFF970
在这里插入图片描述
[RBP + 0xE0] => 0xB083EFFAC0
执行一句, 走到APP+11B16
RAX = B083EFFAC0, 和推算的一样, 这就是[RBP + 0xE0]的值.

在内存区, 去看地址 B083EFFAC0中的值
在这里插入图片描述
[ B083EFFAC0] = 0x44FAE000
用自己做的浮点计算器(小工具 - 浮点计算器)看一下对应的实际浮点值是多少?
在这里插入图片描述
可知, 现在实际值是2007.0
因为现在逻辑是实际值刚取到, 还没更新呢, 应该是UI值一样. 看了一下, 是这样.
在这里插入图片描述
将自己找到的这个合适的补丁点, 在单步调试的界面, 就加入codeList, 后续打补丁(或者供后续调试)用, 防止后续万一找不到了自己辛苦找到的调试点.
在这里插入图片描述
在这里插入图片描述
向下单步执行, 执行完实际数据+1操作后, 看一下xmm0寄存器, 可以看到实际值已经变为了2008.0
在这里插入图片描述
再单步执行到给实际值地址赋值后, 看一下更新后的值, 和自己推算的一样.
在这里插入图片描述

找到自己的调试点 - 方法1

在codelist中找到自己的调试点, 去反汇编区.
在这里插入图片描述

找到自己的调试点 - 方法2

如果下次想根据笔记直接找到调试点(如果脚本没保存), 可以搜索2进制指令
如果搜索到的不是唯一一条, 将目标语句上下文的关联汇编语句加进入一起搜索, 直到能搜索到自己的唯一调试点

48 8B 85 E0 00 00 00 F3 0F 10 00 F3 0F 58 05 AA 92 00 00

搜索的每个字节之间用空格分开, 否则搜索报错.
在这里插入图片描述
在这里插入图片描述

打补丁

打补丁, 让实际数据直接锁定为9999.0
合适的补丁点为将实际数据取出的那句.
在这里插入图片描述
补丁效果
在这里插入图片描述

补丁代码如下:

[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048,"Defence_CE_FindData.exe"+11B16) 
label(returnhere)
label(originalcode)
label(exit)newmem: //this is allocated memory, you have read,write,execute access
//place your code here
// 打补丁, 让实际数据直接锁定为9999mov [rax], (float)9999.0originalcode:
movss xmm0,[rax]
addss xmm0,[Defence_CE_FindData.exe+1ADCC]exit:
jmp returnhere"Defence_CE_FindData.exe"+11B16:
jmp newmem
nop 7
returnhere:[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"Defence_CE_FindData.exe"+11B16:
db F3 0F 10 00 F3 0F 58 05 AA 92 00 00
//movss xmm0,[rax]
//addss xmm0,[Defence_CE_FindData.exe+1ADCC]

备注

CE适合用来找线索(由可见的外在现象找实际数据的操作逻辑), 缩小调试关注的范围.
找到关键代码附近时, 再用IDA来学习.
如果只是关心数据逻辑, 找到关键数据后, 直接打补丁, 就O了.

如果要打补丁/查找数据, 用CE来做是很方便的.

END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/692092.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人工智能_PIP3安装使用国内镜像源_安装GIT_普通服务器CPU_安装清华开源人工智能AI大模型ChatGlm-6B_002---人工智能工作笔记0097

接着上一节来看,可以看到,这里 创建软连接以后 [root@localhost Python-3.10.8]# ln -s /usr/local/python3/bin/python3 /usr/bin/python3 [root@localhost Python-3.10.8]# python3 -V Python 3.10.8 [root@localhost Python-3.10.8]# pwd /usr/local/Python-3.10.8 [root@…

Vue26 内置标签 v-text v-html

实例 <!DOCTYPE html> <html><head><meta charset"UTF-8" /><title>v-text指令</title><!-- 引入Vue --><script type"text/javascript" src"../js/vue.js"></script></head><…

第一件事 什么是 Java 虚拟机 (JVM)

1、什么是虚拟机&#xff1f; - 这个其实是一个挺逗的事情&#xff0c;说白了&#xff0c;就是基于某个硬件架构&#xff0c;在这个硬件部署了一个操作系统&#xff0c;再构架一层虚拟的操作系统&#xff0c;这个新构架的操作系统就是虚拟机。 不知道的兄弟姐妹们&#xff0c;…

重学Java 18.学生管理系统项目

臣无祖母&#xff0c;无以至今日&#xff0c;祖母无臣&#xff0c;无以终余年 母孙二人&#xff0c;更相为命&#xff0c;是以区区不能废远 —— 陈情表.李密 —— 24.2.20 一、编写JavaBean public class Student {//学号private int id;//姓名private String name;//年龄pr…

Codeforces Round 925 (Div. 3)(A,B,C,D,E,F,G)

比赛链接 这场打的很顺&#xff0c;感觉难度和 div 4 差不多&#xff0c;不是很难。D题稍微考了考同余的性质&#xff0c;E题直接模拟过程即可&#xff0c;F题也可以暴力模拟或者拓扑排序&#xff0c;G题是个数学题&#xff0c;是个简单隔板法。A到F题都可以直接模拟就有点离谱…

「WinCC报警系统专题」简述“消息系统”

WinCC通过报警给操作员提供了有关过程故障和错误的信息。它们有助于尽早检测重要情况和避免停机时间。 一、消息系统 消息&#xff08;报警&#xff09;系统由组态和运行系统组件组成。 1、组态系统 报警记录编辑器&#xff08;如图1所示&#xff09;是报警系统的组态组件。报…

docker (九)-进阶篇-docker-compos最佳实践部署zabbix

一 部署docker环境 关闭防火墙、selinux、开启docker&#xff0c;并设置开机自启动 注意点&#xff1a;docker部署的时候&#xff0c;bip要指定&#xff0c;不然会导致虚拟机ip和容器ip冲突&#xff0c;ssh连不上虚拟机 部署请参考 docker &#xff08;二&#xff09;-yum…

为什么程序员不能一次性写好,需要不停改bug?

写程序不是一次性完成的原因有很多&#xff0c;其中包括了解不充分、需求变更、复杂性、人为因素等多个方面的原因。 需求不明确&#xff1a; 在项目一开始&#xff0c;对需求可能存在歧义或不完整的理解。有时候&#xff0c;业务需求会在开发过程中发生变化&#xff0c;导致…

Go应用性能分析实战

Go很适合用来开发高性能网络应用&#xff0c;但仍然需要借助有效的工具进行性能分析&#xff0c;优化代码逻辑。本文介绍了如何通过go test benchmark和pprof进行性能分析&#xff0c;从而实现最优的代码效能。原文: Profiling Go Applications in the Right Way with Examples…

【Vuforia+Unity】AR03-圆柱体物体识别

1.创建数据库模型 这个是让我们把生活中类似圆柱体和圆锥体的物体进行AR识别所选择的模型 Bottom Diameter:底部直径 Top Diameter:顶部直径 Side Length:圆柱侧面长度 请注意&#xff0c;您不必上传所有三个部分的图片&#xff0c;但您需要先为侧面曲面关联一个图像&#…

工具分享:在线键盘测试工具

在数字化时代&#xff0c;键盘作为我们与计算机交互的重要媒介之一&#xff0c;其性能和稳定性直接影响到我们的工作效率和使用体验。为了确保键盘的每个按键都能正常工作&#xff0c;并帮助用户检测潜在的延迟、连点等问题&#xff0c;一款优质的在线键盘测试工具显得尤为重要…

Java后端底座从无到有的搭建(随笔)

文章目录 开发模式的演变草创时期1.0时期&#xff08;基座时期&#xff09;1.1时期&#xff08;低代码时期&#xff09;2.0时期&#xff08;无代码时期&#xff09; 前言&#xff1a;本文是笔者在初创公司&#xff0c;一年多来Java后端服务底座搭建过程的总结&#xff0c;如有不…

四旋翼无人机控制-零散笔记整理

四旋翼无人机控制-零散笔记整理 说明仿真框架 说明 这是低创文章&#xff0c;本意是整理本科留下来的一堆零碎的纸质笔记&#xff0c;整理完就把纸质的扔了。所以前后不连贯&#xff0c;也可能有错误&#xff0c;图片都是直接拍的笔记照片&#xff0c;很丑。如果想系统学习的可…

【C++】STL- > string类(超详解!!!)

文章目录 前言1、string类的出现1.1 C语言中的字符串1.2 平时使用 2. 标准库中的string类2.1 string类的常用文档&#xff08;重要&#xff09;&#xff01;&#xff01;&#xff01;&#xff01;2.2 string类的常用接口说明(接口原型我这里就不展示了&#xff0c;文档中都有可…

前后端分离(delivery-management)部署文档

1. 前端项目:delivery-management 1.1. 前端项目打包 执行命令:npm run build 或者yarn run build,生成dist目录。 构建流程如下图: 1.2. 文件上传 将打包好的前端项目(dist目录),上传到服务器,并拷贝到nginx安装目录html目录下。 执行上传命令(sftp):put -r E:\…

展示用HTML编写的个人简历信息

展示用HTML编写的个人简历信息 相关代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document…

Windows 自带的 Linux 子系统(WSL)安装与使用

WSL官网安装教程&#xff1a; https://learn.microsoft.com/zh-cn/windows/wsl/install Windows 自带的Linux子系统&#xff0c;比用VM什么的香太多了。可以自己看官方教程&#xff0c;也可以以下步骤完成。 如果中间遇到我没遇到的问题百度&#xff0c;可以在评论区评论&#…

Redis(03)——发布订阅

基础命令 基于频道 publish channel message&#xff1a;将信号发送到指定的频道pubsub subcommand [argument [argyment]]&#xff1a;查看订阅或发布系统状态subscribe channel [channel]&#xff1a;订阅一个或多个频道的信息unsubscribe [channel [channel]]&#xff1a;退…

Java——Stream流的学习

在开发过程中&#xff0c;经常或忽略流的使用&#xff0c;导致用的不熟练&#xff0c;于是抽时间系统的学习下stream的使用&#xff0c;找了哔哩哔哩的教程跟着看看练练。 准备工作 创建Book、Aurhor实体类&#xff0c;初始化数据 public static List<Author> getAuth…

解锁文档处理新境界:ONLYOFFICE编辑功能为开发者带来新机遇

引言 ONLYOFFICE最新发布的文档8.0版本带来了一系列引人注目的功能和优化&#xff0c;为用户提供了更强大、更高效的在线编辑体验。这次更新涵盖了多个方面&#xff0c;包括PDF表单、RTL支持、单变量求解、图表向导以及插件界面设计更新等。这些新功能不仅提升了文档处理的便利…