C#本地修改器
C#本地修改器
- C#做外挂的常用API,本人用了很久,基本没发现问题
 - using System;
 - using System.Collections.Generic;
 - using System.Text;
 - using System.Runtime.InteropServices; //这个肯定要的
 - namespace WindowsApplication1
 - {
 - class win32API
 - {
 - public const int OPEN_PROCESS_ALL = 2035711;
 - public const int PAGE_READWRITE = 4;
 - public const int PROCESS_CREATE_THREAD = 2;
 - public const int PROCESS_HEAP_ENTRY_BUSY = 4;
 - public const int PROCESS_VM_OPERATION = 8;
 - public const int PROCESS_VM_READ = 256;
 - public const int PROCESS_VM_WRITE = 32;
 - private const int PAGE_EXECUTE_READWRITE = 0x4;
 - private const int MEM_COMMIT = 4096;
 - private const int MEM_RELEASE = 0x8000;
 - private const int MEM_DECOMMIT = 0x4000;
 - private const int PROCESS_ALL_ACCESS = 0x1F0FFF;
 - //查找窗体
 - [DllImport("User32.dll", EntryPoint = "FindWindow")]
 - public extern static IntPtr FindWindow(
 - string lpClassName,
 - string lpWindowName
 - );
 - //得到目标进程句柄的函数
 - [DllImport("USER32.DLL")]
 - public extern static int GetWindowThreadProcessId(
 - int hwnd,
 - ref int lpdwProcessId
 - );
 - [DllImport("USER32.DLL")]
 - public extern static int GetWindowThreadProcessId(
 - IntPtr hwnd,
 - ref int lpdwProcessId
 - );
 - //打开进程
 - [DllImport("kernel32.dll")]
 - public extern static int OpenProcess(
 - int dwDesiredAccess,
 - int bInheritHandle,
 - int dwProcessId
 - );
 - [DllImport("kernel32.dll")]
 - public extern static IntPtr OpenProcess(
 - uint dwDesiredAccess,
 - int bInheritHandle,
 - uint dwProcessId
 - );
 - //关闭句柄的函数
 - [DllImport("kernel32.dll", EntryPoint = "CloseHandle")]
 - public static extern int CloseHandle(
 - int hObject
 - );
 - //读内存
 - [DllImport("Kernel32.dll ")]
 - public static extern Int32 ReadProcessMemory(
 - IntPtr hProcess,
 - IntPtr lpBaseAddress,
 - [In, Out] byte[] buffer,
 - int size,
 - out IntPtr lpNumberOfBytesWritten
 - );
 - [DllImport("Kernel32.dll ")]
 - public static extern Int32 ReadProcessMemory(
 - int hProcess,
 - int lpBaseAddress,
 - ref int buffer,
 - //byte[] buffer,
 - int size,
 - int lpNumberOfBytesWritten
 - );
 - [DllImport("Kernel32.dll ")]
 - public static extern Int32 ReadProcessMemory(
 - int hProcess,
 - int lpBaseAddress,
 - byte[] buffer,
 - int size,
 - int lpNumberOfBytesWritten
 - );
 - //写内存
 - [DllImport("kernel32.dll")]
 - public static extern Int32 WriteProcessMemory(
 - IntPtr hProcess,
 - IntPtr lpBaseAddress,
 - [In, Out] byte[] buffer,
 - int size,
 - out IntPtr lpNumberOfBytesWritten
 - );
 - [DllImport("kernel32.dll")]
 - public static extern Int32 WriteProcessMemory(
 - int hProcess,
 - int lpBaseAddress,
 - byte[] buffer,
 - int size,
 - int lpNumberOfBytesWritten
 - );
 - //创建线程
 - [DllImport("kernel32", EntryPoint = "CreateRemoteThread")]
 - public static extern int CreateRemoteThread(
 - int hProcess,
 - int lpThreadAttributes,
 - int dwStackSize,
 - int lpStartAddress,
 - int lpParameter,
 - int dwCreationFlags,
 - ref int lpThreadId
 - );
 - //开辟指定进程的内存空间
 - [DllImport("Kernel32.dll")]
 - public static extern System.Int32 VirtualAllocEx(
 - System.IntPtr hProcess,
 - System.Int32 lpAddress,
 - System.Int32 dwSize,
 - System.Int16 flAllocationType,
 - System.Int16 flProtect
 - );
 - [DllImport("Kernel32.dll")]
 - public static extern System.Int32 VirtualAllocEx(
 - int hProcess,
 - int lpAddress,
 - int dwSize,
 - int flAllocationType,
 - int flProtect
 - );
 - //释放内存空间
 - [DllImport("Kernel32.dll")]
 - public static extern System.Int32 VirtualFreeEx(
 - int hProcess,
 - int lpAddress,
 - int dwSize,
 - int flAllocationType
 - );
 - }
 - }
 
