C# 通过 inline-asm 解决嵌入x86汇编

 更新时间:2020年6月25日 11:28  点击:1782

"嵌入"是指什么?资源?注入进程?如果是嵌入资源,那跟嵌入任何其他内容是一样的,vs中只要拖拽就能完成嵌入资源。如果是注入进程,则必须得先将汇编码转为机器码。虽然托管的C#也是能办到,但这似乎是所有人都不推荐的方式。

C#可不可以嵌入汇编 可以 在我眼中C#作为一个介于中上层语言是不可能不可以置入汇编代码的 为什么会被我认为中上层语言呢 从C#保留指针就可以看出 我知道有很多人一定不会相信C#可以使用汇编代码

不过C#会比较麻烦C#不可以直接内联汇编(inline-asm)准确的说C#只可以使用(auto-asm)动态汇编 这种技术不是

C#独有的 易语言、VB、C++ 三种语言都可以 不过动态汇编我见过最多的是被应用在外挂方面 及远程汇编注入 实际上是属于动态汇编技术的一种扩展 不过很难说JIT在编译代码后是通过在远程把汇编代码写入托管进程执行的 又或者说是一种寄生在外壳程序中运行的技术及“内存运行” 懒得讨论这些一想到就头大。

从上图中你可以看见一份简单的x86 / call汇编在C#中内嵌并被调用执行一看你会发现并不是太难 我的一篇博文 写了一大堆废话就是说这个东西不过是易语言的

我们知道软件运行时所有代码会放在虚拟内存中 而可执行的代码在内存中

内存保护一般是PAGE_EXECUTE_READ及32不过经过我研究.NET上的可执行代码应该是PAGE_EXECUTE_READWIRTE及64 如果是P/invoke上执行DLL中的保护是32 就可以我们在内嵌汇编时不可以使用只读保护

如果我们需要使用由.NET去委托去Call那么必须是可读可写 如果通过Win32API去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; 

通过inline-asm技术解决C#语言解决嵌入x86汇编,希望大家能够喜欢。

[!--infotagslink--]

相关文章

  • C#实现简单的登录界面

    我们在使用C#做项目的时候,基本上都需要制作登录界面,那么今天我们就来一步步看看,如果简单的实现登录界面呢,本文给出2个例子,由简入难,希望大家能够喜欢。...2020-06-25
  • 浅谈C# 字段和属性

    这篇文章主要介绍了C# 字段和属性的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下...2020-11-03
  • C#中截取字符串的的基本方法详解

    这篇文章主要介绍了C#中截取字符串的的基本方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-03
  • C#实现简单的Http请求实例

    这篇文章主要介绍了C#实现简单的Http请求的方法,以实例形式较为详细的分析了C#实现Http请求的具体方法,需要的朋友可以参考下...2020-06-25
  • C#连接SQL数据库和查询数据功能的操作技巧

    本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
  • C#中new的几种用法详解

    本文主要介绍了C#中new的几种用法,具有很好的参考价值,下面跟着小编一起来看下吧...2020-06-25
  • 使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序)

    这篇文章主要介绍了使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • C#开发Windows窗体应用程序的简单操作步骤

    这篇文章主要介绍了C#开发Windows窗体应用程序的简单操作步骤,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
  • C#从数据库读取图片并保存的两种方法

    这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
  • C#和JavaScript实现交互的方法

    最近做一个小项目不可避免的需要前端脚本与后台进行交互。由于是在asp.net中实现,故问题演化成asp.net中jiavascript与后台c#如何进行交互。...2020-06-25
  • C++调用C#的DLL程序实现方法

    本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
  • 轻松学习C#的基础入门

    轻松学习C#的基础入门,了解C#最基本的知识点,C#是一种简洁的,类型安全的一种完全面向对象的开发语言,是Microsoft专门基于.NET Framework平台开发的而量身定做的高级程序设计语言,需要的朋友可以参考下...2020-06-25
  • C#变量命名规则小结

    本文主要介绍了C#变量命名规则小结,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-09
  • C#绘制曲线图的方法

    这篇文章主要介绍了C#绘制曲线图的方法,以完整实例形式较为详细的分析了C#进行曲线绘制的具体步骤与相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • C# 中如何取绝对值函数

    本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
  • c#自带缓存使用方法 c#移除清理缓存

    这篇文章主要介绍了c#自带缓存使用方法,包括获取数据缓存、设置数据缓存、移除指定数据缓存等方法,需要的朋友可以参考下...2020-06-25
  • c#中(&&,||)与(&,|)的区别详解

    这篇文章主要介绍了c#中(&&,||)与(&,|)的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
  • 经典实例讲解C#递归算法

    这篇文章主要用实例讲解C#递归算法的概念以及用法,文中代码非常详细,帮助大家更好的参考和学习,感兴趣的朋友可以了解下...2020-06-25
  • C#学习笔记- 随机函数Random()的用法详解

    下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • C#中list用法实例

    这篇文章主要介绍了C#中list用法,结合实例形式分析了C#中list排序、运算、转换等常见操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25