Кейген своими руками GL#0M (gl00m-crk@yandex.ru) Спецвыпуск: Хакер, номер #057, стр. 057-044-2 00409E12 . 8B4C24 1Cmov ecx, dword ptr [esp+1Ch] <= мы тут Теперь попробуем проанализировать, какие же действия произвела программа для проверки действительности введенных данных. Для этих целей больше подойдет дизассемблер IDA, поэтому загрузим нашу цель в него и перейдем на начало данной процедуры. С первых же строк мы замечаем следующее: .text:00409A8C mov eax, [ecx-8]; EAX = длина введенного имени .text:00409A8F cmp eax, 1 .text:00409A92 jge short loc_409AAE .text:00409A94 push30h .text:00409A96 pushoffset aDvCapture ; "DV Capture" .text:00409A9B pushoffset aYouMustEnterAU ; "You must enter a User Name before you c"... .text:00409AA0 mov ecx, ebp .text:00409AA2 call_MessageBoxA 1. Длина имени должна быть больше единицы или равна ей. .text:00409ADA mov eax, [esi-8]; EAX = длина введенного серийного номера .text:00409ADD cmp eax, 1 .text:00409AE0 jge short loc_409AF3 .text:00409AE2 push30h .text:00409AE4 pushoffset aDvCapture ; "DV Capture" .text:00409AE9 pushoffset aYouMustEnterAL ; "You must enter a License Code before yo"... .text:00409AEE jmp loc_409E24 2. Длина серийного номера должна быть больше единицы или равна ей. Если предыдущие проверки пройдены успешно, то далее мы увидим немного странные операции над длиной серийного номера и следующие за ними проверки, поэтому я прокомментирую их более подробно: .text:00409AF3 mov ecx, eax ; ECX = длина введенного серийного номера .text:00409AF5 and ecx, 80000001h ; проверка на четность .text:00409AFB jns short loc_409B02 ; если нет знака (у нас его быть не может) .text:00409AFD dec ecx .text:00409AFE orecx, 0FFFFFFFEh .text:00409B01 inc ecx .text:00409B02 .text:00409B02 loc_409B02: ; CODE XREF: sub_409A10+EB j .text:00409B02 jnz loc_409E18 ; если не четно, то на ошибку .text:00409B08 mov edx, eax ; EDX = длина введенного серийного номера .text:00409B0A and edx, 80000007h ; проверка делимости на восемь без остатка .text:00409B10 jns short loc_409B17 ; проверка на знак .text:00409B12 dec edx .text:00409B13 oredx, 0FFFFFFF8h .text:00409B16 inc edx .text:00409B17 .text:00409B17 loc_409B17: ; CODE XREF: sub_409A10+100 j .text:00409B17 jnz loc_409E18 ; если не делится, то на ошибку .text:00409B1D cmp eax, 10h .text:00409B20 jlloc_409E18 3. Длина лицензионного кода должна быть четной, делиться на 8 и быть больше 15. Например: User Name: GL#0M License Code: 0123456789ABCDEF Если все условия соблюдены, то: .text:00409B41 mov eax, [esi-8]; eax = 16 (длина лицензионного кода) .text:00409B44 cdq .text:00409B45 sub eax, edx .text:00409B47 sar eax, 1; беззнаковое деление на 2 ;) .text:00409B49 pusheax ; cbeax = 8 .text:00409B4A lea eax, [esp+42Ch+b] .text:00409B51 pusheax ; lpb eax = указатель на буфер результата .text:00409B52 pushesi ; lps esi = указатель на лицензионный код .text:00409B53 callHexFromHexStr HexFromHexStr - преобразует указанную часть строки шестнадцатеричных цифр в бинарный вид. Преобразование происходит по два байта, поэтому третий параметр равен частному от деления длины лицензионного кода на два. Вот ее код: .text:00401F40 pushebx .text:00401F41 mov ebx, [esp+cb] ; EBX = длина, деленная на 2 |