Keygenner G*i*l*i*S*o*f*t E*x*e L*o*c*k v10.0.0

Introduction:


Dans ce tutoriel nous allons keygenner E*x*e L*o*c*k v10.0.0

Les outils:



I: Démarrage


Installez l'application, le programme d'installation vous demandera de redémarrer votre ordinateur, cliquez sur non.
Une fois installé, scanner l'exécutable principal (ExeLock.exe) avec DiE pour voir s'il est compressé, on ne dirait pas, cool.
Ouvrons l'application et essayons de nous enregistrer avec un faux numéro de série pour voir le comportement.


1


Nous avons un message qui nous indique que la longueur du sérial n'est pas bonne.
Ok cela nous suffira.


II: Trouver la procédure de calcul


Chargez l'application dans le débogueur et lancez-la complètement avec F9.
Entrez à nouveau un faux numéro de série pour avoir à nouveau le message "Invalid regcode length." Et mettez le débogueur en pause.
Une fois en pause, faites ALT+F9, ou depuis le menu d'olly : debug>Execute till user code


1


Maintenant que l'exécution a repris, cliquez sur OK pour fermez le message "Invalid regcode length.".
Le débogueur break, nous sommes maintenant a l'offset 006A52E6, juste après l'appel à MessageBoxW


1


Après avoir regardé un peu la procédure actuelle, il semble que nous soyons sur le segment d'enregistrement !
Mettez donc un point d'arrêt au début de la procédure en cours : 006A50CC


1


Il est maintenant temps de tracer cette routine.


III: Comprendre la routine



On commence à tracer, on rencontre d'abord un "email check" appelé depuis une API de commondll.dll
Si c'est bon, nous prenons le saut conditionnel et atterrissons juste sous le JMP.
Si ce n'est pas bon alors le saut conditionnel n'est pas pris, un MessageBox est affiché et nous prenons le saut pour quitter le segment.


1


On continue à tracer et puis on a un "empty check" pour le champ du numéro de série. Le code est similaire à ce que l'on a vu précédemment, si c'est bon, nous prenons le saut conditionnel.


1


Après la vérification que le champ ne soit pas vide, nous avons un contrôle de longueur, notre numéro de série doit faire 35 caractères (23 en hexadécimal)
Notre longueur n'est pas bonne, alors corrigeons cela, mettons un point d'arrêt sur la ligne actuelle, puis reprenons l'exécution de l'application.
Fermez la MessageBox d'erreur, et corrigez votre sérial avec quelque chose du genre:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Et cliquez sur Register pour rebreak sur votre ligne.


1


Une fois les vérifications de longueurs passées, le sérial est tronqué dans une routine.
Où l'on peut voir :
MOV ECX,5 (saisis 5 caractères)
MOV EDX,0D (commencez à saisir à la position 13 sur la chaîne)
MOV EAX, DWORD PTR SS:[EBP-8] (la chaîne à tronquer, notre faux sérial)
Une fois cela fait, nous avons un deuxième CALL qui vérifie si c'est un chiffre ou non.
Et une fois cela fait, nous avons une comparaison en hard avec 5541 (21825 en décimale) contre les 5 caractères saisis dans notre sérial.


1


Notre numéro de série n'est pas bon, faisons donc le bon réglage pour passer cette étape.
Placez un point d'arrêt sur la comparaison, reprenez l'exécution et changez votre sérial en quelque chose du genre: AAAAAAAAAAAA21825AAAAAAAAAAAAAAAAAA


Puis revenez à votre CMP et nous pouvons maintenant continuer à tracer.
Une fois cette vérification en hard passée, nous passons sur une liste noire de sérial.
Puis nous traçons jusqu'à atteindre un API call "MS_CheckSN" contenu dans MagicSkin.dll, il semble que les choses intéressantes soient faites par cette dll.
Donc une fois que vous êtes dessus.. F7 pour entrer.


1


Nous pouvons voir la liste des imports avec quelques autres apis intéressants aux noms évocateurs.
Très bien, F7 à nouveau pour entrer dans MagicSkin.dll.


1


