Исследование защиты игры Limbo. Кейген

  • Tutorial


Всем привет. Многие знают об этой замечательной игре — LIMBO! Вы даже наверняка покупали ее в Стиме, или качали с торрентов…
Я тоже ее купил когда-то (что и вам советую!), и прошел). Но, как всегда, мне было этого мало, и я, из спортивного интереса, решил изучить ее защиту. Так и появился кейген к игре LIMBO.

В этой статье я расскажу и покажу вам, как я это делал.

Прежде, чем начинать, помните: все действия вы выполняете на свой страх и риск. Уважайте работу геймдевелоперов.


Этап первый: Поверхностный осмотр пациента

Полный инсталлятор игры можно скачать здесь. Установив игру, первым делом, как обычно, выясняем, на чем написан главный исполняемый файл. Я воспользуюсь для этого ExeInfo PE.



Видим: Visual Studio 2008. IDA Pro прекрасно с ней справляется, поэтому туда и отправим. Я буду пользоваться связкой IDA Pro + HexRays, т.е. с декомпилятором — для ускорения работы.

Этап второй: что мы ищем?

Первым делом, дадим Иде проанализировать limbo.exe — главный исполняемый файл игры.

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



Видим волшебную надпись "UNLOCK FULL GAME". На нее и нажмем. Далее нас ожидает нежданчик (по крайней мере, я, когда первый раз выбирал этот пункт меню, я ожидал увидеть поле ввода на графическом движке игры, или типа того, а оказалось все гораздо проще...):



Да, да! Именно обычное окошко! Нам же легче. Попробуем что-нибудь ввести, и нажать Unlock. Как-то так:



Ну что ж, поищем по тексту в IDA, чтобы затем от него отталкиваться, и найти место проверки. И тут меня ожидал облом…
По тексту сообщения в окне ошибки Ида мне ничего не нашла! То же самое сказал мне и поиск по содержимому через Total Commander. Возможно, сообщение зашифровано. Можно попробовать найти вызов окна отталкиваясь от вызова MessageBoxA/W. Но, я пошел другим путем, который, почему-то, мало где в статьях описывают.

Этап третий: Нажми меня

Мы поступим следующим образом. Откроем любой удобный Вам редактор ресурсов, затащим в него ехе-шник, найдем окошко диалога ввода ключа, а в нем — кнопку Unlock. Сказано — сделано:



На скрине я выделил ID нашей кнопки. По нему мы и будем искать, где именно обрабатывается нажатие. Откроем Иду, нажмем Alt+I (Search -> immediate value...), введем число 203 (без 0x, т.к. десятичное), и посмотрим, что найдется. А нашлось вот это:



Видите те строчки, которые Ида пометила как ; nIDDlgItem? С них и начнем. Двойным кликом переходим на первый из таких результатов:



Зеленой стрелкой я обозначил место, на которое указала Ида, а чуть ниже (привычка: прокручивать выше/ниже искомого места) — стрелкой обозначено место вызова одной интересной API-функции: GetDlgItemTextA. Судя по названию по MSDN, эта функция получает текст указанного элемента окна в буфер.

Почему я сразу не искал по ID поля ввода? Можно, конечно и так было сделать. Но, мало ли какие действия происходят после нажатия кнопки, еще до вычитывания текста из поля.

Итак, проследим, куда уходит полученный серийник. Прокручиваем листинг, чтобы видеть место вызова API-функции целиком:



Мой "намыленный" взгляд подсказывает мне, что полученный буфер (Ида обозначила его как var_134) передается прямиком в следующую за вызовом GetDlgItemTextA функцию, которая возвращает в al нулевое, либо ненулевое значение (похоже на результат проверки ключа). Давайте проверим догадку…

Этап четыре: Декомпиляция

Заходим в функцию. Видим там прыжок на еще один адрес — переходим по нему. Видим нормальный код, поэтому смело жмем там F5 (вызываем HexRays Decompiler).

Результат декомпиляции
bool __cdecl sub_48D410(int a1)
{
  int v1; // esi@7
  char *v2; // ebp@7
  unsigned int v3; // edi@7
  int v4; // ST28_4@9
  int v5; // edx@9
  int v6; // eax@12
  bool result; // al@12
  char v8; // [sp+4h] [bp-44h]@8
  char v9; // [sp+Ch] [bp-3Ch]@12
  char v10; // [sp+1Ch] [bp-2Ch]@7
  char v11; // [sp+3Ch] [bp-Ch]@12

  if ( strlen((const char *)a1) != 37
    || *(_BYTE *)(a1 + 5) != 45
    || *(_BYTE *)(a1 + 11) != 45
    || *(_BYTE *)(a1 + 17) != 45
    || *(_BYTE *)(a1 + 23) != 45
    || *(_BYTE *)(a1 + 30) != 45 )
  {
    result = 0;
  }
  else
  {
    v1 = 0;
    v2 = &v10;
    v3 = 0;
    do
    {
      v8 = *(_BYTE *)(v3 + a1);
      if ( v8 != 45 )
      {
        v4 = (char)sub_412EBD(v8);
        v1 += v4 << 5 * (3 - v5);
        if ( v5 == 3 )
        {
          v2 += sprintf(v2, "%05lx", v1);
          v1 = 0;
        }
      }
      ++v3;
    }
    while ( v3 < 0x25 );
    v6 = sub_40C48C(&v10, 32);
    sprintf(&v9, "%08x", v6);
    result = strcmp(&v9, &v11) == 0;
  }
  return result;
}


Теперь можно попытаться привести этот код к более адекватному.

Первым делом, замечаем, что входной параметр имеет тип int, что не совсем правда. Обозначим его как "char *". Для этого становимся на имя функции и жмем там клавишу Y (Set item type). Исправляем тип и имя входного параметра (я обозвал его как key).

Далее… Видим строчку:

  if ( strlen(key) != 37 || key[5] != 45 || key[11] != 45 || key[17] != 45 || key[23] != 45 || key[30] != 45 )

Т.к. наш входной параметр — строка, давайте в тех местах, где символы ключа сверяются с числами, исправим на сравнение с символами. Для этого на каждом из таких чисел нажмем R (Char). Уже лучше:

  if ( strlen(key) != 37 || key[5] != '-' || key[11] != '-' || key[17] != '-' || key[23] != '-' || key[30] != '-' )

Теперь цикл:

Цикл №1
    v1 = 0;
    v2 = &v10;
    v3 = 0;
    do
    {
      v8 = key[v3];
      if ( v8 != 45 )
      {
        v4 = (char)sub_412EBD(v8);
        v1 += v4 << 5 * (3 - v5);
        if ( v5 == 3 )
        {
          v2 += sprintf(v2, "%05lx", v1);
          v1 = 0;
        }
      }
      ++v3;
    }
    while ( v3 < 0x25 );


Для наглядности дадим v3 имя i, т.к. похоже, что она используется как итератор. Переименовываем нажатием на имени клавиши N (Name).

Замечаем, что в цикле происходит взятие каждого символа из ключа, и передача его в пока неизвестную нам функцию. Предлагаю выяснить, что это за функция. Двойным щелчком переходим в нее. Видим там вызов еще одной функции, переходим туда. И, вот оно — обработка одиночного символа! (Здесь есть куча работы для клавиши R, но я лишь покажу сразу результат обработки).

Функция convert_char
char __cdecl convert_char(char C)
{
  char _C; // al@1

  _C = C;
  if ( C < '0' )
    return -1;
  if ( C <= '9' )
    return C - '0';
  if ( C < 'A' )
    return -1;
  if ( C <= 'Z' )
  {
    if ( C != 'I' && C != 'L' && C != 'O' && C != 'U' )
    {
      if ( C >= 'U' )
        _C = C - 1;
      if ( _C >= 'O' )
        --_C;
      if ( _C >= 'L' )
        --_C;
      if ( _C >= 'I' )
        --_C;
      return _C - '7';
    }
    return -1;
  }
  if ( C < 'a' || C > 'z' || C == 'i' || C == 'l' || C == 'o' || C == 'u' )
    return -1;
  if ( C >= 'u' )
    _C = C - 1;
  if ( _C >= 'o' )
    --_C;
  if ( _C >= 'l' )
    --_C;
  if ( _C >= 'i' )
    --_C;
  return _C - 'W';
}


Прекрасно! Теперь возвращаемся назад клавишей Esc до основной функции. Замечаем, что IDA сама переопределила для нас тип результата возвращаемого функцией обработки символа. Именуем дальше, обозначаем типы, и получаем следующий код цикла:

Цикл №2
    sum = 0;
    x5buf = v10;
    i = 0;
    do
    {
      C = key[i];
      if ( C != '-' )
      {
        new_c = j_convert_char(C);
        sum += new_c << 5 * (3 - itr);
        if ( itr == 3 )
        {
          x5buf += sprintf(x5buf, "%05lx", sum);
          sum = 0;
        }
      }
      ++i;
    }
    while ( i < 0x25 );


Если вы заметили, то тут есть одна интересная бага декомпилера. Видим, что переменная, обозначенная у меня как itr, совершенно не инкрементируется. Чтобы выяснить, что на самом деле происходит, жмем ПКМ -> Copy to assembly, и смотрим, где же используется наша itr. Выясняем: она инкрементируется прямо в этом цикле (чего и стоило ожидать), а до цикла — обнуляется. Учтем это при написании кейгена.

Теперь вторая часть функции проверки ключа… У нас осталась одна неисследованная функция, которая, кстати, очень похожа на функцию подсчета CRC32. Результат обработки (пусть и на скорую руку, но читаемый):

crc32
int __cdecl calc_crc32(char *my_key, int len)
{
  int i; // ebp@1
  unsigned int _xor; // ecx@1
  char *_my_key; // edi@2
  char C; // al@3
  signed int mask; // edx@3
  int B; // esi@3
  bool bit; // al@4
  int crc32; // eax@10
  signed int _len; // edx@10

  i = len;
  _xor = 0xFFFFFFFF;
  if ( len )
  {
    _my_key = my_key;
    do
    {
      C = *_my_key;
      --i;
      ++_my_key;
      mask = 1;
      B = (unsigned __int8)C;
      do
      {
        bit = (_xor & 0x80000000) == 0x80000000;
        _xor *= 2;
        if ( B & mask )
          bit = bit == 0;
        if ( bit )
          _xor ^= 0x4C11DB7u;
        mask *= 2;
      }
      while ( (_BYTE)mask );
    }
    while ( i );
  }
  crc32 = _xor & 1;
  _len = 0x1F;
  do
  {
    _xor >>= 1;
    crc32 = _xor & 1 | 2 * crc32;
    --_len;
  }
  while ( _len );
  return ~crc32;
}


Оставшийся кусок (преобразованный):
    crc32 = j_calc_crc32(my_key, 32);
    sprintf(crc32_, "%08x", crc32);
    result = strcmp(crc32_, &my_key[32]) == 0;


Этап пять: написание кейгена

Задача: определить, что именно происходило с ключом, чтобы написать обратную функцию. Писать я буду, вопреки здравому смыслу и выдаче HexRays, на Delphi, а Вы можете писать на том языке, который проще именно Вам.

Путем отладки выясняем произошедшее:
  1. Игре нужен ключ в 32 символа без дефисов (37 — с дефисами).
  2. Берется по четыре символа из ключа (не учитываются дефисы). Каждый из них пропускается через функцию convert_char и суммируется по формуле: sum += new_c << 5 * (3 — itr);
  3. Каждая такая сумма преобразовывается в lower-case хекс-строку (5 символов) и доклеивается до имеющейся (итого 40 символов);
  4. Берется CRC32 от первых 32 символов получившейся строки и сравнивается с оставшимися восемью символами полученной в предыдущем пункте строки;
  5. Если строки не совпали — наш ключ неправильный.


Обратное мышление:
  1. Написать функцию, преобразующую 40-символьный хэш обратно в ключ;
  2. Сгенерировать 32-символьный хэш;
  3. Посчитать от него 8-символьный CRC32;
  4. Склеить строки, полученные на этапах (2) и (3);
  5. Передать в функцию (1) — получим искомый ключ.


Мысли о преобразующей функции:
  1. Т.к. входной хэш был получен из восьми 5-символьных хэш-кусков, будем обрабатывать его так же, по "пятеркам";
  2. Каждая "пятерка" была получена из четырех символов ключа;
  3. Т.к. при каждом вычислении "пятерки", она сдвигалась на 5 бит влево, получается, что на каждый символ ключа приходится 5 бит;
  4. Внимательное рассмотрение кода функции convert_char приводит нас к такой мысли, что набор символов ключа ограничивается лишь символами набора "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
  5. Итого: 32 символа хэша генерятся из "пятерок". 32 % 5 = 24 целых символа и 2 в остатке — т.е. два символа нам придется просто догенерить.

Итоговый вариант функции, генерирующей хэш (Delphi)
function GenHash(len: byte): string;
var
  i, k: byte;
  sum: integer;
begin
  Randomize;
  Result := '';
  sum := 0;
  k := 0;

  for i := 1 to len do
  begin
    sum := sum + (Random(Length(alphabet)) shl ((3 - k) * 5));
    Inc(k);

    if k = 4 then
    begin
      Result := Result + AnsiLowerCase(Int2Hex(sum, 5));
      sum := 0;
      k := 0;
    end;
  end;

  Result := Result + 'a0'; // Решил не баловаться, а оставить два случайных хекс символа
end;


Далее считаем CRC32 от хэша:
var
  key, hash, crc32: string;

begin
  hash := GenHash(24);
  crc32 := Crc32b(hash); // нашел первый попавшийся модуль, реализующий данный хэш-алгоритм

Код функции-преобразователя:
Функция-преобразователь хэша в код
function Hash2Code(const Hash: string): string;
var
  s: string;
  five: integer;
begin
  Result := '';
  s := Hash;

  while Length(s) > 0 do
  begin
    five := Hex2Int(Copy(s, 1, 5));
    Delete(s, 1, 5);

    Result := Result + alphabet[(five and $F8000 shr 15) + 1] +
                       alphabet[(five and $07C00 shr 10) + 1] +
                       alphabet[(five and $003E0 shr 05) + 1] +
                       alphabet[(five and $0001F shr 00) + 1];
  end;
end;



Ну и, наконец, результирующее получение лицензионного ключа:

  key := Hash2Code(hash + crc32);
  lic_code := Format('%s-%s-%s-%s-%s-%s', [Copy(key, 1, 5),
                                              Copy(key, 6, 5),
                                              Copy(key, 11, 5),
                                              Copy(key, 16, 5),
                                              Copy(key, 21, 6),
                                              Copy(key, 27, 6)
                                              ]);

Проверяем, и… Ввод сгенеренного ключа активировал игру, пункт активации исчез!

Итоги

Главное при написании кейгена — уметь обратно думать. Т.е. уметь написать такой алгоритм, который будет обратным тому, который вы имеете. Это непростая задача, но, и она решаема в большинстве случаев.

P.S.

Возможно, статья получилась слишком сумбурной, не знаю. Главная идея, которую я хотел донести: кейген — не такая и сложная штука, если есть мозги, и желание вместе с усидчивостью.

P.P.S.

