Вопрос

Я обнаружил, что можно извлекать жестко закодированные строки из двоичного файла.
Например, представление свойств Обозреватель процессов отображает всю строку, содержащую более 3 символов.

Вот код простого исполняемого файла, который я написал, чтобы просто протестировать его:

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
    _TCHAR* hiddenString1 =_T("4537774B-CC80-4eda-B3E4-7A9EE77991F5");
    _TCHAR* hiddenString2 =_T("hidden_password_or_whatever");
    for (int i= 0; i<argc; i++) {
        if (0 == _tcscmp(argv[i],hiddenString1)) {
            _tprintf (_T("The guid argument is correct.\n")); }
        else if (0 == _tcscmp(argv[i],hiddenString2)) {
            _tprintf (_T("Do something here.\n")); }
    }

    _tprintf (_T("This is a visible string.\n"));
    //Keep Running
    Sleep(60000);
    return 0;
}

Строки, очевидно, могут быть извлечены из соответствующего исполняемого файла:
alt text

Я думаю, что найти нужные строки слишком просто.

Мои вопросы таковы:

  1. Как сделать просто скрыть Скрытая строка 1 или Скрытая строка 2 в исполняемом файле ?
  2. Есть ли более безопасный способ использовать "чит-код", чем с помощью какого-то непонятного скрытого ввода?
Это было полезно?

Решение

Добро пожаловать в широкий мир защитного программирования.

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

  1. Вместо прямого строкового значения вы можете сохранить текст в какой-либо другой двоичной форме (шестнадцатеричной?).

  2. Вы можете зашифровать строки, которые хранятся в вашем приложении, а затем расшифровать их во время выполнения.

  3. Вы можете разбить их по различным точкам вашего кода и восстановить позже.

Или какая-то их комбинация.

Имейте в виду, что некоторые атаки идут дальше, чем просмотр фактического двоичного файла.Иногда они исследуют адресное пространство памяти программы во время ее выполнения.MS придумала нечто, называемое SecureString в .Net 2.0.Цель состоит в том, чтобы сохранить строки зашифрованными во время работы приложения.

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

Другие советы

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

Просто будьте осознанны:это все игра в кошки-мышки:это так невозможно Для гарантия что никто не узнает ваш "секрет".

Независимо от того, сколько шифрования или других трюков вы используете;независимо от того, сколько усилий или денег вы в это вложили.Неважно, сколько типов из "НАСА / Массачусетского технологического института / ЦРУ / АНБ" вовлечено в сокрытие этого.

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

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

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

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

Если у вас есть действительно критически секретная информация, которая так или иначе понадобится вашей программе, но которая НИКОГДА не должна становиться общедоступной (например, закрытый ключ), тогда вам нужно, чтобы ваша программа взаимодействовала с удаленным сервером под вашим контролем, применяя соответствующие средства аутентификации и авторизации (то есть убедитесь, что только утвержденные пользователи или компьютеры могут отправить запрос на сервер), и пусть этот сервер хранит это в секрете и использует его.

Самый простой способ - зашифровать их с помощью чего-нибудь тривиального, например xor или rot-13, а затем расшифровать их "на лету", когда они используются.Это исключит случайный просмотр их, но это не остановит никого с большим опытом работы задним ходом.

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

  • Создайте хэш (MD5, SHA и т.д.) строки / пароля / id, с которыми вы хотите сравнить, возможно, добавьте к нему значение "соль".Сохраните это в своей программе
  • Когда программа запущена, выполните тот же алгоритм для входной строки / пароля / id и сравните два хэша, чтобы увидеть, совпадают ли они.

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

Есть URL-адреса для http-запросов, которые я бы тоже хотел скрыть.

Если ваше приложение делает запрос, нет смысла скрывать это.Запуск такого приложения, как fiddler, http analyzer или одного из десятков других бесплатных и легкодоступных методов, покажет весь трафик, создаваемый вашим приложением.

Будут ли все ваши секретные коды идентификаторами GUID или это был просто пример?

Возможно, сохраните свой секрет в виде двоичного guid:

const GUID SecretGuid =
    { 0x4537774B, 0xCC80, 0x4eda, { 0x7A, 0x9E, 0xE7, 0x79, 0x91, 0xF5 } };

Затем преобразуйте предоставленный вами guid из string в двоичный формат и сравните два двоичных guid.

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

Если вы не хотите, чтобы люди видели ваш GUID, то сконструируйте его из байтов, а не из строки:

const GUID SecretGuid = 
      { 0x4537774B, 0xCC80, 0x4eda, { 0x7A, 0x9E, 0xE7, 0x79, 0x91, 0xF5 } };

Лучшее, что вы можете сделать, это закодировать свой пароль или другую строку, которую вы хотите скрыть как массив символов.Например:

std::string s1 = "Hello";   // This will show up in exe in hex editor
char* s2 = "World";   // this will show up in exe in hex editor
char s3[] = {'G', 'O', 'D'}; // this will not show up in exe in hex editor.

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

WCHAR T1[28];
 T1[22] = 69;
 T1[15] = 121 - 17;
 T1[9] = L':' + -26;
 T1[12] = L't' - 1;
 T1[6] = 116 - 1;
 T1[17] = 117 - 12;
 T1[3] = 116 - 1;
 T1[14] = L'' - 3;
 T1[13] = L'w' - 3;
 T1[23] = 69;
 T1[26] = L'Y' + 3;
 T1[19] = 111 + 0;
 T1[21] = L'k' - 34;
 T1[27] = L'\\' - 8;
 T1[20] = L'B' + 32;
 T1[4] = 42 + -10;
 T1[25] = L'm' - 17;
 T1[16] = L'H' + 18;
 T1[18] = L'A' + 56;
 T1[24] = 68;
 T1[1] = 105 - 1;
 T1[11] = L'k' - 6;
 T1[10] = 66 + 50;
 T1[2] = 105;
 T1[0] = 117 - 1;
 T1[5] = L'k' - 2;
 T1[8] = 89 + 8;
 T1[7] = 32;

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top