
























很久之前整理了一篇《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 周振兴
IntPtr handle
= IntPtr.Zero;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 Console.ReadLine();
}
[DllImport(
"Kernel32.dll", EntryPoint = "VirtualFree")]事实证明,这种嵌入汇编代码的方式在开启DEP及Vista/Win7可运行。
Win7 (X86)开启DEP环境下测试通过。
注:codeBytes数组中是X86汇编代码,如果要在X64中运行,需修改该代码!
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。