C#仿 CE 注入实例
CE 第 7 关作业
在其它程序注入汇编代码
用到分配打开进程空间,读写内存等 windows API 函数
Tutorial-i386.exe 第 7 关作业,我这里把减 1 变成加 1
//API 调用需要的类
public class Win32
{
public struct MEMORY_BASIC_INFORMATION
{
public int BaseAddress;
public int AllocationBase;
public int AllocationProtect;
public int RegionSize;
public int State;
public int Protect;
public int lType;
}
public const int MEM_COMMIT = 0x1000;
public const int MEM_PRIVATE = 0x20000;
public const int PAGE_READWRITE = 0x04;
[DllImport("kernel32.dll")] //声明 API 函数
public static extern int VirtualAllocEx(IntPtr hwnd, int lpaddress, int size,
//已物理分配
//可读写内存
int type, int tect);
[DllImport("kernel32.dll")]
public static extern int VirtualQueryEx(
//查询内存块信息
IntPtr
hProcess,
IntPtr
lpAddress,
out
MEMORY_BASIC_INFORMATION
lpBuffer, int dwLength);
[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(
IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int size, out
int numBytesRead);
[DllImport("kernel32.dll")]
public static extern bool WriteProcessMemory(
IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int size, out
int numBytesWrite);
[DllImport("kernel32.dll")]
public static extern bool WriteProcessMemory(
IntPtr hProcess, IntPtr lpBaseAddress, int[] lpBuffer, int size, out int
numBytesWrite);
// 以 下 是 注 册 全 局 热 键 要 用 到 Windows 的 API 方 法 RegisterHotKey 和
UnregisterHotKey。
[DllImport("user32.dll")]
private static extern int RegisterHotKey(IntPtr hwnd, int id, int
fsModifiers, int vk);
[DllImport("user32.dll")]
private static extern int UnregisterHotKey(IntPtr hwnd, int id);
///
/// 注册热键
///
///
窗口句柄
///
热键 ID
///
组合键
///
热键
public static void RegKey(IntPtr hwnd, int hotKey_id, int fsModifiers, int
vk)
{
bool result;
if (RegisterHotKey(hwnd, hotKey_id, fsModifiers, vk) == 0)
{
result = false;
}
else
{
result = true;
}
if (!result)
{
MessageBox.Show("注册热键失败!");
}
}
///
/// 注销热键
///
///
窗口句柄
///
热键 ID
public static void UnRegKey(IntPtr hwnd, int hotKey_id)
{
UnregisterHotKey(hwnd, hotKey_id);
}
//数值存入字节中
public static void LongToArray(long numWrite, ref byte[] byWrite, int
bytesSize)
{
}
i * 8);
byWrite = new byte[bytesSize];
//将数据写入 byte 数组中
for (int i = 0; i < bytesSize; i++)
{
byWrite[i] = (byte)((numWrite & (0x00000000000000FF << i * 8)) >>
}
//字节数组转换为长整型
public static long ArrayToLong(byte[] byData, int nReadSize)
{
long numAddr;
numAddr = byData[nReadSize - 1];
for (int j = nReadSize, k = 2; j > 1; j--, k++)
{
numAddr = numAddr << 8;
numAddr = numAddr | byData[nReadSize - k];
}
return numAddr;
}
}
//用到的类库
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;
//根据进程名获得进程,一般是程序文件名
public Process Getprocess(string p_name)
{
string proc_name;
proc_name = p_name.ToLower();
//进程名
Process[] ps = Process.GetProcesses();
foreach (System.Diagnostics.Process p in ps)
{
//Console.WriteLine(p.ProcessName);
柄
IntPtr hwnd = (IntPtr)p.MainWindowHandle.ToInt32();
//进程句
//如果进程为 taskmgr,则关闭进程
if (p.ProcessName.ToLower() == proc_name)
{
return p;
}
}
return null;
}
//调用实例:
private void button2_Click(object sender, EventArgs e)
{
Process ps1 = Getprocess("Tutorial-i386");
int baseaddress = Win32.VirtualAllocEx(ps1.Handle, 0, 0x100, 4096,
4); //分配虚拟空间
int numWriteSize = 0;
int t_Addr = 0x426E99;
int jmpadd = baseaddress - t_Addr - 5; //目标地址-来源地址-5 从
//更改汇编起始位置
来源地址(jmp 跳转命令处)跳到目标地址(要跳转到的地址)
long h_Addr = 0x426E9F;//返回地址
byte BYTE_e9 = 0xE9; //jmp
byte BYTE_nop = 0x90; //nop
byte[] byData = new byte[1];
byData[0] = BYTE_e9;
//jmp
Win32.WriteProcessMemory(ps1.Handle, (IntPtr)t_Addr, byData, 1,
out numWriteSize);
byData = new byte[4];
Win32.LongToArray(jmpadd, ref byData, 4);
Win32.WriteProcessMemory(ps1.Handle, (IntPtr)(t_Addr+1), byData, 4,
//跳转到空间
out numWriteSize);
byData[0] = BYTE_nop;
Win32.WriteProcessMemory(ps1.Handle, (IntPtr)(t_Addr+5), byData, 1,
//空指令
out numWriteSize);
byData[0] = 0xff;
Win32.WriteProcessMemory(ps1.Handle, (IntPtr)baseaddress, byData,
//inc
1, out numWriteSize);
byData[0] = 0x83;
Win32.WriteProcessMemory(ps1.Handle, (IntPtr)(baseaddress + 1),
//ebx
byData, 1, out numWriteSize);
byData = new byte[4];
byData[0] = 0x7c;
byData[1] = 0x04;
byData[2] = 0;
byData[3] = 0;
Win32.WriteProcessMemory(ps1.Handle, (IntPtr)(baseaddress + 2),
byData, 4, out numWriteSize);
byData[0] = BYTE_e9;
Win32.WriteProcessMemory(ps1.Handle, (IntPtr)(baseaddress + 6),
//jmp
byData, 1, out numWriteSize);
h_Addr = h_Addr - 5 - (baseaddress + 7);
byData = new byte[4];
Win32.LongToArray(h_Addr,ref byData,4);
//目标地址-来源地址-5
Win32.WriteProcessMemory(ps1.Handle, (IntPtr)(baseaddress + 7),
byData, 4, out numWriteSize);
}