В следующей статье я опишу, как я писал кейген к другой игре — Unepic.
Support the author
Share post

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 76

  • UFO just landed and posted this here
      0
      Я понимаю. Поэтому для статьи я выбирал наиболее простой вариант, чтобы на нем можно было обучить.
      +13
      Самая интересная и крутая защита, которую приходилось отламывать:

      Прога под дос, переходит в защищенный режим, делает кучу телодвижений с таблицами дескрипторов, попутно распаковываясь, затем читает определенные сектора HDD через порты. Время: две недели почти круглосуточно, т.к. фактически приходилось эмулировать все действо в Win SoftICE. Назначение софта: некая оболочка для работы с швейным оборудованием.
        +4
        У меня тоже есть свой опыт «самой крутой» ненавесной защиты. Но описать ее кейгенинг в статье просто нереально, т.к. будет множество отсылок на «набитую руку» и «намыленный взгляд».
          +4
          Читать про такое всегда интересно.
          Нестандартные приёмы работы с ОС (а порой и оборудованием) и их обход — это читается как детектив.
          Так что пишите!
          0
          В каком году это было?
          Возможно ли было заэмулировать всё это дело в Bochs, к примеру? (там есть встроенный отладчик)
            0
            Более 10 лет назад, про Bochs тогда еще не слышал… Сомневаюсь что получилось бы проще.
          +5
          такое и защитой-то язык не поворачивается назвать. уж очень громкое название статьи :)
            –26
            Мне тоже непонятно, почему автор решил открыть тут филиал кряклаба для самых маленьких. Таких статей базилион на профильных сайтах. Но если пипл хавает, то пусть будет.
              +14
              Не так уж и много статей по кейгенингу. Их раз-два и обчелся.
                –1
                Давайте я поясню почему я к вам придираюсь. Мне кажется, что на хабр следует писать статьи, в которых описывается что то новое и эксклюзивное. Вот ВМПрот, например, еще публично никто не разобрал, это было бы интересно. А такие вот новичковые статьи про патчинг, кейгены из CRC32, которых реально сотни, я считаю не совсем тут к месту.
                  +7
                  Дайте мне в личку хоть одну статью про "кейгены из CRC32". Тогда я с вами соглашусь.

                  И почему новая статья о процессе кейгенинга известного продукта не является «новой и эксклюзивной»?
                    –4
                    exelab.ru/art/?action=list&f=8 Выбирайте на свой вкус. Куча статей о кейгенах к реальным известным продуктам. Продуктов много, а статей об интересных защитах единицы
                      +3
                      Читал я эти статьи. Не все из них простые для понимания и не ко всем из них уже можно достать ломаемый софт. Затем, я решил воспользоваться новыми (с 2005 года — даты последней статьи) представившимися возможностями в плане софта: IDA Pro (именно статья, в которой используется IDA Pro), HexRays, возможность втиснуть скриншоты. На exelab все статьи чисто текстовые.
                        +1
                        Спасибо за статью, всегда читаю такие с интересом.
                        На exelab-е есть возможность выкладывать статьи в файлах, например *.doc.

                        PS: покопался там в архивах и увидел свою статью… ностальгия по былым временам.
                    +2
                    VMProtect публично никто не хочет разбирать лишь потому, чтобы софт, защищенный им, можно было ломать, не опасаясь выхода новой версии протектора. Собственно, так со многими навесными защитами и происходит, если они достаточно тяжелые для снятия.
                      +2
                      У нас больше всего не расскрывают эти знания лишь потому что на этом можно рубить бабло. )
                        0
                        Именно!) Ведь опытный крякер в первую очередь думает о возможном заработке на своем умении, а потом уже о релизах для команды.
                        +1
                        А вот вы могли бы на пальцах объяснить, что такого делает VMProtect, что его настолько сложно взломать?
                        Ну то есть в программе всё равно где-то должна быть проверка вроде if (key.IsValid()), где можно всегда возвращать условный true.
                        Очевидно, что это не так, но в чём сложности и как именно запутывают не осознаю.
                          0
                          На самом деле VMProtect не такой уж и крутой протектор, его фишкой является возможность обфускации кода или интерпритация на собственных виртуальных машинах, такое сложно исследовать и патчить, так как условный переход может быть размазан на десяток ветвлений и т.п.
                        +20
                        И много в последнее время на Хабре нового и эксклюзивного? Внезапно — для меня этим оказались две статьи DrMefistO.
                        Почему вы отсылаете людей на всякие непонятные профильные ресурсы, если все отлично (и в тему) расписано тут?
                          –2
                          Туториалы по взлому — тема скользкая. Наверняка рано или поздно этот пост увидит и создатель игры (кто-нибудь ему/им ссылку-то точно скинет на Гугл Транслейт). И тогда это приобретет неприятный оттенок. Можно исследовать что угодно, но не стояло выкладывать алгоритм генерации на Хабр — это мерзко. Статья могла остаться интересной и без него.

                          А по поводу самой защиты — соглашусь с тем, кто сказал, что её тут и нет вовсе. Разработчики достаточно наивно подошли к этому вопросу. С верой в лучшее, так сказать.
                            +5
                            Вы правы. Поэтому некоторые моменты я сознательно опускал, чтобы прям целиком не выкладывать работающий код.

                            Но, в свое оправдание, я могу сказать, что авторам писал еще давным давно, с той целью, чтобы они улучшили алгоритм. Плюс, ажиотаж к игре прошел.
                              0
                              Пфф, есть мнение, что наличие кряка на продажах не особо отражается. Для массового софта.
                              К тому же rip этого лимбо на любом торрент-трекере можно найти и даже кейгеном пользоваться не придется.
                          +2
                          Для этого существуют crackme и keygenme. Можно найти уровень защиты на свой вкус, не затронув ничьих интересов.
                            +2
                            Верно. Но, порой хочется реальных «боевых» условий, т.е. пощупать именно софт из живой природы, а не специально для этого написанный.
                        +1
                        В моем понимании лицензионная защита — это то, каким образом сделана лицензионная система в программе.
                          +1
                          А где традиционное… «Вся приведенная в статье информация предназначена исключительно для образовательных целей. Все ваши действия вы производите на свой страх и риск. Автор не несет ответственности ни за какие последствия Ваших действий»?
                            0
                            Обновил)
                        +21
                        Покупайте хорошие инди игр, не ломайте их. Маленькие независимые разработчики игр, все же, в первую очередь думают, как игру сделать, а не защиту похитрее написать. Говорю от лица инди гейм девелоперов. :)

                        Вот статья про взлом защиты какого-нибудь энтерпрайз софта была бы намного интереснее и циничнее имхо.
                          0
                          Я полностью с вами согласен! Но, опять же, цель не в том, чтобы обидеть разрабов (им я писал, но ответа не получил), а чтобы кто-то не сделал это с плохой целью (например, барыженье ключами).
                            0
                            Можете сразу от интересного к полезному перейти — предложить разработчикам методы улучшения защиты ))
                              +1
                              Ответа на мое письмо, отправленное разрабам еще 12.04.13, я не получил. Значит улучшать защиту они не хотят. Да и смысла нету уже: все кто хотели, купили и сыграли.
                                +3
                                Я думаю, что они и без вас прекрасно понимают, что их игру легко сломать и не пытались это решить, в надежде, что найдутся люди, которые принципиально купят, даже если кряк будет лежать по соседней ссылке.
                                В любом случае, статься достаточно интересная, хоть и косвенно поощряет не самые порядочные пути в жизни.
                                  +8
                                  =) Я всегда считал и буду считать: "If you like it, you will buy it!"
                          +12
                          Выше в комментариях я встретил упоминание что это не защита и т.д.
                          Так вот что я хочу сказать, если Вы прочитали просто много статей про обход защиты и Вам кажется что это слишком просто, то попробуйте на примере автора обойти своими ручками ходить одну защиту, даже самую простую.
                          Автору спасибо, т.к. эта тема очень специфическая и очень интересная.
                            0
                            А если человек делает вывод не по прочитаным статьям, а по реальному опыту, тогда что?
                              0
                              Если кому — то просто, то не стоит заходить в топик. darked
                              REU Предполагается что Вы родились сразу со «скилом» Взлома?)
                                +2
                                Когда я начинал у меня не было интернета и статей ) а были диски с варезом и в каком-то из них было пару хтмл о отладке и патчинге винрара выдраных с какого-то сайта, пропатчил по ней винрар, немного понял суть, пропатчил вторую, третью,… программу. Потом появился кое какой интернет и желание кейгенить, решил попробовать на простеньком кейгенми, алгорит понимал, но как обратить нет, создал тему на кряклабе (одна с первых :) ) мне там объяснили (да, тогда еще там помагали новичкам :) ) я снова понял суть, и снова много практики во время которой постигаешь новые приемы и техники, всё. )
                                  0
                                  А я начинал вообще с перевода консольных игр на русский язык. Отсюда появилась тяга к реверсу.
                                  Дальше: статьи кряклаба, крякмисы… Писал много статей по патчингу популярных программ.

                                  А затем я понял, что патчи — не тот уровень уже. Надо бы и кейгены научиться делать. Так я и написал свой первый кейген.)
                                  Столько воды утекло.

                                  Потом, списавшись с одним челом по поводу ArtMoney (о которой я тоже как-нибудь напишу), я решил попробовать вступить в одну реверс-команду. Так я и стал участником той тимы, которая чуть ниже в комментах засветилась на скрине)
                            +5
                            Поддерживаю всех поддерживающих автора ) Спасибо за статью. Если кому — то просто, то не стоит заходить в топик.
                            Интересен не сам взлом как таковой — а как логическая задача. Интересно почитать ход мыслей, посмотреть примеры пользование инструментарием.
                              0
                              Скажите, а возможно ли модифицировать функцию sub_48D410 чтобы она возвращала всегда корректность ключа, так ли создаются таблетки?
                              Статья очень интересная, спасибо.
                                0
                                Именно так и создаются патчи/патченые ехе-шники.
                                  +1
                                  Да, можно, и так делают самые простые патчи.
                                  У этого способа есть один минус — меняется исполняемый код. Т.е. из другого места можно просканировать собственный код и понять, правили его или нет.
                                  К примеру, если где-то в дальше игре есть код, который вычисляет MD5 участка кода с защитой, и полученным числом расшифровывает какие-нибудь ресурсы, которые используются ближе к концу игры, то это может вызвать некоторое недовольство воспользовавшихся патчем (а обычно просто проверяют — запустилось или нет). Кстати, такое поведение вполне может стимулировать продажи игры.

                                  Кстати, ещё можно вызывать функцию CheckSerial() с заведомо неправильным номером и, если она вернула True, считать код пропатченным и действовать соответственно.
                                    +1
                                    Именно поэтому кейген всегда лучше! Но он и усилий больших требует, понятное дело.
                                      +1
                                      если где-то в дальше игре есть код, который вычисляет MD5 участка кода с защитой...

                                      … и подселяет неубиваемого скорпиона :)
                                        +1
                                        Это по аналогии с неубиваемым Шреддером?
                                        К счастью, я про него только слышал — у меня, насколько я помню, все Шреддеры убивались.
                                    +14
                                    А я сделал реверсинг картинке :)

                                    image
                                    Restorator 2007 — D:\TPORT\unepic_ko\limbo\limbo.exe


                                    Я прав?
                                      0
                                      Вы правы!) Просто не хотел папку палить) Ибо это цель следующей статьи) Да и имя тимы светится)
                                      Неудачно получилось))
                                        +1
                                        Только не _ko, а kg)
                                        0
                                        Простенькая защита.
                                        Не знал, что код можно так легко декомпилировать обратно в си, просто асмовый код читал сразу.
                                          +3
                                          Для того что бы «можно так легко декомпилировать обратно в си» нужно одать несколько килобаксов.
                                          +1
                                          первым делом, как обычно, выясняем, на чем написан главный исполняемый файл.
                                          Видим: Visual Studio 2008.


                                          Это ещё как бы ни о чём не говорит. Вот вам, для разнообразия, крякми, который Exeinfo PE распознаётся как «Microsoft Visual C++ 9.0 — Visual Studio 2008», но написан не на VS:

                                          CrackMeLV.7z

                                          Кстати, сможете отреверсить пароль, который приведёт к результату, отличному от Access Denied? Ну или как минимум модифицировать исполняемый файл, так, чтобы в ответ на любой пароль получить доступ (это сильно проще)?

                                          image

                                          Вирусов там нет, деструктивных действий код не выполняет, все рантайм библиотеки приложены, исходники естественно вышлю по запросу. Пароль существует и однозначно реверсится из кода.
                                            +4
                                            Это челендж?)
                                              0
                                              Челендж — если будет угодно.
                                              Я знаю, как бы я стал ломать эту штуку (но у меня подход предвзятый, поскольку сам её и написал), но любопытно, как вы подойдёте к снаряду (если есть время недолгими весенними вечерами). Там есть пара забавных мест. Зубодробительных алгоритмов для проверки пароля и обфускаций там не заложено, а изюминка — именно в использованном, скажем так, несколько нетрадиционном, средстве разработки.
                                              0
                                              Программы идентификаторы подсказывают, чем скомпилирована программа, в первую очередь.
                                                0
                                                Что-то оно не похоже на крякми…
                                                  0
                                                  Ну, тут либо крякать, либо кейгенить. Вполне можно.
                                                    0
                                                    Я к тому что внутри много чего лишнего
                                                      +1
                                                      Потому что на LabView
                                                        0
                                                        Об этом, и о многом другом я хотел написать позже)
                                                        0
                                                        Это так. Рантайм там весьма увесистый. Собственно в коде лишнего почти нет, хотя я немного «разнёс» места, где производится нажатие и собственно сравнение. Но чтобы туда добраться, придётся продраться через дебри рантайма, да.
                                                          +2
                                                          Ну ок, посмотрим.
                                                      0
                                                      Чем же не похоже? Мне казалось, крякми примерно так и выглядят — ну разве что поле «Password» — его кто «Key», кто «Serial» называет. А в остальном — есть исходный код, он скомпилирован в исполняемый файл. Все библиотеки, что там в архиве — они к среде исполнения относятся (их там два рантайма). По идее их надо было инсталляторами разворачивать, но я их бросил в ту же директорию для удобства.
                                                      Если крякми с вашей точки зрения по-другому должен выглядеть — напишите как.
                                                      Бывает ещё кейгенми — там обычно два поля, связанных алгоритмом и требуется написать программку, воспроизводящую зашитый туда алгоритм.
                                                    0
                                                    Я правильно понимаю, если игрушку защитить чем-то таким — написать кряк или ещё как-то поломать вообще не получится?
                                                      0
                                                      отсутвующий код или часть приложения никогда ни при каких условиях не покидает доверенные сервера

                                                      Как минимум, если это правда, приложение без доступа в инет вообще будет неработоспособно (очень сомнительная защита).

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

                                                      Если наврали — то как минимум одному человеку придется таки купить, ну а потом собрать «полную локальную версию» — дело техники )
                                                        0
                                                        Ну, я так понял что защита для сетевых игрушек, которые без инета и так не работают нормально
                                                          0
                                                          Как правило, в сетевых игрушках и так легко вычислить\забанить левых пользователей не особо изощряясь, поэтому польза от такой навороченной защиты сомнительна. Неизвестно, есть ли у них вообще поддержка js и пр. В примере на сайте у них «Сапер» и Notepad++ на сях, и метки именно в код в VS встроены, похоже они ориентированы на защиту «локального» десктопного софта.

                                                          Но вообще все это попытки продать то, что умерло 10 лет назад, под новым соусом…
                                                            0
                                                            Про js не знаю, на сайте вроде ничего нету про такое. Про игрушки знаю только что тренировались на Doom 3 и на TTD, вроде норм работает.

                                                            А что 10 лет назад умерло, если не секрет?
                                                              0
                                                              Ну весь этот рынок навесных защит, armadillo, execryptor и т.п. Вообще в первую очередь «умер» рынок десктопного софта, все ушло в веб и на моб. платформы…
                                                                0
                                                                А, понял, спасиб
                                                                  0
                                                                  Вы назвали 2 прота, которые сами уже умерли и не поддерживаются )
                                                        0
                                                        Выше правильно заметили про ассиметричную криптографию. Смотрел как-то софт, а там обычная RSA, простенько и со вкусом. Повезло, что 256-битная оказалась, удалось разложить. А начиная самое позднее с 1024 можно тушить свет.
                                                          0
                                                          Эм, это имеется в виду однонавправленное шифрование серийника в наборе процедур которые скажут «серийник валиден, работай на здоровье»?
                                                            0
                                                            Примерно так. Серийник (с дополнительными данными по вкусу, типа имени клиента) шифруется приватным ключем, а программа пытается расшифровать публичным.
                                                              0
                                                              По типу защиты примененной в FL Studio от Image Line?

                                                        Only users with full accounts can post comments. Log in, please.