You are on page 1of 16

SACCOPHARYNX Tutorial Cracking Program: 2nd Speech Center v1.

PROTECTION: Serial. Description: Program that reads text in English. Difficulty: Novice, Facililla, Average , Advanced, Difficult, Elite, ETC . DOWNLOAD: http://www.zero2000.com Tools: Case out inspector, DEDE, Ollydbg, RegMonitor, MASM32. CRACKER: SACCOPHARYNX DATE: 10/04/2003 Tutorial: 013

INTRODUCTION Greetings to all crackers: Because once they sent an email asking to me like became an Animated KeyGen , of which it did not have nor idea, I put myself to investigate just a little bit and is as east tutorial were born, for which the selected victim was 2nd Speech Center (2SC) .

TO THE ATAKE Intro As it is logical to think, if the objective is to do a KeyGen Animated, about this Presenting/displaying the victim 2SC is a useful application for any person who studies English, since she reproduces text with the purpose of improving the pronunciacin, having in addition the possibility Really of turning of text to MP3 or WAV. an interesting software. Hands to the work is that we have it to buy, but as the purpose is to make this tutorial, we entered a Name and a false Code as it is observed down. Soon we pressed Register and we will see: 4 , for which, what better tool than DEDE ? I believe that there is no another one. Then we opened iisc.exe with DEDE and in clickeamos the lapel called Procedures on About and very interesting ButtonRegClick call appears to us an Event : When doing a double click on him, DEDE takes us to the direction 86F8 , from which we began to investigate the code more down moving until finding to us: before. But if we observed that small piece of code at great length, to the salary a JMP in the 8810 direction , is very probable that somewhere we find a jump to the

direction 8812 or 8817 , but we would not get to obtain this message. Therefore, we began to investigate the code, this time upwards arriving a: the true serial with the false one. But it is hour to give thanks to DEDE for his invaluable aid, and transladamos us to him to Ollydbg . We loaded iisc.exe in Olly, we program. But ohhhhhhhhhh, that burnishes surprise that we took: As it can be observed in Registers (FPU), when the execution of 2SC arrives at 876C, the registries eax and edx contain 584111 respectively and 6405-2946 , being almost is the serial or true code, which comes us as ring to the finger to decipher the algorithm that generates it, since in case he is the correct one, we will with no need identify of easier way the end of the algorithm of tracear lines of more.

Name:

SACCOPHARYNX

and like

Code:

6405-2946

in order to verify that the code is the correct one. Click in Register again, and: The only thing to consider is that if is registered before discovering the algorithm, is, usuary not to be registered, we must eliminate the following entrance of registry: This entrance is discovered with RegMonitor when we entered the option of the Help->About menu , or seeing the code in DEDE. Continuing with cracking, in the previous image of Olly, we see that in 7861 call is another one, after as eax and edx happens to obtain the codes that already we saw. Therefore, we are as opposed to the CALL that generates the code. Again to Olly, and this time we put breakpoint on memory Access in the direction 8761, F9, executes 2SC, we entered any code, click in Register, and Olly is put in pause: As we see, before entering the CALL, eax with it has Name SACCOPHARYNX. We entered the same one pressing F7 , and traceamos lines until seeing the following thing: We are as opposed to the algorithm. The curl that is observed clearly between directions 89A4 and 89B0 , makes sumatoria of codes ASCII of the characters of our Name, whose value is accumulated in the registry ebx while eax is greater to 0, that is, while they are left characters without adding. 89BA to this value sumatoria of the characters is reduced to him (393h), obtaining like result 1905h , which we turned it to decimal and we obtain 6405 , that is the first part of the code. Continuing with the algorithm, in 89CC 43h to ebx is added, which contains 393h , being left 3D6h like result in ebx. In order to finish, in 89CF load in eax the B82h value , since ebx + (ebx*2) = 3D6h + (3D6h*2). Then, if we turned B82h to decimal, we remaining lines do not interest. Now to make the Animated KeyGen. The KeyGens Animated There are million forms to animate to a KeyGen and all depends on the creativity of their author. In this tutorial I will show two forms to animate to a KeyGen, structuring everything of simple way so that it is easy to understand. The aspects of

the KeyGens will be the following ones: KeyGen 1 In KeyGen 1 , a small circle illuminates to the image while it crosses it from a side to another one bouncing in the ends. KeyGen 2 In KeyGen 2 , the image is segmented in different fragments that are changing of location seeming a puzzle. For these animations we needed to insert an image in format BMP in the Keygen, which will be animated. Then, for each animation there will be a KeyGen. For both KeyGens we will use the same file of resources: rsrc.rc # include "c:\masm32\include\resource.h" # defines IDC_STATIC -1 # defines IDD_DIALOG 1000 # defines IDC_NAME 1001 # defines IDC_SERIAL 1002 # defines IDC_EXIT 1003 # defines IDC_ABOUT 1004 # defines IDC_CALC 1005 # defines IDC_BORRAR 1006 # defines Bmp_Con 109 BMP_RES BITMAP cave.bmp gulper2.ico app ICON IDD_DIALOG DIALOG 100,120,400,129 STYLE WS_CAPTION|DS_CENTER|WS_SYSMENU|WS_MINIMIZEBOX CAPTION "2nd. Speech Center v1.3 KeyGen" FONT 8, "MS Sans Serif" BEGIN GROUPBOX "Cracker Information", IDC_STATIC, 8, 5, 214, 30 LTEXT "SACCOPHARYNX", idc_static, 55, 13, 115, 8, to es_center LTEXT "http://www,iespana,es/saccopharynx", IDC_STATIC, 55, 21, 125, 8, ES_CENTER GROUPBOX "2nd Speech Center Website", IDC_STATIC, 8, 38, 214, 20 LTEXT "http://www,zero2000,com", IDC_STATIC, 55, 46, 115, 8, ES_CENTER GROUPBOX "KeyGen", IDC_STATIC, 8, 62, 214, 61 LTEXT "Name:", IDC_STATIC, 23, 78, 55, 8 LTEXT "Code:", IDC_STATIC, 23, 93, 55, 8 EDITTEXT IDC_NAME, 48, 75, 155, 12, es_autohscroll EDITTEXT IDC_SERIAL, 48, 90, 80, 12, es_autohscroll|ES_READONLY

PUSHBUTTON "&Generate Code", IDC_CALC, 137, 90, 66, 13 PUSHBUTTON "&Exit", IDC_EXIT, 154, 105, 49, 13 PUSHBUTTON "&About", IDC_ABOUT, 101, 105, 49, 13 PUSHBUTTON "&Again", IDC_BORRAR, 48, 105, 49, 13 CONTROL "BMP_RES",Bmp_Con," STATIC",SS_BITMAP,233,8,0,0 END in red were added. in KeyGen 1 ( 2ndSc.asm ) file GRAPHIX.INC will be included , whereas in KeyGen 2 ( 2ndSc2.asm ) file GRAPHIX2.INC is included . In both KeyGens a procedure is used whose KeyGen. The main source code is the following one: 2ndSc.asm 386 model flat, stdcall option casemap:none include c:\masm32\include\windows.inc include c:\masm32\include\user32.inc include c:\masm32\include\advapi32.inc include ; or graphix2.inc for 2 KeyGen includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\advapi32.lib includelib c:\masm32\lib\kernel32.lib includelib c:\masm32\lib\gdi32.lib CONST IDD_DIALOG EQU 1000 IDC_EXIT EQU 1003 IDC_ABOUT EQU 1004 IDC_CALC EQU 1005 IDC_BORRAR EQU 1006 IDC_NAME EQU 1001 IDC_SERIAL EQU 1002 ; ;Const to manage the image ; ID_TIMER EQU 1 ; ;Procedures definition ; DlgFunc PROTO:DWORD,:dword,:dword,:dword CodeGen PROTO GraphixTime PROTO data Icon db "app", 0 Iconimage db" app", 0 name db "SACCOPHARYNX", 8 dup(0), 0 serial db 80 dup(0), 0 seraux db 80 dup(0), 0 length db 04 dup(0), 0 head of cattle db 04 dup(0), 0 nothing db 20 dup(0), 0 txt1 db "From the depths of the abyss... least 1 to character is required...!",0 denuevo db" Try again... ",0 sumaascii dd 0 parte1 dd 0 flag dd 0 hInstance dd 0 hIcon dd 0 hWnd dd 0 IniGraphixFlag db 0 code start: the DialogBox; invoke GetModuleHandle, NULL mov hInstance, eax invoke DialogBoxParam, to manage DlgFunc proc hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD if

