What happens exactly when I launch a .NET exe? I know that C# is compiled to IL code and I think the generated exe file just a launcher that starts the runtime and passes the IL code to it. But how? And how complex process is it?
当我启动。net exe的时候会发生什么?我知道c#编译为IL代码,我认为生成的exe文件只是启动运行时并将IL代码传递给它的启动程序。但如何?这个过程有多复杂?
IL code is embedded in the exe. I think it can be executed from the memory without writing it to the disk while ordinary exe's are not (ok, yes but it is very complicated).
IL代码被嵌入到exe中。我认为它可以从内存中执行,而不需要将它写入磁盘,而普通的exe不是(好的,是的,但是它非常复杂)。
My final aim is extracting the IL code and write my own encrypted launcher to prevent scriptkiddies to open my code in Reflector and just steal all my classes easily. Well I can't prevent reverse engineering completely. If they are able to inspect the memory and catch the moment when I'm passing the pure IL to the runtime then it won't matter if it is a .net exe or not, is it? I know there are several obfuscator tools but I don't want to mess up the IL code itself.
我的最终目标是提取IL代码并编写我自己的加密启动程序,以防止scriptkiddy在Reflector中打开我的代码并轻松窃取我的所有类。我不能完全阻止逆向工程。如果他们能够检查内存并捕捉到我将纯粹的IL传递到运行时的时刻那么它是否为。net exe就不重要了,是吗?我知道有一些模糊处理工具,但是我不想把IL代码弄乱。
EDIT: so it seems it isn't worth trying what I wanted. They will crack it anyway... So I will look for an obfuscation tool. And yes my friends said too that it is enough to rename all symbols to a meaningless name. And reverse engineering won't be so easy after all.
编辑:看来不值得去尝试我想要的东西。不管怎样,他们会破解的……我会找一个混淆工具。是的,我的朋友也说过,把所有的符号重命名为一个毫无意义的名字就足够了。逆向工程也不会那么容易。
7 个解决方案
#1
37
If you absolutely insist on encrypting your assembly, probably the best way to do it is to put your program code into class library assemblies and encrypt them. You would then write a small stub executable which decrypts the assemblies into memory and executes them.
如果您绝对坚持对您的程序集进行加密,那么最好的方法是将您的程序代码放入类库程序集并对它们进行加密。然后您将编写一个小的存根可执行文件,该文件将程序集解密到内存中并执行它们。
This is an extremely bad idea for two reasons:
这是一个极其糟糕的想法,有两个原因:
- You're going to have to include the encryption key in your stub. If a 1337 hacker can meaningfully use your reflected assemblies, he can just as easily steal your encryption key and decrypt them himself. (This is basically the Analog Hole)
- 你必须在你的存根中包含加密密钥。如果一个1337黑客能够有意义地使用你的反射程序集,他就可以很容易地窃取你的加密密钥并自己解密。(这基本上是模拟孔)
- Nobody cares about your 1337 code. I'm sorry, but that's tough love. Nobody else ever thinks anyone's code is nearly as interesting as the author does.
- 没人在乎你的1337码。我很抱歉,但那是很残酷的爱。没有人认为任何人的代码比作者更有趣。
#2
25
A "secret" that you share with thousands of people is not a secret. Remember, your attackers only have to break your trivial-to-break-because-the-key-is-right-there "encryption" scheme exactly once.
你与成千上万人分享的“秘密”并不是秘密。记住,您的攻击者只需打破您的“从密匙到密匙”的“加密”方案一次。
If your code is so valuable that it must be kept secret then keep it secret. Leave the code only on your own servers; write your software as a web service. Then secure the server.
如果你的代码非常有价值,必须保密,那就保密。只将代码放在您自己的服务器上;将软件编写为web服务。然后安全服务器。
#3
19
the generated exe file just a launcher that starts the runtime and passes the IL code to it.
生成的exe文件只是一个启动器,它启动运行时并将IL代码传递给它。
Not exactly. There are different ways you can set up your program, but normally the IL code is compiled to native machine code that runs in process with the runtime.
不完全是。有不同的方法可以设置您的程序,但是通常IL代码编译为本机机器代码,运行在运行时中。
As for the kiddies — you're deluding yourself if you think you can sell to them or anyone who uses what they redistribute. If they can't unlock your app they'll move on and find one they can or do without. They represent exactly $0 in potential sales; it makes little sense to spend too much effort attempting to thwart them because there'd be no return on your investment. A basic obfuscator might be fine, but don't go much beyond that.
至于孩子们——如果你认为你可以卖给他们或者任何使用他们重新分配的东西的人,那你就是在欺骗自己。如果他们无法解锁你的应用,他们会继续寻找一个他们可以或不需要的。它们代表了0美元的潜在销售额;花太多的精力去阻止他们是没有意义的,因为你的投资没有回报。一个基本的混淆可能是可以的,但是不要超过这个范围。
Realistically, most developers face a much bigger challenge from obscurity than from piracy. Anything you do that prevents you from getting the word out about your product hurts you more than the pirates do. This includes making people pay money to get it. Most of the time a better approach is to have a free version of your app that the kiddies don't even need to unlock; something that already works for them well enough that cracking your app would just be a waste of their time, and not just a time or feature-limited trial. Let them and as many others as possible spread it far and wide.
实际上,大多数开发人员面临的挑战比盗版要大得多。你所做的任何阻碍你得到关于你的产品的信息的事比盗版更伤害你。这包括让人们花钱买它。大多数情况下,更好的方法是让孩子们免费使用你的应用,甚至不需要解锁;对他们来说已经很有效的东西,破解你的应用程序只是浪费他们的时间,而不仅仅是一个时间或功能有限的试验。让他们和尽可能多的人把它传播得更广。
Now I know that you do eventually need some paying customers. The key is to now use all the attention you get from the free product to upsell or promote something else that's more profitable. One option here is to also have a premium version with additional features targeted largely at a business audience; things like making it easy to deploy to an entire network and manage that way. Businesses have deeper pockets and are more likely to pay your license fees. Your free version then serves to promote your product and give it legitimacy for your business customers.
现在我知道你最终需要一些付费客户。关键是现在要利用你从免费产品中获得的所有注意力来推销或推广其他更有利可图的产品。这里的一种选择是也有一个高级版本,附加的功能主要针对商业用户;比如让它更容易部署到整个网络并以这种方式进行管理。企业有更雄厚的财力,更有可能支付你的许可费。你的免费版本可以推广你的产品,并为你的商业客户提供合法性。
Of course, there are other models as well, but no matter what you do it's worth remembering that obscurity is the bigger challenge and that pirated copies of your software will never translate into sales. Ultimately (and of course this depends on your execution) you'll be able to make more money with a business model that takes advantage of those points than you will trying to fight them.
当然,也有其他的模式,但无论你做什么,都值得记住的是,默默无闻是更大的挑战,盗版软件永远不会转化为销售。最终(当然,这取决于你的执行),你将能够通过利用这些优势的商业模式赚到更多的钱,而不是试图与之斗争。
#4
6
"...prevent scriptkiddies to open my code in Reflector and just steal all my classes easily."
“…防止scriptkiddy在Reflector中打开我的代码并轻松地窃取我的所有类。
Unfortunately, regardless of how you obscure launching, it's a matter of half a dozen commands in a debugger to dump a currently-running assembly to a file of the user's choice. So, even if you can launch your application as Brian suggested, it's not hard to get that application's components into Reflector once it's running (I can post a sample from WinDbg if someone would find it interesting).
不幸的是,不管您如何模糊地启动,在调试器中使用6个命令就可以将当前正在运行的程序集转储到用户选择的文件中。因此,即使您可以按照Brian的建议启动应用程序,也不难在应用程序运行后将其组件导入Reflector(如果有人觉得有趣,我可以从WinDbg上发布一个示例)。
Obfuscation tools are created from huge amounts of technical experience, and are often designed to make it difficult for debuggers to reliably attach to a process, or to extract information from it. As Brian said: I'm not sure why you're determined to preserve the IL and, if you want any meaningful protection from script kiddies, that's something you may have to change your mind on.
模糊化工具是由大量的技术经验创建的,它们的设计目的通常是使调试器难以可靠地附加到进程,或者从进程中提取信息。正如Brian所说:我不知道为什么要保留IL,如果你想要从脚本小子那里得到任何有意义的保护,你可能需要改变你的想法。
#5
6
"They copied all they could follow, but they couldn't copy my mind, so I left them sweating and stealing a year and a half behind." -- R. Kipling
“他们模仿了所有他们能模仿的东西,但他们模仿不了我的想法,所以我让他们汗流浃背,偷了一年半的东西。”——r·吉卜林
#6
3
Personally I think that obfuscation is the way to go. It is simple and can be effective, especially if all your code is within an exe (I'm not sure what the concern is with "messing up the IL").
就我个人而言,我认为混淆是非常有必要的。它很简单,而且可以很有效,尤其是当您的所有代码都在exe中时(我不确定“搞乱IL”有什么关系)。
However, if you feel like that won't work for you, perhaps you can encrypt your exe and embed it as a resoource within your launcher. The simplest way to handle it would be to decrypt the exe resource and write it out too file and execute it. Once the exe has completed executing, delete the file. You might also be able to run it through the Emit functions. I have no idea how this would work, but here is an article to get you started - Using Reflection Emit to Cache .NET Assemblies.
但是,如果您觉得这对您不起作用,也许您可以加密您的exe并将其作为resoource嵌入到您的启动程序中。处理它的最简单的方法是解密exe资源并将其写出来并执行它。exe完成执行后,删除文件。你也可以通过发射函数来运行它。我不知道这将如何工作,但这里有一篇文章让您开始——使用反射发射缓存。net程序集。
Of course your decryption key would probably have to be embedded in the exe as well so somebody really determined will be able to decrypt your assembly anyway. This is why obfuscation is probably the best approach.
当然,你的解密密钥可能也会被嵌入到exe中,所以有人确定无论如何都能解密你的程序集。这就是为什么困惑可能是最好的方法。
#7
2
Copying my answer from this question (which is not exactly duplicate but can be answered with the same answer, hence CW):
从这个问题中复制我的答案(不是完全重复的,但可以用相同的答案来回答,因此CW):
A Windows EXE contains multiple "parts". Simplified, the .net Code (=MSIL) is only a Part of the EXE, and there is also a "real" native Windows Part inside the EXE that serves as some sort of launcher for the .net Framework which then executes the MSIL.
Windows EXE包含多个“部件”。简化后,.net代码(=MSIL)只是EXE的一部分,EXE中还有一个“真正的”本机窗口部分,它充当.net框架的某种启动程序,然后执行MSIL。
Mono will just take the MSIL and execute it, ignoring the native Windows Launcher stuff.
Mono只接受MSIL并执行它,而忽略本地Windows启动程序。
Again, this is a simplified overview.
这是一个简单的概述。
Edit: I fear my understanding of the deep depp details is not good enough for really much detail (I know roughly what a PE Header is, but not really the details), but i found these links helpful:
编辑:我担心我对“深德普”细节的理解不够深入细节(我大致知道什么是PE标题,但不是具体细节),但我发现这些链接很有用:
NET Assembly Structure – Part II
NET组装结构-第2部分。
.NET Foundations - .NET assembly structure
.NET foundation—.NET汇编结构
Appendix: If you really want to go deeper, pick up a copy on Advanced .net Debugging. The very first chapter explains exactly how the .net Assembly is loaded prior and after Windows XP (since XP, the Windows Loader is .net aware which radically changes how .net Applications are started)
附录:如果您真的想要更深入地了解,请获取关于高级。net调试的副本。第一章详细解释了在Windows XP之前和之后,.net程序集是如何加载的(因为XP, Windows加载程序是。net的,它从根本上改变了.net应用程序的启动方式)
#1
37
If you absolutely insist on encrypting your assembly, probably the best way to do it is to put your program code into class library assemblies and encrypt them. You would then write a small stub executable which decrypts the assemblies into memory and executes them.
如果您绝对坚持对您的程序集进行加密,那么最好的方法是将您的程序代码放入类库程序集并对它们进行加密。然后您将编写一个小的存根可执行文件,该文件将程序集解密到内存中并执行它们。
This is an extremely bad idea for two reasons:
这是一个极其糟糕的想法,有两个原因:
- You're going to have to include the encryption key in your stub. If a 1337 hacker can meaningfully use your reflected assemblies, he can just as easily steal your encryption key and decrypt them himself. (This is basically the Analog Hole)
- 你必须在你的存根中包含加密密钥。如果一个1337黑客能够有意义地使用你的反射程序集,他就可以很容易地窃取你的加密密钥并自己解密。(这基本上是模拟孔)
- Nobody cares about your 1337 code. I'm sorry, but that's tough love. Nobody else ever thinks anyone's code is nearly as interesting as the author does.
- 没人在乎你的1337码。我很抱歉,但那是很残酷的爱。没有人认为任何人的代码比作者更有趣。
#2
25
A "secret" that you share with thousands of people is not a secret. Remember, your attackers only have to break your trivial-to-break-because-the-key-is-right-there "encryption" scheme exactly once.
你与成千上万人分享的“秘密”并不是秘密。记住,您的攻击者只需打破您的“从密匙到密匙”的“加密”方案一次。
If your code is so valuable that it must be kept secret then keep it secret. Leave the code only on your own servers; write your software as a web service. Then secure the server.
如果你的代码非常有价值,必须保密,那就保密。只将代码放在您自己的服务器上;将软件编写为web服务。然后安全服务器。
#3
19
the generated exe file just a launcher that starts the runtime and passes the IL code to it.
生成的exe文件只是一个启动器,它启动运行时并将IL代码传递给它。
Not exactly. There are different ways you can set up your program, but normally the IL code is compiled to native machine code that runs in process with the runtime.
不完全是。有不同的方法可以设置您的程序,但是通常IL代码编译为本机机器代码,运行在运行时中。
As for the kiddies — you're deluding yourself if you think you can sell to them or anyone who uses what they redistribute. If they can't unlock your app they'll move on and find one they can or do without. They represent exactly $0 in potential sales; it makes little sense to spend too much effort attempting to thwart them because there'd be no return on your investment. A basic obfuscator might be fine, but don't go much beyond that.
至于孩子们——如果你认为你可以卖给他们或者任何使用他们重新分配的东西的人,那你就是在欺骗自己。如果他们无法解锁你的应用,他们会继续寻找一个他们可以或不需要的。它们代表了0美元的潜在销售额;花太多的精力去阻止他们是没有意义的,因为你的投资没有回报。一个基本的混淆可能是可以的,但是不要超过这个范围。
Realistically, most developers face a much bigger challenge from obscurity than from piracy. Anything you do that prevents you from getting the word out about your product hurts you more than the pirates do. This includes making people pay money to get it. Most of the time a better approach is to have a free version of your app that the kiddies don't even need to unlock; something that already works for them well enough that cracking your app would just be a waste of their time, and not just a time or feature-limited trial. Let them and as many others as possible spread it far and wide.
实际上,大多数开发人员面临的挑战比盗版要大得多。你所做的任何阻碍你得到关于你的产品的信息的事比盗版更伤害你。这包括让人们花钱买它。大多数情况下,更好的方法是让孩子们免费使用你的应用,甚至不需要解锁;对他们来说已经很有效的东西,破解你的应用程序只是浪费他们的时间,而不仅仅是一个时间或功能有限的试验。让他们和尽可能多的人把它传播得更广。
Now I know that you do eventually need some paying customers. The key is to now use all the attention you get from the free product to upsell or promote something else that's more profitable. One option here is to also have a premium version with additional features targeted largely at a business audience; things like making it easy to deploy to an entire network and manage that way. Businesses have deeper pockets and are more likely to pay your license fees. Your free version then serves to promote your product and give it legitimacy for your business customers.
现在我知道你最终需要一些付费客户。关键是现在要利用你从免费产品中获得的所有注意力来推销或推广其他更有利可图的产品。这里的一种选择是也有一个高级版本,附加的功能主要针对商业用户;比如让它更容易部署到整个网络并以这种方式进行管理。企业有更雄厚的财力,更有可能支付你的许可费。你的免费版本可以推广你的产品,并为你的商业客户提供合法性。
Of course, there are other models as well, but no matter what you do it's worth remembering that obscurity is the bigger challenge and that pirated copies of your software will never translate into sales. Ultimately (and of course this depends on your execution) you'll be able to make more money with a business model that takes advantage of those points than you will trying to fight them.
当然,也有其他的模式,但无论你做什么,都值得记住的是,默默无闻是更大的挑战,盗版软件永远不会转化为销售。最终(当然,这取决于你的执行),你将能够通过利用这些优势的商业模式赚到更多的钱,而不是试图与之斗争。
#4
6
"...prevent scriptkiddies to open my code in Reflector and just steal all my classes easily."
“…防止scriptkiddy在Reflector中打开我的代码并轻松地窃取我的所有类。
Unfortunately, regardless of how you obscure launching, it's a matter of half a dozen commands in a debugger to dump a currently-running assembly to a file of the user's choice. So, even if you can launch your application as Brian suggested, it's not hard to get that application's components into Reflector once it's running (I can post a sample from WinDbg if someone would find it interesting).
不幸的是,不管您如何模糊地启动,在调试器中使用6个命令就可以将当前正在运行的程序集转储到用户选择的文件中。因此,即使您可以按照Brian的建议启动应用程序,也不难在应用程序运行后将其组件导入Reflector(如果有人觉得有趣,我可以从WinDbg上发布一个示例)。
Obfuscation tools are created from huge amounts of technical experience, and are often designed to make it difficult for debuggers to reliably attach to a process, or to extract information from it. As Brian said: I'm not sure why you're determined to preserve the IL and, if you want any meaningful protection from script kiddies, that's something you may have to change your mind on.
模糊化工具是由大量的技术经验创建的,它们的设计目的通常是使调试器难以可靠地附加到进程,或者从进程中提取信息。正如Brian所说:我不知道为什么要保留IL,如果你想要从脚本小子那里得到任何有意义的保护,你可能需要改变你的想法。
#5
6
"They copied all they could follow, but they couldn't copy my mind, so I left them sweating and stealing a year and a half behind." -- R. Kipling
“他们模仿了所有他们能模仿的东西,但他们模仿不了我的想法,所以我让他们汗流浃背,偷了一年半的东西。”——r·吉卜林
#6
3
Personally I think that obfuscation is the way to go. It is simple and can be effective, especially if all your code is within an exe (I'm not sure what the concern is with "messing up the IL").
就我个人而言,我认为混淆是非常有必要的。它很简单,而且可以很有效,尤其是当您的所有代码都在exe中时(我不确定“搞乱IL”有什么关系)。
However, if you feel like that won't work for you, perhaps you can encrypt your exe and embed it as a resoource within your launcher. The simplest way to handle it would be to decrypt the exe resource and write it out too file and execute it. Once the exe has completed executing, delete the file. You might also be able to run it through the Emit functions. I have no idea how this would work, but here is an article to get you started - Using Reflection Emit to Cache .NET Assemblies.
但是,如果您觉得这对您不起作用,也许您可以加密您的exe并将其作为resoource嵌入到您的启动程序中。处理它的最简单的方法是解密exe资源并将其写出来并执行它。exe完成执行后,删除文件。你也可以通过发射函数来运行它。我不知道这将如何工作,但这里有一篇文章让您开始——使用反射发射缓存。net程序集。
Of course your decryption key would probably have to be embedded in the exe as well so somebody really determined will be able to decrypt your assembly anyway. This is why obfuscation is probably the best approach.
当然,你的解密密钥可能也会被嵌入到exe中,所以有人确定无论如何都能解密你的程序集。这就是为什么困惑可能是最好的方法。
#7
2
Copying my answer from this question (which is not exactly duplicate but can be answered with the same answer, hence CW):
从这个问题中复制我的答案(不是完全重复的,但可以用相同的答案来回答,因此CW):
A Windows EXE contains multiple "parts". Simplified, the .net Code (=MSIL) is only a Part of the EXE, and there is also a "real" native Windows Part inside the EXE that serves as some sort of launcher for the .net Framework which then executes the MSIL.
Windows EXE包含多个“部件”。简化后,.net代码(=MSIL)只是EXE的一部分,EXE中还有一个“真正的”本机窗口部分,它充当.net框架的某种启动程序,然后执行MSIL。
Mono will just take the MSIL and execute it, ignoring the native Windows Launcher stuff.
Mono只接受MSIL并执行它,而忽略本地Windows启动程序。
Again, this is a simplified overview.
这是一个简单的概述。
Edit: I fear my understanding of the deep depp details is not good enough for really much detail (I know roughly what a PE Header is, but not really the details), but i found these links helpful:
编辑:我担心我对“深德普”细节的理解不够深入细节(我大致知道什么是PE标题,但不是具体细节),但我发现这些链接很有用:
NET Assembly Structure – Part II
NET组装结构-第2部分。
.NET Foundations - .NET assembly structure
.NET foundation—.NET汇编结构
Appendix: If you really want to go deeper, pick up a copy on Advanced .net Debugging. The very first chapter explains exactly how the .net Assembly is loaded prior and after Windows XP (since XP, the Windows Loader is .net aware which radically changes how .net Applications are started)
附录:如果您真的想要更深入地了解,请获取关于高级。net调试的副本。第一章详细解释了在Windows XP之前和之后,.net程序集是如何加载的(因为XP, Windows加载程序是。net的,它从根本上改变了.net应用程序的启动方式)