【外挂修改器简单介绍】
游戏外挂分为很多种类型,例如本地客户端的内存修改、远程服务器的封包破解。
一般的网游由于服务器的机能限制,并不会将游戏产生的所有数据、计算都提供给服务器来承担。经常的,服务器只会将玩家人物的属性、血量、加点、金钱、装备等重要信息储存在服务器本地,计算结果和数据传递则是通过加密封包来和客户端传输。
因此网游如果封包被破解而被用户发送伪造的封包数据将造成非常严重的后果。
【C#本地修改器】
如上所述,虽然封包的一般无法破解,但是利用服务器无法储存所有的信息这个特点,我们可以通过修改本地客户端的内存数据来制作一些建议的外挂,如修改坐标达到穿墙、加速的效果。
修改这类的本地数据,一般我们使用到 Cheatgine 来搜索内存特定数值。关于这个这工具网上已经有很多完善的教程,这边就不赘述了。
这边通过QQ连连看的示例来教程一般的C#的外挂制作。
通过Cheatgine搜索到时间、罗盘、重列的数量、本机座位的内存基址偏移量,再绘制出界面就可以开始制作。

(CheatEngine)

(简易的界面UI)
这边提供一个C#的内存修改读取抽象类

1 public abstract class Helper //内存读写核心
2 {
3 [DllImportAttribute("kernel32.dll", EntryPoint = "ReadProcessMemory")]
4 public static extern bool ReadProcessMemory
5 (
6 IntPtr hProcess,
7 IntPtr lpBaseAddress,
8 IntPtr lpBuffer,
9 int nSize,
10 IntPtr lpNumberOfBytesRead
11 );
12
13 [DllImportAttribute("kernel32.dll", EntryPoint = "OpenProcess")]
14 public static extern IntPtr OpenProcess
15 (
16 int dwDesiredAccess,
17 bool bInheritHandle,
18 int dwProcessId
19 );
20
21 [DllImport("kernel32.dll")]
22 private static extern void CloseHandle
23 (
24 IntPtr hObject
25 );
26
27 //写内存
28 [DllImportAttribute("kernel32.dll", EntryPoint = "WriteProcessMemory")]
29 public static extern bool WriteProcessMemory
30 (
31 IntPtr hProcess,
32 IntPtr lpBaseAddress,
33 int[] lpBuffer,
34 int nSize,
35 IntPtr lpNumberOfBytesWritten
36 );
37
38 //获取窗体的进程标识ID
39 public static int GetPid(string windowTitle)
40 {
41 int rs = 0;
42 Process[] arrayProcess = Process.GetProcesses();
43 foreach (Process p in arrayProcess)
44 {
45 if (p.MainWindowTitle.IndexOf(windowTitle) != -1)
46 {
47 rs = p.Id;
48 break;
49 }
50 }
51
52 return rs;
53 }
54
55 //根据进程名获取PID
56 public static int GetPidByProcessName(string processName)
57 {
58 Process[] arrayProcess = Process.GetProcessesByName(processName);
59
60 foreach (Process p in arrayProcess)
61 {
62 return p.Id;
63 }
64 return 0;
65 }
66
67 //根据窗体标题查找窗口句柄(支持模糊匹配)
68 public static IntPtr FindWindow(string title)
69 {
70 Process[] ps = Process.GetProcesses();
71 foreach (Process p in ps)
72 {
73 if (p.MainWindowTitle.IndexOf(title) != -1)
74 {
75 return p.MainWindowHandle;
76 }
77 }
78 return IntPtr.Zero;
79 }
80
81 //读取内存中的值
82 public static int ReadMemoryValue(int baseAddress, string processName)
83 {
84 try
85 {
86 byte[] buffer = new byte[4];
87 IntPtr byteAddress = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); //获取缓冲区地址
88 IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPid(processName));
89 ReadProcessMemory(hProcess, (IntPtr)baseAddress, byteAddress, 4, IntPtr.Zero); //将制定内存中的值读入缓冲区
90 CloseHandle(hProcess);
91 return Marshal.ReadInt32(byteAddress);
92 }
93 catch
94 {
95 return 0;
96 }
97 }
98
99 //将值写入指定内存地址中
100 public static void WriteMemoryValue(int baseAddress, string processName, int value)
101 {
102 IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPid(processName)); //0x1F0FFF 最高权限
103 WriteProcessMemory(hProcess, (IntPtr)baseAddress, new int[] { value }, 4, IntPtr.Zero);
104 CloseHandle(hProcess);
105 }
106
107 }

