将C#编译为Native?


71

我认为我对将.NET字节码编译为本机代码感到有些困惑,或者我对最终结果感到困惑。因此,在我尝试整理我认为我理解的内容时,请多多包涵,以便您可以帮助我找出我所缺少的内容。

我想做的是将用C#编写的应用程序编译为常规的本机代码,就像用C编写时那样。我的推理与性能无关,而与某种程度的保护无关。我知道我的最终目标并非不可能(甚至确实如此困难),但是我只是觉得反转x86汇编比反转Reflector给我的东西更困难。

现在,如果将我的C#应用​​程序扔到Reflector中,我基本上会得到我的源代码。通常,当我将不受管理的C / C ++应用程序放入IDAPro并使用HexRays反编译器时,我得到的反编译程度并不太相同,我不得不诉诸于x86反汇编以了解逻辑流程。我的理解是,如此出色的反编译来自Reflector,这是因为应用程序位于MSIL中,而不是HexRays尝试反编译的更简洁的本机代码。

我不担心客户端计算机仍然需要.NET运行时,我没有尝试绕过任何这些。我想像upx在我的程序上一样运行普通的软件混淆程序,并且作为.NET二进制文件执行失败。

我对这个相关问题的理解ngen可以满足我的要求。我尝试使用ngen。但是,将输出文件从C:\Windows\assemblies\...\applicationName.ni.exe目录复制到某个位置后,我可以双击,并尝试运行它会产生一个错误,提示它不是“有效的Win32应用程序”。此外,当我将其applicationName.ni.exe扔到Reflector中时,我得到的输出与从中获得的输出相同applicationName.exe。由于applicationName.ni.exe应该是本机代码,因此我希望Reflector会出错,但事实并非如此。如果这是我应该做的方式,为什么Reflector仍然给我这么好的反编译?

因此,再次总结一下我的主要问题:如何将.NET程序编译为Reflector不太容易反编译的本机二进制文件?或有什么最佳实践来保护以.NET语言编写的产品免受新手反向工程师的侵害?

如果我需要其他工具,我会选择免费的东西,而不是像Codewall这样的东西

谢谢!

更新:我了解我在寻找的内容可能会限制该语言的某些功能,例如反射,但是我认为可以。我的代码都没有进行任何显式Assembly.Load调用或任何类似的操作。但是,无论如何都不能将它们替换为GetProcAddress/LoadLibrary通话吗?


2
在代码保护者/观察者中,大多数人都是商业的,如果您不是软件开发公司,则价格适中,但是即使是顶级商业公司也可能在您的代码正常工作后就遇到很多问题。
克里斯·马里西克

出于安全原因,我也需要类似的功能。我的C#应用​​程序需要解密单独分发给每个用户的配置文件(每个文件都不同)。当然,问题在于用于解密的代码和算法必须在C#中,如果可以很容易地重新创建它,则存在风险。我为此感到另类解决方案。
蚂蚁水域

Answers:


25

我刚刚在VS2015Windows 8.1验证了 .Net Native(正确配置后,请检查.proj进行验证),并针对特定架构进行构建(可能是过大的代码,尚未验证),将生成一个本地文件,该文件将为您提供“很难对您正在寻找的代码进行反向工程”,这对我来说是无法通过DotPeek(来自JetBrains的免费.Net反编译器)读取.dll的


18
大!六年后,我的梦想终于实现了。;)
mrduclaw 2015年

9
请注意,这适用于Windows 10 Universal应用程序,不适用于WPF或WinForms。即Windows 8.1及更高版本。
埃里克·埃斯基尔德森

2
@EricEskildsen,所以您不能为WPF / WinForms编译为本机?
jj_

1
@jj_使用.NET Native?从来没听说过。也就是说,今天可能还有其他方法可以将WPF / WinForms编译为本机-我已经有一段时间没有检查该空间了。
埃里克·埃斯基尔德森

1
@EricEskildsen是的,Delphi是其中之一(及其对应的开源项目Lazarus)。
jj_

30

那不是ngen.exe的工作方式。它仅预先运行JIT编译器以生成.ni.exe或.ni.dll模块。该二进制文件不包含元数据,仅包含从IL为方法主体生成的机器代码。CLR仍必须找到原始程序集。只有这样,它才能确定存在可用的ngen-ed映像,以便它可以使用其中的机器代码,而不是根据程序集的IL生成它。

Ngen.exe加快了应用程序的热启动时间,仅此而已。

对于那些可能希望拆卸我的程序集的人,我通常的建议是将它们指向sourceforge.net。它具有数TB的源代码,由程序员编写和维护,通常比我好。有时即使有很好的评论。如果您的混淆器无法正常工作,请货比三家。有许多。


2
谢谢!这正是我正在寻找的关于ngen正在做的事情的解释。您对优质,免费的混淆器有何建议?
mrduclaw

2
我只知道好的和免费的反汇编程序。反汇编程序必须是免费的,要钱就不能使用它。好的混淆器要花钱。Visual Studio附带了一个Dotfuscator。我从未听说过一家公司销售基于受Dotfuscator保护的破解源代码的产品的公司。这表明它运作良好。
汉斯·帕桑

19

昨天,在Build 2014上,Microsoft宣布了.NET Native。根据常见问题解答,“ ...最初,我们专注于使用.NET Native的Windows Store应用程序。从长远来看,我们将继续改进所有.NET应用程序的本机编译。”


但是如何在VS2013中使用它?我没有VS2015许可证,所以我想在VS2013中使用.Net Native
Eldar Zeynalov

1
@EldarZeynalov也许您应该看看VS2015社区版?

17

