скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Исследование Winamp Skin Maker v1.2



Оформил: DeeCo
Автор: http://www.cracklab.narod.ru

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

Приступим к делу. Что нам сейчас нужно:
Softice 4.*
Icedump 6.* - только для того, чтобы копировать текст из Softice"а на диск.
Можете заменить его W32Dasm и ручкой с бумагой.
Hiew 32 6.5
Delphi 4-6 (6 recommended).
ResHacker, WinRar.

Итак, запускаем программу(перед этим Softice и т.д.).
Идем на Help->About->Register. Вводим РИ. Ставим брейкпоинт на hmemcpy.
Жмем OK. Попадаем в Softice. Снимаем брейкпоинт.
Теперь жмем F12 до тех пор, пока не вылезем в Skinner.exe. После этого наблюдаем следующее:
--------------------------------------------------byte--------------PROT---(0)--
-вырезано-
-------------------------------------------------------------------------PROT32-
 -вырезано-
016F:00406D7A        MOV       EDI,[USER32!GetDlgItemTextA]       
016F:00406D80         PUSH      ESI                                
016F:00406D81 CALL    EDI  (То есть USER32!GetDlgItemTextA) Name>      
016F:00406D83  LEA       EAX,[ESP+38]                       
016F:00406D87   PUSH      29                                 
016F:00406D89   PUSH      EAX                                
016F:00406D8A  PUSH      000003FD                           
016F:00406D8F   PUSH      ESI                                
016F:00406D90 CALL      EDI (То есть USER32!GetDlgItemTextA) Our reg.#>  
016F:00406D92    LEA       EAX,[ESP+0C]                       
016F:00406D96       PUSH      EAX                                
016F:00406D97 CALL      00407E30                            
016F:00406D9C      ADD       ESP,04                            
016F:00406D9F       MOV       EBX,EAX           

