Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 12 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Пишем КейГен для WinTools.NET Pro 3.8.1 при помощи TMG Ripper Studio

Обсудить статью на форуме

Хорошая подборка видеоуроков, инструментов крэкера, книг и статей - здесь.

Автор: V0ldemAr <v0ldemar@mail333.com>

Инстументы

1)OllyDebuger,SI
2)Stripper 2.07
3)PeID
4)TMG Ripper Studio v0.03

Анализ

Смотрим через PeID что прога пакована AsPack-ом каким то,
берем Stripper и дальше все ясно что имеем распакованую прогу,
конечно можно было все сделать в ручную типа взять SIce и ImportREC потом
bpm esp-4 в Айсе и так дальше но наша цель не распаковка АсПака, а кейген.

Первый Запуск

Видим прога триальна на 30 дней, это говорит нам появившейся наг,
а в нем Edit куда нужно ввести ключ.
Все ясно, понеслась ... по трубам ;)
Открываем Олли, ясен перец прогу распакованую берем, после анализа Олли,
нажимаем Ctrl+N после чего видим новое окно с импортируеми апихами,
дергаем полосу прокрутки вниз и ищим вот такую апи функ. GetWindowTextA
выбираем ее и кликнем на ней правой кнопкой мыши в контекстном меню выбераем
"Toggle breakpoint on import" то есть устанавливаем бряк на импорт этой апихи.
Теперь запускаем прогу через F9, мы видим Наг скрин вводим ключ: 12344321 жмем
кнопку и выскакиваем в Олли в начале процедури GetWindowTextA проходим ее до ret-а
через Ctrl+F9 далее жмем F8 и выходим из апихи и попадаем сюда:

 .text:00439F7F push esi ; lpString
 .text:00439F80 push edi ; hWnd
 .text:00439F81 call GetWindowTextA
 .text:00439F86 cmp [ebp+var_108], 0
 .text:00439F8D jz loc_43A0CC
 проверяют длину ключа, если 0 тогда прыгаем
 
 .text:00439FA6 lea edi, [ebp+var_108]
 .text:00439FAC push edi
 .text:00439FAD lea edi, [ebp+var_210]
 .text:00439FB3 push edi
 беру копируют наш ключ в иной буфер в такой [ebp+var_108]
 .text:00439FB4 call strcpy
 .text:00439FB9 add esp, 8
 
 .text:00439FBC lea edi, [ebp+var_108]
 .text:00439FC2 push edi
 .text:00439FC3 call strlen
 .text:00439FC8 add esp, 4
 далее берут длину ключа
 .text:00439FCB mov edi, eax
 .text:00439FCD sub edi, 0Fh
 и вычитают 15 и кладут в [ebp+var_214]
 .text:00439FD0 mov [ebp+var_214], edi
 .text:00439FD6 mov edi, [ebp+var_214]
 .text:00439FDC lea edi, [ebp+edi+var_108]
 
а потом устанавливают пойнтер на эти последние 15 символов ключа и суют его в edi значит нам нужно ввести ключ больше 15 символов ставим бряк в Олли на 00439FDC через F2 и повторяем ввод ключа наши 15 последних символов суют в этот call sub_43F432 после трассировки по F8 в еах засунули какое-то очень большое число
 .text:00439FE3 push edi
 .text:00439FE4 call sub_43F432
 .text:00439FE9 add esp, 4
 
а потом это число в [ebp-218h]
 .text:00439FEC mov [ebp-218h], eax
 .text:00439FF2 mov edi, [ebp+var_214]
 кладут длину оставшихся символов в edi
 .text:00439FF8 mov [ebp+edi+var_210], 0
 и затирают последний символ из этих оставшихся символов 00-ми чтобы знать где
 конец строки
 .text:0043A000 lea edi, [ebp+var_210]
 .text:0043A006 push edi
 
и передают эти символы в этот call sub_45E7C0 я не буду в него лезть просто скажу что этот колл превращает эти символы в число если это цифры, если нет то в еах будет 0 значит эти первые символы должны быть цифрами и не простыми а должны быть равными тем что в [ebp-218h]
 .text:0043A007 call sub_45E7C0
 .text:0043A00C add esp, 4
 .text:0043A00F mov [ebp+var_224], edx
 .text:0043A015 mov [ebp+var_228], eax
 .text:0043A01B mov edi, [ebp+var_228]
 .text:0043A021 mov [ebp+var_21C], edi
 .text:0043A027 mov edi, [ebp+var_21C]
 .text:0043A02D cmp [ebp-218h], edi
 если эти цифры неравны то прыгаем с вещами на выход
 .text:0043A033 jnz loc_43A0CC
 
