Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Создание кейгена для EmFTP 2.01 |

14.08.2006, 15:54
|
|
HARDstasy
Регистрация: 26.11.2004
Сообщений: 1,367
Провел на форуме: 4226592
Репутация:
2175
|
|
Создание кейгена для 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
|
|
|
|
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|