------------------------------------SKINNER!.text+5D64--------------------------
Break due to BPX KERNEL!HMEMCPY  (ET=1.26 seconds)                              
:bc *                                                                           
:/Screendump C:\f1.dos
Далее:
016F:00406DA1         LEA       EAX,[ESP+38]                      
016F:00406DA5         PUSH      EAX                                
016F:00406DA6  CALL  00407D00 
016F:00406DAB        ADD       ESP,04                             
016F:00406DAE         MOV       EDI,EAXТеперь в EDI результат (код)! 
016F:00406DB0          TEST      EDI,EDI        
016F:00406DB2           JNZ       00406DEB                            
И вот:
016F:00406DEB    CMP    ED(наш>,EBX(правильный>  
016F:00406DED      JNZ       00406E24
А EBX мы последний раз меняли ещё в первом случае!
Теперь остаётся "всего-то" узнать значение EBX программным способом для Skinner.exe в момент сравнения кодов :)!
Я видел где-то старый некрасивый способ, который предполагает спровоцировать сбой, Windows 95/98 покажет вам табличку с регистрами и сообщением об ошибке. Потом надо взять значение EBX , перевести в десят. систему и это будет код. Нудно, некрасиво, и не работает под другими ОС.
Я нашел способ, который проще и лучше. На это I've spent 24 hours.
Мне всегда нравилась функция ExitProcess(ExitCode:Cardinal). Говорят, что под Win X в ExitCode можно ставить любое число.
Пишем свой код после: (using Hiew)
016F:00406D97 CALL      00407E30 
016F:00406D9C      ADD       ESP,04
push eax
call Kernel32!ExitProcess
это ассемблируется до:
50+FF1548244300,
причем второе я подсмотрел в Imported Functions в W32Dasm, а 1-е написал сам Hiew.
Ну что, теперь программа по нажатию О.К. просто закрывается. Надо как-нибудь получить то, что она передаёт из EAX. Воспользуемся Delphi 6.
Sources:
program Project1;
uses Windows, SysUtils, Messages; //необходимый миниму>
{$APPTYPE GUI} //У нас Gui-приложение>
{$R Icon.res} //иконку возьме>
{$R Dlg.res} //и диалог тож>

var
  rc: Cardinal; //код на>
  StartupInfo: TStartupInfo; //необ. с>
  ProcessInfo: TProcessInformation; //необ. с>

procedure StartProcess(hWnd: THandle); //процедура наш>
begin
  rc := 0;
  FillChar(StartupInfo, Sizeof(StartupInfo), #0); //заполняем с>
  StartupInfo.cb := Sizeof(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := SW_SHOWDEFAULT;
  CreateProcess(nil, Pchar('WSV1.20.KG.exe'), nil, nil, false,
    NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo); //создаем процес>
  WaitforSingleObject(ProcessInfo.hProcess, INFINITE); //ждем завершени>
  GetExitCodeProcess(ProcessInfo.hProcess, rc); //получаем ко>
  if rc<
  >
  0 then
  begin
    SetDlgItemText(hWnd, 108, Pchar(IntToStr(rc)));
    SetDlgItemText(hWnd, 0, Pchar('Here is your Reg.#: '));
  end
  else //если кто-то не может ввести свое имя, то..>
    SetDlgItemText(hWnd, 108, Pchar('Incorrect name.'));
end;

function DialogProc(hWnd: THandle; Msg: Integer; wParam, lParam: Integer): Bool;
  stdcall;
begin
  if Msg = WM_INITDIALOG then
    RESULT := true //нужно для создания диалог>
  else if Msg = WM_CLOSE then
    ExitProcess(0) //если нас захотят закрыт>
  else if (Msg = WM_COMMAND) and (Wparam = 106) then //если нажали нашу кнопк>
  begin
    ShowWindow(hWnd, SW_Hide);
    StartProcess(hWnd);
    ShowWindow(hWnd, SW_Show);
  end
  else
    Result := false;
end;

//===========Не знаю зачем я это сделал================/>

procedure MessageBox(Wnd: Integer; Text: PChar; Caption: PChar; Typ: Integer);
  stdcall;
  external 'user32.dll' name 'MessageBoxA';
//=====================//
begin
  //А это официальное начало программы :-)>
  DialogBoxParam(GetModuleHandle(nil), PChar('DIALOG_0'), 0, @DialogProc, 0);
end.
Файл ресурсов:
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  * * * * *
file: D: \SLAVAPROJECTS\DELPHI\SK_KG\DLG.RC
Generated by Resource Builder 1.0.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  * * * * /
// Below are important 3 lines, don't change them!
/ *
OutputExt = RES
* /
DIALOG_0 DIALOG 127, 65, 180, 86
STYLE DS_ABSALIGN | DS_MODALFRAME | WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX |
  WS_POPUP |WS_CAPTION |WS_BORDER |WS_DLGFRAME
CAPTION "
KeyGen for Winamp Skin Maker 1.20 "
FONT 8, "
MS Sans Serif"
LANGUAGE LANG_NEUTRAL, 0
begin
  CONTROL "
  Start generating - >
  >
  "
  , 106, "
  BUTTON"
  , BS_PUSHBUTTON|WS_VISIBLE|WS_TABSTOP, 7, 62, 165, 20
    CONTROL "
Crack - type
  : KeyGen Author: wersion E - mail: wcrkgroup2002@mail.ru "
  , 65535, "
  STATIC"
  , BS_PUSHBUTTON|WS_VISIBLE|WS_TABSTOP, 10, 7, 159, 26
    CONTROL "
  "
  , 108, "
  EDIT"
  , BS_PUSHBUTTON|WS_VISIBLE|WS_TABSTOP|WS_BORDER, 92, 43, 83, 12
    CONTROL "
  Here will be your Reg.#0"
  , 65536, "
  STATIC"
  , BS_PUSHBUTTON|WS_VISIBLE|WS_TABSTOP, 11, 44, 75, 10
end
Все! Сие приложение занимает 40 кб, упакованное UPX"ом 20 кб. да, а нам нужен ещё и исходный Exe-file(388 кб - написано на MSVC). дабы уменьшить его размер, произведём следующие изменения. дойдём до окна About, затем поставим брейкпоинт на DialogBoxParamA
Жмем Register и попадаем в SoftIce, жмем F12.
016F:00406B8E    JNZ       004068A6                        
016F:00406B94     MOV       ESI,[ESP+78]                      
                                
016F:00406B9A   PUSH      00406D00                           
016F:00406B9F    MOV       EAX,[0042FB70]                     
016F:00406BA4   PUSH      ESI                                
016F:00406BA5   PUSH      0000008A                           
016F:00406BAA  PUSH      EAX                                
016F:00406BAB  CALL      [USER32!DialogBoxParamA]
Хорошо бы с самого начала прыгнуть на Но пусть программа сделает все свои дела, подгрузит ресурсы и т.д., а потом уж и покажет диалог.
Найдем call, который показывает основное окно. для этого загрузим программу в SymBol Loader. Будем заходить по F8 во все call'ы, после которых происходит показ окна, пока не дойдем до конечного, который занимается CreateWindowExA и т.д. Вот он:
  50                  PUSH      EAX
016F:00401D14  56                  PUSH      ESI                                
016F:00401D15  E8B6010000          CALL      00401ED0
С адреса впишем прыжок на . (A) вы уже сделали.
Теперь подредактируйте сей диалог в Skinner.exe. А потом вырежьте все ненужные ресурсы окромя иконок и его. Упакуйте все WinRar"ом.
Вот мой скрипт.
Setup=Start.exe 
Silent=1
Overwrite=1
TempMode
Эпилог Итак, что мы получили?
Кейген в 120 кб. Учитывая, что он содержит ориг. программу, а сам написан на Delphi, то это неплохо.
Чему мы научились?
Рационально работать. Первыми(я, по крайней мере) сделали кейген к этой программе.
Created by Wersion. 11/10/02. E-mail: wcrkgroup2002@mail.ru
Вопросы/пожелания/угрозы - приветствуются.






Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook