让c#的exe只要被修改就无法运行,支持混淆和数字证书
原文:让c#的exe只要被修改就无法运行,支持混淆和数字证书
首先用sdk的sn工具或者makecert工具生成公钥和密钥,推荐makecert,做自己的证书,我做了一个受信任的根证书放在受信任的根证书颁发机构,用这个根证书颁发了一个下级证书放在个认证书里。把这两个证书都保存起来,平时给程序签名就用这个子证书就行了。以后都用这一个,显得正规点。


程序里工程属性-签名把那clickonce和程序清单签名都选上,时间戳用这个http://timestamp.wosign.com/timestamp
2个都从文件选择,这里用刚才子证书的那个带密钥的pfx,需要填入密码。
这样编译后不能防篡改,因为微软有个跳过机制,这样只有生成dll放到gac才会检查强名称是否匹配,而一个单独的exe是没用的,修改里面一点东西后还是可以执行。微软说可以在app.config里加入一条强制检查,那样是行了只要修改exe就没法执行,但是只有exe一直带着那个app.config放在同一目录才行,如果单独把exe拿出来就不行了。
怎么把那句话弄到exe里呢,我费了半天劲,终于想到了一个办法,平时只注意功能实现了,没想到.net里的安全机制这么复杂。
此方法无论是console的还是winform的,无论2.0 3.0 3.5 4.0通用。
如果是console程序,在Main的下面加入
System.Security.Policy.Evidence evi = new System.Security.Policy.Evidence();
evi.AddHost(new System.Security.Policy.Zone(System.Security.SecurityZone.Intranet));
System.Security.PermissionSet ps = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
ps.AddPermission(new System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityPermissionFlag.Assertion | System.Security.Permissions.SecurityPermissionFlag.Execution | System.Security.Permissions.SecurityPermissionFlag.BindingRedirects));
ps.AddPermission(new System.Security.Permissions.FileIOPermission(System.Security.Permissions.PermissionState.Unrestricted));
AppDomainSetup ads = new AppDomainSetup();
ads.ApplicationBase = System.IO.Directory.GetCurrentDirectory();
AppDomain app = AppDomain.CreateDomain("JiaoYanShiFouGaiDongGuo", evi, ads, ps, null);
try
{
string JiaoYanShiFouGaiDongGuo = (string)app.CreateInstanceFromAndUnwrap(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName, typeof(string).FullName);
AppDomain.Unload(app);
}
catch (Exception e)
{
AppDomain.Unload(app);
if (e.Message.Contains("8013141A") || e.Message.Contains("8013141a"))
{
Console.WriteLine("本程序被修改过不允许执行。");
System.Threading.Thread.Sleep(6000);
return;
}
}
如果是winform程序,在Main的下面加入
System.Security.Policy.Evidence evi = new System.Security.Policy.Evidence();
evi.AddHost(new System.Security.Policy.Zone(System.Security.SecurityZone.Intranet));
System.Security.PermissionSet ps = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
ps.AddPermission(new System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityPermissionFlag.Assertion | System.Security.Permissions.SecurityPermissionFlag.Execution | System.Security.Permissions.SecurityPermissionFlag.BindingRedirects));
ps.AddPermission(new System.Security.Permissions.FileIOPermission(System.Security.Permissions.PermissionState.Unrestricted));
AppDomainSetup ads = new AppDomainSetup();
ads.ApplicationBase = System.IO.Directory.GetCurrentDirectory();
AppDomain app = AppDomain.CreateDomain("JiaoYanShiFouGaiDongGuo", evi, ads, ps, null);
try
{
string JiaoYanShiFouGaiDongGuo = (string)app.CreateInstanceFromAndUnwrap(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName, typeof(string).FullName);
AppDomain.Unload(app);
}
catch (Exception e)
{
AppDomain.Unload(app);
if (e.Message.Contains("8013141A") || e.Message.Contains("8013141a"))
{
System.Windows.Forms.MessageBox.Show("本程序被修改过不允许执行。", "危险!", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Stop, System.Windows.Forms.MessageBoxDefaultButton.Button1, System.Windows.Forms.MessageBoxOptions.DefaultDesktopOnly, false);
return;
}
}
原理是在桌面程序的zone是mycomputer,是完全信任的,所以就有一个强名称跳过,这些代码是建一个Intranet的appdomain,不是完全信任的,所以就会检查强名称,这个appdomain是空的,目的不是为了执行里面的内容而是为了让.net去检查强名称,什么时候执行到这些代码什么时候就会出错,所以要放到main下面第一句,如果通过检查不会影响后面的正常代码。在.net4中上面代码可以更简单,有个沙盒GetStandardSandbox,但是2和3中没有,就不通用了,而这样无论234都通用,所以4会报某些方法过时,不去管它。
然后编译就行了,这样就不用拖家带口的带着app.config了,只要修改一点就不能执行了,会出现“已修改不允许执行”的提示,然后程序会自动关闭。
这样还不行,反编译很容易就去掉了,需要混淆。
直接把这个exe混淆,双击没法执行吧。别急。
用sn.exe再用刚才那个子证书pfx把这个混淆过的exe再次签名就可以执行了,好了,这样exe不但混淆了,而且被加上了强名称签名,只要修改1个字节就不能运行了。sn -R是重新签名。
继续,加上数字签名,signtool工具,还是用刚才那个子证书,这样右键就可以看到这样了。


这样这个程序只要修改一点,那么不但不能执行,而且右键看数字证书,也通不过,是这样的

