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 参数一

  1. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  2. public delegate IntPtr CallMethod(IntPtr ptr);

由于是在VC下内联的汇编 最后移植到C# 一般在VC下函数的调用方式是cdcel

何况下面的是按照cdcel导出函数格式进行的 所以不可以使用__stdcall的方式

  1. [STAThread]
  2. static void Main(string[] args)
  3. {
  4. byte[] buf_asm = {
  5. // push        ebp
  6. // mov         ebp,esp
  7. // sub         esp,0C0h
  8. // push        ebx
  9. // push        esi
  10. // push        edi
  11. // lea         edi,[ebp-0C0h]
  12. // mov         ecx,30h
  13. // mov         eax,0CCCCCCCCh
  14. // rep stos    dword ptr es:[edi]
  15. 85, 139, 236, 129, 236, 192, 0, 0, 0, 83, 86, 87, 141, 189, 64,
  16. 255, 255, 255, 185, 48, 0, 0, 0, 184, 204, 204, 204, 204, 243, 171,
  17. // call        dword ptr[ebp+8]
  18. 255, 85, 8,
  19. // pop         edi
  20. // pop         esi
  21. // pop         ebx
  22. // mov         esp,ebp
  23. // pop         ebp
  24. // ret
  25. 95, 94, 91, 139, 229, 93, 195
  26. };
  27. IntPtr ptr_asm = SetHandleCount(buf_asm);
  28. VirtualProtect(ptr_asm, buf_asm.Length);
  29. CallMethod call_method = Marshal.GetDelegateForFunctionPointer(ptr_asm, typeof(CallMethod)) as CallMethod;
  30. call_method(Marshal.GetFunctionPointerForDelegate(new Action(Hello_x86)));
  31. }

首先把你需要嵌入的汇编以字节数组的格式写出来 然后通过

SetHandleCount函数是用于取地址指针的

  1. static void VirtualProtect(IntPtr ptr, int size)
  2. {
  3. int outMemProtect;
  4. if (!VirtualProtect(ptr, size, 64, out outMemProtect))
  5. throw new Exception("Unable to modify memory protection.");
  6. }

上面的函数用于修改内存保护 不过是为了让委托可以进行交互 包括汇编代码可以被互调用

  1. static void Hello_x86()
  2. {
  3. Console.Title = ((new StackFrame()).GetMethod()).Name;
  4. Console.WriteLine("I was x86 assembly call a test function.");
  5. Console.ReadKey(false);
  6. }

上面的函数是一个测试函数 这个函数没有太大意义 只是表现利用了汇编调用

本函数 然后本函数输出一个回应的信息 用于提示该函数被写入内存汇编调用

依赖的外部函数

  1. [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  2. public static extern IntPtr SetHandleCount(byte[] value);
  3. [DllImport("kernel32.dll", SetLastError = true)]
  4. public static extern bool VirtualProtect(IntPtr lpAddress, int dwSize, int flNewProtect, out int lpflOldProtect);

依赖的命名空间

  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Diagnostics;

版权声明:本文为博主原创文章,未经博主允许不得转载。

C# inline-asm / 嵌入x86汇编的更多相关文章

  1. 寄存器理解 及 X86汇编入门

    本文整理自多材料源,感谢原址分享,请查看末尾Url I, 汇编语言分类: 汇编语言和CPU息息相关,但是不能把汇编语言完全等同于CPU的机器指令.不同架构的CPU指令并不相同,如x86,powerpc ...

  2. C/C++ 中嵌入 arm 汇编

    GCC编译器支持直接在C或者C++代码中,嵌入ARM汇编代码.其基本格式非常简单,大致如下: __asm__ [__volatile__] ( assembler template : [output ...

  3. 如何在C或C++代码中嵌入ARM汇编代码

    转载自:http://blog.csdn.net/roland_sun/article/details/42921131 大家知道,用C或者C++等高级语言编写的程序,会被编译器编译成最终的机器指令. ...

  4. 为什么X86汇编中的mov指令不支持内存到内存的寻址?

    在X86汇编中,MOV [0012H], [0016H]这种指令是不允许的,至少得有一个操作数是寄存器.当然,这种问题在用高级语言的时候看不到,感觉好像基本上都是从内存到内存啊,为毛到了汇编就不行了? ...

  5. 对X86汇编的理解与入门

    本文描述基本的32位X86汇编语言的一个子集,其中涉及汇编语言的最核心部分,包括寄存器结构,数据表示,基本的操作指令(包括数据传送指令.逻辑计算指令.算数运算指令),以及函数的调用规则.个人认为:在理 ...

  6. X86汇编概要

    来自:https://www.cnblogs.com/jiftle/p/8453106.html 本文翻译自:http://www.cs.virginia.edu/~evans/cs216/guide ...

  7. x86汇编之十(使用字符串)

    x86汇编之十(使用字符串) 转自网络,出处不详 一.传送字符串 Intel提供了完整的字符串传送指令,就像是MOV指令一样. 1.MOVS指令 1)movs指令格式 把字符串从一个位内存位置传送到另 ...

  8. x86汇编指令脚本虚拟机

    简介 这是一个可以直接解释执行从ida pro里面提取出来的x86汇编代码的虚拟机. 非常精简,整体架构上不能跟那些成熟的虚拟机相比,主要目标是够用.能用.轻量就行,如果觉得代码架构设计的不是很好的话 ...

  9. x64汇编第二讲,复习x86汇编指令格式,学习x64指令格式

    目录 x64汇编第二讲,复习x86汇编指令格式,学习x64指令格式 一丶x86指令复习. 1.1什么是x86指令. 1.2 x86与x64下的通用寄存器 1.3 OpCode 1.4 7种寻址方式 二 ...

随机推荐

  1. Maven项目配置不接文件名

    1.更改finalName为ROOT,在pom.xml中加入下边的build,是可以进行自动启动Tomcat. 2.删除webapps目录下的ROOT文件夹 3.进行maven项目的deploy 4. ...

  2. c# XML序列化与反序列化 属性字段标识

    序列化对象 public class People { [XmlAttribute("NAME")] public string Name { set; get; } [XmlAt ...

  3. JSHint 使用说明

    SHint介绍 翻译自www.jshint.comJSHint(注意不是jslint:))是一个由javascript社区驱动开发的用于检查javascript代码错误和问题的工具,有了他,可以使你保 ...

  4. LightOJ1027 A Dangerous Maze(期望)

    题目大概说你正在起点,面前有$n$个门,每个门有一个数字$x$,正数表示开这个门$x$分钟后会出去,负数表示开这个门$-x$分钟后会回到起点.选择门的概率是一样的且每次选择互不影响.问出去的时间期望是 ...

  5. [Xamarin] 啟動拍照並且儲存 (转帖)

    拍照對手機來說是很常用到的功能,許多App都基於在拍照上面,這篇文章主要大部分是在翻譯官方文件 (http://docs.xamarin.com/recipes/android/other_ux/ca ...

  6. 【WinHec启示录】透过Windows 10技术布局,谈微软王者归来

    每个时代都有王者,王者的成功,往往是因为恰逢其时地发布了一个成功的产品(具有里程碑意义,划时代的产品).Windows 95的成功标示着微软是PC时代的王者:WinXP的成功标示着微软是互联网时代的王 ...

  7. 用c#开发微信 (7) 微渠道 - 推广渠道管理系统 2 业务逻辑实现

    我们可以使用微信的“生成带参数二维码接口”和 “用户管理接口”,来实现生成能标识不同推广渠道的二维码,记录分配给不同推广渠道二维码被扫描的信息.这样就可以统计和分析不同推广渠道的推广效果. 上次介绍了 ...

  8. 讨厌的 StorageFolder.GetFileAsync 异常。

    我们在做WinRT开发的时候,会偶到这样一个场景. 获取一个文件,当他不存在的时候,我们做一些事情. 如果当不存在,我们就创建这么一个文件,那就很好办了. var file = Application ...

  9. 尝试在Linux上编译KestrelHttpServer

    Kestrel是目前在非Windows平台上运行ASP.NET 5应用程序的唯一可用Web服务器,但微软似乎将它冷落在一边,源代码更新很慢. 今天试着在Linux上编译Kestrel的源代码,遇到了很 ...

  10. SQL Server 重新初始化系统数据库中的单引号问题

    在最近的数据库跨机房迁移中,由于硬件的限制,需要滚动式地将数据库一台台迁移到新机房,先在新机房搭建一个新环境,将数据迁移过去,再将旧机房的机器下架搬到新机房,重新配置后用于下一轮的升级,重新配置过程中 ...