惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

W
WeLiveSecurity
T
The Exploit Database - CXSecurity.com
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Security @ Cisco Blogs
T
Threat Research - Cisco Blogs
TaoSecurity Blog
TaoSecurity Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
腾讯CDC
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
The Blog of Author Tim Ferriss
Microsoft Azure Blog
Microsoft Azure Blog
罗磊的独立博客
F
Full Disclosure
博客园 - 【当耐特】
C
CERT Recently Published Vulnerability Notes
Engineering at Meta
Engineering at Meta
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Threatpost
I
Intezer
V2EX - 技术
V2EX - 技术
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The Hacker News
The Hacker News
小众软件
小众软件
Google DeepMind News
Google DeepMind News
T
Tailwind CSS Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
B
Blog RSS Feed
Microsoft Security Blog
Microsoft Security Blog
N
News | PayPal Newsroom
MyScale Blog
MyScale Blog
AI
AI
Vercel News
Vercel News
Spread Privacy
Spread Privacy
美团技术团队
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The GitHub Blog
The GitHub Blog
V
Vulnerabilities – Threatpost
Schneier on Security
Schneier on Security
Cyberwarzone
Cyberwarzone
G
GRAHAM CLULEY
Help Net Security
Help Net Security
Hacker News: Ask HN
Hacker News: Ask HN
Google DeepMind News
Google DeepMind News
MongoDB | Blog
MongoDB | Blog
L
LINUX DO - 热门话题
U
Unit 42
L
LangChain Blog
Recent Announcements
Recent Announcements

博客园 - Zzx飘遥

发布一个注册类型库(TypeLib)的小工具 【软件发布】发布一个查单词的小工具 COM 入门(4) COM 入门(3) COM 入门(2) COM 入门(1) 仿Win7显示桌面的工具 Deep Zoom Composer初探 ASP.NET VirtualPathProvider (下) Silverlight3离线运行 [译]理解Windows消息循环 WPF BitmapImage与byte[]的转换 VC++中启用XP主题外观 C#4.0初探:dynamic 关键字 - Zzx飘遥 - 博客园 四个字节整型转换为IP格式 - Zzx飘遥 - 博客园 拯救开启桌面效果后白屏的openSUSE 遭遇SqlDataReader锁定表 软件更新:网页设计师必备 之 网站截图工具 (附源码) C#4.0初探: Optional and named parameters
C#内嵌汇编代码的讨论
Zzx飘遥 · 2010-06-22 · via 博客园 - Zzx飘遥

很久之前整理了一篇《C# 调用非托管程序》文章,在博客园zhongzf同学在.net程序中嵌入asm汇编代码》进行了简单的讨论,现在才有时间整理。
《C# 调用非托管程序》最后一种方法通俗的讲是构造符合汇编代码(机器代码)格式的数据,把该数据当作可执行代码执行。Windows提供了DEP(Data Execution Prevention 数据执行保护)机制,也就是Windows会试图阻止程序运行非可执行内存区域的可执行代码。如果开启DEP,《C# 调用非托管程序》一文中最后一种方法执行会失败;如果关闭DEP,Windows XP SP2中执行该代码会成功,但Vista/Win7由于安全性增强的原因,该代码执行会失败。
是不是这用嵌入汇编代码的方式在开启DEP及Vista/Win7中一定不能使用呢?答案在下面分析中得出。
如果我们把保存汇编代码的内存区域标记为可执行,上面的方法也许可用。

Win API VirtualAlloc中有参数,可以指定新分配内存的权限。
使用完内存后,调用VirtualFree释放。

沿着这样的思路,将《C# 调用非托管程序》一文中最后一种方法修改如下(篇幅原因简化了注释):

/*修改记录
    2008-5-11 8:07 曲滨
        >> 基本实现预期功能
        [!] 明天进行优化

    2008-5-12 15:54 曲滨
        [E] 优化完成
        [N] 加入 NativeCodeHelper 类便于使用 

    2010-6-17 周振兴

 
        修改兼容性,可在开启DEP及Vista/Win7中运行。
*/ namespace NShellNativeCode
{
    
using System;
    
using System.Runtime.InteropServices; delegate int AddProc(int p1, int p2);
    
class Program
    {
        
static void Main(string[] args)
        {
            
byte[] codeBytes = {
                  
0x8B, 0x44, 0x24, 0x08    // mov eax,[esp+08h]
                , 0x8B, 0x4C, 0x24, 0x04    // mov ecx,[esp+04h]
                , 0x03, 0xC1                // add    eax,ecx
                , 0xC3                        // ret
                }; /*
            上面的字节数组,就是下面函数的本机代码;
            int add(int x,int y) {
                return x+y;
            }
            
            
*/

            IntPtr handle

= IntPtr.Zero;
            handle
= VirtualAlloc(
                IntPtr.Zero,
                codeBytes.Length,
                MEM_COMMIT
| MEM_RESERVE,
                PAGE_EXECUTE_READWRITE);
try
            {

                Marshal.Copy(codeBytes,

0, handle, codeBytes.Length);

                AddProc add

= Marshal.GetDelegateForFunctionPointer(handle, typeof(AddProc)) as AddProc; int r = add(1976, 1);

                Console.WriteLine(

"本机代码返回:{0}", r);

            }

finally
            { 
                VirtualFree(handle,
0, MEM_RELEASE);
            }

            Console.ReadLine();
        }

//Windows API
        [DllImport("Kernel32.dll", EntryPoint = "VirtualAlloc")]
        
public static extern IntPtr VirtualAlloc(IntPtr address, int size, uint allocType, uint protect);

        [DllImport(

"Kernel32.dll", EntryPoint = "VirtualFree")]
        
public static extern bool VirtualFree(IntPtr address, int size, uint freeType); //flags
        const uint MEM_COMMIT = 0x1000;
        
const uint MEM_RESERVE = 0x2000; const uint PAGE_EXECUTE_READWRITE = 0x40; const uint MEM_RELEASE = 0x8000;
    }
}

事实证明,这种嵌入汇编代码的方式在开启DEP及Vista/Win7可运行。
Win7 (X86)开启DEP环境下测试通过。
注:codeBytes数组中是X86汇编代码,如果要在X64中运行,需修改该代码!