读取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文件的签名的更多相关文章

  1. 通过修改EIP寄存器实现32位程序的DLL注入

    功能:通过修改EIP寄存器实现32位程序的DLL注入 <如果是64位 记得自己对应修改汇编代码部分> 原理:挂起目标进程,停止目标进程EIP的变换,在目标进程开启空间,然后把相关的指令机器 ...

  2. 给APK签名,修改签名

    简介: 本来是不需要签名的,但是我有个android的专用设备,限制安装,但是售后给我通过了一个证书的验证. 那么我想装什么软件,就需要这个证书验证. 现在记录一下签名的主要过程,还有修改签名的方法. ...

  3. 如何在vue中修改动态标签中的样式和修改组件库样式

    vue中修改动态标签中的样式和修改组件库样式 因为vue中的标签在渲染的时候,都会给标签加上id 所以你想在<style lang="scss" scoped>直接修改 ...

  4. dll反编译(修改引用文件、修改代码)再生成dll

    问题描述 我们在日常开发中经常会遇到,想要对dll文件做修改的操作,但苦于没有源代码,只能想想其他办法 解决问题 办法就是通过几个工具来反编译.正向编译.修改属性 反编译.正编译 参考https:// ...

  5. Linux Tomcat安装,Linux配置Tomcat,Linux Tomcat修改内存,Linux tomcat修改端口

    Linux Tomcat安装,Linux配置Tomcat,Linux Tomcat修改内存,Linux tomcat修改端口 >>>>>>>>>& ...

  6. 整理 PHPstorm实用个人配置,修改调整个性化快捷键,修改使用phpstorm创建的模板的默认注释:

    对你有助请点赞,请顶------送人玫瑰,手留余香! 1:58 2016/3/12 整理PHPstorm实用个人配置,修改调整个性化快捷键,修改使用phpstorm创建的模板的默认注释: PHPsto ...

  7. CentOS6修改主机名(hostname)及 修改/etc/hosts 文件,增加ip和hostname的映射关系(转)

    CentOS修改主机名(hostname)  需要修改两处:一处是/etc/sysconfig/network,另一处是/etc/hosts,只修改任一处会导致系统启动异常.首先切换到root用户. ...

  8. linux(以ubuntu为例)下Android利用ant自动编译、修改配置文件、批量多渠道,打包生成apk文件

    原创,转载请注明:http://www.cnblogs.com/ycxyyzw/p/4555328.html  之前写过一篇<windows下Android利用ant自动编译.修改配置文件.批量 ...

  9. 直接修改workspace下的配置文件与tomcat下的文件

    项目中直接修改workspace下的配置文件与tomcat下的文件,可是还有错误,例如修改了4个配置文件中的一个配置文件.经查如下: 直接修改workspace下的配置文件与tomcat下的文件,可能 ...

随机推荐

  1. Java 读取Properties配置文件

    1.img_url.properties imgurl=http://10.1.19.65:8090 2.Test.java InputStream inputStream = this.getCla ...

  2. equals(==),toString

    equals/==: 只有指向同一个对象是,才返回true. 特殊: String s1 = new String("hello"); String s2 = new String ...

  3. Windows 打印控件

    Windows窗体的PrintDocument组件用于设置一些属性,这些属性说明,在基于Windows的应用程序中要打印说明内容以及打印文档的能力,可将它与PrintDialog组件一起使用来控制文档 ...

  4. Redis在CentOS6.4中的安装

    首先,介绍一下Redis数据库.Redis是一种面向“键/值”对数据类型的内存数据库,可以满足我们对海量数据的读写需求. 1)redis的键只能是字符串: 2)redis的值支持多种数据类型: a:字 ...

  5. eclipse中无法使用fat.jar

    因为某种需要,我要打jar包,而eclipse中自带的打包功能又太过于繁琐,因此找到这个插件.不过尝试了许久都没有成功,最后终于找到了原因,是因为该插件的版本太低的缘故.相见:https://code ...

  6. DataTableToJson

    public static string CreateJsonParameters(DataTable dt,string JsonName) { StringBuilder JsonString = ...

  7. 第五天:内置对象(7.Javascript内置对象)

    1)中所术是内置对象,2)中为自定义对象 代码说明如下 2.1.1 定义并创建对象实例方式1,代码如下: <!DOCTYPE html><html lang="en&quo ...

  8. Dynamic CRM 2013学习笔记(三十九)流程2 - 业务流程(Business Process Flows)用法详解

    业务流程(Business Process Flows)是CRM 2013 里一个新的流程,它提供了可视化的流程表现.业务人员创建有效.流线型的业务流程让最终用户知道当前在哪.下一步要做什么,用户可以 ...

  9. .NET Core竟然无法在Mac下进行build

    KRuntime 改为 XRE 之后(详见从 KRE 到 XRE :ASP.NET 5 中正在消失的那些K),昨天在 mac 用 git 签出 XRE 的代码库,直接执行其中的 build 命令 sh ...

  10. [游戏模版6] Win32 graph

    >_<:there in the MyPaint(...) function respectively use Ellipse(...) draw ellipse, use RoundRe ...