📄 snreplace.cs
字号:
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
public class SNReplace
{
private byte[] assembly;
public string assemblyFile;
private byte[] currentKey;
public string keyFile;
public string keyPassWord;
public string certKey;
public string rsaKey;
public string newKeyToken;
private byte[] newKey;
/// <summary>
/// 替换文件字节
/// </summary>
/// <param name="oldBytes">待换字节</param>
/// <param name="newBytes">应换字节</param>
public string[] replaceBytes(byte[] oldBytes, byte[] newBytes)
{
byte num = oldBytes[0];
bool assemblyChanged = false;
System.Collections.ArrayList arrReplacePlace = new System.Collections.ArrayList();
for (int i = 0; i < this.assembly.Length - oldBytes.Length + 1; i++)
{
if (this.assembly[i] == num)
{
int j = 0;
for (j = 0; j < oldBytes.Length; j++)
{
if (oldBytes[j] != assembly[i + j]) break;
}
if (j == oldBytes.Length)
{
assemblyChanged = true;
for (j = 0; j < newBytes.Length; j++)
{
assembly[i + j] = newBytes[j];
}
arrReplacePlace.Add("0x" + string.Format("{0:x}", i));
}
}
}
if (assemblyChanged == true) save();
string[] replacePlace = new string[arrReplacePlace.Count];
arrReplacePlace.CopyTo(replacePlace);
return replacePlace;
}
/// <summary>
/// 从文件中读取字节
/// </summary>
public void readAssembly()
{
using (FileStream stream = File.OpenRead(this.assemblyFile))
{
this.assembly = new byte[stream.Length];
stream.Read(this.assembly, 0, (int)stream.Length);
stream.Close();
}
}
/// <summary>
/// 读取程序集公钥
/// </summary>
/// <returns>是否有公钥</returns>
public int readAssemblyKey()
{
if ((this.currentKey = AssemblyName.GetAssemblyName(this.assemblyFile).GetPublicKey()) == null)
{
return 0;
}
return this.currentKey.Length;
}
/// <summary>
/// 从签名文件中读取公钥
/// </summary>
public bool readKeys()
{
bool success = false;
FileStream keyPairFile = File.OpenRead(this.keyFile);
this.certKey = "";
if (keyFile.ToLower().EndsWith(".snk"))
{
try
{
this.newKey = new StrongNameKeyPair(keyPairFile).PublicKey;
this.rsaKey = "";
foreach (byte bytekey in this.newKey)
{
this.rsaKey += String.Format("{0:x2}", bytekey);
}
success = true;
}
catch
{
success = false;
}
}
else
{
try
{
System.Security.Cryptography.X509Certificates.X509Certificate2 certificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(this.keyFile, this.keyPassWord);
this.certKey = certificate.GetPublicKeyString();
System.Security.Cryptography.RSACryptoServiceProvider rsaKey = new System.Security.Cryptography.RSACryptoServiceProvider(1024);
rsaKey.FromXmlString(certificate.PublicKey.Key.ToXmlString(false));
this.newKey = new byte[160];
this.newKey[1] = 0x24;
this.newKey[4] = 0x4;
this.newKey[5] = 0x80;
this.newKey[8] = 0x94;
rsaKey.ExportCspBlob(false).CopyTo(this.newKey, 12);
this.newKey[17] = 0x24;
this.rsaKey = "";
foreach (byte bytekey in this.newKey)
{
this.rsaKey += String.Format("{0:x2}", bytekey);
}
success = true;
}
catch
{
success = false;
}
}
keyPairFile.Close();
return success;
}
/// <summary>
/// 调用sn.exe重签名
/// </summary>
public int resign()
{
ProcessStartInfo startInfo = new ProcessStartInfo("sn.exe");
startInfo.UseShellExecute = false;
if (this.keyPassWord == "")
startInfo.CreateNoWindow = true;
else
startInfo.CreateNoWindow = false;
startInfo.Arguments = string.Format("-q -R {0} {1}", this.assemblyFile, this.keyFile);
try
{
Process process = Process.Start(startInfo);
process.WaitForExit();
return process.ExitCode;
}
catch
{
MessageBox.Show("公钥已被替换,但未能自动重签名,请手动执行sn -R AssemblyFile KeyFile。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return 1;
}
}
/// <summary>
/// 保存文件
/// </summary>
private void save()
{
try
{
FileStream stream = File.Create(this.assemblyFile);
stream.Write(this.assembly, 0, this.assembly.Length);
stream.Close();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "文件保存错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 获取程序集信息
/// </summary>
/// <param name="fname">程序集名称</param>
/// <param name="refInfo">信息</param>
/// <returns>是否有效程序集</returns>
public bool getAssembInfo(string fname, ref ReferenceInfos refInfo)
{
FileStream fs = null;
byte[] bfile = null;
bool success = false;
try
{
fs = new FileStream(fname, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
bfile = new byte[fs.Length];
fs.Read(bfile, 0, (int)fs.Length);
refInfo.tokenByte = Assembly.Load(bfile).GetName().GetPublicKeyToken();
refInfo.assemblyName = Assembly.Load(bfile).GetName().Name;
AssemblyName[] referencenames = Assembly.Load(bfile).GetReferencedAssemblies();
refInfo.assemblyReference = new string[referencenames.Length];
for (int i = 0; i < referencenames.Length; i++)
{
refInfo.assemblyReference[i] = referencenames[i].Name;
}
refInfo.tokenText = "";
foreach (byte b in refInfo.tokenByte)
{
refInfo.tokenText += string.Format("{0:x2}", b);
}
char[] tokenChars = refInfo.tokenText.ToCharArray();
refInfo.tokenString = new byte[tokenChars.Length];
for (int i = 0; i < tokenChars.Length; i++)
{
refInfo.tokenString[i] = (byte)tokenChars[i];
}
success = true;
}
catch (Exception ex)
{
MessageBox.Show("在读取程序集:" + fname + "时发生错误\r\n" + ex.InnerException.Message, "文件读取错误",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
fs.Close();
return success;
}
/// <summary>
/// 执行替换
/// </summary>
public string[] Replace()
{
if (this.readAssemblyKey() == 0) return null;
this.readKeys(); ;
this.readAssembly();
string[] publicKeyPlace = this.replaceBytes(this.currentKey, this.newKey);
this.save();
return publicKeyPlace;
}
}
public struct ReferenceInfos
{
public string filePath;
public string assemblyName;
public string[] assemblyReference;
public byte[] tokenByte;
public byte[] tokenString;
public string tokenText;
}
public struct LogInfos
{
public string filePath;
public string assemblyName;
public string[] keyReplacePosition;
public string oldToken;
public string[] tokenByteReplacePosition;
public string[] tokenStringReplacePositon;
public int resignSuccess;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -