Изменить Emdeded String в C # скомпилированном exe - PullRequest
10 голосов
/ 30 апреля 2010

У меня проблема с тем, что мне нужно иметь скомпилированный exe-файл (.net 3.5 c #), для которого я буду делать копии, чтобы распространять его, например, потребуется изменить ключ, например, перед отправкой exe-файла. *

Я не могу скомпилировать каждый раз, когда требуется новый exe. Это тонкий клиент, который будет использоваться в процессе регистрации.

Можно ли добавить запись в файл ресурсов с пустым значением, тогда, когда поступит запрос, попросите другое приложение взять пустой тонкий клиент по умолчанию, скопировать его, заполнить пустое значение необходимыми данными.

Если да, то как? Если нет, у вас есть идеи? Я почесал голову уже несколько дней и из-за ограничений, в которых я обязан работать.

Другая идея, которую я имею, заключалась в том, чтобы ввести значение в метод, который я даже не представляю, как бы я попытался это сделать.

Спасибо.

Ответы [ 5 ]

6 голосов
/ 30 апреля 2010

Преобразуйте сборку в IL, выполните текстовый поиск и замену, перекомпилируйте IL в сборку снова. Используйте стандартные инструменты из .NET SDK .

4 голосов
/ 30 апреля 2010

Вместо встраивания ключа в сборку поместите его в файл 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 = "<RSAKeyValue><Modulus>uPCow37yEzlKQXgbqO9E3enSOXY1MCQB4TMbOZyk9eXmc7kuiCMhJRbrwild0LGO8KE3zci9ETBWVVSJEqUqwtZyfUjvWOLHrf5EmzribtSU2e2hlsNoB2Mu11M0SaGd3qZfYcs2gnEnljfvkDAbCyJhUlxmHeI+35w/nqSCjCk=</Modulus><Exponent>AQAB</Exponent><P>4SMSdNcOP0qAIoT2qzODgyl5yu9RubpIU3sSqky+85ZqJHXLUDjlgqAZvT71ROexJ4tMfMOgSWezHQwKWpz3sw==</P><Q>0krr7cmorhWgwCDG8jmzLMo2jafAy6tQout+1hU0bBKAQaPTGGogPB3hTnFIr84kHcRalCksI6jk4Xx/hiw+sw==</Q><DP>DtR9mb60zIx+xkdV7E8XYaNwx2JeUsqniwA3aYpmpasJ0N8FhoJI9ALRzzp/c4uDiuRNJIbKXyt6i/ZIFFH0qw==</DP><DQ>mGCxlBwLnhkN4ind/qbQriPYY8yqZuo8A9Ggln/G/IhrZyTOUWKU+Pqtx6lOghVdFjSxbapn0W8QalNMFGz7AQ==</DQ><InverseQ>WDYfqefukDvMhPHqS8EBFJFpls/pB1gKsEmTwbJu9fBxN4fZfUFPuTnCIJsrEsnyRfeNTAUFYl3hhlRYZo5GiQ==</InverseQ><D>qB8WvAmWFMW67EM8mdlReI7L7jK4bVf+YXOtJzVwfJ2PXtoUI+wTgH0Su0IRp9sR/0v/x9HZlluj0BR2O33snQCxYI8LIo5NoWhfhkVSv0QFQiDcG5Wnbizz7w2U6pcxEC2xfcoKG4yxFkAmHCIkgs/B9T86PUPSW4ZTXcwDmqU=</D></RSAKeyValue>";

   rsa.FromXmlString(rsaPrivateKey);
   String signedData = "<SignedData><Key>Insert your key here</Key></SignedData>";
   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();
}

Пример вывода из этого кода:

<?xml version="1.0" encoding="utf-16"?>
<License>
  <SignedData>
    <Key>Insert your key here</Key>
  </SignedData>
  <Signature>cgpmyqaDlHFetCZbm/zo14NEcBFZWaQpyHXViuDa3d99AQ5Dw5Ya8C9WCHbTiGfRvaP4nVGyI+ezAAKj287dhHi7l5fQAggUmh9xTfDZ0slRtvYD/wISCcHfYkEhofXUFQKFNItkM9PnOTExZvo75pYPORkvKBF2UpOIIFvEIU=</Signature>
</License>

Тогда вы можете использовать такой код, чтобы проверить это. Вам никогда не придется распространять закрытый ключ:

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 = "<RSAKeyValue><Modulus>uPCow37yEzlKQXgbqO9E3enSOXY1MCQB4TMbOZyk9eXmc7kuiCMhJRbrwild0LGO8KE3zci9ETBWVVSJEqUqwtZyfUjvWOLHrf5EmzribtSU2e2hlsNoB2Mu11M0SaGd3qZfYcs2gnEnljfvkDAbCyJhUlxmHeI+35w/nqSCjCk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
      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;
   }
}
1 голос
/ 30 апреля 2010

Из-за возможностей самого кода .NET я не уверен, выполнимо ли это. Но возможно динамически генерировать .NET DLL, которая содержит некоторый ключ, на который можно ссылаться из основного приложения. То есть, если вы не возражаете против второго файла в дистрибутиве.

Или, если вы не возражаете, используйте Ildasm для дизассемблирования .exe, измените ключ, затем используйте Ilasm для повторной сборки, затем вы можете сделать что-то для автоматизации этого.

0 голосов
/ 17 марта 2017

Не думаю, что Вы можете уйти, не перекомпилировав свой .exe и не вставив ключ в указанный .exe. Процесс компиляции может быть автоматизирован через использование ildasm.exe и ilasm.exe, как предложил Даниэль Эрвикер в своем ответе https://stackoverflow.com/a/2742902/2358659

Я хотел бы остановиться на этом, если кто-нибудь еще наткнется на эту тему в будущем.

Недавно я столкнулся с подобной проблемой из-за моих плохих привычек контроля версий исходного кода. В двух словах, у меня был исполняемый файл, который должен был записать некоторые данные в таблицу Google, ссылаясь на ее идентификатор. Спустя долгое время после того, как исполняемый файл был выпущен, пришел другой запрос от другой команды, чтобы использовать инструмент, но он должен был записать ту же информацию в другую электронную таблицу, чтобы разделить данные для двух команд. В то время у меня не было исходного исходного кода, поэтому я не смог изменить статическую переменную, содержащую исходный идентификатор электронной таблицы. Я сделал следующее:

  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 . Это действие также можно автоматизировать, написав для этого собственное приложение на 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" в качестве ввода и создает новый .exe со встроенным NewKey .

Надеюсь, это поможет.

0 голосов
/ 30 апреля 2010

Что приходит мне в голову, но еще не пробовали: Создайте строку String в вашей программе, например, как

static public string regGuid = "yourguidhere";

Затем найдите скомпилированный EXE-файл в любом приличном шестнадцатеричном редакторе. Если вы найдете строку, замените ее другим тестом. Если вы все еще можете выполнить программу, вы можете попробовать автоматизировать этот процесс и вуаля! Вот, пожалуйста.

...