修改C#编译的exe中的Emdeded String

我有一个问题,我需要能够有一个编译的exe(.net 3.5 c#),我将复制分发,例如在发送exe之前需要更改密钥。

每次需要新的exe时我都无法编译。 这是一个瘦客户端,将用作注册过程的一部分。

是否可以向具有空值的资源文件添加条目然后当请求进入时,另一个应用程序获取空白的默认瘦客户端,复制它,用所需数据填充空白值。

如果有,怎么样? 如果没有,你有什么想法吗? 我现在已经摸不着头几天了,这个限制是由于我需要工作的边界。

我的另一个想法是将值注入一个方法,我不知道我怎么会尝试这个。

谢谢。

将程序集转换为IL,进行文本搜索和替换,再次将IL重新编译为程序集。 使用.NET SDK中的标准工具 。

不是将密钥嵌入到程序集中,而是将其放在app.config文件(或随应用程序提供的其他文件)中,并在密钥不存在且有效时阻止应用程序运行。 为了防止用户修改它,还要在配置文件中添加RSA签名。

此代码可用于生成包含密钥的XML。

public static void Main() { Console.WriteLine(GenerateKey()); } public static Byte[] Transform(Byte[] bytes, ICryptoTransform xform) { using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) { using (CryptoStream cstream = new CryptoStream(stream, xform, CryptoStreamMode.Write)) { cstream.Write(bytes, 0, bytes.Length); cstream.Close(); stream.Close(); return stream.ToArray(); } } } public static string GenerateKey() { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); // This is the private key and should never be shared. // Generate your own with RSA.Create().ToXmlString(true). String rsaPrivateKey = "uPCow37yEzlKQXgbqO9E3enSOXY1MCQB4TMbOZyk9eXmc7kuiCMhJRbrwild0LGO8KE3zci9ETBWVVSJEqUqwtZyfUjvWOLHrf5EmzribtSU2e2hlsNoB2Mu11M0SaGd3qZfYcs2gnEnljfvkDAbCyJhUlxmHeI+35w/nqSCjCk=AQAB

4SMSdNcOP0qAIoT2qzODgyl5yu9RubpIU3sSqky+85ZqJHXLUDjlgqAZvT71ROexJ4tMfMOgSWezHQwKWpz3sw==

0krr7cmorhWgwCDG8jmzLMo2jafAy6tQout+1hU0bBKAQaPTGGogPB3hTnFIr84kHcRalCksI6jk4Xx/hiw+sw==DtR9mb60zIx+xkdV7E8XYaNwx2JeUsqniwA3aYpmpasJ0N8FhoJI9ALRzzp/c4uDiuRNJIbKXyt6i/ZIFFH0qw==mGCxlBwLnhkN4ind/qbQriPYY8yqZuo8A9Ggln/G/IhrZyTOUWKU+Pqtx6lOghVdFjSxbapn0W8QalNMFGz7AQ==WDYfqefukDvMhPHqS8EBFJFpls/pB1gKsEmTwbJu9fBxN4fZfUFPuTnCIJsrEsnyRfeNTAUFYl3hhlRYZo5GiQ==qB8WvAmWFMW67EM8mdlReI7L7jK4bVf+YXOtJzVwfJ2PXtoUI+wTgH0Su0IRp9sR/0v/x9HZlluj0BR2O33snQCxYI8LIo5NoWhfhkVSv0QFQiDcG5Wnbizz7w2U6pcxEC2xfcoKG4yxFkAmHCIkgs/B9T86PUPSW4ZTXcwDmqU=
"; rsa.FromXmlString(rsaPrivateKey); String signedData = "Insert your key here"; Byte[] licenseData = System.Text.Encoding.UTF8.GetBytes(signedData); Byte[] sigBytes = rsa.SignData(licenseData, new SHA1CryptoServiceProvider()); String sigText = System.Text.Encoding.UTF8.GetString(Transform(sigBytes, new ToBase64Transform())); System.Text.StringBuilder sb = new StringBuilder(); using (System.Xml.XmlWriter xw = System.Xml.XmlTextWriter.Create(sb)) { xw.WriteStartElement("License"); xw.WriteRaw(signedData); xw.WriteElementString("Signature", sigText); xw.WriteEndElement(); } return sb.ToString(); }

