C# 动态修改dll的签名 以及修改引用该dll文件的签名
在读取RedisSessionStateProvider配置 提到用mono ceil 来修改程序集以及它的签名,里面GetPublicKey 和GetPubliKeyToken 方法里面那个字符串的获取 以及后来的签名 我们都应该 用code来实现,还有应用该dll文件的签名也一同需要修改。
所以我这里实现了一个简单的helper方法 如下:
- namespace ConsoleSession
- {
- using Mono.Cecil;
- using System;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Runtime.InteropServices;
- public class ChangeAssemblyInfo
- {
- public string FileName { set; get; }
- public string FullName { set; get; }
- }
- public class keyHelper
- {
- static byte[] GetNewKey(string keyFileName)
- {
- using (FileStream keyPairStream = File.OpenRead(keyFileName))
- {
- return new StrongNameKeyPair(keyPairStream).PublicKey;
- }
- }
- public static void ReSign(string keyFileName, string assemblyFileName)
- {
- AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(assemblyFileName);
- asm.Name.PublicKey = GetNewKey(keyFileName);
- asm.Write(assemblyFileName);
- //用KEY文件建立密钥容器
- byte[] pbKeyBlob = File.ReadAllBytes(keyFileName);
- string wszKeyContainer = Guid.NewGuid().ToString();
- StrongNameKeyInstall(wszKeyContainer, pbKeyBlob, pbKeyBlob.Length);
- //使用新建的密钥容器对程序集经行签名
- StrongNameSignatureGeneration(assemblyFileName, wszKeyContainer, IntPtr.Zero, , , );
- //删除新建的密钥容器
- StrongNameKeyDelete(wszKeyContainer);
- }
- private static byte[] tryGetPublicKeyToken(string keyFileName)
- {
- try
- {
- byte[] newPublicKey;
- using (FileStream keyPairStream = File.OpenRead(keyFileName))
- {
- newPublicKey = new StrongNameKeyPair(keyPairStream).PublicKey;
- }
- int pcbStrongNameToken;
- IntPtr ppbStrongNameToken;
- StrongNameTokenFromPublicKey(newPublicKey, newPublicKey.Length, out ppbStrongNameToken,
- out pcbStrongNameToken);
- var token = new byte[pcbStrongNameToken];
- Marshal.Copy(ppbStrongNameToken, token, , pcbStrongNameToken);
- StrongNameFreeBuffer(ppbStrongNameToken);
- return token;
- }
- catch (Exception)
- {
- return null;
- }
- }
- public static void ReLink(string keyFileName, ChangeAssemblyInfo[] assemblyInfoList)
- {
- byte[] publicKeyToken = tryGetPublicKeyToken(keyFileName);
- if (publicKeyToken == null)
- {
- return;
- }
- //获得每个程序集的名称
- foreach (ChangeAssemblyInfo assemblyInfo in assemblyInfoList)
- {
- assemblyInfo.FullName = AssemblyDefinition.ReadAssembly(assemblyInfo.FileName).Name.FullName;
- }
- //检查是否被引用,是的话,就替换PublicKeyToken
- foreach (ChangeAssemblyInfo assemblyInfo in assemblyInfoList)
- {
- AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(assemblyInfo.FileName);
- foreach (ModuleDefinition module in assembly.Modules)
- foreach (AssemblyNameReference reference in module.AssemblyReferences)
- if (assemblyInfoList.Any(a => a.FullName == reference.FullName))
- {
- reference.PublicKeyToken = publicKeyToken;
- assembly.Write(assemblyInfo.FileName);
- }
- }
- }
- #region StrongName库作为一项资源包含在 MsCorEE.dll 中,其一系列API包含有
- [DllImport("mscoree.dll", EntryPoint = "StrongNameKeyDelete", CharSet = CharSet.Auto)]
- static extern bool StrongNameKeyDelete(string wszKeyContainer);
- [DllImport("mscoree.dll", EntryPoint = "StrongNameKeyInstall", CharSet = CharSet.Auto)]
- static extern bool StrongNameKeyInstall([MarshalAs(UnmanagedType.LPWStr)] string wszKeyContainer,
- [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = ,
- SizeConst = )] byte[] pbKeyBlob, int arg0);
- [DllImport("mscoree.dll", EntryPoint = "StrongNameSignatureGeneration", CharSet = CharSet.Auto)]
- static extern bool StrongNameSignatureGeneration(string wszFilePath, string wszKeyContainer,
- IntPtr pbKeyBlob, int cbKeyBlob, int ppbSignatureBlob,
- int pcbSignatureBlob);
- [DllImport("mscoree.dll", EntryPoint = "StrongNameErrorInfo", CharSet = CharSet.Auto)]
- static extern uint StrongNameErrorInfo();
- [DllImport("mscoree.dll", EntryPoint = "StrongNameTokenFromPublicKey", CharSet = CharSet.Auto)]
- static extern bool StrongNameTokenFromPublicKey(byte[] pbPublicKeyBlob, int cbPublicKeyBlob,
- out IntPtr ppbStrongNameToken, out int pcbStrongNameToken);
- [DllImport("mscoree.dll", EntryPoint = "StrongNameFreeBuffer", CharSet = CharSet.Auto)]
- static extern void StrongNameFreeBuffer(IntPtr pbMemory);
- #endregion
- }
- }
调用code 如下:
- using System;
- using System.IO;
- using System.Linq;
- using Mono.Cecil;
- class Program
- {
- static void Main(string[] args)
- {
- #region 修改程序集
- string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Microsoft.Web.RedisSessionStateProvider3.dll");
- AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(filePath);
- TypeDefinition[] types = asm.MainModule.Types.ToArray();
- //修改ProviderConfiguration为public
- TypeDefinition typeConfiguration = types.FirstOrDefault(x => x.Name == "ProviderConfiguration");
- typeConfiguration.IsPublic = true;
- //修改ProviderConfiguration的字段为public
- TypeDefinition typeRedisProvide = types.FirstOrDefault(x => x.Name == "RedisSessionStateProvider");
- FieldDefinition filedConfiguration = typeRedisProvide.Fields.ToArray().FirstOrDefault(x => x.Name == "configuration");
- filedConfiguration.IsPublic = true;
- //保存dll文件
- filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Microsoft.Web.RedisSessionStateProvider.dll");
- asm.Write(filePath);
- #endregion
- string keyfileName = @"D:\mykey.snk";
- //修改单个dll文件的签名
- keyHelper.ReSign(keyfileName,filePath);
- //修改引用该dll文件的签名
- keyHelper.ReLink(keyfileName, new ChangeAssemblyInfo[] {
- new ChangeAssemblyInfo { FileName = filePath }
- ,new ChangeAssemblyInfo { FileName=Path.Combine(@"C:\Users\UNIT12\Documents\visual studio 2015\Projects\SessionWebApp\SessionWebApp\bin","SessionWebApp.dll")}
- });
- //Console.ReadLine();
- }
- }
参考资料:
利用Mono-cecil实现.NET程序的重新签名,重新链接相关库的引用
C# 动态修改dll的签名 以及修改引用该dll文件的签名的更多相关文章
- 通过修改EIP寄存器实现32位程序的DLL注入
功能:通过修改EIP寄存器实现32位程序的DLL注入 <如果是64位 记得自己对应修改汇编代码部分> 原理:挂起目标进程,停止目标进程EIP的变换,在目标进程开启空间,然后把相关的指令机器 ...
- 给APK签名,修改签名
简介: 本来是不需要签名的,但是我有个android的专用设备,限制安装,但是售后给我通过了一个证书的验证. 那么我想装什么软件,就需要这个证书验证. 现在记录一下签名的主要过程,还有修改签名的方法. ...
- 如何在vue中修改动态标签中的样式和修改组件库样式
vue中修改动态标签中的样式和修改组件库样式 因为vue中的标签在渲染的时候,都会给标签加上id 所以你想在<style lang="scss" scoped>直接修改 ...
- dll反编译(修改引用文件、修改代码)再生成dll
问题描述 我们在日常开发中经常会遇到,想要对dll文件做修改的操作,但苦于没有源代码,只能想想其他办法 解决问题 办法就是通过几个工具来反编译.正向编译.修改属性 反编译.正编译 参考https:// ...
- Linux Tomcat安装,Linux配置Tomcat,Linux Tomcat修改内存,Linux tomcat修改端口
Linux Tomcat安装,Linux配置Tomcat,Linux Tomcat修改内存,Linux tomcat修改端口 >>>>>>>>>& ...
- 整理 PHPstorm实用个人配置,修改调整个性化快捷键,修改使用phpstorm创建的模板的默认注释:
对你有助请点赞,请顶------送人玫瑰,手留余香! 1:58 2016/3/12 整理PHPstorm实用个人配置,修改调整个性化快捷键,修改使用phpstorm创建的模板的默认注释: PHPsto ...
- CentOS6修改主机名(hostname)及 修改/etc/hosts 文件,增加ip和hostname的映射关系(转)
CentOS修改主机名(hostname) 需要修改两处:一处是/etc/sysconfig/network,另一处是/etc/hosts,只修改任一处会导致系统启动异常.首先切换到root用户. ...
- linux(以ubuntu为例)下Android利用ant自动编译、修改配置文件、批量多渠道,打包生成apk文件
原创,转载请注明:http://www.cnblogs.com/ycxyyzw/p/4555328.html 之前写过一篇<windows下Android利用ant自动编译.修改配置文件.批量 ...
- 直接修改workspace下的配置文件与tomcat下的文件
项目中直接修改workspace下的配置文件与tomcat下的文件,可是还有错误,例如修改了4个配置文件中的一个配置文件.经查如下: 直接修改workspace下的配置文件与tomcat下的文件,可能 ...
随机推荐
- 【转】HTTP状态码(HTTP Status Code)
原文链接:http://www.chaoji.com/features/httpstatus.aspx 一些常见的状态码为: 200 - 服务器成功返回网页 404 - 请求的网页不存在 503 - ...
- 使用jquery的trigger方法优化页面代码
我们做页面级联的时候经常会用到ajax处理数据,会为下拉菜单编写change事件. //城市和区域联动 $("#City").change(function () { var ci ...
- Floyd 求最短路(poj 1161)
Floyd-Warshall算法介绍: Floyd-Warshall算法的原理是动态规划. 设为从到的只以集合中的节点为中间节点的最短路径的长度. 若最短路径经过点k,则: 若最短路径不经过点k,则. ...
- Yii中事件触发机制
控制器初始化中添加事件处理方法,在需要触发的地方直接触发 public function init() { parent::init(); // TODO: Change the autogenera ...
- Form居中显示
(1)居中显示 Form1->Position = poScreenCenter; (2)无边框显示 Form1->BorderStyle = bsNone; (3)显示透明性 Form1 ...
- C++Builder 中 Enter键或者Tab键无效
VC++中或者C++Builder中 当回车键不能换行时应该就是因为自己不小心按到了键盘上的insert键,要想恢复只需要再按一下就可以了. 小经验
- 用代码控制UI界面
public class MainActivity extends Activity { //当第一次创建Activity时回调该方法 @Override protected void ...
- Largest Rectangle in a Histogram(HDU1506)
Largest Rectangle in a Histogram HDU1506 一道DP题: 思路:http://blog.csdn.net/qiqijianglu/article/details/ ...
- 使用java 程序创建格式为utf-8文件的方法(写入和读取json文件)
使用java 程序创建格式为utf-8文件的方法: try{ File file=new File("C:/11.jsp"); ...
- 记一次SQLServer数据库误删数据找回
昨天 同事在本机清理数据库表时,连接到了生产机,误删了二十几张表,幸好是晚上加班的时候删除的,生产机上当时是一天一备份,还原备份是最后的策略,最关键的还是要找回数据. ...