Une fois sur la dll, on continue à tracer, celle-ci est un peu plus compliquée à comprendre.
Mais on reconnaît facilement des choses en traçant ce que l'on a vu précédemment: le contrôle de longueur et le contrôle de la partie dure.
Et aussi une armée de numéros de série.


1


Après avoir passé les numéros de série, nous approchons de la fin du segment de MS_CheckSN, notre intérêt se porte à 00A01CB5.
Pour mieux comprendre ce qui se passe, mettons d'abord un point d'arrêt et reprenons/modifions notre numéro de série en quelque chose répondant aux attentes du développeur.
Par exemple: 11111-22222-21825-33333-44444-55555


1


Expliquons en traçant maintenant,
Nous rencontrons d'abord un appel à une procédure (CALL 00A040AC) celle-ci va mettre C3BC dans EAX (50108 en décimal)
MOV DWORD PTR SS:[EBP-28],EAX: C3BC est mis dans un buffer.
MOV EAX,DWORD PTR SS:[LOCAL.2]: Place '22222' de notre faux sérial dans EAX
ADD EAX,DWORD PTR SS:[LOCAL.10] fait une addition dans EAX, 22222+50108 (=11A8A, 72330 en décimal)


Ensuite, nous avons une division:
XOR EDX,EDX: Mets EDX à zéro
MOV ECX,1869F: Mets 1869F dans ECX (9999 en décimal)
DIV ECX: Divise ECX par 1869F, le résultat et EAX=0 et EDX=11A8A


Ensuite nous avons une comparaison:
CMP DWORD PTR SS:[LOCAL.8],EDX: compare '33333' de notre numéro de série contre 11A8A (72330 en décimal)
Après cela, nous avons un saut conditionnel qui est effectué si le résultat de la comparaison n'est pas égal.
Donc pour passer cette vérification en numéro de série il faudrait avoir: 11111-22222-21825-72330-44444-55555


Une fois cette première vérification passée, nous avons le même genre de calcul, mais cette fois avec la partie '11111' de notre numéro de série qui va être calculé et comparé à '44444' de notre numéro de série. Le résultat de 11111+50108 est égal à 61219
Après la division, le résultat est encore comparé dans EDX.
Pour passer celui-ci, le numéro de série doit être: 11111-22222-21825-72330-61219-55555


1


Une fois cette deuxième vérification passée, la procédure de MS_CheckSN est terminée, on obtient EAX=1
Puis on revient au segment d'enregistrement, mais rien de spécial ne se passe ensuite hormis la décision du saut final sur le good boy/bad boy.
La partie '55555' de notre numéro de série n'est pas vérifiée et peut contenir n'importe quoi.


1


Nous avons terminé et nous sommes enregistrés si on reprend l'exécution.


1


Nous pouvons maintenant coder un keygen.


IV: Faire un keygen


Juste un peu d'aléatoire, d'addition et de division, rien d'extraordinaire.
Sur mon précédent tutoriel (Keygenner A*D S*t*r*e*a*m R*e*c*o*r*d*e*r v5.0), nous avons déjà vu un peu d'aléatoire avec GetLocalTime, cette fois nous allons utiliser GetTickCount pour changer.
Les numéros sont stockés dans une base szNumberz, et peut être utilisé simplement en faisant: invoke GenRandomNumbers,addr szBuffer,5
5 ici représente le nombre de caractères a généré dans szBuffer.


Les divisions longues sont à prendre en compte pour faire un keygen valide si vous souhaitez vous embêter avec ça.
par exemple: C537 (50487) + C3BC (50108) = 188F3 (100595)
Dans le cas présent notre dividende a 6 chiffres et notre diviseur en a 5 (99999).
En divisant 100595 par 99999, on obtient 1 comme quotient et 596 comme reste (dans edx)
Le programme va donc comparer 596 a votre sérial.
sérial valide: 50487-22222-21825-72330-596-5555555
La dernière partie du sérial n'étant pas vérifié on lui rajoute de la pagination pour atteindre les 35 caractères.
Ou sinon si vous ne souhaitez pas vous embêter avec ça (comme moi) et avoir un sérial harmonieux, vous faite un lenght check et si ça ne va pas on recalcule.


keygen.asm:

.486
.model flat, stdcall
option casemap :none ; case sensitive
include            \masm32\include\windows.inc
include            \masm32\include\user32.inc
include            \masm32\include\kernel32.inc
include            \masm32\include\shlwapi.inc
include            \masm32\macros\macros.asm

includelib         \masm32\lib\user32.lib
includelib         \masm32\lib\kernel32.lib
includelib         \masm32\lib\shlwapi.lib

DlgProc            PROTO    :DWORD,:DWORD,:DWORD,:DWORD
GenRandomNumbers   PROTO    :DWORD,:DWORD
NumbToStr          PROTO    :DWORD,:DWORD
Randomize          PROTO

.const
IDD_MAIN           equ 1000
IDB_EXIT           equ 1001
IDB_GEN            equ 1002
IDC_DATE_STATIC    equ 1003
IDC_SERIAL         equ 1004

.data
; Keygen details
szRndm             dd 0
szNumberz          db "0123456789",0

; App detail
szSerialDialog     db "Software Registeration",0
szClassSerial      db "TfrmReg",0

; Dialog details
szTitle            db "GiliSoft Exe Lock v10.0.0 *keygen*",0
szIDBExit          db "eXiT",0
szIDBGen           db "gENERATE!",0
szDateStatic       db "09/07/2021",0

.data?
hInstance          dd ?
szSerial1          db 100h dup(?)
szSerial2          db 100h dup(?)
szFinalSerial      db 100h dup(?)
szSerialRand       db 100h dup(?)
buff               db 11 dup(?) ; the maximum unsigned number
                                ; stored by a DWORD = 4294967296 ( 10 chars )
                                ; size of the buffer = 10 + 1
                                ; the last character is the NULL terminator
szSize             DWORD ?
windhand           dd ? ; Window handle of the registration dlg

.code
start:
    invoke GetModuleHandle,NULL
    mov hInstance,eax
    invoke DialogBoxParam,hInstance,IDD_MAIN,0,ADDR DlgProc,0
    invoke ExitProcess,eax

DlgProc proc    hWnd    :DWORD,
                uMsg    :DWORD,
                wParam  :DWORD,
                lParam  :DWORD
    mov eax,uMsg

    .if eax == WM_INITDIALOG
        ; Set the dialog controls texts. Done here in the code instead of resource
        ; file to reduce the required bytes (strings in the rc file are UNICODE not ANSI)
        invoke SetWindowText,hWnd,addr szTitle ; Set the window title text
        invoke SetDlgItemText,hWnd,IDB_GEN,addr szIDBGen
        invoke SetDlgItemText,hWnd,IDB_EXIT,addr szIDBExit
        invoke SetDlgItemText,hWnd,IDC_DATE_STATIC,addr szDateStatic
    .elseif eax == WM_COMMAND
        mov eax,wParam
        .if eax == IDB_EXIT
            invoke SendMessage,hWnd,WM_CLOSE,0,0
        .elseif eax == IDB_GEN
            @GenAgain:
            call clean
            invoke GenRandomNumbers,addr szSerial1,5
            invoke lstrcpy,addr szFinalSerial,addr szSerial1
            invoke lstrcat,addr szFinalSerial,chr$('-')
            invoke GenRandomNumbers,addr szSerial2,5
            invoke lstrcat,addr szFinalSerial,addr szSerial2
            invoke lstrcat,addr szFinalSerial,chr$('-21825-')
            invoke StrToInt,addr szSerial2 ; (shlwapi)
            add eax,50108
            xor edx,edx
            mov ecx,01869Fh
            div ecx
            invoke NumbToStr,edx,addr buff
            invoke lstrcat,addr szFinalSerial,eax
            invoke lstrlen,addr szFinalSerial
            push eax
            mov szSize, eax
            .if szSize != 23 ;lenght check
                pop eax
                jmp @GenAgain
            .endif
            pop eax
            invoke RtlZeroMemory,addr szSize,sizeof szSize
            invoke lstrcat,addr szFinalSerial,chr$('-')
            invoke StrToInt,addr szSerial1
            add eax,50108
            xor edx,edx
            mov ecx,01869Fh
            div ecx
            invoke NumbToStr,edx,addr buff
            invoke lstrcat,addr szFinalSerial,eax
            invoke lstrlen,addr szFinalSerial
            push eax
            mov szSize, eax
            .if szSize != 29 ;lenght check
                pop eax
                jmp @GenAgain
            .endif
            invoke lstrcat,addr szFinalSerial,chr$('-')
            invoke GenRandomNumbers,addr szSerialRand,5
            invoke lstrcat,addr szFinalSerial,addr szSerialRand
            invoke SetDlgItemText,hWnd,IDC_SERIAL,addr szFinalSerial
            ; Try to send serial infos to the app.
            invoke FindWindow,addr szClassSerial,addr szSerialDialog
            .if eax
                mov windhand, eax
                invoke SendDlgItemMessageA,windhand,263524,WM_SETTEXT,0,addr szFinalSerial
            .endif
        .endif
	.elseif eax == WM_CLOSE
        invoke EndDialog,hWnd,0
    .endif
    xor eax,eax
    ret
