混淆时可以进行反射
自上周以来我一直在努力解决这个问题。我已经混淆了我的应用程序的 exe。我们的应用程序是在线网络应用程序的离线工具。客户端将安装此应用程序并连接到互联网,应用程序将下载相关信息并将其存储在客户端计算机上的 xml 文件中以供进一步显示。出于安全目的,我们对这些 xml 文件进行加密。不幸的是,我们在 exe 中有一种方法 GetCryptXML,它将读取客户端计算机上加密的 settings.xml 并在解密后返回它。此setting.xml 还包含其他xml 的加密密钥。
我在这里面临的问题是,即使在混淆之后,人们也可以通过传递混淆名称来调用 GetCryptXML 方法。
有什么办法可以解决这个问题吗?
这是我解决问题的想法,但我不知道如何实施。
我的想法:调用我的函数的唯一方法是使用 InvokeMember() 函数通过反射。在调用此函数之前,他/她需要使用此函数加载程序集。
Assembly.LoadFrom("myapplication.exe")
如果 myapplication.exe 中的代码可以识别哪个应用程序正在尝试加载我,那么我们可以限制它们加载(如果它不是预期的应用程序)。我不知道该如何解决。
非常感谢任何帮助。
谢谢。
I am struggling with this problem since last one week. I have obfuscated exe of my application. Our application is offline tool for online web application. Client will install this application and connect once to internet, application will download relevant information and store in xml file on client machine for further display. for security purpose we are encrypting these xml files. Unfortunately we have one method GetCryptXML inside exe which will read encrypted settings.xml on client machine and return it after decrypting. this setting.xml contain encryption key for other xml as well.
Problem I am facing here is, even after obfuscation, person can invoke GetCryptXML method by passing obfuscated name.
Is there any way to solve this problem?
This is my idea to solve problem but I am not sure how to implement.
My idea: Only way to invoke my function is through reflection by using InvokeMember() function. before one can call this function he/she needs to load assembly by using this.
Assembly.LoadFrom("myapplication.exe")
If code inside myapplication.exe can identify which application is trying to load me then we can restrict them to load if it is not intended application. I dont know how can I solve.
Any help is greatly appreciated.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
混淆不会改变 .net 或您的应用程序的基础 - 最后,它所做的只是使其更难以阅读,并尝试添加反编译工具无法处理的情况......但无论如何,IL 仍然存在。如果您向他们提供加密文本(xml)和密钥(通过线路发送或隐藏在代码中),他们就可以解密。你所做的一切只是让它变得更难,而不是不可能。
您可以做的一件事是强名称您的程序集,并验证您的类型的调用方是否来自具有 StrongNameIdentityPermission 属性。请注意,KeeperOfTheSoul 是正确的 - 在 4.0 之前的 .net 版本中,完全信任程序集可以绕过此功能(据我了解,在 4.0 中,此属性不再使用身份权限,只有在存在正确证据的情况下才会成功)。
您还可以编写代码通过 System.Diagnostics.StackTrace 获取调用堆栈,并检查调用方法以验证它是否是预期的调用方之一。这意味着执行速度会慢一些,代码会更多,但您可以控制它。
编辑请参阅此处了解使用 StrongNameIdentityPermission 的演练。这是一篇关于检查堆栈跟踪的文章。再次请注意,这些都不是灵丹妙药,但如果您认为值得花时间的话,可以给攻击者增加一个障碍。 (请记住,在互联网时代,只需一名成功的攻击者,任意数量的人就可以通过谷歌搜索结果)
Obfuscation doesn't change the underpinnings of .net or your application - in the end, all it does is make it much harder to read, and tries to add cases that decompilation tools cannot handle... but either way the IL is still there. If you give them the encrypted text (the xml) and the key (sent over the wire or hidden in your code), they can decrypt it. All you are doing is making it harder, not impossible.
One thing you can do is strong name your assemblies, and verify that the caller of your type is from a specific strongly-named assembly with the StrongNameIdentityPermission attribute. Note that KeeperOfTheSoul is correct- full trust assemblies can bypass this in versions of .net prior to 4.0 (it is my understanding that in 4.0 this attribute no longer uses the identity permission and only succeeds if the correct evidence is there).
You can also write code to get the call stack via
System.Diagnostics.StackTrace
, and check the calling methods to verify that it is one of the expected callers. This means a bit slower execution and more code, but you would have control of it.EDIT See here for a walkthrough of using the StrongNameIdentityPermission. And here is an article on inspecting the stack trace. Again, note that neither of these is a silver bullet, but can add one more hurdle to the attacker, if you think it's worth your time. (Remember that in the day of the internet, it only takes one successful attacker for any number of people to google the result)
如果您想限制对特定程序集的方法的访问,您可以执行以下操作:
此方法的优点之一是,如果有人使用来自未经授权的程序集的反射,则调用将失败。
If you want to restrict access to a method to a particular assembly you could do the following:
One of the advantages of this approach is that if someone used reflection from an unauthorized assembly the call would fail.
如果某个东西可以通过反射调用,那么它就必须可以(以某种方式)通过常规代码调用。
我建议反对这一点(因为没有办法完全阻止那些坚持执行他们不应该执行的代码的人)。
如果您确实有兴趣做这样的事情,您可以打破 C# 的面向对象原则并将所有方法设为私有。这样,只有从类内部执行的代码才能定期调用它们。其他人都必须通过反射来调用它们(通过反射调用私有成员通常被认为是不好的做法)。
奇怪的是,我越想越觉得该方法可能应该被标记为私有,因为您不希望每个人都能够调用它。调用者应该必须通过公共外观进行调用,这将确定是否允许您调用该方法......并且只允许授权调用。
If something can be called through Reflection, it has to be callable (somehow) through regular code.
I would suggest against this (as there is no way to fully thwart somebody that is adamant about executing code they shouldn't).
If you're truly interested in doing something like this, you could break the OO Principals of C# and make all of your methods private. That way only code executing from inside your class could call them regularly. Everybody else would have to call them via Reflection (and calling private members via Reflection is considered bad practice more often than not).
Oddly enough, the more I think about it, the method should probably be marked as private anyway since you don't want everybody to be able to call it. Callers should have to call through a public facade which would determine if you're allowed to call the method or not...and only allow authorized calls.