让c#的exe只要被修改就无法运行,支持混淆和数字证书

简介: 原文: 让c#的exe只要被修改就无法运行,支持混淆和数字证书 首先用sdk的sn工具或者makecert工具生成公钥和密钥,推荐makecert,做自己的证书,我做了一个受信任的根证书放在受信任的根证书颁发机构,用这个根证书颁发了一个下级证书放在个认证书里。
原文: 让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改了,那么就会显示”数字签名无效“而不是”无法验证证书“,所以凭这一点也可以验证是否被篡改过,但是其实用不着了,这个只是好看用的,因为刚才说了,只要修改连运行都不能运行了。

 

如果用的人多了,可以让用户把你的证书导入他的证书库或者去买个真正的证书,那样就不会出那个红叉号了。

目录
相关文章
|
4月前
|
缓存 C#
C# 操作路径(Path)类方法的使用与解析运行实例
C# 操作路径(Path)类方法的使用与解析运行实例
|
6月前
|
C#
C#程序Debug文件夹可以运行,无法调试
C#程序Debug文件夹可以运行,无法调试
|
4月前
|
编译器 应用服务中间件 数据库连接
解决C#运行程序修改数据后数据表不做更新的问题
解决C#运行程序修改数据后数据表不做更新的问题
43 0
|
10月前
|
XML 存储 测试技术
在C#下运行Python:IronPython和Pythonnet
在C#下运行Python可能有不同的原因。其中一些原因包括: 1. 使用C#应用程序中不可用的特定Python功能或库。 2. 结合Python的简单性和表现力以及C#的性能和稳健性,完成不同任务。 3. 与基于Python的系统或服务进行集成。
144 0
|
C#
C# 判断当前控制台程序是否重复运行
C# 判断当前控制台程序是否重复运行
125 0
|
C# C++ Windows
C#工程中输出类型转换以及程序运行后控制台窗口不退出设置
C#工程中输出类型转换以及程序运行后控制台窗口不退出设置
307 0
C#工程中输出类型转换以及程序运行后控制台窗口不退出设置
|
C# 数据安全/隐私保护 Windows
C# Windows服务以指定用户运行
参考一下 https://bbs.csdn.net/topics/330151879 服务程序以Local System安装运行没问题,但用这个账户运行的服务无法访问局域网共享资源,比较麻烦,所以想指定用某个账户来启动服务。
1924 0