打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
编程开发:内存型游戏外挂讲解

一,要想做好外挂,那么必不可少的就是要找到游戏基址和偏移,首先讲解一下游戏基址和偏移的找法:

这里我们使用CE来找寻基址和偏移

我们先来找寻游戏生命基址

首先选择游戏进程,选择好后,数值类型选择“字节”,扫描类型选择“精确数值”。然后在数值框中输入当前生命,点“新的扫描”按扭。

扫描完成后,把人物挂一次,改变一下生命,然后再在数据框中输入现在的生命,点“再次扫描”,直到找到生命动态地址为止。

这里我们找到了,我们的生命动态地址为02A5E05B,我们双击他到下面,这时我们发现,我们修改他的数值,游戏的生命也会发生改变。

但是这只是一个动态地址,重新打开游戏我们会发现,这个地址会改变。

这里我要阐明一下动态地址计算法则:

动态地址=游戏一级基址的值+偏移

下面我们右击这个地址,并选择图中所选菜单:

我们游戏中再次改变一下生命,就会发现扫描出了结果

此时点击详细信息

从图中我们可以得知,更改的地址是02A5E008.

这时候,偏移我们就可以计算出来了,我们拿现在动态地址02A5E05B减去这个地址02A5E008,得到的结果是十六进制53.这个结果就是偏移。

此时我们扫描一下这个值:

扫描出了2个结果,地址以绿色显示,表示已经是一级基址,我们取00622880,这样一级基址也就出来了。

我们的生命基址和偏移顺利找到。

同理我们也要先找到子弹基址,在找子弹基址时候我们首次扫描选择“未知的初始数值',然后在改变子弹后或没有改变子弹的情况下选择”改变的数值“或”未改变的数值'

最终我们子弹基址偏移为00622898+偏移B8

二,编写这个外挂

好了,相信大家已经对内存弄的外挂已经有了一定的了解了,那么如何使用编程语言去编写这个外挂呢?

当然,易语言乃内在型外挂开发首选利器,精易模块对内存写入写出的操作做出了很好的封装。但题主今天偏偏不走正道,带大家使用c#来开发这个外挂,目的也就是为了让大家更清楚的认识编程语言对内存的底层操作。

内在操作工具类Memory:

class Memory { public static bool IsRunning = false; public int dwProcessId; [DllImport('kernel32.dll')] public static extern bool ReadProcessMemory(int hProcess, int IpBaseAddress, out int IpBuffer, int nSize, IntPtr IpNumberOfBytesRead); [DllImport('kernel32.dll')] public static extern bool WriteProcessMemory(int hProcess, int IpBaseAddress, int[] IpBuffer, int nSize, IntPtr IpNumberOfBytesWritten); [DllImport('User32.dll')] public static extern IntPtr FindWindow(string IpClassName, string IpWindowName);//根据窗口名得到窗口句柄 [DllImport('User32.dll', CharSet = CharSet.Auto)] public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);//获取进程ID,第一个参数从FindWindow获取 [DllImport('kernel32.dll')] public static extern int OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId); //返回进程句柄,第三个参数从GetWindowThreadProcessId获取 [DllImport('kernel32.dll')] private static extern void CloseHandle(int hObject); public int getHProcess(bool IsRead) { int hProcess; if (IsRead == true) { hProcess = OpenProcess(0x0010 | 0x0020, false, dwProcessId); } else { hProcess = OpenProcess(0x1F0FFF, false, dwProcessId);//获取最高写入权限 } return hProcess; } public bool injectionProcess(string processTitle)//注入进程 { IntPtr hwnd = FindWindow(null, processTitle); GetWindowThreadProcessId(hwnd, out dwProcessId); if (dwProcessId != 0) { IsRunning = true; } return IsRunning; } public int readMemory(int processAddress) { if (IsRunning == true) { int hProcess = getHProcess(true); ReadProcessMemory(hProcess, processAddress, out processAddress, 4, IntPtr.Zero); CloseHandle(hProcess); return processAddress; } else return 0; } public void wirteMemory(int value, int processAddress, int offset) { if (IsRunning == true) { int hProcess = getHProcess(false); processAddress += offset; WriteProcessMemory(hProcess, processAddress, new int[] { value }, 4, IntPtr.Zero); CloseHandle(hProcess); } } public void wirteMemory(int value, int processAddress) { if (IsRunning == true) { int hProcess = getHProcess(false); WriteProcessMemory(hProcess, processAddress, new int[] { value }, 4, IntPtr.Zero); CloseHandle(hProcess); } } }

主程序调用:

public partial class Form1 : Form { public Form1() { InitializeComponent(); } Memory memory = new Memory(); private void button1_Click(object sender, EventArgs e) { } private void button3_Click(object sender, EventArgs e) { int processAddress = memory.readMemory(0x00622898); memory.wirteMemory(100, processAddress, 0x53); } private void button2_Click(object sender, EventArgs e) { int processAddress = memory.readMemory(0x00622898); memory.wirteMemory(3, processAddress, 0x53); } private void Form1_Load(object sender, EventArgs e) { this.Size = new Size(200, 200); } private void button4_Click(object sender, EventArgs e) { bool isRunning = memory.injectionProcess('SMYNES v1.20'); if (isRunning == false) { MessageBox.Show('注入游戏失败,请检查游戏是否启动!'); } else { this.Size = new Size(450, 200); button4.Visible = false; panel1.Visible = true; } } private void radioButton3_CheckedChanged(object sender, EventArgs e) { timer1.Start(); } private void timer1_Tick(object sender, EventArgs e) { int processAddress = memory.readMemory(0x00622898); memory.wirteMemory(2, processAddress, 0xB8); } private void radioButton4_CheckedChanged(object sender, EventArgs e) { timer1.Stop(); } }

这样,内存型外挂就此大功告成。

偷偷告诉大家的是,百度云本地300秒免费试用,同样通过此方面,可以随意修改免费试用时间,享受终身免费百度云加速下载,赶快试试吧!

作者:北晨

原文:https://www.cnblogs.com/huihui123/p/7775182.html

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
C# 操作地址 从内存中读取写入数据(初级)
C#下拉框集合元素写法
C#读写内存也不差!(发布C#编写的<植物大战僵尸>作弊器源码)
网站在线人数以及历史访问人数的统计代码
c#写的折叠菜单
C#中判断空字符串的3种方法性能分析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服