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

"嵌入"是指什么?资源?注入进程?如果是嵌入资源,那跟嵌入任何其他内容是一样的,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汇编,希望大家能够喜欢。

(0)

相关推荐

  • C#中嵌入SQLite数据库的简单方法

    SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中.它是D.RichardHipp建立的公有领域项目.它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了.它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl.C#.PHP.Java等,还有ODBC接口,同样比起Mysql.PostgreSQL这两款开源的世界著名数据库

  • C#通过WIN32 API实现嵌入程序窗体

    本文实例讲述了C#通过WIN32 API实现嵌入程序窗体的方法,分享给大家供大家参考.具体如下: 这是一个不使用COM,而是通过WIN32 API实现的示例, 它把写字板程序嵌在了自己的一个面板中. 这么做可能没有实际意义, 因为两个程序之前没有进行有价值的交互, 这里仅仅是为了演示这么做到, 以下是详细注释过的主要源代码. 我们把它封装到一个类中: using System; using System.Collections.Generic; using System.Linq; using

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

    "嵌入"是指什么?资源?注入进程?如果是嵌入资源,那跟嵌入任何其他内容是一样的,vs中只要拖拽就能完成嵌入资源.如果是注入进程,则必须得先将汇编码转为机器码.虽然托管的C#也是能办到,但这似乎是所有人都不推荐的方式. C#可不可以嵌入汇编 可以 在我眼中C#作为一个介于中上层语言是不可能不可以置入汇编代码的 为什么会被我认为中上层语言呢 从C#保留指针就可以看出 我知道有很多人一定不会相信C#可以使用汇编代码 不过C#会比较麻烦C#不可以直接内联汇编(inline-asm)准确的说C#

  • x86汇编DOS编程环境搭建过程

    目录 前言 相关工具的介绍 DOSBOX 汇编工具包 DOSBOX的使用 汇编 连接 执行 调试 其它 前言 在学习x86汇编时,第一步是搭建一个可以编译.运行代码的环境 这方面的教程有一些,但是给出的下载链接还要付费,或者内容不全,我看不起这些人,所以自己写一个,方便看到这个文档的大家,需要下载附件以度盘给出,免费下载 链接: https://pan.baidu.com/s/1syKK2kZoGLrCjF8WxvYM6g 提取码: e8et 相关工具的介绍 DOSBOX 这个软件在PC上模拟出

  • X86汇编调试环境搭建的过程

    最近毕设需要做一个基于X86的微型OS内核,一直在学习汇编,前来记录一下 汇编环境搭建 本次使用vscode搭建的,需要的插件有X86 and X86_64 Assembly(也可以使用masm插件),还有一个hexdump for VSCode. 安装NASM,并添加到环境变量 安装QEMU,并将其添加到环境变量下 编写代码:(代码来自30天自制操作系统) ; hello-os ; TAB=4 ; 标准FAT12格式软盘专用的代码 Stand FAT12 format floppy code

  • 汇编语言:x86汇编指令大全及其注意事项

    目录 Part 1:instruction Part 2 2.1 (逻辑)运算.移位等常用指令 2.1 (逻辑)运算.移位等常用指令 2.2 循环移位指令 2.3 数据串操作指令 2.4 逻辑运算指令 2.5 基于大小关系的跳转指令 2.6 基于单标志位的转移指令 Part 1:instruction 积少成多,持续更新.(这将会是一个极其漫长的过程) 表格中各条指令的顺序根据笔者所认为的重要或常用程度进行排序,仅供参考. Part 2 本表格中所涉及的F是指状态寄存器,CF指进位标志位,其它以

  • C语言ASM汇编内嵌语法详解

    3 GCC Inline ASM GCC 支持在C/C++代码中嵌入汇编代码,这些汇编代码被称作GCC Inline ASM--GCC内联汇编.这是一个非常有用的功能,有利于我们将一些C/C++语法无法表达的指令直接潜入C/C++代码中,另外也允许我们直接写 C/C++代码中使用汇编编写简洁高效的代码. 1.基本内联汇编 GCC中基本的内联汇编非常易懂,我们先来看两个简单的例子: __asm__("movl %esp,%eax"); // 看起来很熟悉吧! 或者是 __asm__(&q

  • iOS汇编入门教程之在Xcode工程中嵌入汇编代码的方法

    简介 上一篇文章ARM64汇编基础中介绍了汇编在iOS开发中的应用以及ARM汇编基础知识,本文将介绍在C或Objective-C构成的工程中如何嵌入汇编代码. 注意 在调试ARM汇编时,Xcode的Build对象必须为真机,如果对象为模拟器则是x86汇编. 内联汇编 汇编与C间接通信 在函数中可以直接插入汇编代码来影响函数的运行逻辑,使用的语法为编译指令 __asm__ ,注意插入汇编有可能会被编译器忽略,因此需要加入 __volatile__ 修饰符保证汇编代码有效. 下面给出一个简单的例子,

  • C指针原理教程之C内嵌汇编

    内联汇编的重要性体现在它能够灵活操作,而且可以使其输出通过 C 变量显示出来.因为它具有这种能力,所以 "asm" 可以用作汇编指令和包含它的 C 程序之间的接口.简单得说,内联汇编,就是可以让程序员在C语言中直接嵌入汇编代码,并与汇编代码交互C程序中的C表达式,享受汇编的高运行效率. 内联汇编的格式是直接在C代码中插入以下格式: asm( .... .... ) 其中的"..."为汇编代码,比如下面例子中,在 result=a*b和printf("%d\

  • ARM体系下的GCC内联汇编教程详解

    在操作系统级的编程中,有时候,C语言并不能完全的使用硬件的功能,这时候就需要嵌入一些汇编代码来实现功能. 有两种方式可以使C语言和assemly语言一起工作,一种是两种语言分开写成两个文件,链接的时候链接成一个文件;另一种就是在C语言中嵌入汇编代码.下面简单介绍一下如何在GCC中嵌入汇编代码. GCC规定了一个内联汇编的语法,不同硬件平台上的GCC内联汇编几乎都是这样的: asm( 汇编指令列表 :输出运算符列表 :输入运算符列表 :被更改的资源列表 }; 在GCC中插入汇编代码,需要以asm关

  • 浅析Go汇编语法和MatrixOne使用介绍

    目录 MatrixOne数据库是什么? Go汇编介绍 为什么使用Go汇编? 为什么不用CGO? Go汇编语法特点 操作数顺序 寄存器宽度标识 函数调用约定 对写Go汇编代码有帮助的工具 avo text/template 在Go汇编代码中使用宏 在MatrixOne数据库中的Go语言汇编应用 基本向量运算加速 Go语言无法直接调用的指令 编译器无法达到的特殊优化效果 MatrixOne是一个新一代超融合异构数据库,致力于打造单一架构处理TP.AP.流计算等多种负载的极简大数据引擎.MatrixO

  • ARM汇编逆向iOS 实战

    我们先讲一些ARM汇编的基础知识.(我们以ARMV7为例,最新iPhone5s上的64位暂不讨论) 基础知识部分: 首先你介绍一下寄存器: R0-R3:用于函数参数及返回值的传递 R4-R6, R8,R10-R11:没有特殊规定,就是普通的通用寄存器 R7:栈帧指针(Frame Pointer).指向前一个保存的栈帧(stack frame)和链接寄存器(link register, lr)在栈上的地址. R9:操作系统保留 R12:又叫IP(intra-procedure scratch),

随机推荐