Теперь мы знаем как делать кейген:

значит ми должни ввести любых 15 букв или цифр потом передать их в call sub_43F432 потом превратить число что есть в еах в строку, и сложить эти цифры и буквы и не забыть что между ними нужно поставить какой то знак например "-" Но как мы передадим ету строку с нашыми 15-а символами. Очень просто мы вытащим этот call sub_43F432 с помощью TMG Ripper Studio v0.03. Запускаем Риппер и открываем в нем нашу прогу в поле Virtual Offset: ставим 00439FDC и устанавливаем EndPoints: 00439FEC После чего нажимаем на кнопку StartTrace так Риппер трасирует нашу прогу, далее выбираем адрес, который появился в поле Data-references и нажимаем Process datarefs вот и все сохр. наш колл в файл.

Теперь смотрим в наш файл, и что же мы там видим, что по адрессу LOC_004A8590 стоят нули интересно смотри где они используютсf а вот где

AND EDI, 0000000FFh MOV EDI,DWORD PTR [EDI*4+OFFSET LOC_004A8590] Здесь явно не всегда надо подставлять ноли давайте посмотри что там по адресу 004A8590, Берем Олли открываем нашу прогу и в поле стека нажимаем Ctrl+G и пишем 004A8590 теперь все ясно что там по адресу 004A8590 это массив, а какой он длины все просто, смотрим в edi макс значенее может бить 256 а edi умножают на 4 начит массив должен иметь размер 1024.Копируем этот массив и сохр. в файл. После некоторых корректировок наш колл на МАСМ32 выглядит так:
 GenKey proc
 .Data
 hRes dd 0
 hRes1 dd 0
 
 .code
 invoke FindResource,0,1666,RT_RCDATA
 mov hRes1,eax
 invoke LoadResource,0,eax
 mov hRes,eax
 invoke LockResource,eax
 ;в hRes наш массив на 1024
 ;почему я его сделал как ресурс потому-то если например выйдет новая версия
 ;проги и алгоритм не поменяют, а поменяют массив то ми просто заменим ресурс
 
 LEA EDI,buff1 ;строка с 15 символами
 
 PUSH EDI
 CALL LOC_0043F432
 ADD ESP,004h
 push eax
 invoke FreeResource,hRes1
 pop eax
 
 ret
 
 LOC_0043F432:
 PUSH EBP
 MOV EBP,ESP
 PUSH ECX
 PUSH EAX
 PUSH EBX
 PUSH ESI
 PUSH EDI
 
 invoke lstrlen,addr buff1
 
 MOV DWORD PTR [EBP-008h],EAX
 MOV DWORD PTR [EBP-004h],0FFFFFFFFh
 JMP LOC_0043F47D
 LOC_0043F451: ;Ref: 0043F48B
 MOV EDI,DWORD PTR [EBP+008h]
 MOV ESI,EDI
 ADD ESI,001h
 MOV DWORD PTR [EBP+008h],ESI
 MOV ESI,DWORD PTR [EBP-004h]
 MOVSX EDI,BYTE PTR [EDI]
 MOV EBX,ESI
 XOR EBX,EDI
 MOV EDI,EBX
 AND EDI,0000000FFh
 mov eax,[hRes]
 MOV EDI,DWORD PTR [EDI*4+eax]
 SHR ESI,008h
 XOR EDI,ESI
 MOV DWORD PTR [EBP-004h],EDI
 LOC_0043F47D: ;Ref: 0043F44F
 MOV EDI,DWORD PTR [EBP-008h]
 MOV ESI,EDI
 SUB ESI,001h
 MOV DWORD PTR [EBP-008h],ESI
 CMP EDI,000h
 JG LOC_0043F451
 XOR DWORD PTR [EBP-004h],-001h
 MOV EAX,DWORD PTR [EBP-004h]
 POP EDI
 POP ESI
 POP EBX
 LEAVE
 RETN
 
 ret
 
 GenKey endp
 
Чтобы вызвать наш колл делаем так:
 .data
 buff1 db 15 dup (0)
 buff2 db 64 dup (0)
 conv db "%lu-",0
 
 invoke GetWindowTextA,hEdit1,addr buff1,15
 call GenKey
 
 invoke wsprintf,addr buff2,addr conv,eax
 invoke lstrcat,addr buff2,addr buff1
 
Все в buff2 мы имеем наш ключ 2299561597-V0LDEMARPRESENT