DlgProc endp


NumbToStr proc  uses ebx x:DWORD,buffer:DWORD
    mov ecx,buffer
    mov eax,x
    mov ebx,10
    add ecx,ebx          ; ecx = buffer + max size of string
@@:
    xor edx,edx
    div ebx
    add edx,48           ; convert the digit to ASCII
    mov byte ptr[ecx],dl ; store the character in the buffer
    dec ecx              ; decrement ecx pointing the buffer
    test eax,eax         ; check if the quotient is 0
jnz @b
    inc ecx
    mov eax,ecx          ; eax points the string in the buffer
    ret
NumbToStr endp

GenRandomNumbers proc uses ebx pIn:DWORD,pLen:DWORD
    mov edi,pIn
    mov ebx,pLen
    .repeat
        invoke Randomize
        mov ecx,10       ; Change this number to a new Alphabet size if your gonna modify it
        xor edx,edx
        idiv ecx
        movzx eax,byte ptr [edx+szNumberz]
        stosb
        dec ebx
    .until zero?
    ret
GenRandomNumbers endp

Randomize proc uses ecx
    invoke GetTickCount
    add szRndm,eax
    add szRndm,eax
    add szRndm,'abcd'
    rol szRndm,4
    mov eax,szRndm
;   imul eax,'seed'
    ret
Randomize endp

clean proc
    invoke RtlZeroMemory,addr szFinalSerial,sizeof szFinalSerial
    invoke RtlZeroMemory,addr szSerial1,sizeof szSerial1
    invoke RtlZeroMemory,addr szSerial2,sizeof szSerial2
    invoke RtlZeroMemory,addr szSerialRand,sizeof szSerialRand
    invoke RtlZeroMemory,addr szSize,sizeof szSize
    ret
clean endp

end start

keygen.rc:

;This Resource Script was generated by WinAsm Studio.

#define IDD_MAIN 1000
#define IDB_EXIT 1001
#define IDB_GEN 1002
#define IDC_DATE_STATIC 1003
#define IDC_SERIAL 1004

IDD_MAIN DIALOGEX 10,10,184,43
FONT 8,"Tahoma"
STYLE 0x90c80804
EXSTYLE 0x00000188
BEGIN
    CONTROL "",IDB_EXIT,"Button",0x10010000,127,28,51,13,0x00000000
    CONTROL "",IDC_SERIAL,"Edit",0x50010801,3,9,177,12,0x00000200
    CONTROL "",IDB_GEN,"Button",0x10010000,70,28,51,13,0x00000000
    CONTROL "",IDC_DATE_STATIC,"Static",0x58000000,3,34,44,9,0x00000000
END

make.bat:

@echo off
\masm32\bin\rc /v keygen.rc
\masm32\bin\ml.exe /c /coff /Cp /nologo keygen.asm
\masm32\bin\link.exe /SUBSYSTEM:WINDOWS /RELEASE /VERSION:4.0 /OUT:Keygen.exe keygen.obj keygen.res
del keygen.res
del keygen.obj
pause

Une fois compilé, ça ressemble à ça:

1



C'est tout pour le moment!


Xylitol, 08/07/2021




Copyright (C)- xtx Team (2021)

XHTML valide 1.1 CSS Valide !