C# inline-asm / 嵌入x86汇编
C#可不可以嵌入汇编 可以 在我眼中C#作为一个介于中上层语言是不可能不可以
置入汇编代码的 为什么会被我认为中上层语言呢 从C#保留指针就可以看出 我知
道有很多人一定不会相信C#可以使用汇编代码 不过C#会比较麻烦C#不可以直接
内联汇编(inline-asm)准确的说C#只可以使用(auto-asm)动态汇编 这种技术不是
C#独有的 易语言、VB、C++ 三种语言都可以 不过动态汇编我见过最多的是被应
用在外挂方面 及远程汇编注入 实际上是属于动态汇编技术的一种扩展 不过很难
说JIT在编译代码后是通过在远程把汇编代码写入托管进程执行的 又或者说是一种
寄生在外壳程序中运行的技术及“内存运行” 懒得讨论这些一想到就头大。
从上图中你可以看见一份简单的x86 / call汇编在C#中内嵌并被调用
执行一看你会发现并不是太难 我的一篇博文 写了一大堆废话就是说
这个东西不过是易语言的 http://blog.csdn.net/u012395622/article/details/46400569
我们知道软件运行时所有代码会放在虚拟内存中 而可执行的代码在内存中
内存保护一般是PAGE_EXECUTE_READ及32不过经过我研究.NET上的
可执行代码应该是PAGE_EXECUTE_READWIRTE及64 如果是P/invoke
上执行DLL中的保护是32 就可以我们在内嵌汇编时不可以使用只读保护
如果我们需要使用由.NET去委托去Call那么必须是可读可写 如果通过Win32
API去Call那么使用32就可以 有些区别 、我曾研究过易语言上字节集在内存
中的内存保护到底是多少结果与C#是一致 4 / PAGE_READWRITE 不过为什
么易语言可以CALL而C#不可以CALL一直是让我感到较为迷惑的事情 可能是
托管堆与非托管堆之间不同造成的 不过我更希望有大神出来帮忙指点一下下。
由于是X86汇编 首先需要把目标平台切换为x86 这样才不会造成C#调用汇编
代码时出错 一定不要省略这个步骤
首先你需要定义一个有参数的委托 重点在于在汇编中有这样一句话
call dword ptr[ebp+8] // call 参数一
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate IntPtr CallMethod(IntPtr ptr);
由于是在VC下内联的汇编 最后移植到C# 一般在VC下函数的调用方式是cdcel
何况下面的是按照cdcel导出函数格式进行的 所以不可以使用__stdcall的方式
- [STAThread]
- static void Main(string[] args)
- {
- byte[] buf_asm = {
- // push ebp
- // mov ebp,esp
- // sub esp,0C0h
- // push ebx
- // push esi
- // push edi
- // lea edi,[ebp-0C0h]
- // mov ecx,30h
- // mov eax,0CCCCCCCCh
- // rep stos dword ptr es:[edi]
- 85, 139, 236, 129, 236, 192, 0, 0, 0, 83, 86, 87, 141, 189, 64,
- 255, 255, 255, 185, 48, 0, 0, 0, 184, 204, 204, 204, 204, 243, 171,
- // call dword ptr[ebp+8]
- 255, 85, 8,
- // pop edi
- // pop esi
- // pop ebx
- // mov esp,ebp
- // pop ebp
- // ret
- 95, 94, 91, 139, 229, 93, 195
- };
- IntPtr ptr_asm = SetHandleCount(buf_asm);
- VirtualProtect(ptr_asm, buf_asm.Length);
- CallMethod call_method = Marshal.GetDelegateForFunctionPointer(ptr_asm, typeof(CallMethod)) as CallMethod;
- call_method(Marshal.GetFunctionPointerForDelegate(new Action(Hello_x86)));
- }
首先把你需要嵌入的汇编以字节数组的格式写出来 然后通过
SetHandleCount函数是用于取地址指针的
- static void VirtualProtect(IntPtr ptr, int size)
- {
- int outMemProtect;
- if (!VirtualProtect(ptr, size, 64, out outMemProtect))
- throw new Exception("Unable to modify memory protection.");
- }
上面的函数用于修改内存保护 不过是为了让委托可以进行交互 包括汇编代码可以被互调用
- static void Hello_x86()
- {
- Console.Title = ((new StackFrame()).GetMethod()).Name;
- Console.WriteLine("I was x86 assembly call a test function.");
- Console.ReadKey(false);
- }
上面的函数是一个测试函数 这个函数没有太大意义 只是表现利用了汇编调用
本函数 然后本函数输出一个回应的信息 用于提示该函数被写入内存汇编调用
依赖的外部函数
- [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
- public static extern IntPtr SetHandleCount(byte[] value);
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern bool VirtualProtect(IntPtr lpAddress, int dwSize, int flNewProtect, out int lpflOldProtect);
依赖的命名空间
- using System;
- using System.Runtime.InteropServices;
- using System.Diagnostics;
版权声明:本文为博主原创文章,未经博主允许不得转载。
C# inline-asm / 嵌入x86汇编的更多相关文章
- 寄存器理解 及 X86汇编入门
本文整理自多材料源,感谢原址分享,请查看末尾Url I, 汇编语言分类: 汇编语言和CPU息息相关,但是不能把汇编语言完全等同于CPU的机器指令.不同架构的CPU指令并不相同,如x86,powerpc ...
- C/C++ 中嵌入 arm 汇编
GCC编译器支持直接在C或者C++代码中,嵌入ARM汇编代码.其基本格式非常简单,大致如下: __asm__ [__volatile__] ( assembler template : [output ...
- 如何在C或C++代码中嵌入ARM汇编代码
转载自:http://blog.csdn.net/roland_sun/article/details/42921131 大家知道,用C或者C++等高级语言编写的程序,会被编译器编译成最终的机器指令. ...
- 为什么X86汇编中的mov指令不支持内存到内存的寻址?
在X86汇编中,MOV [0012H], [0016H]这种指令是不允许的,至少得有一个操作数是寄存器.当然,这种问题在用高级语言的时候看不到,感觉好像基本上都是从内存到内存啊,为毛到了汇编就不行了? ...
- 对X86汇编的理解与入门
本文描述基本的32位X86汇编语言的一个子集,其中涉及汇编语言的最核心部分,包括寄存器结构,数据表示,基本的操作指令(包括数据传送指令.逻辑计算指令.算数运算指令),以及函数的调用规则.个人认为:在理 ...
- X86汇编概要
来自:https://www.cnblogs.com/jiftle/p/8453106.html 本文翻译自:http://www.cs.virginia.edu/~evans/cs216/guide ...
- x86汇编之十(使用字符串)
x86汇编之十(使用字符串) 转自网络,出处不详 一.传送字符串 Intel提供了完整的字符串传送指令,就像是MOV指令一样. 1.MOVS指令 1)movs指令格式 把字符串从一个位内存位置传送到另 ...
- x86汇编指令脚本虚拟机
简介 这是一个可以直接解释执行从ida pro里面提取出来的x86汇编代码的虚拟机. 非常精简,整体架构上不能跟那些成熟的虚拟机相比,主要目标是够用.能用.轻量就行,如果觉得代码架构设计的不是很好的话 ...
- x64汇编第二讲,复习x86汇编指令格式,学习x64指令格式
目录 x64汇编第二讲,复习x86汇编指令格式,学习x64指令格式 一丶x86指令复习. 1.1什么是x86指令. 1.2 x86与x64下的通用寄存器 1.3 OpCode 1.4 7种寻址方式 二 ...
随机推荐
- Ubuntu12.04配置mod_python
安装: sudo apt-get install libapache2-mod-python python-mysqldb 然后编辑配置文件/etc/apache2/sites-enabled/000 ...
- step by step 之餐饮管理系统三
1.说明 表名的长度最长为18个字符 茶色的字段为主键或联合主键 浅黄色的字段为索引 浅灰底色的字段为临时表中比正式表多出的字段 数据库系统:Sqlserver2008 脚本工具:使用CodeGene ...
- PyPy 2.1 正式版发布
PyPy 2.1 Beta1 才刚刚在2天前发布,今天 PyPy 宣布 2.1 正式版发布. 值得关注的改进内容有: JIT support for ARM, architecture version ...
- 开源免费ERP/CRM/SCM:iDempiere 2.0 安装配置
首先简单介绍一下iDempiere:iDempiere是一款Java平台的基于Compiere/ADempiere的开源企业级开源ERP/CRM/SCM系统, 由于是在ADempiere基础上用O ...
- HttpLib - 一个对 Http 协议进行封装的库
今日,在 Codeplex 上看到一个开源项目,对 Http 协议进行了封装,这下可以方便这些在 .NET 平台下访问 Web 服务器的同学们了,比如,从 Web 服务器抓取一个页面,使用 .NET ...
- ajax异步请求Response.Redirect重定向
一个ajax异步请求报错->捕获异常->重定向错误提示页面. 一个简单的流程 结果一直搞不定.重定向无效.各种百度之. 后来突然想起 ajax的请求是不能在后台重定向的. 如果硬要重定向 ...
- [MSSQL]SCOPE_IDENTITY,IDENT_CURRENT以及@@IDENTITY的区别
简单解释下SCOPE_IDENTITY函数,IDENT_CURRENT函数以及@@IDENTITY全局变量的区别 SCOPE_IDENTITY函数返回当前作用域内,返回最后一次插入数据表的标识,意思是 ...
- DDD领域驱动设计之运用层代码
1.DDD领域驱动设计实践篇之如何提取模型 2.DDD领域驱动设计之聚合.实体.值对象 3.DDD领域驱动设计之领域基础设施层 4.DDD领域驱动设计之领域服务 5.整体DEMO代码 什么是运用层,说 ...
- ybutton 高端大气上档次华丽的按钮特效
小菜偶然在某网站中看到一款非常华丽的按钮特效,感觉十分有必要抄袭下来,以备日后使用. 简单描述一下按钮的效果:鼠标移到按钮上的时候,会出现灯光闪过的效果,非常的高端. 但遗憾的,这么牛逼的效果,仅仅兼 ...
- iOS企业级开发
2015移动技术白皮书 Android篇 iOS篇 项目管理篇 综合篇 结束语 iOS项目框架设计 项目结构的设计 基类的设计 自定义生命周期 跳转器 自定义UV打点控件 图片缓存 iOS网络底层框架 ...