此代码的示例输出:

    Insert your key here  cgpmyqaDlHFetCZbm/zo14NEcBFZWaQpyHXViuDa3d99AQ5Dw5Ya8C9WCHbTiGfRvaP4nVGyI+ezAAKj287dhHi7l5fQAggUmh9xTfDZ0slRtvYD/wISCcHfYkEhofXUFQKFNItkM9PnOTExZvo75pYPORkvKBF2UpOIIFvEIU=  

然后你可以使用这样的代码来validation它。 您永远不必分发私钥:

 public static Boolean CheckLicenseSignature(String licXml) { try { System.Xml.XmlDocument xd = new System.Xml.XmlDocument(); xd.LoadXml(licXml); String licSig = xd.SelectSingleNode("/License/Signature").InnerText; RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); String rsaPublicKey = "uPCow37yEzlKQXgbqO9E3enSOXY1MCQB4TMbOZyk9eXmc7kuiCMhJRbrwild0LGO8KE3zci9ETBWVVSJEqUqwtZyfUjvWOLHrf5EmzribtSU2e2hlsNoB2Mu11M0SaGd3qZfYcs2gnEnljfvkDAbCyJhUlxmHeI+35w/nqSCjCk=AQAB"; rsa.FromXmlString(rsaPublicKey); Byte[] licenseData = System.Text.Encoding.UTF8.GetBytes(xd.SelectSingleNode("/License/SignedData").OuterXml); return rsa.VerifyData(licenseData, new SHA1CryptoServiceProvider(), Transform(System.Text.Encoding.UTF8.GetBytes(licSig), new FromBase64Transform())); } catch (System.Xml.XmlException ex) { return false; } catch (InvalidOperationException ex) { return false; } } 

从.NET代码本身的能力来看,我不确定这是否可行。 但是可以动态生成一个.NET DLL,其中包含一些可以从主应用程序引用的密钥。 也就是说,如果你不介意发行版中的第二个文件。

或者,如果您不介意使用Ildasm来反汇编.exe,更改密钥,然后使用Ilasm重新组装,那么您可以做一些事情来自动化。

我不认为你可以逃脱而不重新编译你的.exe并将密钥嵌入到所述.exe中。 编辑过程可以通过使用ildasm.exe和ilasm.exe自动进行,因为Daniel Earwicker在他的回复中建议https://stackoverflow.com/a/2742902/2358659

如果其他人在将来偶然发现这个话题,我想扩展一下。

由于我的源代码版本控制习惯不佳,我最近遇到了类似的问题。 简而言之,我有一个可执行文件,它应该通过引用它的ID将一些数据写入Google电子表格。 在可执行文件发布后很久,来自不同团队的另一个请求使用该工具,但它必须将相同的信息写入不同的电子表格,以便为两个团队保持数据分离。 当时我没有原始源代码,因此我无法更改保存原始电子表格ID的静态变量。 我做的是如下:

  1. 使用CMD.exe→ 调用“C:\ Program Files(x86)\ Microsoft SDKs \ Windows \ v8.0A \ bin \ NETFX 4.0 Tools \ ildasm.exe”“myApplication.exe”/out=”myApplication.il“
  2. 使用Notepad ++→在myApplication.il文件中查找原始ID并将其替换为新ID。 此操作也可以通过编写自己的C#应用​​程序来实现,或使用PowerShell ,或使用vb / j-script或使用现成的其他一些查找和替换工具(如FART) (使用CMD.exe→ 调用) fart.exe myApplication.il“OldKey”“NewKey”
  3. 使用CMD.exe→ 调用“C:\ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ ilasm.exe”“myApplication.il”/res=”myApplication.res“/key=”myApplicationKeyFile.snk”

如您所见,所有这些步骤都可以放在一个.bat文件中,该文件将“NewKey”作为输入并生成嵌入了NewKey的新.exe 文件

我希望有所帮助。

我想到了什么,但还没有尝试过:在程序中创建一个默认的String,例如as

 static public string regGuid = "yourguidhere"; 

然后,使用任何体面的hex编辑器搜索已编译的EXE。 如果找到该字符串,请将其替换为另一个测试。 如果你仍然可以执行该程序,你可以尝试自动化这个过程,瞧! 这个给你。