将找到的内存基址定义好

1 //将值写入指定内存中
2 public void WriteMemory(int baseAdd, int value)
3 {
4 Helper.WriteMemoryValue(baseAdd, processName, value);
5 }
6
7 private int baseAddress = 0x00111DEC; //游戏内存基址
8 private string processName = "QQ游戏 - 连连看角色版"; //游戏进程名字
9
10 int temp = 0; int sit = 0;
11

利用所提供的内存读写抽象类写入内存,并利用一个timer持续写入这个内存数值以达到锁定数值的目的。

1 private void timer1_Tick(object sender, EventArgs e) //冻结时间
2 {
3 int address = ReadMemoryValue(baseAddress);
4 address += 0x49d8;
5
6 if (checkBox1.Checked == true)
7 {
8 timer1.Enabled = true;
9 WriteMemory(address, 700);
10 label1.Text = "已冻结";
11
12 }
13
14 if (checkBox1.Checked != true) label1.Text = "未冻结";
15 }

以上就是一个例子,一般的单机游戏修改器也可以用这样的方法制作完成。
当然现在有不少网游有保护盾,可以防止游戏客户端内存被修改,这类的技术一般是用驱动、内核、进程挂钩完成,可以利用XT手动解除这些保护。
C#本地修改器的更多相关文章
- CE修改器修改DNF 测试视频 阿修罗提升智力增加攻击力
		
使用CE修改器来修改网络游戏,如DNF 测试视频: CE修改器:指的是Cheat Engine,字面上的意思指的是作弊引擎的意思,是一款内存修改编辑工具.通过修改游戏的内存数据来得到一些原本无法实现的 ...
 - tp5 中 model 的修改器
		
