cracking
TRANSCRIPT
SACCOPHARYNX Tutorial Cracking
Program:
2nd Speech Center v1.3
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 pronunciación, 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: invoke GetModuleHandle, NULL mov hInstance, eax invoke DialogBoxParam,
hInstance, IDD_DIALOG, NULL, addr DlgFunc, NULL invoke ExitProcess, NULL; to manage
the DialogBox; DlgFunc proc hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD if
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
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: mov
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: mov edi, offset serial;edi aims at serial,
that will have the correct serial ciclo3: mov to, byte ptr[esi+ebx-1 ];se reduces one
so that byte points at the correct character mov ptr[edi], to Inc. edi DEC ebx cmp
ebx, 0;ciclo3 invests the serial invested, from seraux to serial jne ciclo3;de this
the doubts again ret badly: 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 animación 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 EQU 4
Y_Blocks EQU 3
SwapFrames EQU 14
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)
Block_dx DD 0
Block_dy DD 0
Main_TopX DD 0
Main_BottomY DD 0
Block1_X DD 0
Block1_Y DD 0
Block2_X DD 0
Block2_Y DD 0
seed DD 0
hwndBMP DD 0
hBMP DD 0
hDC DD 0
Counter DD 0
hdcMem1 DD 0
hdcMem2 DD 0
h1 dd 0
h2 dd 0
BlocksArray 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 códigos fuentes completos de cada KeyGen se pueden bajar de aquí:
KeyGen 1
KeyGen 2
en escribirme. Hasta el próximo tutorial.
Saludos
se pudra en sus cerebros. Continuemos así.
Desde las profundidades del abismo...
http://www.iespana.es/saccopharynx