而且exe还是混淆过的,嘿嘿嘿,大功告成。
当然自己用makecert做的证书在自己的机器上,显示“数字签名正常”,但是别人的机器上没有你的证书,会显示无法验证此证书之类的,但是还是会校验,就是说如果把这个exe改了,那么就会显示”数字签名无效“而不是”无法验证证书“,所以凭这一点也可以验证是否被篡改过,但是其实用不着了,这个只是好看用的,因为刚才说了,只要修改连运行都不能运行了。
如果用的人多了,可以让用户把你的证书导入他的证书库或者去买个真正的证书,那样就不会出那个红叉号了。
让c#的exe只要被修改就无法运行,支持混淆和数字证书的更多相关文章
- dnSpy进行反编译修改并编译运行EXE或DLL
dnSpy对目标程序(EXE或DLL)进行反编译修改并编译运行 本文为原创文章.源代码为原创代码,如转载/复制,请在网页/代码处明显位置标明原文名称.作者及网址,谢谢! 本文使用的工具下载地址为: h ...
- Atitit.Java exe bat 作为windows系统服务程序运行
Atitit.Java exe bat 作为windows系统服务程序运行 1. 使用SC命令+srvany.exe (不错,推荐)+net start1 1.1. First 创建一个java的运 ...
- 让InstallShield 2015 Limited Edition for Visual Studio 2015生成的setup.exe双击时以管理员权限运行
转载:http://blog.csdn.net/zztoll/article/details/52096700 如题,如何让InstallShield 2015 Limited Edition for ...
- 将Python文件打包为exe文件,并在控制台运行之简易教程
第一步 在线安装 pyinstaller. 方法:打开win+ R,输入cmd,在命令行输入"pip install pyinstaller" 静等几分钟后即可安装成功. ...
- 修改json源码支持datetime序列化
修改json源码支持datetime序列化 import json import datetime now = datetime.datetime.today() json.dumps(now) 抛出 ...
- 如何修改Docker已运行实例的端口映射
如何修改Docker已运行实例的端口映射 Docker的端口映射,往往出现在两个阶段需要处理: 1.是在docker启动前就已经确定好,哪个docker实例映射哪个端口(往往这个情况比较,需要提前做规 ...
- Linux单用户模式(修改密码、运行级别)方法详解
很多新手当面对"忘记 root 账户密码导致无法登陆系统"这个问题时,直接选择重新系统.其实大可不必,我只需要进入 emergency mode(单用户模式)更新 root 账户的 ...
- [C#]使用dnSpy对目标程序(EXE或DLL)进行反编译修改并编译运行
本文为原创文章.源代码为原创代码,如转载/复制,请在网页/代码处明显位置标明原文名称.作者及网址,谢谢! 本文使用的工具下载地址为: https://github.com/cnxy/dnSpy/arc ...
- 使用dnSpy对目标程序(EXE或DLL)进行反编译修改并编译运行
本文为原创文章.源代码为原创代码,如转载/复制,请在网页/代码处明显位置标明原文名称.作者及网址,谢谢! 本文使用的工具下载地址为: https://github.com/cnxy/dnSpy/arc ...
随机推荐
- xcode 改动整个项目名
目标为:将项目名XCD4改成xcd5. 先上结果图:==> 1.在左側的导航区域点击两次项目名,两次间隔时间略微长些,项目名会变成可编辑状态. 将名称改动为xcd5后按enter键弹出一个对话框 ...
- 初步C++运算符重载学习笔记<3> 增量递减运算符重载
初步C++运算符重载学习笔记<1> 初探C++运算符重载学习笔记<2> 重载为友元函数 增量.减量运算符++(--)分别有两种形式:前自增++i(自减--i).后自增i ...
- Java 小样例:图书馆课程设计(Java 8 版)
用 Java 模拟一个图书馆.包含创建图书.创建读者.借书.还书.列出全部图书.列出全部读者.列出已借出的图书.列出过期未还的图书等功能. 每一个读者最多仅仅能借 3 本书,每一个书最多仅仅能借 3 ...
- IL来理解属性
IL来理解属性 阅读目录 概述: C#中如何定义一个属性 Student类 属性Name Main方法 实现get,set方法 性能 访问权限 回到最开始提出的问题 参考资料 .Net底层剖析目录 ...
- java 处理时间的各种方式——获取时间——时间格式化
TimeUtil.java package com.snow; import java.text.DateFormat; import java.text.ParseException; import ...
- Maven 中配置 Urlrewrite 基本配置
1. 在maven项目的pom.xml文件里加入: <!-- URL Rewrite --> <dependency> <groupId>org.tuckey< ...
- 解决set /p yn= 接受键盘输入导致ECHO 处于关闭状态的问题
今天写了一个自动更新程序的批处理脚本,但是有个变量一直赋值有问题.弄了一个下午终于找到原因及解决方法: ----转载要说明来自:博客园--邦邦酱好 哦 有问题的代码如下: @echo off echo ...
- MySQL 改动用户password及重置rootpassword
为数据库用户改动password是DBA比較常见的工作之中的一个.对于MySQL用户账户的password改动,有几种不同的方式.推荐的方式使用加密函数来改动password. 本文主要描写叙述了通过 ...
- PB数据库相关
---------------------------------------------------------------- 数据库画板: 一张表定义了主键或者唯一索引,则能够在Results视窗 ...
- 一旦ORA-28000: the account is locked用户锁定故障排除
今天我的同事们反映的问题,测试库的变化password,并改变相关的应用程序中使用password后,其中一个仍然会出现在帐户被锁定,报告ORA-28000: the account is locke ...