hInstance, IDD_DIALOG, NULL, addr DlgFunc, NULL invoke ExitProcess, NULL;

uMsg==WM_INITDIALOG mov eax, hDlg mov hWnd, eax invoke SetTimer, hWnd, ID_TIMER, 300, OFFSET GraphixTime invoke LoadIcon, hInstance, ADDR Icon mov hIcon, eax invoke SendMessage, hDlg, WM_SETICON, 1, hIcon invoke SetDlgItemText, hDlg, IDC_NAME, ADDR names elseif uMsg==WM_CLOSE invoke TerminateThread, hThread1, NULL invoke CloseHandle,

hEvent1 invoke EndDialog, hDlg, NULL SendMessage, hDlg, WM_CLOSE, 0, 0 elseif eax==IDC_ABOUT invoke MessageBox, hDlg, ADDR txt1, ADDR txt2, MB_OK elseif eax==IDC_BORRAR invoke SetDlgItemText, hDlg, IDC_NAME, ADDR nothing invoke SetDlgItemText, hDlg, IDC_SERIAL, ADDR nothing ret elseif eax==IDC_CALC invoke GetDlgItemText, hDlg, IDC_NAME, ADDR names, 21 invoke lstrcmp, ADDR names, ADDR nohay1 if eax==0 ret endif invoke lstrlen, ADDR names mov edx, offset long mov dword ptr [ edx], eax invoke CodeGen if eax==1 invoke SetDlgItemText ; to generate the code; CodeGen proc mov edi, offset name mov esi, offset

seraux;seraux will contain the xor inverted serial eax, eax xor ebx, ebx xor ecx, ecx;pongo in 0 the registries xor edx, edx mov flag, 0 mov edx, offset long mov edx, dword ptr [ edx ];edx happens to have the length of the name cmp edx, 1 jl badly;si name has less than 1 characters is error ciclo1: add ebx, 1 cmp edx, ebx jl to mov turn;cuando edx=ebx added all codigos ASCII mov to, byte ptr[edi ] add ecx, eax;sumo Inc. code ASCII edi jmp ciclo1;se repeats the cycle the next character to turn: sumaascii, ecx;guardo the sum in an auxiliary variable shl ecx, 3;al result of the previous sum;le I make a landslide of 3 bits to the left sub ecx, sumaascii;y soon him rest the value of the sum,; being left in ecx the correct serial mov parte1, ecx

mov ecx, sumaascii add ecx, 67 reads eax, [ecx+ecx*2 ] xor ebx, ebx mov ecx, 0ah ciclo2: beginning of this cycle eax contains the xor correct serial edx, edx;es necessary to put edx in 0 before making the division div ecx;div. eax by ecx. eax will have the result and edx the rest add dl, 48;sumo 48 to obtain the numerical character mov byte ptr[esi+ebx], dl add ebx, 1 final;al of ciclo2 ebx will contain the length of the serial cmp eax, 0;cuando eax is worth 0 copied all the digits to seraux je addfirstpart jmp ciclo2;ciclo2 copies the serial from eax to esi, being invested 1 mov eax, parte1 jmp ciclo2 to invest: that will have the correct serial ciclo3: so that ebx, 0;ciclo3 invests the serial invested, the doubts again ret badly: mov edi, offset serial;edi aims at serial, mov to, byte ptr[esi+ebx-1 ];se reduces one from seraux to serial jne ciclo3;de this