如果要保护代码,则通常使用混淆器。 Dotfuscator参加了带有反射镜的军备竞赛已有一段时间了,我们将其用于我们的产品。但是,实际上,技术人员可以轻松阅读混淆的代码。

编译为本地代码会破坏使用托管语言的目的。主要好处是允许目标运行时将IL JIT转换为对目标CPU最合适的东西。否则,您将在mono中使用类似提前选项


Dotfuscator难道不只是混淆变量名以使其更难阅读吗?而且我知道我不会接受运行时优化,对此我是可以的。我使用C#的主要目的是使该语言的语法和库更加轻松和美观,其次是精美的优化。
mrduclaw

23
“编译为本机代码会破坏使用托管语言的目的” –这是不正确的。
zezba9000 2013年

.NET语言的托管功能之一是,它们可以被验证为安全。将可验证的IL编译为本机代码不会丢失此特定功能。另外,您描述为“主要收益”的东西甚至根本不存在(甚至在最初写此答案的5年后):尽管从理论上讲是可能的,.NET的JIT编译器还是非常保守的,并且唯一值得注意的优化是自成立以来发生的事情是提高了代码吞吐量。在优化发出的本机代码方面尚未完成任何工作。
IInspectable

也许使用托管语言毕竟无法达到拥有机器代码的目的,即速度和功率-计算机本身的存在理由
逆向工程师

8

Spoon(以前是Xenocode)的产品可能符合您的需求。我们将其用于基于WPF的安装程序UI,因此不必加载.net即可加载安装程序本身。


这看起来棒极了,因为我只是一个孤独的开发人员,并且不为公司做这件事,所以它只比我想要的贵一点。
mrduclaw

确实,价格可能有点高。不过效果很好。不知道是否有任何开源或其他替代品。另一个缺点是它会产生非常大的可执行文件,但是环境虚拟化非常流畅。
dkackman

7

NGEN添加了本机代码,但没有删除MSIL。因此,在MSIL上运行的任何工具仍然可以使用。您还需要进行反射,这对于真正的本机编译器而言将非常困难。


我的代码都没有明确使用反射,没有它我也可以。除非对语言本身有一些限制,这可能吗?
mrduclaw

您知道这一点,但是假设的C#到本机编译器不能真正假设它。
MSalters

7

其他答案提到了Microsoft的.NETNative编译器,但没有告诉您如何执行此操作。

是一个CoreRT有关如何将C#项目编译为本地代码的教程。

注意:为了使所有工作正常,我还必须注释掉以下行:

<!-- <add key="helloworld" value="https://api.helloworld.org/v3/index.json" /> -->

输出是一个大致4MB大小的可执行文件:

实际上,.NET反编译器不再可读该代码,并且IDA Pro(本机代码反汇编程序)将其识别为本机代码。



5

终于可以使用Microsoft的.NET Native编译器了

它会自动编译以托管代码(C#或Visual Basic)编写的应用程序的发行版本,这些应用程序将.NET Framework和Windows 10定位为本机代码。

..

•您的应用程序将提供本机代码的卓越性能。

•您可以继续使用C#或Visual Basic进行编程。

•您可以继续利用.NET Framework提供的资源,包括其类库,自动内存管理和垃圾回收以及异常处理。

对于您的应用程序用户,.NET Native具有以下优点:

•快速执行时间

•持续快速的启动时间

•低部署和更新成本

•优化的应用程序内存使用率

但是.NET Native不仅仅涉及对本机代码的编译。它改变了.NET Framework应用程序的构建和执行方式。特别是:

•在预编译期间,.NET Framework的必需部分已静态链接到您的应用程序中。这使该应用程序可以与.NET Framework的应用程序本地库一起运行,并且编译器可以执行全局分析以实现性能双赢。因此,即使在.NET Framework更新之后,应用程序仍可以始终如一地启动。

•.NET Native运行时针对静态预编译进行了优化,因此能够提供卓越的性能。同时,它保留了开发人员发现如此高效的核心反射功能。

•.NET Native使用与C ++编译器相同的后端,后者针对静态预编译方案进行了优化。

https://msdn.microsoft.com/zh-CN/library/dn584397(v=vs.110).aspx

仅在VS.NET 2015中可用。


3

我可能会退一步,问您为什么要寻找这种类型的保护。我并不是要争辩说您不需要保护,但是我认为值得了解动机。

例如,如果您想要保护是因为您的系统中有一个算法,如果有人对其进行反向工程,它将对安全性造成破坏,那么您可能需要考虑采用其他方法。这意味着算法中存在缺陷,并且没有任何混淆或本机编译可以为您提供帮助。

如果是IP问题,那么我认为混淆可能是您最好的方法。这有点像在您的门上放一把锁。有人可以打破锁并进入,但他们故意这样做,而不是仅仅走进门。


哦,不,我的算法没有做任何花哨的事情。它介于学术好奇心和知识产权关注之间。我认为一个不错的(但免费的)混淆器可能很适合我的IP问题,但是我确实有一个以前编写的自定义代码打包器,我也想在.NET应用程序中使用它。对混淆器有什么建议吗?
mrduclaw

3

使用IL2CPU编译器可以做到这一点。IL2CPU是由制作COSMOS(C#开源托管操作系统)的人开发的,并且只能通过下载cosmos获得。IL2CPU生成可以通过Nasm进行编译的ASM文件(某些其他汇编程序也可以工作,但最好使用nasm)。IL2CPU的唯一问题是它内置在Cosmos项目中,很难使其独立运行。


1
这看起来像是基于csnative.codeplex.com上基于IL2C的工作(该链接可能会随着
Codeplex的
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.