Кряк написал; хочу кейген!

Тема в разделе "WASM.RESEARCH", создана пользователем DEEP, 23 сен 2011.

  1. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Доброго времени суток воинам Дзена.

    Есть одна программа, которую я только что запатчил для разблокировки без регистрации.
    Но моя радость была неполной (©), т.к. захотелось всё-таки подобрать алгоритм, по которому генерируются для неё ключи.

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

    Но у меня нет ни валидного ключа, ни принципиального понимания того, как ломаются такие защиты.
    Максимум, чего я добился — заставил ключ проходить первый этап проверки (соответствовать маске #####-#####-#####-#####).
    А, ещё узнал, что верность введённого ключа определяется после вызова проверяющей функции как неравенство AL ≠ BL.
    Ну и ещё, сначала символы ключа заменяются по принципу «тарабарской грамоты»: строится биективное отображение алфавита в себя.
    А затем следует какое-то адовое преобразование на несколько десятков экранов, которое, если просто позволить ему выполняться, оставив memory-breakpoint на строке с введённым ключом, идёт где-то восемнадцать секунд.

    Ну так вот.
    Прошу советов мудрых и статей грамотных, как не погрязнуть в этом километре кода, а ухватить суть метода шифровки.
    Все туториалы по созданию кейгенов, что нашёл в Сети, покрывают лишь те типы защит, что используют «тупое» сравнение введённого ключа со сгенерированным, а это здесь явно не сработает.
     
  2. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    Тема очень сложная, и вот так спроста ничего не получится. Поэтому могу лишь дать основные советы:
    1) Начать нужно, как говорится, с конца. Наверняка BL = 0, а тип функции BOOLEAN, т.е. ищете где в конце функции задаётся её результат, и смотрите как к этой точке прийти.
    2) Наверняка весь код подбирать не придётся. Часто бывает, что несколько частей можно сгенерировать случайным образом, а оставшиеся уже подбирать.
    3) Чем глубже можно зайти трейсингом, тем "правильнее" введённый код (как правило, для подобных случаев, где можно обойтись патчем одного байта). Смотрите что нужно в нём изменить, чтобы зайти ещё глубже.
     
  3. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    DEEP
    Может я не в теме но imho зачем искать единственно правильный?
    может, если уж кряк осмыслен как-то, то позаботиться о том
    чтобы AL ≠ BL было верно при любых раскладах?
     
  4. 100gold

    100gold New Member

    Публикаций:
    0
    Регистрация:
    26 фев 2010
    Сообщения:
    165
    Самое первое что нужно сделать - это выдрать из бинарника функцию проверки ключа.
    Теперь когда есть некоторая f(key) которая возвращает true если ключ правильный можно сделать следующее.
    - Попробовать обратить алгоритм, т.е. найти некоторое подобие f^-1. На простых функциях сработает.
    - Можно перебирать входные значения пока функция не вернёт true
    - Если перебирать слишком долго, то придётся покопаться во внутренностях функции. И тогда
    1) Можно сократить перебор ключей выяснив например что часть бай должна быть строго определённой.
    2) Можно попытаться "оптимизировать" функцию, убрав оттуда искусственное замедление работы
    3) Попытаться переделать функцию, чтобы возвращала число от 0..1, характеризующее степень правильности ключа. Например, если функция выглядит как
    Код (Text):
    1. for(i=0;i<check_count;++)
    2. {
    3.    if(!some_check(key,i))
    4.    {
    5.       return false;
    6.    }
    7.    some_transform(key,i);
    8. }
    То, очевидно, что чем больше проверок прошло, тем "правильнее" ключ.
    После того как функция преобразована, можно применить какойнить метод оптимизации, например генетический алгоритм.
     
  5. newbie

    newbie New Member

    Публикаций:
    0
    Регистрация:
    2 дек 2008
    Сообщения:
    1.246
    А что за программа то собственно? ссылки в студию!
     
  6. litrovith

    litrovith Member

    Публикаций:
    0
    Регистрация:
    20 июн 2007
    Сообщения:
    509
    DEEP, ну *ля и пишите кейген!
    Лохмать километры кода и пытайся понять "суть метода шифровки".
     
  7. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    litrovith,
    да, к такому безрадостному выводу я и сам пришёл.
    Сейчас медленно, но верно составляю карту функций, завязанных в генерации.

    newbie,
    Zuma Deluxe, какая-то свежая версия, два дня назад скачанная:
    http://www.playzuma.ru/game-10.html

    Если кому-то надо, вот UDD-файл: в нём уже есть некоторые комментарии, хотя основная информация (вход-выход, общий алгоритм работы, вызовы внутренние и внешние [т.е. кого вызываем из тела функции, и кто вызывает нас]) у меня в бывшей тетрадке по урматам.
    Опять же, если вдруг кому надо, могу сфотографировать.

    [UPD] что-то не прикрепляется.
    В общем, спрашивайте, коли нужен, вышлю на емыло.
    Вкратце, суть кряка — в замене MOV BL, AL (8A D8) на MOV BL, 1 (B3 01) по адресу 4045B1.

    …К слову: заменяются, как оказалось, далеко не все символы, а только 1, 0, o и O (в порядке следования по коду функции разбора).
     
  8. PSR1257II

    PSR1257II New Member

    Публикаций:
    0
    Регистрация:
    25 июн 2011
    Сообщения:
    228
    DEEP

    Это на самом деле единственный и часто самый быстрый способ. Все попытки (если целью является именно криптоанализ а не патченг) сократить время анализа за счет скипанья части кода скорее всего только увеличат общее время.

    Только нужно не "составлять карту" а в дизассемблере (IDA/hview/etc) найти самую внешнюю функцию и затем - все критичные которые она вызывает. Далее выдергиваете все эти куски (пока думать много не нужно) и пытаетесь их скомпелировать асссемблером.

    Когда конпеляция будет успешна (те не останеца неотрезольвенных вызовов - а вызовы ойпишек типа memcpy нужно также аккуратно поддержать) нужно будет проверить что все это работает точно так же как и в внутри проги.

    После этого нужно переписать (подстрочно или сразу) все на C/etc. Так придет понимание чего тут происходит, тут и начинаецца собственно анализ - оценка можно ли брутить, нет ли слабостей и так далее.

    PS То, что что-то там работает 18 секунд и это здоровая функция - это может быть что-то типа многократно вызванного MD5, например:

    Код (Text):
    1. memcpy(&hash, &pass, len);
    2. for (i=0; i<TOO_BIG_NUM; i++) { hash= MD5(hash); }
     
  9. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    PSR1257II,
    хм. так а я не скипаю код, а просто составляю дерево вызовов, с описанием того, что какая функция делает, будучи из данного места вызванной. Пока что прошёл где-то треть (если дальше той точки, докуда прокомментировал, запустить с F9 — проходит секунд десять-двенадцать). Наткнулся на весьма любопытный XOR, пока что для захардкоженной строки "06NBBO...E4GXf3O0" и также захардкоженного паттерна "10325476-98BADCFE-EFCDAB89-67452301".

    А патчинг-то уже давно и успешно проведён. Вопрос в том, что мне этого мало =)
     
  10. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    DEEP
    Покопался, выяснил следующее:
    На основе данных (это данные из файла properties\partner.xml и часть данных зашита в Zuma.exe) вычисляется MD5 хеш.
    Файл properties\partner.xml.sig должен содержать этот хеш, зашифрованный RSA.
    Закрытого ключа нет, кейген написать невозможно.
     
  11. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Ezrah,
    Да, то что это MD5, я уже понял, когда увидел в коде добавление в конец шифруемого сообщения байта 0x80 (а сам паттерн, про который я уже писал выше, меня почему-то вообще не смутил, видимо я слишком сильно хотел спать).

    Как считаете, разумно ли попробовать сгенерировать набор «радужных таблиц», и попробовать этот хэш поатаковать?
    Набор допустимых символов из бинаря вытащен: 234679ACDEFGHJKLMNPQRTUVWXYZ.
     
  12. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Кстати, сам файл partner.xml не так уж и важен.
    Просто в нём содержится информация о зарегистрированности/незарегистрированности продукта.

    А важен сам лицензионный ключ, который состоит из четырёх групп по пять символов, разделённых дефисом.
    От него тоже считается, насколько понимаю, MD5-хэш, и сравнивается с хэшем 81E1D2F0-B78252DE-9D792422 (не удивляйтесь, что здесь всего 96 бит, вместо 128 — крайние 32 бита, так называемое число D из вектора ABCD, алгоритм проверки просто выкидывает, в силу работы некоей самопильной, как понимаю, надстройки над MD5 — см. функцию 41D510).
     
  13. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    DEEP
    http://www.mechanism8.com/popcap/docs/html/_sexy_app_8cpp-source.html
    Validate проверка введенного пароля в окне регистрации;
    CheckSignature проверка зарегистрированности продукта.
     
  14. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Вот это да!
    Да, теперь согласен (и где Вы только это откопали, знал бы — не дебажил бы вообще, т.к. пока что дошёл только до строки 110, если смотреть по исходнику, т.е. про RSA даже не догадывался).

    Тем не менее, положим что это RSA.
    Но ведь, насколько я понимаю, 42BF94023BBA6D040C8B81D9 и D99BC76AB7B2578738E606F7 — это всего лишь 96-битные ключи (в отличие от принятых по стандарту RSA 768- и 1024-битных).
    Если их факторизовать — то можно найти и вожделенный закрытый ключ, правильно?
    Или я упускаю какую-то важную деталь?
     
  15. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    В общем, первое из чисел разложил и вычислил приватную экспоненту: 18227306851051505561502625853d.
    Сейчас попробуем чего-нибудь нагенерить.
     
  16. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Ура, товарищи!
    Бессонная ночь себя оправдала: мне удалось подобрать алгоритм, и вручную вычислить первый подходящий серийник.
    Для успешной регистрации с выбранным именем (по которому и генерится ключ) нельзя его вводить в окошко, т.к. имена пользователям гадкая программа придумывает сама, и все они весьма неблаговидны, как например "E.....A..O6NbBo....E4GXf3O0..0.sB3A.....". Поэтому кейген, по задумке, будет сам править ключ реестра, ответственный за имя.

    Итак, для имени DEEP, серийник будет иметь вид 6XZFW-MLCN4-GURDL-MENPW.
    Алгоритм генерации — под катом:
    Код (Text):
    1. алгоритм получения «совместимого» MD5 (CMD5):
    2. 1. посчитать MD5 от строки "ИМЯПОЛЬЗОВАТЕЛЯ",0Ah,"ZUMA"
    3. 2. выкинуть последний DWORD, и записать оставшееся в обратном порядке байтов.
    4. 3. по-WORD-ово пройтись по полученному, и применить (чит.: скопипастить в кейген) ОЧЕНЬ ТУПОЙ сдвиг; см. 41D280.
    5.  
    6. далее, следует:
    7. 4. снова поменять порядок байт в CMD5.
    8. 5. вычислить от CMD5 ModPow(D, N), где D = 3AE5465C52D0C4C0A8FE303Dh, N = 42BF94023BBA6D040C8B81D9h, E = 11h (в программах — Decrypt).
    9. 6. то, что получилось — это то самое число, в которое раскрывается серийник (для имени DEEP: 27C41585 8EBD8A7C CA41EDE0).
    10.    (если вставлять это число прямой правкой памяти, надо не забыть про обратный порядок байт: E0ED41CA 7C8ABD8E 8515C427).
    11. 7. последовательным делением на 28, подставляя остатки по таблице (234679ACDEFGHJKLMNPQRTUVWXYZ, 2 соответствует индексу 0, таким образом двоек в серийнике заведомо нет), раскрыть серийник.
    И, кстати, вопрос к администрации: как на форуме относятся к релизам программ подобного не слишком легального толка?
    Иными словами, когда напишу автоматический кейген, можно(нужно?) ли выкладывать его сюда?

    P.S. Ezrah, премного благодарен за утёкший исходник фреймворка; сам бы нипочём не нашёл =)
    Жаль только, что там лишь часть кода шифровки-расшифровки. Хочется без напряга посмотреть, как генерится имя пользователя…
     
  17. PSR1257II

    PSR1257II New Member

    Публикаций:
    0
    Регистрация:
    25 июн 2011
    Сообщения:
    228
    DEEP

    Good job, mate.
     
  18. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    DEEP
    А каким продуктом факторизовали, если не секрет? или самопал?
     
  19. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    gorodon, для факторизации использовал RSA Tool от TMG (находится в аттаче, поскольку я на эту полезность набрёл только на странице где-то десятой в выдаче поисковика), для готовой реализации ModPow — вот этот онлайновый калькулятор (учтите — E там задаётся шестнадцатирично).
     
  20. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Ах да. RSA Tool, кроме разложения на множители, поддерживает ещё и создание случайных RSA-ключей.
    Для того, чтобы разблокировать эту функцию, в папку к RSA Tool нужно добавить файл rsaseed.rnd (находится в аттаче), задающий, насколько понимаю, зерно ГСЧ.