Динамически дешифровать ссылочную DLL - PullRequest
4 голосов
/ 06 января 2012

Я хочу, чтобы ссылка DLL в моем проекте приложения Windows Forms. Для меня обязательно, чтобы сначала dll зашифровывался, а потом расшифровывался во время выполнения, когда его нужно было использовать.

Пожалуйста, рассмотрите следующий пример, где подпрограмма первоначально зашифрована, но затем расшифрована и создана. Обратите внимание, что это только концептуальная идея, я понятия не имею, как это нужно сделать с точки зрения кода.

Class clsSO
{
void myVoid()
{
Console.WriteLine("We are here now ...");
}
} // End class

Приведенный выше код будет обернут в .dll и добавлен как dll, на который ссылаются, в мой проект. Затем будет указана ссылка на dll и подпрограмма под названием:

clsSo myRef = new clsSo();

myRef.myVoid();

Вывод на консоль:

Мы сейчас здесь ...

Что мне нужно сделать: Содержимое dll-оболочки будет зашифровано и, следовательно, нечитаемо / не сможет напрямую ссылаться на класс. Таким образом, dll необходимо каким-то образом расшифровать и динамически обновить с помощью расшифрованных данных, чтобы я мог затем ссылаться на них.

Что-то подобное уже существует? Можно ли это сделать?

Я ценю время всех!

Спасибо

Evan

1 Ответ

4 голосов
/ 06 января 2012

Вам потребуется вызвать Assembly.Load (Byte []) для расшифрованных байтов вашего файла.как только вы это сделаете, вам нужно будет использовать отражение или привести класс к интерфейсу, чтобы вы могли получить доступ к методам.

Вот пример

class Example
{
    static void Main(string[] args)
    {
        byte[] decryptedLibArray;
        using (var fs = new FileStream("clsSo.cDll", FileMode.Open, FileAccess.Read))
        using (var aesProvider = new AesCryptoServiceProvider())
        using (var aesTransform = aesProvider.CreateDecryptor(YourKey, YourIV))
        using (var cryptoStream = new CryptoStream(fs, aesTransform, CryptoStreamMode.Read))
        {
            decryptedLibArray = ReadFully(cryptoStream);
        }

        var lib = Assembly.Load(decryptedLibArray);

        IclsSO classInstance = (IclsSO)lib.CreateInstance("clsSO"); //If you use a namespace this will be namespace.clsSO

        classInstance.myVoid();

    }

    /// <summary>
    /// Reads data from a stream until the end is reached. The
    /// data is returned as a byte array. An IOException is
    /// thrown if any of the underlying IO calls fail.
    /// </summary>
    /// <param name="stream">The stream to read data from</param>
    public static byte[] ReadFully (Stream stream)
    {
        byte[] buffer = new byte[32768];
        using (MemoryStream ms = new MemoryStream())
        {
            while (true)
            {
                int read = stream.Read (buffer, 0, buffer.Length);
                if (read <= 0)
                    return ms.ToArray();
                ms.Write (buffer, 0, read);
            }
        }
    }
}

interface IclsSO
{
    void myVoid();
}

ReadFully от это объявление .Прочтите его, чтобы понять, почему я не просто сделал cryptoStream.Read(data, 0, decryptedLibArray.Length); В последнем примере есть некоторые ошибки, но пример потока памяти, который он приводит, идеален.

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

...