byte points at the correct character mov ptr[edi], to Inc. edi DEC ebx cmp mov eax, 1 ret CodeGen endp

controled by to timer;

GraphixTime Proc invoke Ini_Graphix_Parameters, hWnd,

hInstance invoke CreateThread, NULL, null, offset SwapIt, 0, NULL, \ OFFSET Thread1ID Mov hThread1, eax invoke CreateEventA, 0, FALSE, FALSE, NULL Mov hEvent1, eax invoke KillTimer, hWnd, ID_TIMER RET GraphixTime Endp

end start En los archivos GRAPHIX.INC y GRAPHIX2.INC se encuentran los respectivos preocedimientos de animacin para KeyGen 1 y KeyGen 2. A cualquiera que se le ocurra

GRAPHIX.INC

Ini_Graphix_Parameters PROTO :DWORD,:DWORD

El_Radius EQU 26 Speed EQU 20 Bmp_Con EQU 109

.DATA ;---------------------------------Bmp_info DD 0,0,0,0,0,0,0 ;Type ,*Width ,*Height ,WidthBytes ,Planes ,BitsPixel ,Bits

Bmp_Info_Size DD ($-OFFSET Bmp_info) Main_MaxX DD 0 Main_MaxY DD 0 SelBlock_X DD 0 SelBlock_Y DD 0 LastSel_X DD 0 LastSel_Y DD 0 seed DD 0 hwndBMP DD 0 hBMP DD 0 hDC DD 0 TFlag DB 0 XFlag DB 0 YFlag DB 0 hdcMem DD 0 hRgn DD 0 hLastRgn DD 0

BmpStr DB "BMP_RES",0 WindowMiniFlag DB 0

hEvent1 dd 0 Thread1ID dd 0 hThread1 dd 0

.CODE ;------------------------------------------Ini_Graphix_Parameters PROC ParentWindow:DWORD,hIns2:DWORD push ebx push ecx push edx push esi push edi

invoke LoadBitmap, hIns2, OFFSET BmpStr Mov hBMP, eax invoke GetDlgItem, ParentWindow, Bmp_Con Mov hwndBMP,eax invoke GetObjectA, hBMP, Bmp_Info_Size, OFFSET Bmp_info Mov eax, dword ptr [Bmp_info+4] ;width Mov Main_MaxX,eax Mov eax, dword ptr [Bmp_info+8] ;hieght Mov Main_MaxY,eax Mov SelBlock_X,1 Mov SelBlock_Y,14 Push SelBlock_X Pop LastSel_X Push SelBlock_Y Pop LastSel_Y pop edi pop esi pop edx pop ecx pop ebx RET Ini_Graphix_Parameters ENDP

;--------------------------------SwapIt PROC event:DWORD invoke GetDC , hwndBMP Mov hDC, eax

.IF XFlag==0 Inc SelBlock_X Mov eax,SelBlock_X Add eax, El_Radius

.IF (eax>Main_MaxX) Mov XFlag,1 .ENDIF .ELSE Dec SelBlock_X Mov eax,SelBlock_X .IF ((eax<0)||(eax==0)) Mov XFlag,0 .ENDIF .ENDIF

.IF YFlag==0 Inc SelBlock_Y Mov eax,SelBlock_Y Add eax, El_Radius .IF (eax>Main_MaxY) Mov YFlag,1 .ENDIF .ELSE Dec SelBlock_Y Mov eax,SelBlock_Y .IF ((eax<0)||(eax==0)) Mov YFlag,0 .ENDIF .ENDIF