Генерим наш ключ и вводим в прогу, перезапускаем и все ок нету НАГа. Пробуем сканировать реестр, а потом удалить ключ, и что за черт снова НАГ. Что-то не то. Кстати у меня был такой кейген что генерировал что то похожее он также работал генерил первое число относительно 15 символов, но там этими символами было число которое генерилось псевдо рандомом то есть там использовалась библиотека msvcrt.dll и функ. rand конечно это число что выдавала функ. rand подвергалась еще многим математическим операциям, и на последок этот кейген был сделан группой CORE, халявщики ;)

Ну сейчас мы все исправим.
Заходим в Олли и открываем нашу прогу и переходим в наш колл генерации 43F432 и устанавливаем там брейк по F2.И пускаем прогу на выполнение F9 мы в колле теперь жмем Ctrl+F9 чтобы выйти и видим такой интересный код:
 Тут как и сверху сгенерили первое число
 .text:0043A234 call sub_43F432
 .text:0043A239 add esp, 4
 .text:0043A23C mov [ebp+var_15C], eax
 .text:0043A242 mov edi, [ebp+var_158]
 .text:0043A248 mov [ebp+edi+var_151], 0
 .text:0043A250 lea edi, [ebp+var_151]
 .text:0043A256 push edi
 Тут превратили первие символы
 .text:0043A257 call sub_45E7C0
 .text:0043A25C add esp, 4
 .text:0043A25F mov [ebp+var_164], edx
 .text:0043A265 mov [ebp+var_168], eax
 .text:0043A26B mov edi, [ebp+var_168]
 .text:0043A271 mov [ebp+var_160], edi
 .text:0043A277 mov edi, [ebp+var_160]
 вот здесь интересно после проверки, если сходятся числа
 .text:0043A27D cmp [ebp+var_15C], edi
 .text:0043A283 jnz short loc_43A2D2
 
 то записываем сюда в эти 7 переменных какие-то значения
 .text:0043A285 mov dword_479458, 175h
 .text:0043A28F mov dword_47945C, 2CEh
 .text:0043A299 mov dword_479460, 13Ah
 .text:0043A2A3 mov dword_479464, 0B2h
 .text:0043A2AD mov dword_479468, 247h
 .text:0043A2B7 mov dword_47946C, 0B2h
 .text:0043A2C1 mov dword_479470, 247h
 а также в еах 1 и на выход интересно
 .text:0043A2CB mov eax, 1
 .text:0043A2D0 jmp short loc_43A2D7
 понятно если некатит то мы прыгаеми сюда
 
 .text:0043A2D2 mov eax, 0
 .text:0043A2D7 pop edi
 .text:0043A2D8 pop esi
 .text:0043A2D9 leave
 .text:0043A2DA retn
 
 самое интересное идет дальше трассируем по F8 и выходим по рету сюда:
 
 .text:0040B091 call sub_43A17C
 .text:0040B096 cmp eax, 0
 конечно ключ не тот то мы и не прыгаем
 .text:0040B099 jnz short loc_40B105
 .text:0040B09B push 0 ; dwInitParam
 .text:0040B09D push offset DialogFunc ; lpDialogFunc
 .text:0040B0A2 push ds:hWndParent ; hWndParent
 .text:0040B0A8 push offset aDlgg ; lpTemplateName
 .text:0040B0AD push ds:hInstance ; hInstance
 тут делают наш НАГ
 .text:0040B0B3 call DialogBoxParamA
 .text:0040B0B8 cmp eax, 0
 .text:0040B0BB jz short loc_40B117
 и вот опять эти 7 переменных которым присваивают 1 если ключ не тот
 .text:0040B0BD mov dword_479458, 1
 .text:0040B0C7 mov dword_47945C, 1
 .text:0040B0D1 mov dword_479460, 1
 .text:0040B0DB mov dword_479464, 1
 .text:0040B0E5 mov dword_479468, 1
 .text:0040B0EF mov dword_47946C, 1
 .text:0040B0F9 mov dword_479470, 1
 .text:0040B103 jmp short loc_40B117
 
 сюда мы попадаем если все ок, здесь деактивируют пункт меню "Регистрация"
 .text:0040B105
 .text:0040B105 loc_40B105: ; CODE XREF: sub_40AE2A+26F j
 .text:0040B105 push 1 ; uEnable
 .text:0040B107 push 467h ; uIDEnableItem
 .text:0040B10C push ds:hMenu ; hMenu
 .text:0040B112 call EnableMenuItem
 
 Я запускал Айс и ставил так:
 bpm 479458
 bpm 47945c
 ...
 Чтобы туториал не превращать в книгу я сразу скажу что
 еще одна проверка будет здесь:
 
 .text:0043B86B sub edi, 0Ch --- устанавливают указатель на
 последних 12 символов ключа
 .text:0043B86E mov [ebp+var_1C0], edi
 .text:0043B874 lea edi, [ebp+var_1BA] --- сюда кладут указатель на буфер
 .text:0043B87A lea esi, ds:4A543Dh --- а здесь массив на
 .text:0043B880 mov ecx, 16Dh --- 365 елементов
 .text:0043B885 rep movsb
 .text:0043B887 lea edi, [ebp+var_1BA]
 .text:0043B88D push edi
 .text:0043B88E call sub_43E3FC --- эта функ. ксорит этот массив
 так как ключ сохр в заксореном состоянии в wintools.ini
 то и массив с которым будут сравнивать наш ключ тоже ксорят
 
 .text:0043B893 add esp, 4
 .text:0043B896 mov edi, [ebp+var_1C0]
 .text:0043B89C lea edi, [ebp+edi+ReturnedString]
 .text:0043B8A0 push edi
 .text:0043B8A1 lea edi, [ebp+var_1BA]
 .text:0043B8A7 push edi
 Эта функ. ищет строку с 12 символов в этом массиве 004A543D
 |
 .text:0043B8A8 call strstr
 .text:0043B8AD add esp, 8
 .text:0043B8B0 cmp eax, 0
 .text:0043B8B3 jnz short loc_43B929
 
 А вот как я догадался где будет еще одна проверка
 .text:0043B8B5 push 0 ; nDefault
 .text:0043B8B7 push offset aData3 ; lpKeyName
 .text:0043B8BC push offset aRam ; lpAppName
 .text:0043B8C1 call GetProfileIntA
 .text:0043B8C6 cmp eax, 0
 .text:0043B8C9 jmp short loc_43B913
 Нашы 7 переменых
 .text:0043B8CB mov dword_479458, 1
 .text:0043B8D5 mov dword_47945C, 1
 .text:0043B8DF mov dword_479460, 1
 .text:0043B8E9 mov dword_479464, 1
 .text:0043B8F3 mov dword_479468, 1
 .text:0043B8FD mov dword_47946C, 1
 .text:0043B907 mov dword_479470, 1
 .text:0043B911 jmp short loc_43B96E
 
