Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Авторские статьи (https://forum.antichat.xyz/forumdisplay.php?f=31)
-   -   Создание кейгена для EmFTP 2.01 (https://forum.antichat.xyz/showthread.php?t=22613)

ProTeuS 14.08.2006 15:54

Создание кейгена для EmFTP 2.01
 
Создание кейгена для EmFTP 2.01

Исследуемая программа - FTP-клиент EmFTP 2.01, имеет 30 day trial и позволяет вводить к окне регистрации полученый от разработчиков регкод. PEID выдал после проверки файла EmFTP.exe такой результат: Microsoft Visual C++ 7.0 [Debug]. Это не может не радовать и дает пищу для дальнейших непродолжительных экспериментов.

Сразу переходим к исследованию. Жмем Help->About EmFTP...(попутно замечаем надпись Unregistered)->How To Purchase->Enter Registration Key и видим 4 поля по 4 символа для ввода регистрационной информации. Сюда можно запихнуть лишь цифры (запомним...). Вводим набум 1111-2222-3333-4444 и
получаем в ответ месаджбокс "Wrong registration key". Для отлова вызова этого сообщения грузим выполняемый файл в ольку и ставим "bp MessageBoxA" в плагине Command Bar. После повторного ввода "1111-2222-3333-4444" и нажатия на ОК прерываемся. Чтобы выяснить место, откуда функция вызывается, просмотрим стек вызовов (Alt+K). Он имеет такой вид:

Код:

Address Stack  Procedure                          Called from                Frame
0012F3EC 00416F11 USER32.MessageBoxA              EmFTP.00416F0B            0012F60C
0012F400 00416F47 EmFTP.00416ED8                  EmFTP.00416F42            0012F60C
0012F610 00418BCC EmFTP.00416F14                  EmFTP.00418BC7            0012F60C
0012F668 00401220 EmFTP.00418A61                  EmFTP.0040121B            0012F664
0012F670 004094A8 EmFTP.004011F7                  EmFTP.004094A3            0012F6C8
0012F6CC 0040A02D EmFTP.00409281                  EmFTP.0040A028            0012F6C8
0012FD64 77D38734 Maybe EmFTP.00409F64            USER32.77D38731            0012FD60
0012FD90 77D38816 ? USER32.77D3870C                USER32.77D38811            0012FD8C
0012FDF8 77D389CD ? USER32.77D3875F                USER32.77D389C8            0012FDF4
0012FE58 77D396C7 ? USER32.77D388F1                USER32.77D396C2            0012FE54

Последовательно проверяем функции столбца "Called from" пока не дойдем до 00418BC7. Именно тут произошел вызов MessageBox с сообщением о неправильно введенном регистрационном коде

Код:

.text:00418B84                call    __RegOpenKey
.text:00418B89                mov    esi, eax
.text:00418B8B                cmp    esi, ebx
.text:00418B8D                jz      short end
.text:00418B8F                push    esi            ; hKey
.text:00418B90                call    ReadRegKey_FromRegistry_And_Check
.text:00418B95                cmp    eax, ebx
.text:00418B97                jle    short loc_418BB0 ; no JMP for registration!
.text:00418B99                xor    ecx, ecx
.text:00418B9B                cmp    eax, 2
.text:00418B9E                setz    cl
.text:00418BA1                mov    dword_466984, eax
.text:00418BA6                push    40h
.text:00418BA8                add    ecx, 455h      ; registered!
.text:00418BAE                jmp    short loc_418BC6
.text:00418BB0 ; ---------------------------------------------------------------------------
.text:00418BB0
.text:00418BB0 loc_418BB0:                            ; CODE XREF: sub_418A61+136j
.text:00418BB0                jz      short loc_418BCC
.text:00418BB2                xor    ecx, ecx
.text:00418BB4                cmp    eax, 0FFFFFFFEh
.text:00418BB7                setnz  cl
.text:00418BBA                push    30h            ; uType
.text:00418BBC                dec    ecx
.text:00418BBD                and    ecx, 3
.text:00418BC0                add    ecx, 454h      ; not registered!
.text:00418BC6
.text:00418BC6 loc_418BC6:                            ; CODE XREF: sub_418A61+14Dj
.text:00418BC6                push    ecx            ; uID
.text:00418BC7                call    _LoadString    ;!!!! here loads "Wrong regcode" and calls MessageBox
.text:00418BCC
.text:00418BCC loc_418BCC:                            ; CODE XREF: sub_418A61:loc_418BB0j
.text:00418BCC                push    esi            ; hKey
.text:00418BCD                call    ds:RegCloseKey
.text:00418BD3
.text:00418BD3 end:                                    ; CODE XREF: sub_418A61+FCj
.text:00418BD3                                        ; sub_418A61+101j ...
.text:00418BD3                xor    eax, eax
.text:00418BD5                inc    eax
.text:00418BD6
.text:00418BD6 loc_418BD6:                            ; CODE XREF: sub_418A61+196j
.text:00418BD6                pop    esi
.text:00418BD7                pop    ebx
.text:00418BD8                leave
.text:00418BD9                retn    4

Как видно с листинга, по адресу 00418BC7 просиходит загрузка из файла ресурса с ID 454h (или 1108, "Wrong registration key", как показывает любой редактор ресурсов). Пробежавшись немного вверх по коду, замечаем, что по адресу 00418BA8 точно такая же загрузка ресурса с ID 455h (или 1109, "Thank for registering!"). Стало быть, этот код исполняется в случае удачно введенного регкода (и мы на верном пути, движемся выше...).

Код:

.text:00418B90                call    ReadRegKey_FromRegistry_And_Check
.text:00418B95                cmp    eax, ebx
.text:00418B97                jle    short loc_418BB0 ; no JMP for registration!

Поскольку после вызова функции 00418B90 (ReadRegKey_FromRegistry_And_Check) выполняется проверка регистров (программа будет выводить сообщение о зарегистрированности если eax > ebx), то
можно сделать вывод, что именно в этой функции и сосредоточен модуль проверки введенного регкода на валидность.

Код:

.text:004189FE ; int __stdcall ReadRegKey_FromRegistry_And_Check(HKEY hKey)
.text:004189FE ReadRegKey_FromRegistry_And_Check proc near ; CODE XREF: sub_418A61+2Cp
.text:004189FE                                        ; sub_418A61+12Fp
.text:004189FE
.text:004189FE Data            = byte ptr -10h
.text:004189FE Type            = dword ptr -8
.text:004189FE cbData          = dword ptr -4
.text:004189FE hKey            = dword ptr  8
.text:004189FE
.text:004189FE                push    ebp
.text:004189FF                mov    ebp, esp
.text:00418A01                sub    esp, 10h
.text:00418A04                and    [ebp+cbData], 0
.text:00418A08                push    esi
.text:00418A09                mov    esi, ds:RegQueryValueExA
.text:00418A0F                push    edi
.text:00418A10                lea    eax, [ebp+cbData]
.text:00418A13                push    eax            ; lpcbData
.text:00418A14                push    0              ; lpData
.text:00418A16                lea    eax, [ebp+Type]
.text:00418A19                push    eax            ; lpType
.text:00418A1A                push    0              ; lpReserved
.text:00418A1C                mov    edi, offset ValueName ; "EmFTP-Pro"
.text:00418A21                push    edi            ; lpValueName
.text:00418A22                push    [ebp+hKey]      ; hKey
.text:00418A25                call    esi ; RegQueryValueExA
.text:00418A27                test    eax, eax
.text:00418A29                jnz    short loc_418A59
.text:00418A2B                cmp    [ebp+Type], 3
.text:00418A2F                jnz    short loc_418A59
.text:00418A31                cmp    [ebp+cbData], 8
.text:00418A35                jnz    short loc_418A59
.text:00418A37                lea    eax, [ebp+cbData]
.text:00418A3A                push    eax            ; lpcbData
.text:00418A3B                lea    eax, [ebp+Data]
.text:00418A3E                push    eax            ; lpData
.text:00418A3F                lea    eax, [ebp+Type]
.text:00418A42                push    eax            ; lpType
.text:00418A43                push    0              ; lpReserved
.text:00418A45                push    edi            ; lpValueName
.text:00418A46                push    [ebp+hKey]      ; hKey
.text:00418A49                call    esi ; RegQueryValueExA
.text:00418A4B                test    eax, eax
.text:00418A4D                jnz    short loc_418A59
.text:00418A4F                lea    eax, [ebp+Data]
.text:00418A52                call    main_reg_routine
.text:00418A57                jmp    short loc_418A5B
.text:00418A59 ; ---------------------------------------------------------------------------
.text:00418A59
.text:00418A59 loc_418A59:                            ; CODE XREF: ReadRegKey_FromRegistry_And_Check+2Bj
.text:00418A59                                        ; ReadRegKey_FromRegistry_And_Check+31j ...
.text:00418A59                xor    eax, eax
.text:00418A5B
.text:00418A5B loc_418A5B:                            ; CODE XREF: ReadRegKey_FromRegistry_And_Check+59j
.text:00418A5B                pop    edi
.text:00418A5C                pop    esi
.text:00418A5D                leave
.text:00418A5E                retn    4
.text:00418A5E ReadRegKey_FromRegistry_And_Check endp

В это модуле считывается записаный только что ключ в реесте "HKEY_LOCAL_MACHINE\SOFTWARE\Emurasoft\Regist" "EmFTP-Pro", который в нашем случае имеет тип
REG_BINARY и равен "57 04 AE 08 05 0D 5C 11".

Код:

lea    eax, [ebp+Data]
call    main_reg_routine

Указатель на введенный код будет доступен в функции в регистре EAX. Давайте теперь расберемся в алгоритме генерации сохраняемого в реестре значения параметра EmFTP-Pro:
если вводимый ключ состоит из 4 полей (вспоминаем, что доступны только цифры 0..9), а запись состоит из 8 байт, то логично предположить, что это 4 переменные размером в WORD, каждая отвечающая за соответственное поле ввода. Проверим: переведем "04 57" (не забываем про обратный порядок следования байт) из 16ричной системы в 10чную и получим "1111", "08 AE" - "2222", "0D 05" - "3333", "11 5C" - "4444" - точно те же данные, что мы и вводили при регистрации. Перейдем к изучению основной функции проверки введенных данных main_reg_routine.

Код:

.text:00425328 main_reg_routine proc near              ; CODE XREF: ReadRegKey_FromRegistry_And_Check+54p
.text:00425328                push    esi  ; бэкапим старое значение регистра
.text:00425329                mov    esi, eax ; заносим в esi указатель на считаные с реестра данные
.text:0042532B                movzx  eax, word ptr [esi] ; первый ворд из 4
.text:0042532E                push    0Ah  ; заносим в верхушку стека 0A
.text:00425330                cdq         
.text:00425331                pop    ecx  ; ecx = 0A
.text:00425332                idiv    ecx              ; eax : = eax div 0Ah
.text:00425334                cmp    eax, 0BFh        ; если eax = 0BFh тогда можно продолжать
.text:00425339                jz      short loc_425340 ; прыгаем если не равно
.text:0042533B                or      eax, 0FFFFFFFFh  ; записываем в EAX значение провала регистрации и выходим 
.text:0042533E                pop    esi ; восстанавливаем старое значение регистра
.text:0042533F                retn
.text:00425340 ; ---------------------------------------------------------------------------
.text:00425340
.text:00425340 loc_425340:                            ; CODE XREF: main_reg_routine+11j
.text:00425340                push    edi
.text:00425341                mov    di, [esi+6]    ; 4 ворд
.text:00425345                call    zamut
.text:0042534A                cmp    eax, 1
.text:0042534D                jnz    short loc_42535C
.text:0042534F                xor    eax, eax
.text:00425351                cmp    di, [esi+6]    ; сравниваем 4 ворд с результатом функции
.text:00425355                setz    al
.text:00425358                lea    eax, [eax+eax-1]
.text:0042535C
.text:0042535C loc_42535C:                            ; CODE XREF: main_reg_routine+25j
.text:0042535C                pop    edi
.text:0042535D                pop    esi
.text:0042535E                retn
.text:0042535E main_reg_routine endp

С первой части функции видно, что в первом поле должно быть такое число, что chislo div $0A = $BF.
Если это условие правдиво, то мы движемся дальше и по адресу 00425345 происходит вызов основной функции просчета валидного серийника и окончательной его проверки с нами введенным.

Код:

.text:0042522E zamut          proc near              ; CODE XREF: main_reg_routine+1Dp
.text:0042522E
.text:0042522E var            = dword ptr -8
.text:0042522E first_word      = dword ptr -4
.text:0042522E
.text:0042522E                push    ecx
.text:0042522F                push    ecx
.text:00425230                mov    dx, [esi+2]    ; 2 ворд
.text:00425234                and    word ptr [esi+6], 0 ; 4 ворд
.text:00425239                cmp    dx, 270Fh
.text:0042523E                ja      ending
.text:00425244                mov    ax, [esi+4]
.text:00425248                cmp    ax, 270Fh
.text:0042524C                ja      ending
.text:00425252                xor    ecx, ecx
.text:00425254                mov    cx, [esi]      ; 1 ворд
.text:00425257                cmp    cx, 715h
.text:0042525C                mov    [esp+8+first_word], ecx
.text:00425260                jnz    short loc_425276
.text:00425262                cmp    dx, 1C1Eh
.text:00425267                jnz    short loc_425276
.text:00425269                cmp    ax, 159Dh
.text:0042526D                jnz    short loc_425276
.text:0042526F
.text:0042526F fail:                                  ; CODE XREF: zamut+5Aj
.text:0042526F                                        ; zamut+6Ej
.text:0042526F                push    0FFFFFFFEh
.text:00425271                jmp    ending2
.text:00425276 ; ---------------------------------------------------------------------------
.text:00425276
.text:00425276 loc_425276:                            ; CODE XREF: zamut+32j
.text:00425276                                        ; zamut+39j ...
.text:00425276                cmp    cx, 71Ah
.text:0042527B                jnz    short loc_42528A
.text:0042527D                cmp    dx, 1009h
.text:00425282                jnz    short loc_42528A
.text:00425284                cmp    ax, 15h
.text:00425288                jz      short fail
.text:0042528A
.text:0042528A loc_42528A:                            ; CODE XREF: zamut+4Dj
.text:0042528A                                        ; zamut+54j
.text:0042528A                cmp    cx, 714h
.text:0042528F                jnz    short loc_42529E
.text:00425291                cmp    dx, 1321h
.text:00425296                jnz    short loc_42529E
.text:00425298                cmp    ax, 0B6Ch
.text:0042529C                jz      short fail
.text:0042529E
.text:0042529E loc_42529E:                            ; CODE XREF: zamut+61j
.text:0042529E                                        ; zamut+68j
.text:0042529E                push    ebx
.text:0042529F                push    ebp
.text:004252A0                push    edi
.text:004252A1                movzx  edi, ax
.text:004252A4                movzx  eax, dx
.text:004252A7                mov    [esp+14h+var], eax
.text:004252AB                push    64h
.text:004252AD                pop    ebx
.text:004252AE                mov    eax, edi
.text:004252B0                cdq
.text:004252B1                idiv    ebx            ; 3 word div 64h
.text:004252B3                push    0Ah
.text:004252B5                pop    ebp
.text:004252B6                movzx  ecx, cx
.text:004252B9                push    64h
.text:004252BB                mov    ebx, eax
.text:004252BD                mov    eax, ecx
.text:004252BF                cdq
.text:004252C0                idiv    ebp            ; 1 word div Ah
.text:004252C2                add    ebx, [esp+18h+var] ; добавляем 3 word к остатку от "3 word div 64h"
.text:004252C6                add    eax, ebx        ; + eax
.text:004252C8                add    eax, edi        ; + 3 word
.text:004252CA                cdq
.text:004252CB                pop    edi
.text:004252CC                idiv    edi            ; eax div 64h
.text:004252CE                mov    eax, [esp+14h+var] ; eax = 2 word
.text:004252D2                push    64h
.text:004252D4                pop    ebx
.text:004252D5                push    64h
.text:004252D7                pop    ebp
.text:004252D8                push    ebp
.text:004252D9                mov    di, word ptr byte_463E20[edx*4]
.text:004252E1                cdq
.text:004252E2                imul    di, 64h
.text:004252E6                idiv    ebx            ; div 64h
.text:004252E8                mov    ebx, eax
.text:004252EA                mov    eax, ecx
.text:004252EC                cdq
.text:004252ED                idiv    ebp            ; div 64h
.text:004252EF                add    ebx, ecx
.text:004252F1                pop    ecx
.text:004252F2                add    eax, ebx
.text:004252F4                cdq
.text:004252F5                idiv    ecx            ; div 64h
.text:004252F7                add    di, word ptr byte_463E20[edx*4]
.text:004252FF                cmp    word ptr [esp+14h+first_word], 77Bh
.text:00425306                mov    [esi+6], di    ; result?
.text:0042530A                pop    edi
.text:0042530B                pop    ebp
.text:0042530C                pop    ebx
.text:0042530D                jz      short fail2    ; no JMP!
.text:0042530F                cmp    word ptr [esp+8+first_word], 77Ah
.text:00425316                jz      short fail2    ; no JMP!
.text:00425318                xor    eax, eax
.text:0042531A                inc    eax
.text:0042531B                jmp    short end
.text:0042531D ; ---------------------------------------------------------------------------
.text:0042531D
.text:0042531D fail2:                                  ; CODE XREF: zamut+DFj
.text:0042531D                                        ; zamut+E8j
.text:0042531D                push    2
.text:0042531F
.text:0042531F ending2:                                ; CODE XREF: zamut+43j
.text:0042531F                pop    eax
.text:00425320                jmp    short end
.text:00425322 ; ---------------------------------------------------------------------------
.text:00425322
.text:00425322 ending:                                ; CODE XREF: zamut+10j
.text:00425322                                        ; zamut+1Ej
.text:00425322                or      eax, 0FFFFFFFFh
.text:00425325
.text:00425325 end:                                    ; CODE XREF: zamut+EDj
.text:00425325                                        ; zamut+F2j
.text:00425325                pop    ecx
.text:00425326                pop    ecx
.text:00425327                retn
.text:00425327 zamut          endp


ProTeuS 14.08.2006 15:55

Вся "красота" функции заключается в математических операциях над первыми тремя введенными числами и записи просчитанного валидного для них четвертого (.text:00425306 mov [esi+6], di).
Как мы помним, по адресу 00425351 (cmp di, [esi+6] ; сравниваем 4 ворд с результатом функции) происходит окончательная их проверка. Так что для создания кейгена достаточно "понять" алгоритм проверок и преобразовать его на любой любимый язык. Но можно сделать проще, просто рипнув эту функцию и использовав ее для своих нужд (я употребил плагин для ольки AsmToClipboard -> Copy Fixed Asm To Clipboard).

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

Код:

004252D9  |. 66:8B3C95 203E>MOV DI,WORD PTR DS:[EDX*4+463E20] ; ТУТ
004252E1  |. 99            CDQ
004252E2  |. 66:6BFF 64    IMUL DI,DI,64
004252E6  |. F7FB          IDIV EBX
004252E8  |. 8BD8          MOV EBX,EAX
004252EA  |. 8BC1          MOV EAX,ECX
004252EC  |. 99            CDQ
004252ED  |. F7FD          IDIV EBP
004252EF  |. 03D9          ADD EBX,ECX
004252F1  |. 59            POP ECX
004252F2  |. 03C3          ADD EAX,EBX
004252F4  |. 99            CDQ
004252F5  |. F7F9          IDIV ECX
004252F7  |. 66:033C95 203E>ADD DI,WORD PTR DS:[EDX*4+463E20] ; И ТУТ

чтобы сделать полностью рабочий кейген нужно рипнуть и эту таблицу. Для этого щелкаем в ольке на строке
"004252D9 |. 66:8B3C95 203E>MOV DI,WORD PTR DS:[EDX*4+463E20] ; ТУТ" и жмем Follow in dump -> Address Constant
и получаем в окне дампов начало искомой таблицы (00463E20).

Код:

00463E20  26 00 00 00 5B 00 00 00 62 00 00 00 36 00 00 00  &...[...b...6...
00463E30  34 00 00 00 60 00 00 00 13 00 00 00 35 00 00 00  4...`......5...
00463E40  19 00 00 00 54 00 00 00 3F 00 00 00 44 00 00 00  ...T...?...D...
00463E50  4C 00 00 00 38 00 00 00 5D 00 00 00 33 00 00 00  L...8...]...3...
00463E60  56 00 00 00 61 00 00 00 42 00 00 00 21 00 00 00  V...a...B...!...
00463E70  3E 00 00 00 2D 00 00 00 23 00 00 00 0E 00 00 00  >...-...#......
00463E80  1E 00 00 00 5F 00 00 00 57 00 00 00 12 00 00 00  ..._...W......
00463E90  1B 00 00 00 17 00 00 00 22 00 00 00 58 00 00 00  ......"...X...
00463EA0  2C 00 00 00 63 00 00 00 5C 00 00 00 18 00 00 00  ,...c...\......
00463EB0  37 00 00 00 41 00 00 00 59 00 00 00 4D 00 00 00  7...A...Y...M...
00463EC0  15 00 00 00 5A 00 00 00 53 00 00 00 0B 00 00 00  ...Z...S......
00463ED0  05 00 00 00 1C 00 00 00 10 00 00 00 2E 00 00 00  .............
00463EE0  49 00 00 00 40 00 00 00 0D 00 00 00 07 00 00 00  I...@..........
00463EF0  50 00 00 00 3D 00 00 00 32 00 00 00 46 00 00 00  P...=...2...F...
00463F00  0A 00 00 00 43 00 00 00 2B 00 00 00 00 00 00 00  ....C...+.......
00463F10  3B 00 00 00 48 00 00 00 5E 00 00 00 4E 00 00 00  ;...H...^...N...
00463F20  51 00 00 00 1F 00 00 00 20 00 00 00 3A 00 00 00  Q...... ...:...
00463F30  01 00 00 00 2A 00 00 00 45 00 00 00 55 00 00 00  ...*...E...U...
00463F40  4A 00 00 00 02 00 00 00 52 00 00 00 27 00 00 00  J......R...'...
00463F50  03 00 00 00 4B 00 00 00 08 00 00 00 3C 00 00 00  ...K......<...
00463F60  0F 00 00 00 14 00 00 00 24 00 00 00 25 00 00 00  ......$...%...
00463F70  28 00 00 00 29 00 00 00 16 00 00 00 1D 00 00 00  (...).........
00463F80  1A 00 00 00 11 00 00 00 2F 00 00 00 39 00 00 00  ....../...9...
00463F90  09 00 00 00 47 00 00 00 06 00 00 00 4F 00 00 00  ....G......O...
00463FA0  04 00 00 00 31 00 00 00 0C 00 00 00 30 00 00 00  ...1.......0...

копируем дамп по адрес 463FB0 (ровно 400 байт, которые имеют визуально схожую структуру).

Забив в своем кейгене дамп в отдельную таблицу, получаем примерно такое:

Код:

unit main; //на форме баттон и 4 спинедита

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Spin;

type
  TForm1 = class(TForm)
    Button1: TButton;
    SpinEdit1: TSpinEdit;
    SpinEdit2: TSpinEdit;
    SpinEdit3: TSpinEdit;
    SpinEdit4: TSpinEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const
Data: array [1..400] of byte =(
 $26, 00, 00, 00, $5B, 00, 00, 00, $62, 00, 00, 00, $36, 00, 00, 00,  //&...[...b...6...
 $34, 00, 00, 00, $60, 00, 00, 00, $13, 00, 00, 00, $35, 00, 00, 00,  //4...`......5...
 $19, 00, 00, 00, $54, 00, 00, 00, $3F, 00, 00, 00, $44, 00, 00, 00,  //...T...?...D...
 $4C, 00, 00, 00, $38, 00, 00, 00, $5D, 00, 00, 00, $33, 00, 00, 00,  //L...8...]...3...
 $56, 00, 00, 00, $61, 00, 00, 00, $42, 00, 00, 00, $21, 00, 00, 00,  //V...a...B...!...
 $3E, 00, 00, 00, $2D, 00, 00, 00, $23, 00, 00, 00, $0E, 00, 00, 00,  //>...-...#......
 $1E, 00, 00, 00, $5F, 00, 00, 00, $57, 00, 00, 00, $12, 00, 00, 00,  //..._...W......
 $1B, 00, 00, 00, $17, 00, 00, 00, $22, 00, 00, 00, $58, 00, 00, 00,  //......"...X...
 $2C, 00, 00, 00, $63, 00, 00, 00, $5C, 00, 00, 00, $18, 00, 00, 00,  //,...c...\......
 $37, 00, 00, 00, $41, 00, 00, 00, $59, 00, 00, 00, $4D, 00, 00, 00,  //7...A...Y...M...
 $15, 00, 00, 00, $5A, 00, 00, 00, $53, 00, 00, 00, $0B, 00, 00, 00,  //...Z...S......
 $05, 00, 00, 00, $1C, 00, 00, 00, $10, 00, 00, 00, $2E, 00, 00, 00,  //.............
 $49, 00, 00, 00, $40, 00, 00, 00, $0D, 00, 00, 00, $07, 00, 00, 00,  //I...@..........
 $50, 00, 00, 00, $3D, 00, 00, 00, $32, 00, 00, 00, $46, 00, 00, 00,  //P...=...2...F...
 $0A, 00, 00, 00, $43, 00, 00, 00, $2B, 00, 00, 00, $00, 00, 00, 00,  //....C...+.......
 $3B, 00, 00, 00, $48, 00, 00, 00, $5E, 00, 00, 00, $4E, 00, 00, 00,  //;...H...^...N...
 $51, 00, 00, 00, $1F, 00, 00, 00, $20, 00, 00, 00, $3A, 00, 00, 00,  //Q...... ...:...
 $01, 00, 00, 00, $2A, 00, 00, 00, $45, 00, 00, 00, $55, 00, 00, 00,  //...*...E...U...
 $4A, 00, 00, 00, $02, 00, 00, 00, $52, 00, 00, 00, $27, 00, 00, 00,  //J......R...'...
 $03, 00, 00, 00, $4B, 00, 00, 00, $08, 00, 00, 00, $3C, 00, 00, 00,  //...K......<...
 $0F, 00, 00, 00, $14, 00, 00, 00, $24, 00, 00, 00, $25, 00, 00, 00,  //......$...%...
 $28, 00, 00, 00, $29, 00, 00, 00, $16, 00, 00, 00, $1D, 00, 00, 00,  //(...).........
 $1A, 00, 00, 00, $11, 00, 00, 00, $2F, 00, 00, 00, $39, 00, 00, 00,  //....../...9...
 $09, 00, 00, 00, $47, 00, 00, 00, $06, 00, 00, 00, $4F, 00, 00, 00,  //....G......O...
 $04, 00, 00, 00, $31, 00, 00, 00, $0C, 00, 00, 00, $30, 00, 00, 00); //...1.......0...


var
  Form1: TForm1;

implementation

{$R *.dfm}

function Generate(first, second, third, fourth :word): word;
begin
  asm
    PUSH ESI
    PUSH ECX
    PUSH ECX
    MOV DX, second
    AND fourth, 0
    CMP DX, 270Fh
    JA @ending
    MOV AX, third
    CMP AX, 270Fh
    JA @ending
    XOR ECX, ECX
    MOV CX, first
    CMP CX, 715h
    MOV esi, ECX //!!!
    JNZ @next
    CMP DX, 1C1Eh
    JNZ @next
    CMP AX, 159Dh
    JNZ @next
  @fail:
    PUSH -2
    JMP @ending2
  @next:
    CMP CX, 71Ah
    JNZ @next2
    CMP DX, 1009h
    JNZ @next2
    CMP AX, 15h
    JE @fail
  @next2:
    CMP CX, 714h
    JNZ @main
    CMP DX, 1321h
    JNZ @main
    CMP AX, 0B6Ch
    JE @fail
  @main:
    PUSH EBX
    PUSH EBP
    PUSH EDI
    MOVZX EDI,AX
    MOVZX EAX,DX
    MOV esi, EAX //!!!
    PUSH 64h
    POP EBX
    MOV EAX,EDI
    CDQ
    IDIV EBX
    PUSH 0Ah
    POP EBP
    MOVZX ECX, CX
    PUSH 64h
    MOV EBX, EAX
    MOV EAX, ECX
    CDQ
    IDIV EBP
    ADD EBX, esi
    ADD EAX, EBX
    ADD EAX, EDI
    CDQ
    POP EDI
    IDIV EDI
    MOV EAX, esi
    PUSH 64h
    POP EBX
    PUSH 64h
    POP EBP
    PUSH EBP
    MOV DI, WORD PTR DS:[EDX*4 + Data]
    CDQ
    IMUL DI,DI,64h
    IDIV EBX
    MOV EBX, EAX
    MOV EAX, ECX
    CDQ
    IDIV EBP
    ADD EBX, ECX
    POP ECX
    ADD EAX, EBX
    CDQ
    IDIV ECX
    ADD DI, WORD PTR DS:[EDX*4 + Data]
    MOV DX, DI
    POP EDI
    POP EBP
    POP EBX
    CMP first, 77Bh
    MOV fourth, DX //result
    JE @fail2
    CMP first, 77Ah
    JE @fail2
    XOR EAX, EAX
    INC EAX
    JMP @end
  @fail2:
    PUSH 2
  @ending2:
  POP EAX
    JMP @end
  @ending:
    OR EAX, -1h
  @end:
    MOV CX, fourth
    MOV RESULT, CX
    POP ECX
    POP ECX
    POP ESI
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
label
next_iteration;
var
first, second, third, fourth: word;
begin
    randomize;
  next_iteration:
    first := random(9999); //генерируем 4 случайных числа
    second := random(9999);
    third := random(9999);
    fourth := random(9999);
    if first div $A <> $BF then goto next_iteration; //значение первого числа не подходит
    if first = $77B then goto next_iteration; //эти значения не следует брать, т.к. они используются только в
    if first = $77A then goto next_iteration; //education и academic version, а нам нужна FULL
    SpinEdit1.Value := first;
    SpinEdit2.Value := second;
    SpinEdit3.Value := third;
    SpinEdit4.Value := Generate(first, second, third, fourth);
end;

end.

gl hf!

[hidden] 14.08.2006 16:07

Отлично! Но есть вопрос - что за олька?
Я пользовался только SoftICE и WinDASM для реверсинга.... "олька" лучше?

------
UPD: насчет ольки (ollyDBG) вопрос снят.

ProTeuS 14.08.2006 16:34

олька - отлад4ик OllyDbg, о4ень удобен для на4инающих, да и вообще незаменим при отладке приложений пользовательского уровня. имеет ку4у дополнительных плагинов, скриптов для автораспаковки многих пакеров\протекторов - вообщем наземенимая тулза для исследований и отладки багов в своем же софте!

ка4аем последний релиз:
http://wasm.ru/baixado.php?mode=tool&id=89
http://cracklab.ru/download.php?action=get&n=MzYw


Время: 02:26