+ Reply to Thread
Results 1 to 5 of 5

Thread: Написание кейгена для keygenme #00 by KSDR

  1. #1
    ARCHANGEL's Avatar

    Default Написание кейгена для keygenme #00 by KSDR

    Написание кейгена для keygenme #00


    Знаете, даже не знаю, с чего начать свой рассказ. Пока я дни и ночи напролёт реверсил сиё творение, в моей голове зародилось и погибло несколько вариантов этой статьи, а сейчас, когда кейген лежит передо мной (и действительно генерит валидные серийники) я как-то растерялся…

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


    Начало


    Когда я увидел на форуме предложение закейгенить этот keygenme #00, я даже особо и не проникся идеей загрузить его в отладчик, так как таких кейгенми на http://www.crackmes.de состав, и если каждый пробовать сломать, то и здоровья не хватит. Но для интереса, конечно, качнул это добро. Когда я запустил его и увидел в заголовка главного диалогового окна надпись: KeygenMe for gwsoft.ahteam.org, мой интерес возрос. Стало любопытно, какое отношение это программное творение имеет к AHTeam’у. Правда, на этот вопрос я так и не получил исчерпывающего ответа, но не это главное. А главное - я скачал его и начал реверсить.


    Инструментарий


    Обязательным инструментом, пожалуй, в данном случае является IDA + HexRays. Дальше отладчик по вкусу – я использовал OllyDebug. В качестве компилятора я выбрал Microsoft Visual Studio 2008. 2008 потому, что она наиболее стабильна (если верить людям, которые использовали всё разнообразие версий этого пакета, я же могу сравнить её только с 6 версией – по сравнению с ней действительно стабильна), кейген написан на С (правда, на весьма корявом, за что просьба сильно не пинать) с ассемблерными вставками. Но, опять же, вас это ни к чему не обязывает – вы можете пользоваться тем компилятором, который удобен лично вам. Ещё я использовал Pe Tools, но это уже только по причине моей лени. Как вы сами увидите позже, в этом не было особой необходимости.

    С инструментами определились – начинаем исследования.


    Первичный досмотр


    Это лишь анализ, но пока ещё не взлом.

    Загрузив программу в отладчик, останавливаемся на ЕР:

    Code:
     
    00401000 >/$  6A 00         PUSH 0                                   ; /pModule = NULL
    00401002  |.  E8 5B070000   CALL <JMP.&kernel32.GetModuleHandleA>    ; \GetModuleHandleA
    00401007  |.  A3 60304000   MOV DWORD PTR DS:[403060],EAX
    0040100C  |.  6A 00         PUSH 0                                   ; /lParam = NULL
    0040100E  |.  68 2B104000   PUSH keygenme.0040102B                   ; |DlgProc = keygenme.0040102B
    00401013  |.  6A 00         PUSH 0                                   ; |hOwner = NULL
    00401015  |.  68 E8030000   PUSH 3E8                                 ; |pTemplate = 3E8
    0040101A  |.  FF35 60304000 PUSH DWORD PTR DS:[403060]               ; |hInst = NULL
    00401020  |.  E8 13070000   CALL <JMP.&user32.DialogBoxParamA>       ; \DialogBoxParamA
    00401025  |.  50            PUSH EAX                                 ; /ExitCode
    00401026  \.  E8 31070000   CALL <JMP.&kernel32.ExitProcess>         ; \ExitProcess
    Здесь абсолютно бесхитростно вызывается DialogBoxParamA, поэтому нас дальше будет интересовать исключительно то, что происходит в DlgProc, а именно – по адресу 0040102B.

    WM_INITDIALOG нас в данном случае не интересует:

    Code:
     
    00401034   .  3D 10010000   CMP EAX,110
    00401039   .  75 25         JNZ SHORT keygenme.00401060
    WM_COMMAND более интересен, если пользователь не выбрал Exit, то последний переход не выполняется:

    Code:
     
    00401060   > \3D 11010000   CMP EAX,111
    00401065   .  0F85 E9010000 JNZ keygenme.00401254
    0040106B   .  8B45 10       MOV EAX,DWORD PTR SS:[EBP+10]
    0040106E   .  3D EE030000   CMP EAX,3EE
    00401073   .  0F85 C4010000 JNZ keygenme.0040123D
    Необычный момент – кейгенми первым делом считывает серийник, а не имя пользователя:

    Code:
     
    00401079   .  6A 23         PUSH 23                                  ; /Count = 23 (35.)
    0040107B   .  8D45 BA       LEA EAX,DWORD PTR SS:[EBP-46]            ; |
    0040107E   .  50            PUSH EAX                                 ; |Buffer
    0040107F   .  68 ED030000   PUSH 3ED                                 ; |ControlID = 3ED (1005.)
    00401084   .  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
    00401087   .  E8 B8060000   CALL <JMP.&user32.GetDlgItemTextA>       ; \GetDlgItemTextA
    Теперь хитроумным способом проверяется длина введенного серийника. Проверка завершается успешно в случае, если в конце проверки еах равен нулю:

    Code:
     
    00401094   .  8945 B4       MOV DWORD PTR SS:[EBP-4C],EAX
    00401097   .  0FAFC0        IMUL EAX,EAX
    0040109A   .  C1C8 36       ROR EAX,36                               ;  Shift constant out of range 1..31
    0040109D   .  8BD8          MOV EBX,EAX
    0040109F   .  35 CA593201   XOR EAX,13259CA
    004010A4   .  0FAFDB        IMUL EBX,EBX
    004010A7   .  81EB CA593201 SUB EBX,13259CA
    004010AD   .  2BC3          SUB EAX,EBX
    004010AF   .  2D 94B35402   SUB EAX,254B394
    Признаюсь, что вначале для эстетики я хотел решить это уравнение на листе бумаги, а потом показать, что в школе у меня была пятёрка по математике. Но, видимо, пятёрка была мне подарена, поэтому пришлось идти другим путём. Этот код я прямо в отладчике запатчил следующим образом:

    Code:
     
    00401094      FF45 B4       INC DWORD PTR SS:[EBP-4C]
    00401097      8B45 B4       MOV EAX,DWORD PTR SS:[EBP-4C]
    0040109A      0FAFC0        IMUL EAX,EAX
    0040109D      C1C8 36       ROR EAX,36                               ;  Shift constant out of range 1..31
    004010A0      8BD8          MOV EBX,EAX
    004010A2      35 CA593201   XOR EAX,13259CA
    004010A7      0FAFDB        IMUL EBX,EBX
    004010AA      81EB CA593201 SUB EBX,13259CA
    004010B0      2BC3          SUB EAX,EBX
    004010B2      2D 94B35402   SUB EAX,254B394
    004010B7    ^ 75 DB         JNZ SHORT 00401094                       ;  keygenme.00401094
    004010B9      90            NOP
    Т.е. по адресу [EBP-4C] я записал нуль, потом на адресе 004010B9 поставил брейкпоинт, и когда он сработал, на вершине стека лежала длина пароля – 32 символа. Вот такой минибрут.

    Теперь, наконец-то, считывается имя пользователя:

    Code:
     
    004010BA   .  6A 23         PUSH 23                                  ; /Count = 23 (35.)
    004010BC   .  8D45 DD       LEA EAX,DWORD PTR SS:[EBP-23]            ; |
    004010BF   .  50            PUSH EAX                                 ; |Buffer
    004010C0   .  68 EB030000   PUSH 3EB                                 ; |ControlID = 3EB (1003.)
    004010C5   .  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
    004010C8   .  E8 77060000   CALL <JMP.&user32.GetDlgItemTextA>       ; \GetDlgItemTextA
    Проверяется, не равна ли длина имени нулю, и если не равна, то имя копируется по адресу 00403064:

    Code:
     
    004010CD   .  0BC0          OR EAX,EAX
    004010CF   .  0F84 54010000 JE keygenme.00401229
    004010D5   .  8BC8          MOV ECX,EAX
    004010D7   .  8D75 DD       LEA ESI,DWORD PTR SS:[EBP-23]
    004010DA   .  BF 64304000   MOV EDI,keygenme.00403064
    004010DF   .  F3:A4         REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
    Дальше следует функция, которая вычисляет хэш от имени. Эту функцию я ласково назвал StrongCreateHash. С ней у меня возникло очень близкое знакомство в процессе реверсинга, но об этом позже.

    Code:
     
    004010E1   .  E8 14020000   CALL keygenme.004012FA
    Теперь 42h байта неизвестного пока содержания перемещаем из адреса 0040301A в 004011BC.

    Code:
     
    004010E6   .  B9 42000000   MOV ECX,42
    004010EB   .  BE 1A304000   MOV ESI,keygenme.0040301A
    004010F0   .  BF BC114000   MOV EDI,keygenme.004011BC                ;  Entry address
    004010F5   .  F3:A4         REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
    Сами эти байты вот:


    Code:
     
    0040301A  1F 7B 31 17 EF EF 04 40 E7 EF F6 FB 45 40 23 EF  *{1пп 
    @зпцыE@#п
     
    0040302A  F2 F7 F6 05 F4 E9 FC 05 F4 FD EF F2 F3 40 ED EF  тчцфйьфэпту@нп
     
    0040303A  E9 40 F7 EF EF 04 40 03 F6 05 03 FB F9 F6 45 60  й@чпп 
    @ 
     
    ц 
     
    ыщцE`
     
    0040304A  F8 9F 55 20 60 F8 71 63 60 60 5F E9 58 78 08 59  шџU `шqc``_йXxY
    0040305A  60 60
    Считываем указатель на длину серийника, разыменовываем, получая тем самым длину серийника, и делим её на 2:

    Code:
     
    004010F7   .  8D4D B4       LEA ECX,DWORD PTR SS:[EBP-4C]
    004010FA   .  8B09          MOV ECX,DWORD PTR DS:[ECX]
    004010FC   .  D1E9          SHR ECX,1
    Получаем адрес серийника и крутим цикл - счётчик цикла в есх равен 16. В цикле мы из серийника читаем по два байта, от символа цифры вычитаем 30h, от другого - 37h, после младшему байту делаем ROL AL,4, складываем два байта и пишем назад в серийник.

    Code:
     
    004010FE   .  8D75 BA       LEA ESI,DWORD PTR SS:[EBP-46]
    00401101   .  8BFE          MOV EDI,ESI
    00401103   >  66:AD         LODS WORD PTR DS:[ESI]
    00401105   .  3C 39         CMP AL,39
    00401107   .  7F 04         JG SHORT 0040110D                        ;  keygenme.0040110D
    00401109   .  2C 30         SUB AL,30
    0040110B   .  EB 02         JMP SHORT 0040110F                       ;  keygenme.0040110F
    0040110D   >  2C 37         SUB AL,37
    0040110F   >  80FC 39       CMP AH,39
    00401112   .  7F 05         JG SHORT 00401119                        ;  keygenme.00401119
    00401114   .  80EC 30       SUB AH,30
    00401117   .  EB 03         JMP SHORT 0040111C                       ;  keygenme.0040111C
    00401119   >  80EC 37       SUB AH,37
    0040111C   >  C0C0 04       ROL AL,4
    0040111F   .  02C4          ADD AL,AH
    00401121   .  AA            STOS BYTE PTR ES:[EDI]
    00401122   .^ E2 DF         LOOPD SHORT 00401103                     ;  keygenme.00401103
    То, что случилось с серийным номером, я (опять всё также ласково) назвал преобразованием серийника. От этого преобразованного серийника вычисляем хэш, но уже с помощью функции WeakCreateHash. Простите, если мои названия слабо отражают суть алгоритма, но я старался. Вот и сам вышеописанный код:

    Code:
     
    00401124   .  8D45 BA       LEA EAX,DWORD PTR SS:[EBP-46]
    00401127   .  E8 3D010000   CALL 00401269                            ;  keygenme.00401269
    Из хэша серийного номера мы вычисляем некое подобие контрольной суммы. Назовём её просто CRC. Если принять во внимание то, что хэш состоит из четырёх DWORD’ов, то CRC=DWORD1 - DWORD2 xor DWORD3 + DWORD4:

    Code:
     
    0040112F   .  8B18          MOV EBX,DWORD PTR DS:[EAX]
    00401131   .  2B58 04       SUB EBX,DWORD PTR DS:[EAX+4]
    00401134   .  3358 08       XOR EBX,DWORD PTR DS:[EAX+8]
    00401137   .  0358 0C       ADD EBX,DWORD PTR DS:[EAX+C]
    Полученное значение взаимодействует с хэшем имени: CRC xor DWORD1 + DWORD2 - DWORD3 xor DWORD4. Здесь DWORD1 и т.д. – значения хэша имени:

    Code:
     
    0040113A   .  331D 64304000 XOR EBX,DWORD PTR DS:[403064]
    00401140   .  031D 68304000 ADD EBX,DWORD PTR DS:[403068]
    00401146   .  2B1D 6C304000 SUB EBX,DWORD PTR DS:[40306C]
    0040114C   .  331D 70304000 XOR EBX,DWORD PTR DS:[403070]
    Результирующее значение записывается в EDX, после чего вычисляется значение CRC1 (опять моё название) и записывается в EDX:

    Code:
     
    0401152   .  8BD3          MOV EDX,EBX
    00401154   .  C1CA 10       ROR EDX,10
    Т.е. сейчас в EDX - CRC1, а в EBX – CRCfixed. Отличаются они только тем, что их младшее и старшее слова стоят в разном порядке. Теперь получаем начала загадочных 42h байт и крутим цикл расшифровки каждого байта. DecryptByte = Byte - CRCfixed [1] xor CRC1[0] - CRCfixed [0] + CRC1[1]:

    Code:
     
    00401157   .  BE BC114000   MOV ESI,4011BC                           ;  Entry address
    0040115C   .  8BFE          MOV EDI,ESI
    0040115E   .  B9 42000000   MOV ECX,42
    00401163   >  AC            LODS BYTE PTR DS:[ESI]
    00401164   .  2AC7          SUB AL,BH
    00401166   .  32C2          XOR AL,DL
    00401168   .  2AC3          SUB AL,BL
    0040116A   .  02C6          ADD AL,DH
    0040116C   .  AA            STOS BYTE PTR ES:[EDI]
    0040116D   .^ E2 F4         LOOPD SHORT 00401163
    Первые 20h расшифрованных байт переписывают хэш имени:

    Code:
     
    0040116F   .  BE BC114000   MOV ESI,keygenme.004011BC                ;  Entry address
    00401174   .  BF 64304000   MOV EDI,keygenme.00403064
    00401179   .  B9 20000000   MOV ECX,20
    0040117E   .  F3:A4         REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
    Для первых 16 расшифрованных байт применяется StrongCreateHash:

    Code:
     
    00401180   .  E8 75010000   CALL 004012FA                            ;  keygenme.004012FA
    Если значения хэша совпали с константами, то выполняем расшифрованные байты как код, и они должны выполняться, не генерируя исключений. Любое исключение будет для кейгенми последним, т.к. ни структурированная, ни векторная обработка исключений в нём не применяется:

    Code:
     
    00401185   .  812D 64304000>SUB DWORD PTR DS:[403064],A3C54A91
    0040118F   .  75 29         JNZ SHORT 004011BA                       ;  keygenme.004011BA
    00401191   .  812D 68304000>SUB DWORD PTR DS:[403068],C2F7E86A
    0040119B   .  75 1D         JNZ SHORT 004011BA                       ;  keygenme.004011BA
    0040119D   .  812D 6C304000>SUB DWORD PTR DS:[40306C],4084B41C
    004011A7   .  75 11         JNZ SHORT 004011BA                       ;  keygenme.004011BA
    004011A9   .  812D 70304000>SUB DWORD PTR DS:[403070],96A2D976
    004011B3   .  75 05         JNZ SHORT 004011BA                       ;  keygenme.004011BA
    004011B5   .  E8 02000000   CALL 004011BC                            ;  keygenme.004011BC
    На этом первичное исследование кода закончено. Настало время продумать стратегию дальнейших действий, которые должны привести нас к кейгену.


    Атака перебором и радужные таблицы


    Очевидно, что серийник должен обеспечивать правильную расшифровку байт по адресу 004011BC. Первоначально я хотел обратить функцию StrongCreateHash, чтоб по хэшу получать plain-text. Функция оказалась достаточно длинной, но через неделю я даже составил псевдокод на С её обратного аналога. Проблема в том, что работал бы этот аналог только лишь в том случае, если бы мне удалось решить систему нелинейных уравнений (соответственно, с большим количеством коллизий), а потом из получившихся вариантов отфильтровать прямым перебором правильные значения. Но куда уж мне – я даже уравнение длины серийника брутил. Так что со мной всё ясно – этот метод был от меня далёк, как секс от Советского Союза.

    Но тут я понял, что, на самом деле, всё гораздо проще. CRC1 используется для манипуляций над зашифрованными байтами, и если мы точно знаем правильное значение CRC1, то мы однозначно получим правильные расшифрованные значения.

    Если вы прокрутите немного вверх, то можете увидеть, что для декриптовки кода по адресу 004011BC используется ещё одно значение, названное мной как CRCfixed. Но, как я упоминал ранее, на самом деле, используется лишь младшее слово как CRC1, так и CRCfixed. Т.е. два младших слова обеих переменных. Но всё ещё упрощается, когда мы видим, что старшее слово CRC1 – это младшее слово CRCfixed.

    Теперь суть ясна – наша задача методом перебора найти все валидные значения CRC1. «Почему все?» - спросите вы. Все потому, что их гораздо больше одного. Их много. Насколько много – навскидку сказать сложно, но после полного перебора мы будем знать точно.

    Алгоритм перебора сводится к тому, что мы с помощью IDA Pro рипаем код StrongCreateHash, немного подправляем его, потому что в keygenme код этой функции настроен на жёстко прописанные в него смещения. далее делаем 4 вложенных цикла, каждый из которых ищет свой байт. В случае, когда все 4 байта, сложенные в правильном порядке, дают валидное значение CRC1, то мы записываем эти значения в файл, который я назвал RainbowTables.dat. Для чего нужен этот файл, и что он из себя представляет? Всё очень просто – это радужные таблицы.

    Возможно, вы слышали, что радужные таблицы применяются для быстрого восстановления паролей из хэшей. В частности, радужные таблицы применяются против алгоритма md5, т.к. этот алго очень распространён на сегодня. Как выглядит их применение? Да очень просто – для наиболее популярных слов (god, admin, password и т.д.) вычисляются и сохраняются в таблице значения хэша. Далее, когда на вход поступает хэш, то его значение ищется в таблице, и если совпадение найдено – хэш удачно взломан. Думаю, преимущества и недостатки этого метода вы оцените сами.

    У нас же радужные таблицы применяются в двух целях – для ускорения нахождения правильного значения CRC1, а также для рандомизации ключей. Сейчас я постараюсь объяснить, что я имел ввиду.

    Понятное дело, что первый раз нам придётся перебирать значения CRC1, но это – достаточно длительная операция. У меня она занимает около 20 минут (2ГГц на двух ядрах Intel Pentium). Возможно, у вас она будет выполняться быстрее, а, возможно, и нет. Но представьте, что бы это был за кейген, который бы выдавал надпись: «Генерируется ключ, подождите 20 минут…». Радужные таблицы позволяют найти правильный CRC1 за долю секунды.

    Второе – это получение разных ключей для одного и того же имени. Логично предположить, что если за основу ключа (а как мы позже увидим - CRC1 является основой ключа) берётся разное значение, то каждый раз и ключи будут разные. Радужные таблицы как раз и предоставляют возможность выбора этих самых разных значений.

    Более подробно о программе генерации радужных таблиц повествуют её исходники, которые вы найдёте в приложении к статье.


    Генерация правильных ключей


    Зная правильное значение CRC1, обратить весь процесс проверки серийника несложно. Я хотел бы подробно пояснить лишь пару моментов.

    Во-первых, нам всё-таки придётся обратить одну хэш-функцию – WeakCreateHash. Т.е. по определению если функцию можно обратить, то это уже не хэш-функция. Просто я назвал её так, потому что при беглом просмотре кода сложно было выявить, возможно ли её обратить. Сам обратный код можно найти в исходниках кейгена, поэтому я не буду здесь его приводить. Кстати, все вышеприведенные имена дублируются в кейгене, так что если где-то описывается WeakCreateHash или CRC1, то и в кейгене они имеют такой же смысл, как и в статье.

    При написании обратной функции для WeakCreateHash я использовал Hex-Rays, поэтому задача обращения кода упростилась в разы. Правда, этот плагин не всегда корректно генерирует псевдокод, поэтому я рекомендую перепроверять результаты его работы на стадии отладки.

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

    И последнее – в результате последним преобразованием будет преобразование, обратное тому, которое в самом начале делалось с серийником вот здесь:
    Code:
     
    004010FE   .  8D75 BA       LEA ESI,DWORD PTR SS:[EBP-46]
    00401101   .  8BFE          MOV EDI,ESI
    00401103   >  66:AD         LODS WORD PTR DS:[ESI]
    00401105   .  3C 39         CMP AL,39
    00401107   .  7F 04         JG SHORT 0040110D                        ;  keygenme.0040110D
    00401109   .  2C 30         SUB AL,30
    0040110B   .  EB 02         JMP SHORT 0040110F                       ;  keygenme.0040110F
    0040110D   >  2C 37         SUB AL,37
    0040110F   >  80FC 39       CMP AH,39
    00401112   .  7F 05         JG SHORT 00401119                        ;  keygenme.00401119
    00401114   .  80EC 30       SUB AH,30
    00401117   .  EB 03         JMP SHORT 0040111C                       ;  keygenme.0040111C
    00401119   >  80EC 37       SUB AH,37
    0040111C   >  C0C0 04       ROL AL,4
    0040111F   .  02C4          ADD AL,AH
    00401121   .  AA            STOS BYTE PTR ES:[EDI]
    00401122   .^ E2 DF         LOOPD SHORT 00401103                     ;  keygenme.00401103
    Хотя я не делала никакой обратной функции, я поступил проще – написал аналог этой функции на С и перебором подбирал WORD’ы, соответствующие байтам после обращения WeakCreateHash. Перебор начинался со значения 0х3030, т.к. символы, лежащие ниже этого значения, иногда даже не хотели отображаться. Более того, кейген генерирует серийники, не выглядящие так уж красиво – иногда они содержат нечитаемые символы, а очень редко такие символы даже не копируются в буфер обмена (правда, в результате тестов у меня такое было только один раз, и после повторной генерации другой серийник уже нормально копировался), но, тем не менее, они работают, и даже дают такой вот результат:



    И ещё – я писал выше, что использовал Pe Tools при написании кейгена. На самом деле, это громко сказано. Дело в том, что изначально я хотел написать кейген как консольное приложение. Но когда стало видно, какие там мутки с серийниками (т.е. какой они имеют неудобный для отображения вид) я решил написать графическое приложение. Но переделывать проект было лень, поэтому я добавил в начало вызов FreeConsole(), но меня раздражало это мигание, вот почему я с помощью Pe Tools подкорректировал поле Subsystem на GUI.


    Финал


    Вот и подошло к концу очередное повествование. Надеюсь, оно было интересным и полезным для вас. Как говорили в «Спокойной ночи, малыши»: «До новых встреч!». )))

    Материалы к статье
    ARCHANGEL © AHTeam, r0 Crew
    Last edited by ARCHANGEL; 02-09-2010 at 07:26.
    Добрым быть просто - достаточно обратить свой гнев на негодяев...

  2. 4 пользователя(ей) сказали cпасибо:
    dahaka (02-09-2010) korsader (02-09-2010) root (02-09-2010) ximera (02-09-2010)
  3. #2
    ARCHANGEL's Avatar

    Default Re: Написание кейгена для keygenme #00 by KSDR

    Хоть бы прокомментировали как-то ... Кейген-то хоть работает? )))
    Добрым быть просто - достаточно обратить свой гнев на негодяев...

  4. #3
    root's Avatar

    Default Re: Написание кейгена для keygenme #00 by KSDR

    Вууух! Замутки с генерацией дествительно маниакальные, как и сама реализация кейгена! На выходных покопаюсь в кейгене и посмотрю, как все работает - руки зачесались)) Респект!
    Успех – это путь от провала до провала без потери энтузиазма. (В. Черчиль)

    Не бойся идти медленно, бойся остановиться. (Китайская пословица)

    When you lose fun and start doing things only for the payback, you're dead. (c) TCLH (Phrack 65, Intro)

  5. #4
    korsader's Avatar

    Default Re: Написание кейгена для keygenme #00 by KSDR

    ARCHANGEL, спасибо за отличную статью.
    Теперь несколько слов о самом кейгенми. Он было выложен на сайте у King Size , примерно пару лет назад, в разделе конкурсы. Автор сего творения не я, а ev1l^4 из [tPORt] (если мне не изменяет память). Решение первым нашел некто 0x00786F72, и выложил кейген.
    King Size человек известный, и многие из вас его знают, поэтому я немного придержал эту информацию.
    з.ы. Сам я потратил на его решение 3 дня.

  6. #5
    ARCHANGEL's Avatar

    Default Re: Написание кейгена для keygenme #00 by KSDR

    Quote Originally Posted by [KSDR] View Post
    Сам я потратил на его решение 3 дня.
    Круто, я потратил 2 недели (+- пару дней). Не буду прибедняться и говорить, что я был сильно занят. Просто я много тупил. Вначале хэш неделю обращал, а потом когда он ну никак не хотел обращаться, трассировал его и обратный алгоритм в олли, делал логи пошагового прохода и бегал по кругу с бубном. Потом когда создавал радужны таблицы, дня три отлаживал переборщик, а всё из-за недостаточного знания С и того, как sizeof работает с массивами. Потом при бруте из преобразованного серийника нормальных значений не учёл, что cmp может применяться для сравнения знаковых операндов. Было ещё много косяков, это только самые основные.

    А ev1l^4 теперь в AHTeam'e.
    Добрым быть просто - достаточно обратить свой гнев на негодяев...

+ Reply to Thread

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
All times are GMT. The time now is 01:39
vBulletin® Copyright ©2000 - 2018
www.reverse4you.org