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下的文件,可能 ...
随机推荐
- 包含min函数的栈
题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数 解法一: 思路:采用java中自带的迭代函数进行处理. public class Solution{ /** * @pa ...
- 对象转型 casting
一个基类的引用类型变量可以"指向"其子类对象. 一个基类的引用不可以访问其子类对象新增加的成员(属性和方法). 基类强制转型成子类,则能访问子类独有的成员. 可以使用 引用变量in ...
- css省略号
效果图如下: 效果图如下:
- 用PHP实现URL转换短网址的算法示例
短网址就是把一个长的地址转换在超级短的网址,然后访问短网址即可跳转到长网址了,下面来看用PHP实现URL转换短网址的算法与例子. 短网址(Short URL) ,顾名思义就是在形式上比较短的网址.在W ...
- PHP中的 extends与implements 区别 [转]
extends 是继承某个类 继承之后可以使用父类的方法 也可以重写父类的方法 implements 是实现多个接口 接口的方法一般为空的 必须重写才能使用 extends是继承父类,只要那个类不是声 ...
- 10个经典的C语言面试基础算法及代码
10个经典的C语言面试基础算法及代码作者:码农网 – 小峰 原文地址:http://www.codeceo.com/article/10-c-interview-algorithm.html 算法是一 ...
- Linq to SQL 基础篇
LinqtoSqlDataContext Linq = new LinqtoSqlDataContext(ConfigurationManager.ConnectionStrings["sz ...
- centos安装 mysql
centos安装 mysql 1. 下载mysqlmysql被oracle收购后现在退出了企业版和社区版本,社区版本是开源的,企业版是收费的.社区版可以下载源码也可以下载二进制文件包.源码安装比较麻烦 ...
- Yaf零基础学习总结3-Hello Yaf
Yaf零基础学习总结3-Hello Yaf 上一次我们已经学习了如何安装yaf了,准备工作做好了之后我们来开始实际的编码了,码农都知道一个经典的语句就是“Hello World”了,今天我们开始入手Y ...
- 在myeclipse文件中如何创建properties类型的文件,从而连接数据库
File->New->File->点击->在编辑处出输入:文件名.properties 文件的主要功能连接数据库,例如: driver=oracle.jdbc.Oracle ...