修改器可以在数据赋值的时候自动进行转换处理 class User extends Model { public function setNameAttr($value){ return strtolo ...
 - Blender 之修改器代码分析
		
Blender的修改器(modifier)模块,默认界面右下块(Property)面板的扳手,分类(修改.生成.形变.模拟)列出所有的修改器.也可以空格键 ...
 - mongodb的修改器
		
在mongodb中通常文档只会有一部分要更新,利用原子的更新修改器,可以做到只更新文档的一部分键值,而且更新极为高效,更新修改器是种特殊的键,用来指定复杂的更新操作,比如调整.增加.或者删除键,还可以 ...
 - 【MongoDB】4.MongoDB 原子修改器的  极速修改
		
文档转自:http://blog.csdn.net/mcpang/article/details/7752736 对于文档的更新除替换外,针对某个或多个文档只需要部分更新可使用原子的更新修改器,能够高 ...
 - MongoDB修改器的使用1
		
为什么要使用修改器? 通常我们只会修改文档的一部分,这时候更新整个文档就显得很麻烦,通常是通过原子性的更新修改器来完成. 1."$set"修改器 "$set ...
 - UWP游戏防内存修改器的方法
		
最近我一直在编写适用于Windows 10商店的游戏.这款游戏比较怕玩家用修改器改金钱,因为这种修改会导致某些内购失效并且损害公平性.于是我把自己见过的三种反修改器的方法给网友们介绍一下. 首先说明一 ...
 - mongodb_修改器($inc/$set/$unset/$push/$pop/upsert......)
		
主从复制:http://blog.csdn.net/drifterj/article/details/7833883 对于文档的更新除替换外,针对某个或多个文档只需要部分更新可使用原子的更新修改器,能 ...
 - ce游戏内存修改器(Cheat Engine)
		
ce修改器(Cheat Engine)一款专门修改内存修改编辑的游戏工具它包括16进制编辑,反汇编程序,内存查找工具新版6.1 版的CE与6.0 最大的区别就是添加了修改器制作工具,比之前 5.6.1 ...
 
随机推荐
- Problem 3 二维差分
			
$des$ 考虑一个 n ∗ n 的矩阵 A,初始所有元素均为 0.执行 q 次如下形式的操作: 给定 4 个整数 r,c,l,s, 对于每个满足 x ∈ [r,r+l), y ∈ [c,x−r+c] ...
 - Luogu5591 小猪佩奇学数学 【单位根反演】
			
题目链接:洛谷 \[ Ans=\frac{1}{k}(\sum_{i=0}^n\binom{n}{i}p^ii-\sum_{i=0}^n\binom{n}{i}p^i(i \ \mathrm{mod} ...
 - Video Reviews
			
题目链接:http://codeforces.com/gym/101755/problem/K 题目理解: 一家公司想让n个人给他们的产品评论,所以依次去找这n个人,第i个人会评论当且仅当已经有ai个 ...
 - @RestController和@GetMapping
			
@RestController 可以代替@Controller使用,使用了@RestController的控制器默认所有请求方法都用了@ResponseBody注解. @GetMapping(&quo ...
 - CFD计算过程发散诸多原因分析【转载】
			
转载自: http://blog.sina.com.cn/s/blog_5fdfa7e601010rkx.html 今天探讨引起CFD计算过程中发散的一些原因.cfd计算是将描述物理问题的偏微分方程转 ...
 - 在mybtis的映射文件中判断集合大小
			
<if test="groupIds != null and groupIds.size>0"> and (group_id in<foreach coll ...
 - 【转】JVM类装载机制的解析,热更新的探讨(二)
			
同样,一个Class对象必须知道自己的超类.超级接口.因此,Class对象会引用自己的超类和超级接口的Class对象.这种引用一定是实例引用.(实际上,超类.超级接口的引用也存储在常量池中,但为了区分 ...
 - 如何选题?| 什么样的科学问题 | 研究项目才是有意义的?| scientific method
			
搞科研,尤其是生命科学,经常会觉得自己做的东西是坨屎,没有任何意义. 在硕博的时候这种感觉会非常强烈,一个是自己思考能力不足:二是你的项目不是你设计的,不懂个中缘由,只执行的话就会很无聊,找不到意义感 ...
 - Nexus入门【转】
			
介绍 DevOps平台采用的介质服务器类型为NEXUS,NEXUS是一个强大的maven仓库管理器,它极大的简化了本地内部仓库的维护和外部仓库的访问. 一.配置Maven [root@meteor ~ ...
 - Linux内存中的Cache真的能被回收吗? 【转】
			
在Linux系统中,我们经常用free命令来查看系统内存的使用状态.在一个RHEL6的系统上,free命令的显示内容大概是这样一个状态: [root@tencent64 ~]# free ...