写在开头:看了一些视频教程,感觉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[] { + * }, );

WinTestRe.zip

C# 简单内存补丁的更多相关文章

  1. X86逆向12:内存补丁的制作

    本章我们将学习各种打补丁的方式,补丁在软件的破解过程中非常的重要,比如软件无法脱壳我们就只能通过打补丁的方式来破解程序,补丁原理就是当程序运行起来会被释放到内存并解码,然后补丁就通过地址或特征码定位到 ...

  2. 【转】简单内存泄漏检测方法 解决 Detected memory leaks! 问题

    我的环境是: XP SP2 . VS2003 最近在一个项目中,程序退出后都出现内存泄漏: Detected memory leaks! Dumping objects -> {98500} n ...

  3. _CrtSetBreakAlloc简单内存泄漏检测方法,解决Detected memory leaks!问题

    我的环境是: XP SP2 . VS2003 最近在一个项目中,程序退出后都出现内存泄漏: Detected memory leaks! Dumping objects -> {98500} n ...

  4. mapreduce on yarn简单内存分配解释

    关于mapreduce程序运行在yarn上时内存的分配一直是一个让我蒙圈的事情,单独查任何一个资料都不能很好的理解透彻.于是,最近查了大量的资料,综合各种解释,终于理解到了一个比较清晰的程度,在这里将 ...

  5. JAVA简单内存泄露分析及解决

    一.问题产生    项目采用Tomcat6.0为服务器,数据库为mysql5.1,数据库持久层为hibernate3.0,以springMVC3.0为框架,项目开发完成后,上线前夕进行稳定性拷机,测试 ...

  6. Java创建对象时的简单内存分析

    简单创建对象的内存分析 主程序: 1 public class Application { 2 public static void main(String[] args) { 3 Animal do ...

  7. java构造器级简单内存分析

    java构造器的使用(基础篇) 构造方法也叫构造器,是创建对象时执行的特殊方法,一般用于初始化新对象的属性. 基本定义语法: 访问控制符 构造方法名([参数列表]){ 方法体 } 注:"访问 ...

  8. 简单内存池的C实现

    1. 序言 对于程序开发人员来说,会经常听到这种"池"的概念,例如"进程池","线程池","内存池"等,虽然很多时没有吃 ...

  9. 从零开始学C++之重载 operator new 和 operator delete 实现一个简单内存泄漏跟踪器

    先来说下实现思路:可以实现一个Trace类,调用 operator new 的时候就将指向分配内存的指针.当前文件.当前行等信息添加进Trace 成员map容器内,在调用operator delete ...

随机推荐

  1. c# for 和 foreach 的区别

    foreach 能够进行foreach的类型结构,都必须实现IEnumerable接口. IEnumerable接口,有一个GetEnumerator的方法,返回一个实现IEnumerator接口的对 ...

  2. 《图解http》知识点笔记

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica } p.p2 { margin: 0.0px 0.0px 0.0px 0. ...

  3. java中强,软,弱,虚引用 以及WeakHahMap

    java中强,软,弱,虚引用  以及WeakHahMap   一:强软引用: 参考:http://zhangjunhd.blog.51cto.com/113473/53092/进行分析   packa ...

  4. reduceByKeyLocally

    2017年3月15日, 星期三 reduceByKeyLocally--Transformation类算子 代码示例  

  5. IE调试网页之三:使用 F12 工具控制台查看错误和状态 (Windows)

    IE调试网页之三:使用 F12 工具控制台查看错误和状态 (Windows)  等 请见博客园的  我的收藏

  6. @为Java注解

    spring的@service(创建对象)@Autowired(自动装配)

  7. J.U.C JMM. pipeline.指令重排序,happen-before(续)

    前面已经介绍硬件平台Cache Coherence问题和解决办法,下面来看看Java虚拟机平台的相关知识.硬件平台处理器,高速缓存,主存之间的交互关系如下: Java内存模型(JMM)         ...

  8. struts学习总结

    -- struts2 是在struts1和webwork基础上发展的全新框架. -- struts2解决的问题: 原始的servlet中,每需要操作一个crud的操作就要创建一个servlet,虽然后 ...

  9. 006-接收键盘的输入(read)

    read  -ptns   变量名 -p 在等待read输入的时候,显示的提示信息 -t 秒数,read等待用户输入的时间 -n read接收用户输入的字符数,只接收指定字符数,就会执行 -s 隐藏输 ...

  10. BFC(块级格式上下文)

    BFC的生成 满足下列css声明之一的元素便会生成BFC 根元素 float的值不为none overflow的值不为visible display的值为inline-block.table-cell ...