背景:
1、标题的好像有点长;
2、这个工具是干什么用的?能看明白标题的人估计能用得上,看懂的估计也不需要。
3、可以根据签名文件更改、也可以根据程序集文件更改。
4、欢迎交流,尽请留言。
原始代码:
代码
1 using System;
2 using System.Linq;
3 using System.Windows.Forms;
4 using System.IO;
5 using Mono.Cecil;
6 using System.Diagnostics;
7 using System.Runtime.InteropServices;
8 using System.Reflection;
9 namespace AssemblyResign
10 {
11 public partial class FormMain : Form
12 {
13 public FormMain()
14 {
15 InitializeComponent();
16 }
17
18 private void btnReSign_Click(object sender, EventArgs e)
19 {
20 if (tBoxSourceAse.Text == "" && tBoxSourceSign.Text == "")
21 {
22 MessageBox.Show("Please select a source assembly or signfile!", "Error");
23 return;
24 }
25 if (lBoxObjectAse.Items.Count == 0)
26 {
27 MessageBox.Show("Please select object assembly!", "Error");
28 return;
29 }
30 AssemblyInfo[] assemblyInfoList = new AssemblyInfo[lBoxObjectAse.Items.Count];
31 for (int i = 0; i < lBoxObjectAse.Items.Count; i++)
32 {
33 assemblyInfoList[i] = new AssemblyInfo { FileName = lBoxObjectAse.Items[i].ToString() };
34 }
35 try
36 {
37 if (tBoxSourceSign.Text != "")
38 {
39 ReSignByKeyFile(assemblyInfoList, tBoxSourceSign.Text.Trim());
40 MessageBox.Show("Resign by signfile ucceed!", "Information");
41 }
42 else
43 {
44 ReSignByAssembly(assemblyInfoList, tBoxSourceAse.Text.Trim());
45 MessageBox.Show("Resign by assembly ucceed!", "Information");
46 }
47 }
48 catch(Exception ex)
49 {
50 MessageBox.Show("Resign error,Detail Infor:" + ex.ToString(), "Information");
51 }
52
53 }
54 private void btnRelink_Click(object sender, EventArgs e)
55 {
56 AssemblyInfo[] assemblyInfoList = new AssemblyInfo[lBoxObjectAse.Items.Count];
57 for (int i = 0; i < lBoxObjectAse.Items.Count; i++)
58 {
59 assemblyInfoList[i] = new AssemblyInfo { FileName = lBoxObjectAse.Items[i].ToString() };
60 }
61 try
62 {
63 ReSignature rs = new ReSignature();
64 rs.ReLink(assemblyInfoList, tBoxSourceSign.Text.Trim());
65 MessageBox.Show("Relink by singfile succeed!", "Information");
66 }
67 catch (Exception ex)
68 {
69 MessageBox.Show("Relink error,Detail Infor:" + ex.ToString(), "Error");
70 }
71 }
72 private void btnSourceAse_Click(object sender, EventArgs e)
73 {
74 OpenFileDialog ofd = new OpenFileDialog();
75 ofd.Filter = "Assembly(*.exe,*.dll)|*.exe;*.dll";
76 ofd.ShowDialog();
77 if (ofd.FileName != "")
78 tBoxSourceAse.Text = ofd.FileName;
79 }
80 private void btnSourceSign_Click(object sender, EventArgs e)
81 {
82 OpenFileDialog ofd = new OpenFileDialog();
83 ofd.Filter = "签名文件(*.snk)|*.snk";
84 ofd.ShowDialog();
85 if (ofd.FileName != "")
86 tBoxSourceSign.Text = ofd.FileName;
87 }
88 private void btnObjectAse_Click(object sender, EventArgs e)
89 {
90 OpenFileDialog ofd = new OpenFileDialog();
91 ofd.Multiselect = true;
92 ofd.Filter = "应用程序集(*.exe,*.dll)|*.exe;*.dll";
93 ofd.ShowDialog();
94 if (ofd.FileNames.Length > 0)
95 {
96 lBoxObjectAse.Items.Clear();
97 foreach(string strFileName in ofd.FileNames)
98 {
99 lBoxObjectAse.Items.Add(strFileName);
100 }
101 }
102 }
103
104 private void ReSignByAssembly(AssemblyInfo[] assemblyInfoList, string assemblyFileName)
105 {
106 byte[] publicKey = null;
107 byte[] publicKeyToken = null;
108 Assembly assembly = Assembly.LoadFile(assemblyFileName);
109 publicKey = assembly.GetName().GetPublicKey();
110 publicKeyToken = assembly.GetName().GetPublicKeyToken();
111
112 foreach (AssemblyInfo assemblyInfo in assemblyInfoList)
113 {
114 AssemblyDefinition ass = AssemblyFactory.GetAssembly(assemblyInfo.FileName);
115 ass.Name.PublicKey = publicKey;
116 ass.Name.PublicKeyToken = publicKeyToken;
117 AssemblyFactory.SaveAssembly(ass, assemblyInfo.FileName);
118 }
119 }
120 private void ReSignByKeyFile(AssemblyInfo[] assemblyInfoList, string keyFileName)
121 {
122 ReSignature rs = new ReSignature();
123 rs.ReSign(assemblyInfoList, keyFileName);
124 }
125
126 }
127
128 #region 重新签名
129 public class ReSignature
130 {
131 [DllImport("mscoree.dll", EntryPoint = "StrongNameKeyDelete", CharSet = CharSet.Auto)]
132 public static extern bool StrongNameKeyDelete(string wszKeyContainer);
133 [DllImport("mscoree.dll", EntryPoint = "StrongNameKeyInstall", CharSet = CharSet.Auto)]
134 public static extern bool StrongNameKeyInstall([MarshalAs(UnmanagedType.LPWStr)] string wszKeyContainer, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2, SizeConst = 0)] byte[] pbKeyBlob, int arg0);
135 [DllImport("mscoree.dll", EntryPoint = "StrongNameSignatureGeneration", CharSet = CharSet.Auto)]
136 public static extern bool StrongNameSignatureGeneration(string wszFilePath, string wszKeyContainer, IntPtr pbKeyBlob, int cbKeyBlob, int ppbSignatureBlob, int pcbSignatureBlob);
137 [DllImport("mscoree.dll", EntryPoint = "StrongNameErrorInfo", CharSet = CharSet.Auto)]
138 public static extern uint StrongNameErrorInfo();
139 [DllImport("mscoree.dll", EntryPoint = "StrongNameTokenFromPublicKey", CharSet = CharSet.Auto)]
140 public static extern bool StrongNameTokenFromPublicKey(byte[] pbPublicKeyBlob, int cbPublicKeyBlob, out IntPtr ppbStrongNameToken, out int pcbStrongNameToken);
141 [DllImport("mscoree.dll", EntryPoint = "StrongNameFreeBuffer", CharSet = CharSet.Auto)]
142 public static extern void StrongNameFreeBuffer(IntPtr pbMemory);
143
144 private byte[] GetNewKey(string keyFileName)
145 {
146 using (FileStream keyPairStream = File.OpenRead(keyFileName))
147 {
148 return new StrongNameKeyPair(keyPairStream).PublicKey;
149 }
150 }
151 private byte[] GetPublicKeyToken(string keyFileName)
152 {
153 try
154 {
155 byte[] newPublicKey;
156 using (FileStream keyPairStream = File.OpenRead(keyFileName))
157 {
158 newPublicKey = new StrongNameKeyPair(keyPairStream).PublicKey;
159 }
160 int pcbStrongNameToken;
161 IntPtr ppbStrongNameToken;
162 StrongNameTokenFromPublicKey(newPublicKey, newPublicKey.Length, out ppbStrongNameToken, out pcbStrongNameToken);
163 var token = new byte[pcbStrongNameToken];
164 Marshal.Copy(ppbStrongNameToken, token, 0, pcbStrongNameToken);
165 StrongNameFreeBuffer(ppbStrongNameToken);
166 return token;
167 }
168 catch (Exception)
169 {
170 return null;
171 }
172 }
173 public void RunSnTool(string assemblyName, string keyFileName)
174 {
175 //SN工具进程
176 Process snProcess = new Process
177 {
178 StartInfo =
179 {
180 FileName = "SN.exe",
181 Arguments = string.Format("/Ra {0} {1}", assemblyName, keyFileName)
182 }
183 };
184 snProcess.Start();
185 snProcess.WaitForExit();
186 }
187 public void ReSign(AssemblyInfo[] assemblyInfoList, string keyFileName)
188 {
189 //用KEY文件建立密钥容器
190 string wszKeyContainer = Guid.NewGuid().ToString();
191 byte[] pbKeyBlob = File.ReadAllBytes(keyFileName);
192 StrongNameKeyInstall(wszKeyContainer, pbKeyBlob, pbKeyBlob.Length);
193 byte[] publicKey = GetNewKey(keyFileName);
194
195 foreach (AssemblyInfo assemblyInfo in assemblyInfoList)
196 {
197 string assemblyName = assemblyInfo.FileName;
198 AssemblyDefinition asm = AssemblyFactory.GetAssembly(assemblyName);
199 asm.Name.PublicKey = publicKey;
200 AssemblyFactory.SaveAssembly(asm, assemblyName);
201 StrongNameSignatureGeneration(assemblyName, wszKeyContainer, IntPtr.Zero, 0, 0, 0);
202 }
203 //删除新建的密钥容器
204 StrongNameKeyDelete(wszKeyContainer);
205 }
206 public void ReLink(AssemblyInfo[] assemblyInfoList, string keyFileName)
207 {
208 byte[] publicKeyToken = GetPublicKeyToken(keyFileName);
209
210 if (publicKeyToken == null)
211 {
212 return;
213 } //初始化一个要重新签名的程序信息列表
214 //获得每个程序集的名称
215 foreach (AssemblyInfo assemblyInfo in assemblyInfoList)
216 {
217 assemblyInfo.FullName = AssemblyFactory.GetAssembly(assemblyInfo.FileName).Name.FullName;
218 }
219 //检查是否被引用,是的话,就替换PublicKeyToken
220 foreach (AssemblyInfo assemblyInfo in assemblyInfoList)
221 {
222 AssemblyDefinition assembly = AssemblyFactory.GetAssembly(assemblyInfo.FileName);
223 foreach (ModuleDefinition module in assembly.Modules)
224
225 foreach (AssemblyNameReference reference in module.AssemblyReferences)
226 {
227 if (assemblyInfoList.Any(a => a.FullName == reference.FullName))
228 {
229 reference.PublicKeyToken = publicKeyToken;
230 AssemblyFactory.SaveAssembly(assembly, assemblyInfo.FileName);
231 }
232 }
233 }
234 }
235 }
236 #endregion
237
238 public class AssemblyInfo
239 {
240 public string FileName { get; set; }
241 public string FullName { get; set; }
242 }
243 }