C# 简单内存补丁
写在开头:看了一些视频教程,感觉OD为什么别人学个破解那么容易,我就那么难了呢,可能是没有那么多时间吧。
解释:个人见解:所谓内存补丁,即:通过修改运行程序的内容,来达到某种目的的操作。修改使用OpenProcess打开,WriteProcessMemory写入,CloseHandle关闭。部分需要读取数据判断使用:ReadProcessMemory
0x1 看教程
关于有的学习教程,确实要看看视频才能了解别人的操作,或者很简单一个东西,如果没有别人的指导那么自己操作确实不太容易。
0x2 学习到部分概念
肯定不可能一味的模仿,做一样的东西,所以需要学以致用就很关键了。于是乎,用vs2013 c++写了几行代码,用于自己测试,用C#写内存补丁
0x3 网上检索
没有人生而知之,所以网上查询也是很关键的一步,查询哪些内容呢?就是查询C#如何写内存补丁,代码大同小异不过不一定能用。
0x4 代码实践
网上找到的代码也是要在实践中得出能否使用的。所以这一步也是必不可免的。
于是乎有了下面的代码。需要使用OD找到代码的位置即和在内存中和代码的相差位置。
MCF程序 C++ OK方法中
void CMFCTestDlg::OnBnClickedOk()
{
CString str;
GetDlgItemText(IDC_EDIT1, str); if (str == "test123456789"){
::MessageBox(NULL, L"OK", L"提示", );
}
else{
::MessageBox(NULL, L"Fail", L"提示", );
}
}
C#程序中调用,首先贴一个帮助类,来源网上。当然对其中添加和修改了部分方法。
public abstract class ApiHelper
{
[DllImportAttribute("kernel32.dll", EntryPoint = "ReadProcessMemory")]
public static extern bool ReadProcessMemory
(
IntPtr hProcess,
IntPtr lpBaseAddress,
IntPtr lpBuffer,
int nSize,
IntPtr lpNumberOfBytesRead
); [DllImportAttribute("kernel32.dll", EntryPoint = "OpenProcess")]
public static extern IntPtr OpenProcess
(
int dwDesiredAccess,
bool bInheritHandle,
int dwProcessId
); [DllImport("kernel32.dll")]
private static extern void CloseHandle
(
IntPtr hObject
); //写内存
[DllImportAttribute("kernel32.dll", EntryPoint = "WriteProcessMemory")]
public static extern bool WriteProcessMemory
(
IntPtr hProcess,
IntPtr lpBaseAddress,
int[] lpBuffer,
int nSize,
IntPtr lpNumberOfBytesWritten
); //获取窗体的进程标识ID
public static int GetPid(string windowTitle)
{
int rs = ;
Process[] arrayProcess = Process.GetProcesses();
foreach (Process p in arrayProcess)
{
if (p.MainWindowTitle.IndexOf(windowTitle) != -)
{
rs = p.Id;
break;
}
} return rs;
} //根据进程名获取PID
public static int GetPidByProcessName(string processName, ref IntPtr baseAddress)
{
Process[] arrayProcess = Process.GetProcessesByName(processName);
foreach (Process p in arrayProcess)
{
baseAddress = p.MainModule.BaseAddress;
return p.Id;
} return ;
} //根据进程名获取PID
public static int GetPidByProcessName(string processName)
{
Process[] arrayProcess = Process.GetProcessesByName(processName);
foreach (Process p in arrayProcess)
{
return p.Id;
} return ;
} //根据窗体标题查找窗口句柄(支持模糊匹配)
public static IntPtr FindWindow(string title)
{
Process[] ps = Process.GetProcesses();
foreach (Process p in ps)
{
if (p.MainWindowTitle.IndexOf(title) != -)
{
return p.MainWindowHandle;
}
}
return IntPtr.Zero;
} //读取内存中的值
public static int ReadMemoryValue(int baseAddress, string processName)
{
try
{
byte[] buffer = new byte[];
IntPtr byteAddress = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, ); //获取缓冲区地址
IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName));
ReadProcessMemory(hProcess, (IntPtr)baseAddress, byteAddress, buffer.Length, IntPtr.Zero); //将制定内存中的值读入缓冲区
CloseHandle(hProcess);
return Marshal.ReadInt32(byteAddress);
}
catch
{
return ;
}
} //将值写入指定内存地址中
public static bool WriteMemoryValue(int baseAddress, string processName, int[] value)
{
IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName)); //0x1F0FFF 最高权限
bool result = WriteProcessMemory(hProcess, (IntPtr)baseAddress, value, value.Length, IntPtr.Zero);
CloseHandle(hProcess); return result;
}
}
最后是在具体按钮中的调用了。
private string processName = "MFCTest"; // private void button1_Click(object sender, EventArgs e)
{
IntPtr startAddress = IntPtr.Zero;
int pid = ApiHelper.GetPidByProcessName(processName, ref startAddress);
if (pid == )
{
MessageBox.Show("哥们启用之前该运行吧!");
return;
} int baseAddress = startAddress.ToInt32() + 0x1000;
int value = ReadMemoryValue(baseAddress); // 读取基址(该地址不会改变)
int address = baseAddress + 0x14F3; // 获取2级地址
value = ReadMemoryValue(address);
bool result = WriteMemory(address, new int[] { });
address = address + 0x1;
result = WriteMemory(address, new int[] { }); MessageBox.Show(result ? "成功" : "失败");
} //读取制定内存中的值
public int ReadMemoryValue(int baseAdd)
{
return ApiHelper.ReadMemoryValue(baseAdd, processName);
} //将值写入指定内存中
public bool WriteMemory(int baseAdd, int[] value)
{
return ApiHelper.WriteMemoryValue(baseAdd, processName, value);
}
0x5 总结
只有不断学习才能知道新的知识,同时在学习中进步。很多不懂的概念其实很简单。当然前提是你明白以后。
其中注意一点。
测试代码下载:WriteProcessMemory的buffer填入一个数组也是可以的。需要计算长度。然后nSize就是,前面的数组作为几个字节进行使用。
// 重构了些许代码 //将值写入指定内存地址中
public static bool WriteMemoryValue(int baseAddress, string processName, int[] value, int len)
{
IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName)); //0x1F0FFF 最高权限
bool result = WriteProcessMemory(hProcess, (IntPtr)baseAddress, value, len, IntPtr.Zero);
CloseHandle(hProcess); return result;
} // 144=0x90 表示 nop
bool result = ApiHelper.WriteMemoryValue(address, processName, new int[] { + * }, );
C# 简单内存补丁的更多相关文章
- X86逆向12:内存补丁的制作
本章我们将学习各种打补丁的方式,补丁在软件的破解过程中非常的重要,比如软件无法脱壳我们就只能通过打补丁的方式来破解程序,补丁原理就是当程序运行起来会被释放到内存并解码,然后补丁就通过地址或特征码定位到 ...
- 【转】简单内存泄漏检测方法 解决 Detected memory leaks! 问题
我的环境是: XP SP2 . VS2003 最近在一个项目中,程序退出后都出现内存泄漏: Detected memory leaks! Dumping objects -> {98500} n ...
- _CrtSetBreakAlloc简单内存泄漏检测方法,解决Detected memory leaks!问题
我的环境是: XP SP2 . VS2003 最近在一个项目中,程序退出后都出现内存泄漏: Detected memory leaks! Dumping objects -> {98500} n ...
- mapreduce on yarn简单内存分配解释
关于mapreduce程序运行在yarn上时内存的分配一直是一个让我蒙圈的事情,单独查任何一个资料都不能很好的理解透彻.于是,最近查了大量的资料,综合各种解释,终于理解到了一个比较清晰的程度,在这里将 ...
- JAVA简单内存泄露分析及解决
一.问题产生 项目采用Tomcat6.0为服务器,数据库为mysql5.1,数据库持久层为hibernate3.0,以springMVC3.0为框架,项目开发完成后,上线前夕进行稳定性拷机,测试 ...
- Java创建对象时的简单内存分析
简单创建对象的内存分析 主程序: 1 public class Application { 2 public static void main(String[] args) { 3 Animal do ...
- java构造器级简单内存分析
java构造器的使用(基础篇) 构造方法也叫构造器,是创建对象时执行的特殊方法,一般用于初始化新对象的属性. 基本定义语法: 访问控制符 构造方法名([参数列表]){ 方法体 } 注:"访问 ...
- 简单内存池的C实现
1. 序言 对于程序开发人员来说,会经常听到这种"池"的概念,例如"进程池","线程池","内存池"等,虽然很多时没有吃 ...
- 从零开始学C++之重载 operator new 和 operator delete 实现一个简单内存泄漏跟踪器
先来说下实现思路:可以实现一个Trace类,调用 operator new 的时候就将指向分配内存的指针.当前文件.当前行等信息添加进Trace 成员map容器内,在调用operator delete ...
随机推荐
- Visual Studio 2017 安装后无法创建c++或MFC项目
话话不多说,直接上图
- 使用 SVG 和 JS 创建一个由星形变心形的动画
序言:首先,这是一篇学习 SVG 及 JS 动画不可多得的优秀文章.我非常喜欢 Ana Tudor 写的教程.在她的教程中有大量使用 SVG 制作的图解以及实时交互 DEMO,可以说教程的所有细枝末节 ...
- 利用脚本将EXCEl表倒入PowerDesigner中
1.Excel表格样式 2.脚本代码 '****************************************************************************** O ...
- .31-浅析webpack源码之doResolve事件流(2)
放个流程图: 这里也放一下request对象内容,这节完事后如下(把vue-cli的package.json也复制过来了): /* { context: { issuer: '', compiler: ...
- yourphp目录结构
Yourphp企业网站管理系统是一款完全开源免费的PHP+MYSQL系统.核心采用了Thinkphp框架等众多开源软件,同时核心功能也作为开源软件发布的网站后台管理系统. 二.目录说明 /Cache ...
- 解决nginx: [error] open() "/usr/local/nginx/logs/nginx.pid" failed错误
重新启动服务器,访问web服务发现无法浏览啦!登陆服务器之后进到nginx使用./nginx -s reload重新读取配置文件,发现报nginx: [error] open() "/usr ...
- Maven打包时去掉项目版本号
Maven打包后,jar或war文件名里带有版本号信息,如projectname0.0.1-SNAPSHOT.jar等,怎么去掉呢? 解决办法: 打开项目pom.xml文件,在<build> ...
- Linux安装mysql 在/etc下没有my.cnf 解决办法
进入 /usr/share/mysql 将my-medium.cnf 移动到etc 并且改名为my.cnf
- [转]怎么查看和修改 MySQL 的最大连接数?
使用 MySQL 数据库的站点,当访问连接数过多时,就会出现 "Too many connections" 的错误.出现这种错误有两种情况,一种是网站访问量实在太大,服务器已经负担 ...
- _3_form_标签
什么是input标签? 处理输入信息 input有哪些类型? 选择: <input type="checkbox"> 多选框,选择爱好等 <input type= ...