Mov eax,SelBlock_X Mov ebx,SelBlock_Y Add eax,El_Radius Add ebx,El_Radius Push ebx Push eax Push SelBlock_Y Push SelBlock_X call CreateEllipticRgn Mov hRgn, eax

Mov hdcMem, eax Mov eax,LastSel_X Mov ebx,LastSel_Y Add eax,El_Radius Add ebx,El_Radius Push ebx Push eax

Push LastSel_Y Push LastSel_X call CreateEllipticRgn Mov hLastRgn, eax

.IF TFlag!=0 invoke CombineRgn,hRgn,hLastRgn,hRgn, RGN_XOR .ELSE invoke CombineRgn,hRgn,hRgn,hLastRgn, RGN_COPY Mov TFlag,1 .ENDIF

invoke InvertRgn, hDC, hRgn

invoke ReleaseDC, hwndBMP,hDC invoke DeleteObject, hLastRgn invoke DeleteObject, hRgn

invoke WaitForSingleObject,hEvent1,Speed .IF eax==WAIT_OBJECT_0 invoke ResetEvent, hEvent1 Mov TFlag,0 .ENDIF

Push SelBlock_X Pop LastSel_X Push SelBlock_Y Pop LastSel_Y Jmp SwapIt RET SwapIt ENDP

GRAPHIX2.INC

LIni_Graphix_Parameters PROTO :DWORD,:DWORD Random PROTO :DWORD

X_Blocks Y_Blocks Bmp_Con

EQU 4 EQU 3 EQU 109

SwapFrames EQU 14

.DATA ;------------------------------------------------Bmp_info DD 0,0,0,0,0,0,0 ;Type ,*Width ,*Height ,WidthBytes ,Planes ,BitsPixel ,Bits Bmp_Info_Size DD ($-OFFSET Bmp_info) Block_dx Block_dy Main_TopX Main_BottomY Block1_X Block1_Y Block2_X Block2_Y seed hwndBMP hBMP hDC Counter DD 0 DD 0 DD 0 DD 0 DD 0 DD 0 DD 0 DD 0 DD 0 DD 0 DD 0 DD 0 DD 0

hdcMem1 hdcMem2

DD 0 DD 0

h1 h2 BlocksArray

dd 0 dd 0 DD 2*(4*SwapFrames) dup(0)

BmpStr

DB "BMP_RES",0

WindowMiniFlag DB 0

.CODE ;------------------------------------------------------------------Ini_Graphix_Parameters PROC ParentWindow:DWORD,hIns2:DWORD invoke LoadBitmap, hIns2, OFFSET BmpStr Mov hBMP, eax invoke GetDlgItem, ParentWindow, Bmp_Con Mov hwndBMP,eax invoke GetObjectA, hBMP, Bmp_Info_Size, OFFSET Bmp_info ; Width / X_Blocks => Block_dx ; Width Mod X_Blocks => Main_TopX Mov eax, dword ptr [Bmp_info+4] ;width Mov ecx,X_Blocks Xor edx,edx Div ecx Mov Block_dx,eax Mov Main_TopX,edx Mov eax, dword ptr [Bmp_info+8] ;Hieght Mov ecx,Y_Blocks Xor edx,edx Div ecx Mov Block_dy,eax Mov eax, dword ptr [Bmp_info+8] Sub eax,edx Mov Main_BottomY,eax RET Ini_Graphix_Parameters ENDP

;------------------------------------------------------------------SwapIt PROC .IF WindowMiniFlag==1 Mov Counter,0 RET .ENDIF invoke GetDC , hwndBMP Mov hDC, eax .IF Counter==0 Mov Counter, SwapFrames Mov ecx, SwapFrames Shr ecx,1 Mov edi, OFFSET BlocksArray @FillArray: Call SelectTwoBlocks Mov eax, Block1_X

Stosd Mov eax, Block1_Y Stosd Mov eax, Block2_X Stosd Mov eax, Block2_Y Stosd loop @FillArray Mov esi, edi Sub esi, 16 Mov ecx, Counter Shr ecx,1 @MirrorArray: lodsd stosd lodsd stosd lodsd stosd lodsd stosd Sub esi, 16*2 loop @MirrorArray .ENDIF

