C# 外挂编写_汇编语言
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
大家都以为C#做不了真正的外挂,原因是由于它对底层支撑不好,不能内联汇编码等等!确切,C#运行在NET之上,就算要用到汇编也是微软的IL(中间语言)汇编,而不是X86这类的汇编码!但在外挂的开发中,应用汇编码是不可避免的,那么我们可以在C#中应用机器码来取代汇编码,这样实现的后果是一样的!有了这个方式我们就可以在C#中开发一个汇编组件来供外挂程序调用,使其能支撑内联汇编码,其语法也和普通的汇编码差未几(至于为什么要开发成组件,那是由于C#原来就是即面向对象又面向组件的编程工具,所以我们要尽可能的施展它的上风)!
首先,树立一个Windows窗体利用程序,然后再添加一个组件,切换到代码模式,基础步骤省略,先容重点部分:
导进体系API函数及定义所要调用的变量各体系API的用法在API手册有查)
[DllImport("kernel32.dll", EntryPoint = "CloseHandle")]
public static extern int CloseHandle(
int hObject
);
[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 lpThreadI );
[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
);
[DllImport("kernel32.dll", EntryPoint = "OpenProcess")]
public static extern int OpenProcess(
int dwDesiredAccess,
int bInheritHandle,
int dwProcessId
);
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;
private const int PROCESS_CREATE_THREAD = 0x2;
private const int PROCESS_VM_OPERATION = 0x8;
private const int PROCESS_VM_WRITE = 0x20;
public string Asmcode="";//储存汇编码变量
功效实现部分:
public string intTohex(int value, int num) //将整形数据转换成16进制数据,并进行高下位转换及补位
{
string str1;
string str2 = "";
str1 = "0000000" + this.hex(value);
str1 = str1.Substring(str1.Length - num,num);
for (int i = 0; i < str1.Length/2; i++)
{
str2 = str2 + str1.Substring(str1.Length - 2 - 2 * i, 2);
}
return str2;
}
private string hex(int address) //重截字符串,使其以16进制格局输出
{
string str = address.ToString("X");
return str;
}
private byte[] AsmChangebytes(string asmPram) //将16进制样式的字符串转换成以字节数组表现的汇编码
{
byte[] reAsmCode = new byte[asmPram.Length / 2];
for (int i = 0; i < reAsmCode.Length; i++)
{
reAsmCode = Convert.ToByte(Int32.Parse(asmPram.Substring(i * 2, 2), System.Globalization.NumberStyles.AllowHexSpecifier));
}
return reAsmCode;
}
public void RunAsm(int pid) //在目的空间(游戏空间)分配运行汇编码所需的内存空间,并启动远程线程函数调用代码
{
int hwnd, addre, threadhwnd;
byte[] Asm = this.AsmChangebytes(this.Asmcode);
if (pid != 0)
{
hwnd = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_CREATE_THREAD | PROCESS_VM_WRITE, 0, pid);
if (hwnd != 0)
{
addre = VirtualAllocEx(hwnd, 0, Asm.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hwnd, addre, Asm, Asm.Length, 0);
threadhwnd = CreateRemoteThread(hwnd, 0, 0, addre, 0, 0, ref pid);
VirtualFreeEx(hwnd, addre, Asm.Length, MEM_RELEASE);
CloseHandle(threadhwnd);
CloseHandle(hwnd);
}
}
this.Asmcode = "";
}
public void Mov_DWORD_Ptr_ESP(int addre) //汇编指令中的MOV指令例子
{
this.Asmcode = this.Asmcode + "C70424" + intTohex(addre, 8);
}
public void Add_EAX(int addre) //汇编指令中的ADD指令例子
{
this.Asmcode = this.Asmcode + "05" + intTohex(addre, 8);
}
public void Pushad() //汇编指令中的Pushad指令例子
{
this.Asmcode = this.Asmcode + "60";
}
public void Push_EAX() //汇编指令中的Push指令例子
{
this.Asmcode = this.Asmc
ode + "50";
}
public void Call_EAX() //汇编指令中的Call指令例子
{
this.Asmcode = this.Asmcode + "FFD0";
}
上面几个函数就是实现C#汇编组件的主要部分,而下面的汇编指令函数都是依据X86汇编指令所对应的机器码来设定的,其语法也和汇编码差未几,只是多了一条下划线而已!这里只给出了几条指令而已,假如要设计成真正的汇编组件还须要收集非常非常多的指令机器码!