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 ...
随机推荐
- 编写shell时,提示let/typeset:not found
刚刚开始接触linux shell 编程,脚本里面有一条let命令,在运行该脚本时却提示 let:not found 于是各种找自己写的脚本的问题,没发现错误,只好去网上百度,好心人告诉了我答案: / ...
- AspectCore动态代理中的拦截器详解(一)
前言 在上一篇文章使用AspectCore动态代理中,简单说明了AspectCore.DynamicProxy的使用方式,由于介绍的比较浅显,也有不少同学留言询问拦截器的配置,那么在这篇文章中,我们来 ...
- ubuntu下使用nginx搭建流媒体服务器,实现视频点播
首先我们看如何实现视频点播,视频点播支持flv文件及H264编码视频,ACC编码音频的mp4文件: 第一步,创建单独的目录(因为软件较多,容易混乱),下载需要的软件: 我们需要下载nginx,pcre ...
- JEECG 3.7.1 版本发布,企业级JAVA快速开发平台
JEECG 3.7.1 版本发布,企业级JAVA快速开发平台 ---------------------------------------- Version: Jeecg_3.7.1项 目: ...
- 获取屏幕宽高度与可视区域宽高度(availWidth、clientWidth、width、innerWidth)
经常会遇到需要获取屏幕宽度.高度,可视区域宽度.高度等问题,也就常跟这几个打交道,一不小心,还真爱弄混淆了. 先来列举下这几个吧: screen.availHeight.screen.availWid ...
- HDU 1233 还是畅通工程(模板——克鲁斯卡尔算法)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1233 题意描述: 输入n个城镇以及n*(n-1)/2条道路信息 计算并输出将所有城镇连通或者间接连通 ...
- Spark算子--flatMapValues
转载请标明出处http://www.cnblogs.com/haozhengfei/p/e7a46cecc65720997392516d553d9891.html flatMapValues--Tra ...
- 实例说明optimize table在优化MySQL时很重要
今天在看CU的时候,发现有人问有关optimize来表优化的问题,当年因为这个问题,困扰我很长一段时间,今天有空我把这个问题,用实际数据来展示出来,让大家可以亲眼来看看,optimize table的 ...
- vue集成百度UEditor富文本编辑器
在前端开发的项目中.难免会遇到需要在页面上集成一个富文本编辑器.那么.如果你有这个需求.希望可以帮助到你 vue是前端开发者所追捧的框架,简单易上手,但是基于vue的富文本编辑器大多数太过于精简.于是 ...
- Win7如何分享局域网并设置共享文件夹账户和密码
https://jingyan.baidu.com/article/ceb9fb10ddf6c08cad2ba017.html 在办公或者其他场所,我们需要分享自己的文件给朋友或者同事,但又不想同一局 ...