当前位置: 首页 > article >正文

windows平台游戏外挂实现原理

游戏开发


文章目录

  • 游戏开发
  • 前言


前言

windows游戏外挂泛滥的根本原因就是太容易,只需要明白windows的原理。

我们都知道windows下的可执行文件的扩展名为exe(executable file)。

exe文件是一个二进制文件,是由0、1构成的数据流(stream),把这个数据流想象成一条有固定长度的纸带,纸带上有等分的格子,每个格子上有一个符号,要么是0,要么是1,然后按照一定的要求来读取上面的内容,比如每8个格子代表一个信息如:01000101。

我们并不清楚01000101意味着什么,但是我们有一本字典,这本字典记录了01000101对应的意思,这本字典就叫做汇编指令集。

汇编指令很容易看懂,但逻辑并不易懂,它看起来就像一本故事书,故事的内容并不是连续的,需要根据一定的信息来猜测它要表达的意义。

没错就是猜测,既然是猜测那么猜测的根据是什么?那就要根据想要做的事情来想办法,比如我要修改游戏里人物的血量,血量是一个整数并且知道血量的具体数值,那么问题就简单了,使用CE(Cheat Engine)就可以根据数值找到对应的汇编指令,改写汇编指令,然后再把汇编编译成exe可执行文件,这样我们就达到了修改目的,破解版软件可以使用这种方式。

以上的方法在软件执行之前通过修改逻辑达到目的,更容易的方法是通过修改内存(memory)来达到同样的目的。

下面举一个小例子,TargetApp002.exe为例,我们在内存当中修改它内部的数值:
在这里插入图片描述

TargetApp002内部有一个弹窗,弹窗里有一个自增长的值,当前值为1,我们现在将这个值修改为1050:
在这里插入图片描述

windows程序执行起来,程序就会加载到内存当中,内存中有软件的执行逻辑,也有数据。

windows首先会给程序分配一个pid(process id),然后把进程加载到内存中,映射内存地址。

我们只需要知道程序的映射内存的起始地址,就可以确定具体数值的位置,只要程序不变,数据在映射内存中的位置不变。

首先使用CE查找到弹窗当中值为1的数据在内存中的地址:
在这里插入图片描述

TargerApp002.exe+6788就是我们使用CE查找到的数值,TargetApp002.exe代表的就是程序的起始地址,+6788代表着该数据存放的位置,这个+6788就叫做偏移地址(offset address),可以理解成相对位置。

!!!每次启动程序都会给程序分配不同的pid,起始地址会变,但是这个偏移地址永远不会变。

OK,我们知道这个,按照这个思路就可以写对应的代码,代码使用python调用window32 API操作。

第一步:获取程序的映射起始地址。

第二步:写入内存地址+6788的值

第三步:读取内存地址+6488的值

#1
def imageBase(self):
pModules = win32process.EnumProcessModules(self.hProcess)
return pModules[0]
#1代码可以获取到程序所有模块的映射地址,第一个就是程序的起始地址。

#2
def write(self, memAddr, num, dataLen, dataType=‘’):
if dataType == ‘int’:
addr = ctypes.c_int32(num)
elif dataType == ‘float’:
addr = ctypes.c_float(num)
elif dataType == ‘double’:
addr = ctypes.c_double(num)
dataLen = 8
elif dataType == ‘long’:
addr = ctypes.c_ulong(num)
else:
addr = ctypes.c_int32(num)
return ctypes.windll.kernel32.WriteProcessMemory(int(self.hProcess), ctypes.c_void_p(memAddr), ctypes.byref(addr), dataLen, None)
#2代码写入内存。

#3
def read(self, memAddr, dataLen=4, dataType=‘’):
if dataType == ‘int’:
addr = ctypes.c_int32()
elif dataType == ‘float’:
addr = ctypes.c_float()
elif dataType == ‘double’:
addr = ctypes.c_double()
dataLen = 8
else:
addr = ctypes.c_ulong()

    ctypes.windll.kernel32.ReadProcessMemory(int(self.hProcess), ctypes.c_void_p(memAddr), ctypes.byref(addr), dataLen, None)return addr.value

#3代码读取内存地址。

#4
def main():
w32 = mem.MemOperation(“TargetApp002”, None)
image = w32.imageBase()
w32.write(image+0x6788,1050,4,int)
value = w32.read(image+0x6788,4,int)
print(“当前值为:{var}”.format(var=value))
根据程序标题名称查找到程序,然后获取到映射起始地址,向+6788内存写入数据,读取数据,我们将数据修改为1050,效果如下。

由于是自增长数据,所以执行弹窗的时候自加1,显示为1051。

OK明白了原理,代码就很简单。

http://www.lryc.cn/news/2413181.html

相关文章:

  • 关于破解邮箱的一点心得
  • 【毕业设计】简易无线点餐系统设计【实物+硬件+原理图+论文】【可定制】
  • C语言写飞机大战编程项目
  • 中级ASP程序员的编程技巧(转)
  • 博客能赚钱吗?如何赚钱
  • 教你轻松看懂源代码
  • 使用Adobe AIR开发Android应用
  • DAU、MAU、UV:谁是最有参考价值的活跃指标?
  • mp3
  • Java-网络编程基础
  • 旅游网站设计
  • Python爬虫从入门到精通:(45)JS逆向:空中网逆向分析:js混淆_Python涛哥
  • IntelliJ IDEA 2016.2激活方法汇总
  • 程序设计竞赛推荐两本实用书给你
  • cuteftp8.3序列号
  • 使用jsmooth将jar文件转换成可在无java的环境中运行的exe文件
  • 禁漫排行榜周目公告版_华泰证券手机版下载-华泰证券涨乐财富通手机版下载V7.5.0安卓版...
  • 影音先锋云服务器,影音先锋云服务器
  • ——Diary5(Java面向对象2——多态,内部类)
  • 转载:一些射频相关的网站
  • Activity Monitor使用说明
  • Python调试器-Pdb的简介及调试命令
  • 跨时空的相遇~为她制作一个专属的QQ空间相册(附源代码)
  • 【BLOCK】Oracle 块管理常用SQL
  • 北京师范大学珠海分校论坛 http://www.bnubbs.net
  • Springboot计算机毕业设计乐途网站的设计与实现ck8f1
  • 从头到尾彻底理解KMP(2014年8月22日版)
  • 计算机论文投稿指南
  • 扫雷游戏C语言代码实现——万字长文超详细,手把手教你实现,新手也能学会
  • opencv学习篇(3)snake轮廓检测