Dec Counter Mov ecx,Counter Shl ecx,4 Add ecx,OFFSET BlocksArray Mov eax, [ecx] Mov Block1_X,eax Mov eax, [ecx+4] Mov Block1_Y,eax Mov eax, [ecx+8] Mov Block2_X,eax Mov eax, [ecx+12] Mov Block2_Y,eax

call SaveFirstBlock Call SaveSecondBlock

Call Block1ToScreen Call Block2ToScreen

invoke DeleteDC, hdcMem1 invoke DeleteDC, hdcMem2 invoke ReleaseDC, hwndBMP,hDC

invoke DeleteObject, h1 invoke DeleteObject, h2 RET SwapIt ENDP

;------------------------------------------------------------------SelectTwoBlocks PROC push eax push ebx push ecx push edx Mov eax,X_Blocks invoke Random, eax Mov ecx, Block_dx Mul cx Add eax,Main_TopX Mov Block1_X,eax

Mov eax,Y_Blocks invoke Random, eax Mov ecx, Block_dy Mul cx Mov Block1_Y,eax @Select2ndBlock: Mov eax,X_Blocks invoke Random, eax Mov ecx, Block_dx Mul cx Add eax,Main_TopX Mov Block2_X,eax

Mov eax,Y_Blocks invoke Random, eax

Mov ecx, Block_dy Mul cx Mov Block2_Y,eax

Mov eax,Block1_X .IF eax==Block2_X Mov eax,Block1_Y .IF eax==Block2_Y Jmp @Select2ndBlock .ENDIF .ENDIF pop edx pop ecx pop ebx pop eax RET SelectTwoBlocks ENDP

;------------------------------------------------------------------Random Proc ModLimit:DWORD push ecx push ebx push edx invoke GetTickCount Mov cl,al Rol eax,cl Xor edx,edx Mov ecx, ModLimit Div ecx Mov eax,edx pop edx pop ebx pop ecx RET Random Endp

;------------------------------------------------------------------SaveFirstBlock PROC invoke CreateCompatibleDC, hDC Mov hdcMem1, eax invoke CreateCompatibleBitmap, hDC, Block_dx,Block_dy Mov h1, eax invoke SelectObject, hdcMem1, eax

invoke BitBlt, hdcMem1, 0, 0, Block_dx, Block_dy, hDC, \ Block1_X, Block1_Y, SRCCOPY RET SaveFirstBlock ENDP

;------------------------------------------------------------------SaveSecondBlock PROC invoke CreateCompatibleDC, hDC Mov hdcMem2, eax invoke CreateCompatibleBitmap, hDC, Block_dx,Block_dy Mov h2, eax invoke SelectObject, hdcMem2, eax invoke BitBlt, hdcMem2, 0, 0, Block_dx, Block_dy, hDC, \ Block2_X, Block2_Y, SRCCOPY RET SaveSecondBlock ENDP

;------------------------------------------------------------------Block1ToScreen PROC invoke BitBlt, hDC, Block2_X, Block2_Y,Block_dx, Block_dy, hdcMem1, \ 0,0, SRCCOPY RET Block1ToScreen ENDP

;------------------------------------------------------------------Block2ToScreen PROC invoke BitBlt, hDC, Block1_X, Block1_Y,Block_dx, Block_dy, hdcMem2, \ 0,0, SRCCOPY RET Block2ToScreen ENDP

-------------------------------------------------------------------------------

Los cdigos fuentes completos de cada KeyGen se pueden bajar de aqu:

KeyGen 1

KeyGen 2

en escribirme. Hasta el prximo tutorial.

Saludos se pudra en sus cerebros. Continuemos as. Desde las profundidades del abismo... http://www.iespana.es/saccopharynx saccopharynx@yahoo.com

You might also like