2013-12-04 4 views
5

После прочтения нескольких документов о криптографии и криптографии PE, я решил написать свои собственные. Это очень просто и только в образовательных целях.C++ XOR-шифрование

Вот GitHub репо: https://github.com/Jyang772/XOR_Crypter

У меня есть два вопроса.

  • Первый, почему я должен постоянно менять свои права доступа к файлам, чтобы начать каждый выводимый .exe (Файл, созданный Builder.exe не компилятор)? Он создает файл Shared. Я должен щелкнуть правой кнопкой мыши и выбрать общий доступ с помощью Nobody. Связано ли это с правами доступа к файлам и безопасности? Я использую CreateFile() и Readfile для чтения и записи входных и выходных файлов.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx

enter image description here

  • Второй, я не могу показаться, чтобы получить шифрование XOR работать. Кажется довольно прямо вперед для того, что я сделал. Размеры байтов одинаковы. Пока я исследовал, у меня был Builder и Stub, каждый из которых выводил файл с незашифрованными файловыми данными. Они одинаковые. Затем я попытался с зашифрованными данными. Нет сомнений, что данные шифруются с помощью шифрования, однако он отображается пустым, когда он позже расшифровывается заглушкой. Я смущен.

Вот моя реализация XOR:

фс = размер байт Rsize = размер байта Должно быть то же самое.

Builder:

char cipher[] ="penguin"; 
     for (int i = 0; i < fs; i++) 
     { 
       FB[i] ^= cipher[i % strlen(cipher)]; // Simple Xor chiper 
     } 

Заглушка:

char cipher[] = "penguin"; 
for (int i = 0; i < Rsize; i++) 
    { 
     RData[i] ^= cipher[i % strlen(cipher)]; 
    } 

Если бы я закомментировать функцию шифрования в Builder и Ста, то зашифрованный файл работает нормально. Uhh, за исключением ошибки с разрешениями.

Я также пытаюсь включить меню опций, в котором пользователь может выбрать используемый метод шифрования. Может, я, возможно, сделал что-то не так? Builder.exe добавляет один байт, содержащий выбор пользователя до конца буфера FB. Stub.exe читает это и определяет, какой метод шифрования используется для дешифрования данных.

+0

Вы не забыли открыть свои файлы как 'binary'? –

+0

@JoeZ Я думал, что CreateFile() и ReadFile() всегда открывают файлы в двоичном режиме. –

+0

Разрешения к файлу, не имеющие отношения к шифрованию или программированию. – EJP

ответ

10

Во-первых, с XOR «шифрования», ваш «шифровать» и «расшифровать» функции должны быть одинаковыми:

void xor_crypt(const char *key, int key_len, char *data, int data_len) 
{ 
    for (int i = 0; i < data_len; i++) 
     data[i] ^= key[ i % key_len ]; 
} 

Вы должны быть в состоянии использовать эту же функцию в обоих " XOR Crypter ", а также вашу программу" Stub ".

Это не очень C++ стиль; обычно вы используете std::string или std::vector. Например:

void xor_crypt(const std::string &key, std::vector<char> data) 
{ 
    for (size_t i = 0; i != data.size(); i++) 
     data[i] ^= key[ i % key.size() ]; 
} 

Затем в программе, которая вызывает это, вы бы объявить:

std::string key = "penguin"; 

и вы бы прочитать файл в следующим образом:

std::vector<char> file_data; // With your current program, make this a global. 

fs = GetFileSize(efile, NULL); 
file_data.resize(fs); // set vector length equal to file size 

// Note: Replace &(file_data[0]) with file_data.data() if you have C++11 support 
ReadFile(efile, (LPVOID)(&(file_data[0])), fs, &bt, NULL); 

if (fs != bt) 
    // error reading file: report it here. 

Тогда вам будет просто шифроваться с помощью xor_crypt(key, file_data);. Для записи XOR-шифрованных данных на ваш ресурс, я полагаю, вы бы назвали существующую функцию с:

// replace &(file_data[0]) with file_data.data() if C++11 
WriteToResources(output, 1, (BYTE *)&(file_data[0]), file_data.size()); 

Я подозреваю, что реальная проблема с Windows API, которые вы используете. LoadResource дает вам изменяемые данные, или их необходимо скопировать? Я не знаю Windows API, но я не удивлюсь, если LoadResource дает вам копию только для чтения.

Если вам нужно сделать свою собственную копию, чтобы изменить ресурс, то в вашей программе «Stub» восстановления XOR-зашифрованный ресурс должен выглядеть следующим образом:

std::vector<char> RData; 

void Resource(int id) 
{ 
    size_t Rsize; 

    HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(1), RT_RCDATA); 
    HGLOBAL temp = LoadResource(NULL, hResource); 
    Rsize = SizeofResource(NULL, hResource); 
    RData.resize(RSize); 
    memcpy((void*)&(RData[0]), temp, RSize); // replace &RData[0] with RData.data() if C++11 
} 

и дешифрование в ваш «Stub» должен быть только xor_crypt(key, RData);.

У меня есть последняя мысль. Самая большая ошибка, я вижу в программе «Stub» эта линия:

switch (RData[strlen(RData)-1]) 

После того, как вы XOR-шифрованных данных, некоторые из байтов будет равен нулю. Функция strlen() не вернет индекс последнего байта в вашем RData. И есть другая, более тонкая ошибка: возвращает последний байт строки, а не последний байт ресурса. Я не могу понять, как эта строка была правильной; скорее, я подозреваю, что ваша программа работала, когда шифрование было отключено, несмотря на то, что оно провалилось до default коммутационного футляра.

Если вы действительно собираетесь различать различные типы данных на основе последнего байта полезной нагрузки ресурса, то вам действительно нужно просто использовать размер, возвращаемый API Windows, чтобы найти этот байт.

Если вы переключитесь на использование vector<char>, как я предлагаю выше, вы можете найти это с помощью RData.back(). В противном случае, если вы продолжите использовать char *, тогда этот байт будет RData[RSize - 1].

+0

Спасибо, что нашли время, чтобы прочитать мой код и дать мне очень подробный ответ. Я принял ваш совет и прокомментировал функции C-стиля с теми, которые вы предложили. Единственная часть, которую мне нужно было исправить, заключалась в том, что 'file_data' и' data' в функции xor были одинаковыми. В противном случае я просто XOR шифрую копию 'file_data' –

+0

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

+0

Вот небольшая вариация, в которой в качестве ключа используется 64-разрядное целое. '_UINT8 * гаммирование (_UINT8 * обр, size_t arrLen, _UINT64 ключ) { \t // Выделим выходной буфер \t _UINT8 * outArr = новый _UINT8 [arrLen]; \t \t // Обратитесь к 64-битному ключу, как 8 байт массивы байт в \t _UINT8 * keyArr = (_UINT8 *) &key; \t для (size_t = 0; г

2

В зависимости от ваших данных контента вы записываете опцию char в выделенную память, указанную FB или после нее (buffer overrun) в «C++ Builder/main.cpp» при вызове strcat (FB, choice).

Исправить: выделить достаточное пространство в FB для данных + параметр char. Поскольку вы имеете дело с двоичными данными, вы не должны использовать строковые функции (например: strcat).

FB = new char[fs + 1]; 
memcpy(FB +fs, option, 1); // copy the option at end 
+0

У меня вопрос. Зачем мне выделять только 5 пробелов для FB? –

+0

Обновление, должен быть размер данных не 4 ... моя ошибка –

+0

Хм, не знаю, почему он не работает. Я решил удалить меню выбора. Должно быть что-то с шифрованием. –

Смежные вопросы