Как сделать C-макрос перед сборкой препроцессора? - PullRequest
2 голосов
/ 24 октября 2011

Допустим, у меня есть строка, которую я хотел бы запутать в своем коде. (Этот пример только для изучения.)

Мой план состоит в том, чтобы обернуть строковый литерал макросом, например

#define MY_STRING "lol"
const char *get_string() { return _MY_ENCRYPTION_MACRO(MY_STRING); }

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

Как мне выполнить предварительную обработку в Visual C ++?

Ответы [ 2 ]

1 голос
/ 24 января 2016

Я разместил этот ответ на пару вопросов, поскольку у многих людей есть такая проблема, как у меня, я также думал, что это невозможно, хотя это очень просто, люди писали решения, где вам нужен специальный инструмент для сканирования встроенного потом файл, отсканируйте строки и зашифруйте такие строки, что неплохо, но я хотел пакет, скомпилированный из Visual Studio, и теперь это возможно!

Что вам нужно, это C++ 11 (Visual Studio 2015, обновление 1 из коробки)

магия происходит с этой новой командой constexpr

По волшебству происходит в этом #define

#define XorString( String ) ( CXorString<ConstructIndexList<sizeof( String ) - 1>::Result>( String ).decrypt() )

Он не будет расшифровывать XorString во время компиляции, только во время выполнения, но он будет шифровать строку только во время компиляции, поэтому строки не будут отображаться в исполняемом файле

printf(XorString( "this string is hidden!" ));

Он распечатает "this string is hidden!", но вы не найдете его в исполняемом файле в виде строк! Проверьте сами с помощью Microsoft Sysinternals Strings ссылки для загрузки программы: https://technet.microsoft.com/en-us/sysinternals/strings.aspx

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

Создать файл с именем XorString.h

#pragma once

//-------------------------------------------------------------//
// "Malware related compile-time hacks with C++11" by LeFF   //
// You can use this code however you like, I just don't really //
// give a shit, but if you feel some respect for me, please //
// don't cut off this comment when copy-pasting... ;-)       //
//-------------------------------------------------------------//

////////////////////////////////////////////////////////////////////
template <int X> struct EnsureCompileTime {
    enum : int {
        Value = X
    };
};
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
//Use Compile-Time as seed
#define Seed ((__TIME__[7] - '0') * 1  + (__TIME__[6] - '0') * 10  + \
              (__TIME__[4] - '0') * 60   + (__TIME__[3] - '0') * 600 + \
              (__TIME__[1] - '0') * 3600 + (__TIME__[0] - '0') * 36000)
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
constexpr int LinearCongruentGenerator(int Rounds) {
    return 1013904223 + 1664525 * ((Rounds> 0) ? LinearCongruentGenerator(Rounds - 1) : Seed & 0xFFFFFFFF);
}
#define Random() EnsureCompileTime<LinearCongruentGenerator(10)>::Value //10 Rounds
#define RandomNumber(Min, Max) (Min + (Random() % (Max - Min + 1)))
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
template <int... Pack> struct IndexList {};
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
template <typename IndexList, int Right> struct Append;
template <int... Left, int Right> struct Append<IndexList<Left...>, Right> {
    typedef IndexList<Left..., Right> Result;
};
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
template <int N> struct ConstructIndexList {
    typedef typename Append<typename ConstructIndexList<N - 1>::Result, N - 1>::Result Result;
};
template <> struct ConstructIndexList<0> {
    typedef IndexList<> Result;
};
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
const char XORKEY = static_cast<char>(RandomNumber(0, 0xFF));
constexpr char EncryptCharacter(const char Character, int Index) {
    return Character ^ (XORKEY + Index);
}

template <typename IndexList> class CXorString;
template <int... Index> class CXorString<IndexList<Index...> > {
private:
    char Value[sizeof...(Index) + 1];
public:
    constexpr CXorString(const char* const String)
    : Value{ EncryptCharacter(String[Index], Index)... } {}

    char* decrypt() {
        for(int t = 0; t < sizeof...(Index); t++) {
            Value[t] = Value[t] ^ (XORKEY + t);
        }
        Value[sizeof...(Index)] = '\0';
        return Value;
    }

    char* get() {
        return Value;
    }
};
#define XorS(X, String) CXorString<ConstructIndexList<sizeof(String)-1>::Result> X(String)
#define XorString( String ) ( CXorString<ConstructIndexList<sizeof( String ) - 1>::Result>( String ).decrypt() )
////////////////////////////////////////////////////////////////////
0 голосов
/ 28 октября 2011

Если вы использовали недавний GCC (т.е. GCC 4.6) в Linux, у вас также может быть плагин, который предоставляет встроенную функцию для «шифрования» строк времени компиляции, или вы даже можете сделать это *Расширение 1003 * GCC MELT (MELT - это высокоуровневый язык, специфичный для домена для расширения GCC).

Если вы используете какой-либо другой C ++, у вас могут быть собственные сценарии предварительной обработки для поиска макросов.Например, у вас может быть программа, которая сканирует каждое вхождение ENCRYPTSTRING("anyconstantstring") во всех ваших источниках C ++ и генерирует файл mycrypt.h, который вы #include "mycrypt.h" делаете в своем коде C ++.Тогда вы можете выполнять такие трюки, как

#define ENCRYPTSTRING(S) ENCRPYTSTRING_AT(S,__LINE__)
#define ENCRYPTSTRING_AT(S,L) cryptstring_#L

, и ваши сгенерированные "mycrypt.h" содержат такие вещи, как

const char crypstring_123[]="thecryptedstringatline123";

и т. Д.Генератор "mycrypt.h" может быть скриптом awk или python или ocaml (и т. Д.).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...