Попытка защитить мой исполняемый файл с помощью некоторого хеширования, но натолкнулся на неожиданное и неизвестное поведение компилятора - PullRequest
0 голосов
/ 17 февраля 2020

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

У меня есть идея вычислить простое значение ha sh моей программы, просто добавив все байты в двоичном файле и используя остаток от этого общего значения, разделенного на 256, как значение ha sh.

Я решил, что если в моей программе у меня есть строковый литерал «0000», и что ха sh Я рассчитываю с помощью приведенного выше алгоритма, например, 163, что я мог бы получить 164, заменив одну из '0' на '1'. Однако результаты, которые я получаю, далеки от этого. Заменив один символ одним значением, я получу совершенно другой результат ha sh. Для этого примера 163 может стать 84, что меня озадачивает.

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

int calcHash(const char *filename) {
    int hash = 0;
    int c;
    FILE *fh = fopen(filename, "r");

    if (!fh)
        return -1;

    while((c = fgetc(fh)) != EOF)
        hash = (hash + c) % 256;

    fclose(fh);

    return hash;
}

И я называю это из main () с этим оператором.

int hash = calcHash(argv[0]);

Что именно происходит во время компиляции? В любом случае, я могу получить более предсказуемые значения ha sh?

Возможно, это происходит не со всеми компиляторами. Я просто совершенно сбит с толку этим неожиданным поведением.

Я использую g cc в Ubuntu.

1 Ответ

0 голосов
/ 17 февраля 2020

Это более сложная проблема, чем кажется, а также худшая идея, чем кажется - я не могу этого не рекомендовать.

Я работал над системой клиента, где они это сделали, и это было так же больно в заднице, как и предполагалось, поэтому я закончил реверс-инжиниринг, чтобы написать свою собственную утилиту перепечатывания, чтобы я мог отредактировать чертов файл и применить новый ha sh. И эти изменения были всегда в пользу поставщика программного обеспечения и его клиентов, никогда не красть его или что-либо еще.

Но в любом случае, насколько я помню, это работало, включая некоторые области данных в коде:

char tamper_marker_1[] = "SOME MAGIC STRING";
int  fileSize;
unsigned checksum;
char endmarker[] = "OTHER MAGIC STRING";

Внешняя программа apply-seal откроет .exe и найдет строку magi c, которая приведет к указанной выше области данных, и заполнит fileSize и checksum всех данных , отличных от в области информации о печати. ​​

Исполняемый файл проверит на фальсификацию, открыв себя в виде файла и выполнив те же проверки. .

В Windows вы можете использовать GetModuleFilename(), чтобы найти полный путь к исполняемому файлу, а в Linux вы можете открыть /proc/12345/exe (где 12345 - ваш идентификатор процесса), который является символом c ссылка на программу и т. П. Тоже самое.

Я не знаю, способствую ли я ухудшить мир, описав это, но ТАК для вопросов и ответов, и, возможно, есть законная необходимость. Пожалуйста, не делайте этого, если вы действительно, действительно не должны.

РЕДАКТИРОВАТЬ: Вы могли бы указать, что очень немногие будут go на проблемы, которые я сделал в области обратного проектирования, но я укажу, что все вам нужно один человек , чтобы создать инструмент для повторного запечатывания и выпустить его, и вся ваша умная работа ни к чему.

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

...