在Windows 8 (c++或.net / c#)的WinRT上动态执行代码

Dynamic code execution on WinRT in Windows 8 (either C++ or .NET/C#)?

本文关键字:WinRT 动态 代码 执行 Windows c++ net      更新时间:2023-10-16

WinRT在windows 8 metro下允许你动态加载和执行代码吗?例如,是否有可能将dll下载到内存或隔离存储并从中运行代码?JIT将脚本语言编译为本机汇编语言(例如第三方浏览器)的代码是否能够在WinRT中做同样的事情,或者它被禁止为"不安全"操作?

在WinRT中运行的"托管"代码的答案是否不同?例如,在托管代码中,您是否可以从互联网下载程序集,并在MEF中发现它,或者在运行时加载它?你会使用反射吗?以某种形式释放?在c++中,您可以运行程序在运行时生成的汇编代码,或者在运行时动态加载DLL(可能是某种形式的WinRT DLL)吗?

一般来说,你不能在Metro风格的应用程序中加载和执行新代码。你可以访问的是应用程序附带的内容。

LoadLibrary和GetProcAddress丢失,所以c++不能动态加载代码。
同样,c#也不能,因为没有Assembly.Load.
JavaScript可以,但只能在web容器中,而不能在代码中更完整的信任部分。

这一切的原因是,如果一个应用程序可以加载和运行任意代码,商店的安全/恶意软件保护将是没有意义的。

实际上,Metro风格的应用程序可以动态加载和执行代码。有一些限制;Metro和Desktop应用程序在关键方面略有不同。

机制有所不同,取决于调用者(LoadPackagedLibrary() Assembly.Load()等)。Metro和Desktop之间的一个关键区别是Metro应用程序只能动态加载应用程序的包图(你的包和s)和系统代码(否则可以静态加载)。

查看我的帖子了解更多细节http://social.msdn.microsoft.com/Forums/en-US/wingameswithdirectx/thread/d1ebe727-2d10-430e-96af-46964dda8225

windows 8 metro下的WinRT允许你动态加载和执行代码?

例如,是否有可能将dll下载到内存或隔离存储并从中运行代码?

JIT将脚本语言编译为本机汇编语言(例如第三方浏览器)的代码是否能够在WinRT中做同样的事情,或者它被禁止为"不安全"操作?

这是被禁止的。

在WinRT中运行的"托管"代码的答案是否不同?

例如,在托管代码中,您可以从互联网下载程序集并在MEF中发现它,或者在运行时能够加载它吗?

你可以使用反射吗?以某种形式释放?

在c++中,你可以运行程序在运行时生成的汇编代码,或者在运行时动态加载DLL(可能是某种形式的WinRT DLL)吗?

你所描述的一切都允许绕过WinRT的安全保证。

你的问题有点不清楚…一些通用的指针:

  • 。. NET应用程序使用WinRT(但不是新的UI模型!)
    在这种情况下,你今天的一切都是可能的(也许不是OLEDB),但反射等

  • 。为Metro UI构建的。NET应用程序
    我想这是不可能的(见http://blogs.microsoft.co.il/blogs/sasha/archive/2011/09/17/metro-net-framework-profile-windows-tailored.aspx和http://tirania.org/blog/),至少只要你想通过Windows Store销售…在这个范围之外(Windows Store),可能有一些技巧可以绕过这个限制,正如一些人已经证明的那样……但我不指望……也许你可以使用一些JavaScript (eval等)来做一些动态的事情,但我不确定目前

Windows 10为此添加了codeGeneration功能。这允许VirtualAllocFromApp和VirtualProtectFromApp函数在WinRT应用程序中使用,就像VirtualAlloc和VirtualProtect将在Win32中使用一样。

更有趣的是,IE 10实际上在它的js代码上做了JIT,所以API显然是允许的。

您可以创建一个Windows运行时组件(通用Windows) c++,你可以从c#代码中访问组件,在组件中你可以调用LoadPackagedLibrary,它有一个限制,它只能加载与你的应用程序打包的DLL。否则它与LoadLibrary相同。

你不能下载和动态加载,因为ApplicationData和InstalledLocation是不同的位置。(LoadPackagedLibrary不允许指定路径)。你只能写ApplicationData…

从AppX包目录动态加载程序集的示例(来自MSDN论坛):

private async Task<IEnumerable<Assembly>> GetAssemblyListAsync()
{
    var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
    List<Assembly> assemblies = new List<Assembly>();
    foreach (StorageFile file in await folder.GetFilesAsync())
    {
        if (file.FileType == ".dll" || file.FileType == ".exe")
        {
            var name = file.Name.Substring(0, file.Name.Length - file.FileType.Length);
            Assembly assembly = Assembly.Load(new AssemblyName() { Name = name });
            assemblies.Add(assembly);
        }
    }
    return assemblies;
}

程序集必须添加到应用程序包中。你不能从外部下载它们。

然而,这种方法在。net Native中不起作用,因为所有内容都合并到一个DLL中。您应该在某处保存一个程序集名称列表(在Assets中的一个简单文件中),并为每个项目调用Assembly.Load

调试模式下的动态程序集列表和发布模式下的预定义程序集名称数组的示例。. NET原生工具链)。

#if DEBUG
using Windows.Storage;
#endif
    // ...
    IEnumerable<string> assemblyNames;
#if DEBUG
    assemblyNames = Windows.ApplicationModel.Package.Current.InstalledLocation.GetFilesAsync().AsTask().Result
        .Where(file => file.FileType == ".dll" && file.Name.Contains("Business"))
        .Select(file => file.Name.Substring(0, file.Name.Length - file.FileType.Length));
#else
    assemblyNames = new[] { "California.Business", "Colorado.Business" };
#endif
    foreach (var name in assemblyNames)
    {
        var assembly = Assembly.Load(new AssemblyName() { Name = name });
        // Load required types.
        // ...
    }

这是可能的,检查Windows 8中的谷歌Chrome应用程序,他们提供了一种在正常模式之间切换的方法&