Ну вот и все теперь можно писать работающий кейген.

Теперь мы знаем как должен выглядеть наш ключ:
(число)-(3 любые знака)(строка с массива)
Вот пример:
1116421270-8YN98VXY4TLNUIY
Я не буду очень напрягаться и напишу кейген без генерации 3 любых знаков я просто возьму строку на 15 из массива конечно количество разных ключей значительно меньше, чем с 3-ма знаками но это не главное.
 -----------------------------------------------------------------
 .Data
 
 conv db "%lu-",0
 conv2 db "%.15s",0
 buff1 db 255 dup (0)
 let dd 0
 let1 dd 0
 rnd dd 0
 
 
 -----------------------------------------------------------------
 
Делаем цикл надеюсь все догадались что здесь я делаю, просто беру время как случайное число
 back:
 invoke GetLocalTime,addr systime
 lea eax,systime.wMilliseconds
 xor ebx,ebx
 mov bl,[eax]
 mov rnd,ebx
 .if rnd > 0 && rnd < 349
 jmp go
 .endif
 jmp back
 
 go:
 потом это число использую как смещение в массиве
 и конечно массив в ресурсе
 invoke FindResource,0,1777,RT_RCDATA
 mov let1,eax
 invoke LoadResource,0,eax
 mov let,eax
 invoke LockResource,eax
 mov eax,rnd
 mov ebx,let
 add eax,ebx
 invoke wsprintf,addr buff1,addr conv2,eax
 
 invoke lstrcpy,addr buff2,addr buff1
 call GenKey
 
 invoke wsprintf,addr buff1,addr conv,eax
 invoke lstrcat,addr buff1,addr buff2
 invoke SetDlgItemText,hWin,1002,addr buff1
 invoke FreeResource,let1
 ------------------------------------------------------------
 
Ну вот и все.

ЗЫЖ Кто захочет кейген могу выслать исходник или .ехе-шник.


Пишите на : v0ldemar@mail333.com

Обсуждение статьи: Пишем КейГен для WinTools.NET Pro 3.8.1 при помощи TMG Ripper Studio >>>


Комментарии к статье: Пишем КейГен для WinTools.NET Pro 3.8.1 при помощи TMG Ripper Studio

Панкрат-крутень 29.05.2004 17:44:30
грамотно всё вроде. Для новичка неплохо написано короче.
---

Материалы находятся на сайте https://exelab.ru



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS