___           ___           ___           ___           ___           ___     
     /\  \         /\__\         /\  \         /\__\         /\  \         /\  \    
     \:\  \       /:/  /        /::\  \       /::|  |       /::\  \       /::\  \   
      \:\  \     /:/__/        /:/\:\  \     /:|:|  |      /:/\:\  \     /:/\ \  \  
      /::\  \   /::\  \ ___   /:/  \:\  \   /:/|:|__|__   /::\~\:\  \   _\:\~\ \  \ 
     /:/\:\__\ /:/\:\  /\__\ /:/__/ \:\__\ /:/ |::::\__\ /:/\:\ \:\__\ /\ \:\ \ \__\
    /:/  \/__/ \/__\:\/:/  / \:\  \ /:/  / \/__/~~/:/  / \/__\:\/:/  / \:\ \:\ \/__/
   /:/  /           \::/  /   \:\  /:/  /        /:/  /       \::/  /   \:\ \:\__\  
   \/__/            /:/  /     \:\/:/  /        /:/  /        /:/  /     \:\/:/  /  
                   /:/  /       \::/  /        /:/  /        /:/  /       \::/  /   
                   \/__/         \/__/         \/__/         \/__/         \/__/    
				   .openmod.org

Reversing complet des crackmes ABEX.

-|- A. Introduction


Bonjour à tous.

Aprés quelques periples divers et variés j'ai longtemps hesité à reprendre l'ecriture de tutoriaux sur le 
reverse engeneering. Cette fois si l'on ma tres clairement fait comprendre que s'en ete fini pour moi de 
decortiquer divers protections commerciales ou divers softs payants. De plus, face à la véracité de la 
recente Loi sur l'economie numerique , je n'ai pas vraiment envie de me retrouver dans l'obligation de 
me laver dans des douches collectives avec d'horrible gars bariollés de cicatrices et ne pensant qu'à
une chose ; faire tomber ma savonnette. L'etude du reverse engeneering au travers mes articles se fera 
donc par le bias de crackmes et autres softs LEGAUX prevus à cet effet.


J'ai recement recuperer un pack de 5 crackmes developpés par l'honorable ABEX. L'ensemble des ces 
crackmes sont annotés du "LEVEL 1" sur une echelle de 5. Excellent donc pour débuter. Ces crackmes 
ne semble pas etre de premiere jeunesse mais feront tout à fait l'affaire pour ceux qui decouvre le 
reverse engeneering, et pour moi de me remettre a mon sport preferé...action.


-|- B. Abex's Crackme


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

crackme : 1
crackme author : abex
type : cdrom check
level : easy

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


Analyse :
-----------

A peine on lance ce crackme, qu'un message apparait : "Make me think your HD is a CD-ROM"
On clique sur OK, et Hop "This is not a CD-ROM drive".

bon. On sort ollydebug et on va se faire plaisir. Et Hop voila ce que nous affiche ollydebug(1.10) :



00401000 >/$ 6A 00 PUSH 0 ; /Style MB_OK|MB_APPLMODAL
00401002 |. 68 00204000 PUSH abexcm1.00402000 ; |Title "abex' 1st crackme"
00401007 |. 68 12204000 PUSH abexcm1.00402012 ; |Text "Make me think your HD is a CD-Rom."
0040100C |. 6A 00 PUSH 0 ; |hOwner NULL
0040100E |. E8 4E000000 CALL ; \MessageBoxA
00401013 |. 68 94204000 PUSH abexcm1.00402094 ; /RootPathName "c:\"
00401018 |. E8 38000000 CALL ; \GetDriveTypeA
0040101D |. 46 INC ESI
0040101E |. 48 DEC EAX
0040101F |. EB 00 JMP SHORT abexcm1.00401021
00401021 |> 46 INC ESI
00401022 |. 46 INC ESI
00401023 |. 48 DEC EAX
00401024 |. 3BC6 CMP EAX,ESI
00401026 |. 74 15 JE SHORT abexcm1.0040103D
00401028 |. 6A 00 PUSH 0 ; /Style MB_OK|MB_APPLMODAL
0040102A |. 68 35204000 PUSH abexcm1.00402035 ; |Title "Error"
0040102F |. 68 3B204000 PUSH abexcm1.0040203B ; |Text "Nah... This is not a CD-ROM Drive!"
00401034 |. 6A 00 PUSH 0 ; |hOwner NULL
00401036 |. E8 26000000 CALL ; \MessageBoxA
0040103B |. EB 13 JMP SHORT abexcm1.00401050
0040103D |> 6A 00 PUSH 0 ; |/Style MB_OK|MB_APPLMODAL
0040103F |. 68 5E204000 PUSH abexcm1.0040205E ; ||Title "YEAH!"
00401044 |. 68 64204000 PUSH abexcm1.00402064 ; ||Text "Ok, I really think that your HD is a CD-ROM! :p"
00401049 |. 6A 00 PUSH 0 ; ||hOwner NULL
0040104B |. E8 11000000 CALL ; |\MessageBoxA
00401050 \> E8 06000000 CALL ; \ExitProcess
00401055 $-FF25 50304000 JMP DWORD PTR DS:[<&KERNEL32.GetDriveTyp>; kernel32.GetDriveTypeA
0040105B .-FF25 54304000 JMP DWORD PTR DS:[<&KERNEL32.ExitProcess>; kernel32.ExitProcess
00401061 $-FF25 5C304000 JMP DWORD PTR DS:[<&USER32.MessageBoxA>] ; USER32.MessageBoxA



Reversing :
-------------

Les BPX les plus utilisés dans le CD checks sont: GETDRIVETYPEA et GETVOLUMEINFORMATIONA.
pas manqué, l'api getdrivetypeA est presente.


Un autre truc me saute aux yeux directement :

00401024 |. 3BC6 CMP EAX,ESI
00401026 |. 74 15 JE SHORT abexcm1.0040103D


Le crackme compare (CMP) la valeur EAX et ESI.
l'instruction CMP soustrait l'opérande source à l'opérande de destination.
Si ces deux valeurs sont egales (JE Jump if Equal) il saute jusqu'en 0040103D.
C'est a dire qu'il affiche que l'on a reussi : "YEAH" ..machin truc


Petit tableau recapitulatif des sauts conditionnels :

JNE (jump if not equal) jump if not equal to zero (JNZ sous Soft-ice)
JE (jump if equal) jump if equal to zero (JZ sous Soft-ice)
JG (jump if greater) jump si c'est supérieur
JGE (jump if greater or equal) jump si c'est supérieur ou égal
JL (jump if less) jump si c'est inférieur
JLE (jump if less or equal) jump si c'est inférieur ou égal
JA (jump if Above)
JNA (jump if not above)


bon easy.



Tous d'abors je vais poser un BPX (breakpoint) (F2) sur :

00401024 |. 3BC6 CMP EAX,ESI

afin de savoir quel valeur il compare. Je lance le prog (F9) je clique sur OK,
et comme prevu il break, me permettant de connaitre les deux valeurs de ESI et EAX.

ESI 00000003
EAX 00000001

Ok, vous allez me dire .. Sympa .. mais sa nous sert a koi ?

Voila un petit tableau recapitulatif vous allez vite comprendre :

La valeur dans EAX veux dire:

0 Lecteur indéterminé
1 Répertoire sur la racine n'existe pas
2 Disque removable
3 Disque dur
4 Remote Drive(Network)
5 CD ROM
6 RamDisk

Donc le crackme ici compare EAX avec 3 ! Donc il veut un DISQUE DUR, sinon il saute!!

ON va donc pas se casser la tronche .. on va directement patcher la ligne suivante :

00401026 |. 74 15 JE SHORT abexcm1.0040103D
par
00401026 |. 75 15 JNE SHORT abexcm1.0040103D



Dans ollydebug (logiquement vous etes encore dans le break precedent) on se place sur
00401026 et on se fait un clik droit BINARY -> EDIT et op on change le 74 par 75 .. et OP F9

"Ok, I really think that your HD is a CD-ROM! :p"

Bingo.

easy non ? .. allez on s'endort pas et on passe au crackme suivant :




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

crackme : 2
crackme author : abex
type : Serial
level : easy

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




Analyse :
-----------

Ce second crackme se presente sous la forme d'un Name/Serial. On tente de rentrer des informations
bidons : name : "thomas" et serial : "999999" > "Nop this serial is wrong"

Je lance ollydebug et je m'apperçois aussitot que ce crackme est devellopé en VB. En effet des le
debut on peut y remarquer la patate de lignes y faisant reference :
00401000 > . 0CA44673 DD MSVBVM60._CIcos
00401004 > . A05B4673 DD MSVBVM60._adj_fptan
00401008 > . 6E884773 DD MSVBVM60.__vbaVarMove
0040100C > . 9E004773 DD MSVBVM60.__vbaFreeVar
00401010 > . 14DF3973 DD MSVBVM60.__vbaEnd
....

Deux choix s'offre a nous. Soit on continue sous ollydebug. Soit on enchaine avec SmartCheck. SmartCheck 
c'est ZE debugger Visual Basic de chez Numega. Pompable sur le net sans aucune difficulté. On va donc se 
faire plaisir avec smartcheck

Une fois SmartCheck installé, il convient avant de se lancer dans ce crackme de le configurer
avec les options adéquates. Tout d'abord Open > crackme2.exe puis dans le menu Program Settings:

- Error Detection: cocher toutes les cases excepté "Report errors immediately".

- Advanced: cocher les 4 premières cases.
Mais surtout ne pas cocher "Suppress system API and OLE calls" is not "ticked"

- Reporting: sélectionner toutes les cases excepté "Report MouseMove events from OCX controls".


Ensuite dans le menu View, il faut que "argument" soit sélectionné ainsi que "suppressed error".

voila....suffit ensuite de cliquer tout simplement sur la petite fleche verte .. et c parti..



Reversing :
-------------

On réinscrit nos informations bidons, et on clique sur check. Encore une fois > Nop ton serial
y pue. en tache de fond SmartCheck a decortiqué tout ce que fait le crackme pour verifier que ton serial 
est soit bon soit mauvais. En gros on y observe comment a partir du Name "thomas" il genere un Serial.

Asc(String"t") returns integer:116
Hex(VARIANT:Integer:216)

et cette operation ce repete pour chaque lettre du name "thomas"


En cliquant sur "show all events" (c'est le petit bouton en haut avec une bulle jaune), SmartCheck nous 
affiche la totalité des operations effectuées par ce crackme durant le processus de verification du 
serial. Bon j'ui d'accord avec vous y a beaucoup de merdier à l'ecran, mais vous allez voir que
ce n'est pas si compliqué que ça :

en dessous de notre Hex(VARIANT:Integer:216), on y retrouve ceci :
__VbaVarMove(VARIANT:String:"D8", VARIANT:Integer:216)returns DWORD:12F4D4

la lettre "t" de mon prenom, correspond donc a "D8"

Il nous est ainsi possible de visionner la totalité du Bon serial : D8CCD3D1

IL nous ai donné tout a la fin de la verification :

__VbaVarTstEq(VARIANT:String:"D8CCD3D1", VARIANT:String:"999999")returns DWORD:0

Reste a comprendre comment il calcul ce serial afin d'en faire un keygen



Keygen :
----------

pour reprendre l'algo :

t 116(dec) + 100 216 (dec) > converti en HEX D8

easy, merci smartcheck

allez Hop, on se fait meme un keygen en VB histoire
de vraiment se faire chier :


++++++++++++++++++++++++++++++++++++++++++++++++++
If Len(Text1.Text) < 4 Then

Text2.Text "Le nom doit être supérieur à 4 chars"

Else
For i 1 To 4

ASCII Hex(Asc(Mid$(Text1.Text, i, 1)) + 100)
CODE CODE + ASCII


Next i
Text2.Text CODE
End If
End Sub
++++++++++++++++++++++++++++++++++++++++++++++++++

et voila...et de deux...on continue sur la lancé avec le 3eme crackme de
notre ami ABEX.


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

crackme : 3
crackme author : abex
type : keyfile
level : easy

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



Analyse :
------------

Dans ce 3eme crackme ABEX semble avoir decidé de faire une protection du type keyfile.
Ne perdons pas de temps, il commence a se faire tard, lançons le directos sous ollydebug...


00401000 >/$ 6A 00 PUSH 0 ; /Style MB_OK|MB_APPLMODAL
00401002 |. 68 00204000 PUSH abexcrac.00402000 ; |Title "abex' 3rd crackme"
00401007 |. 68 12204000 PUSH abexcrac.00402012 ; |Text "Click OK to check for the keyfile."
0040100C |. 6A 00 PUSH 0 ; |hOwner NULL
0040100E |. E8 8C000000 CALL ; \MessageBoxA
00401013 |. 6A 00 PUSH 0 ; /hTemplateFile NULL
00401015 |. 68 80000000 PUSH 80 ; |Attributes NORMAL
0040101A |. 6A 03 PUSH 3 ; |Mode OPEN_EXISTING
0040101C |. 6A 00 PUSH 0 ; |pSecurity NULL
0040101E |. 6A 00 PUSH 0 ; |ShareMode 0
00401020 |. 68 00000080 PUSH 80000000 ; |Access GENERIC_READ
00401025 |. 68 B9204000 PUSH abexcrac.004020B9 ; |FileName "abex.l2c"
0040102A |. E8 5E000000 CALL ; \CreateFileA
0040102F |. A3 CA204000 MOV DWORD PTR DS:[4020CA],EAX
00401034 |. 83F8 FF CMP EAX,-1
00401037 |. 74 3C JE SHORT abexcrac.00401075
00401039 |. 6A 00 PUSH 0 ; /pFileSizeHigh NULL
0040103B |. FF35 CA204000 PUSH DWORD PTR DS:[4020CA] ; |hFile NULL
00401041 |. E8 4D000000 CALL ; \GetFileSize
00401046 |. 83F8 12 CMP EAX,12
00401049 |. 75 15 JNZ SHORT abexcrac.00401060
0040104B |. 6A 00 PUSH 0 ; /Style MB_OK|MB_APPLMODAL
0040104D |. 68 35204000 PUSH abexcrac.00402035 ; |Title "Well done!"
00401052 |. 68 40204000 PUSH abexcrac.00402040 ; |Text "Yep, keyfile found!"
00401057 |. 6A 00 PUSH 0 ; |hOwner NULL
00401059 |. E8 41000000 CALL ; \MessageBoxA
0040105E |. EB 28 JMP SHORT abexcrac.00401088
00401060 |> 6A 00 PUSH 0 ; /Style MB_OK|MB_APPLMODAL
00401062 |. 68 79204000 PUSH abexcrac.00402079 ; |Title "Error"
00401067 |. 68 7F204000 PUSH abexcrac.0040207F ; |Text "The found file is not a valid keyfile!"
0040106C |. 6A 00 PUSH 0 ; |hOwner NULL
0040106E |. E8 2C000000 CALL ; \MessageBoxA
00401073 |. EB 13 JMP SHORT abexcrac.00401088
00401075 |> 6A 00 PUSH 0 ; |/Style MB_OK|MB_APPLMODAL
00401077 |. 68 54204000 PUSH abexcrac.00402054 ; ||Title "Error"
0040107C |. 68 5A204000 PUSH abexcrac.0040205A ; ||Text "Hmmmmm, I can't find the file!"
00401081 |. 6A 00 PUSH 0 ; ||hOwner NULL
00401083 |. E8 17000000 CALL ; |\MessageBoxA
00401088 \> E8 0C000000 CALL ; \ExitProcess
0040108D $-FF25 54304000 JMP DWORD PTR DS:[<&KERNEL32.CreateFileA>; kernel32.CreateFileA
00401093 $-FF25 58304000 JMP DWORD PTR DS:[<&KERNEL32.GetFileSize>; kernel32.GetFileSize
00401099 .-FF25 5C304000 JMP DWORD PTR DS:[<&KERNEL32.ExitProcess>; kernel32.ExitProcess
0040109F $-FF25 64304000 JMP DWORD PTR DS:[<&USER32.MessageBoxA>] ; USER32.MessageBoxA



Reversing :
-------------

Tout est devant nos yeux.

00401025 |. 68 B9204000 PUSH abexcrac.004020B9 ; |FileName "abex.l2c"
0040102A |. E8 5E000000 CALL ; \CreateFileA

avec notepad on va donc creer un fichier s'appelant abex.l2c a coté du crackme.
on relance le crackme et hop .. "the found key is not a valid machin.." Bon on avance.
Un deuxieme truc me semble interessant :

00401041 |. E8 4D000000 CALL ; \GetFileSize
00401046 |. 83F8 12 CMP EAX,12
00401049 |. 75 15 JNZ SHORT abexcrac.00401060

il compare la taille de notre abex.l2c avec 12... on va claquer un bpx sur 00401046 et
modifier le CMP EAX 12, en CMP EAX 0, vu ke la taille de notre abex.l2c..et on lance..

.. bon bingo .. pas d'explosion de joie. celui là etait plutot facile. Suivant


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

crackme : 4
crackme author : abex
type : serial/keygen
level : easy

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



Analyse :
------------

Encore une fois ce crackme est developpé sous VB. On reprend donc SmartChek pour decortiquer ce truc.
Une fois lancé dans SmartChek, nous pouvons retrouver dans la partie LOAD :

NOW()
HOUR(VARIANT:Date:votre/date/ votre:heure)
NOW()
YEAR(VARIANT:Date:votre/date/ votre:heure)




Reversing :
-------------


...ok. on va regarder les "show all events".. et on tombe sur un truc fort interessant :

__vbaVarMul(VARIANT:Integer:13, VARIANT:Integer:5)returns DWORD:15FACC
__vbaVarAdd(VARIANT:Integer:65, VARIANT:Integer:1000)returns DWORD:15FABC
__vbaVarMul(VARIANT:Integer:1065, VARIANT:Integer:2004)returns DWORD:15FA8C
__vbaStrVarMove(VARIANT:Long:2134260)returns DWORD:14DDAC


pour résumé :
--> il prend l'heure et la multiplie par 5
--> le resultat est additionné à 1000
--> et le tout est multiplié par l'année.

donc >> [(13x5)+1000]x2004 2134260

et voila .. on a pu k'a coder un bo keygen pour etre heureux


Keygen :
------------

op, on ressort VB pour cette dobe :


++++++++++++++++++++++++++++++++++++++++++++++

Private Sub Form_Load()
a (1000 + Hour(Time) * 5) * Year(Date)

MsgBox a

End
End Sub

++++++++++++++++++++++++++++++++++++++++++++++





Allez plus qu'un et on va se coucher





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

crackme : 5
crackme author : abex
type : serial
level : easy

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






Analyse :
------------


Bon..allez, il se fait tard, on va torcher ça vite fait. On sort ollydebug et on obtient ça :

00401000 >/$ 6A 00 PUSH 0 ; /pModule NULL
00401002 |. E8 34010000 CALL ; \GetModuleHandleA
00401007 |. A3 EC234000 MOV DWORD PTR DS:[4023EC],EAX
0040100C |. 6A 00 PUSH 0 ; /lParam NULL
0040100E |. 68 29104000 PUSH abexcm5.00401029 ; |DlgProc abexcm5.00401029
00401013 |. 6A 00 PUSH 0 ; |hOwner NULL
00401015 |. 6A 01 PUSH 1 ; |pTemplate 1
00401017 |. FF35 EC234000 PUSH DWORD PTR DS:[4023EC] ; |hInst NULL
0040101D |. E8 3D010000 CALL ; \DialogBoxParamA
00401022 |. 6A 00 PUSH 0 ; /ExitCode 0
00401024 \. E8 1E010000 CALL ; \ExitProcess
00401029 /. C8 000000 ENTER 0,0
0040102D |. 817D 0C 110100>CMP DWORD PTR SS:[EBP+C],111
00401034 |. 75 07 JNZ SHORT abexcm5.0040103D
00401036 |. E8 1B000000 CALL abexcm5.00401056
0040103B |. EB 13 JMP SHORT abexcm5.00401050
0040103D |> 837D 0C 02 CMP DWORD PTR SS:[EBP+C],2
00401041 |. 75 07 JNZ SHORT abexcm5.0040104A
00401043 |. E8 E5000000 CALL abexcm5.0040112D
00401048 |. EB 06 JMP SHORT abexcm5.00401050
0040104A |> 33C0 XOR EAX,EAX
0040104C |. C9 LEAVE
0040104D |. C2 1000 RETN 10
00401050 |> 33C0 XOR EAX,EAX
00401052 |. C9 LEAVE
00401053 \. C2 1000 RETN 10
00401056 /$ 837D 10 65 CMP DWORD PTR SS:[EBP+10],65
0040105A |. 74 10 JE SHORT abexcm5.0040106C
0040105C |. 837D 10 02 CMP DWORD PTR SS:[EBP+10],2
00401060 |. 0F84 C7000000 JE abexcm5.0040112D
00401066 |. 33C0 XOR EAX,EAX
00401068 |. C9 LEAVE
00401069 |. C2 1000 RETN 10
0040106C |> 6A 25 PUSH 25 ; /Count 25 (37.)
0040106E |. 68 24234000 PUSH abexcm5.00402324 ; |Buffer abexcm5.00402324
00401073 |. 6A 68 PUSH 68 ; |ControlID 68 (104.)
00401075 |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
00401078 |. E8 F4000000 CALL ; \GetDlgItemTextA
0040107D |. 6A 00 PUSH 0 ; /pFileSystemNameSize NULL
0040107F |. 6A 00 PUSH 0 ; |pFileSystemNameBuffer NULL
00401081 |. 68 C8204000 PUSH abexcm5.004020C8 ; |pFileSystemFlags abexcm5.004020C8
00401086 |. 68 90214000 PUSH abexcm5.00402190 ; |pMaxFilenameLength abexcm5.00402190
0040108B |. 68 94214000 PUSH abexcm5.00402194 ; |pVolumeSerialNumber abexcm5.00402194
00401090 |. 6A 32 PUSH 32 ; |MaxVolumeNameSize 32 (50.)
00401092 |. 68 5C224000 PUSH abexcm5.0040225C ; |VolumeNameBuffer abexcm5.0040225C
00401097 |. 6A 00 PUSH 0 ; |RootPathName NULL
00401099 |. E8 B5000000 CALL ; \GetVolumeInformationA
0040109E |. 68 F3234000 PUSH abexcm5.004023F3 ; /StringToAdd "4562-ABEX"
004010A3 |. 68 5C224000 PUSH abexcm5.0040225C ; |ConcatString ""
004010A8 |. E8 94000000 CALL ; \lstrcatA
004010AD |. B2 02 MOV DL,2
004010AF |> 8305 5C224000 >/ADD DWORD PTR DS:[40225C],1
004010B6 |. 8305 5D224000 >|ADD DWORD PTR DS:[40225D],1
004010BD |. 8305 5E224000 >|ADD DWORD PTR DS:[40225E],1
004010C4 |. 8305 5F224000 >|ADD DWORD PTR DS:[40225F],1
004010CB |. FECA |DEC DL
004010CD |.^75 E0 \JNZ SHORT abexcm5.004010AF
004010CF |. 68 FD234000 PUSH abexcm5.004023FD ; /StringToAdd "L2C-5781"
004010D4 |. 68 00204000 PUSH abexcm5.00402000 ; |ConcatString ""
004010D9 |. E8 63000000 CALL ; \lstrcatA
004010DE |. 68 5C224000 PUSH abexcm5.0040225C ; /StringToAdd ""
004010E3 |. 68 00204000 PUSH abexcm5.00402000 ; |ConcatString ""
004010E8 |. E8 54000000 CALL ; \lstrcatA
004010ED |. 68 24234000 PUSH abexcm5.00402324 ; /String2 ""
004010F2 |. 68 00204000 PUSH abexcm5.00402000 ; |String1 ""
004010F7 |. E8 51000000 CALL ; \lstrcmpiA
004010FC |. 83F8 00 CMP EAX,0
004010FF |. 74 16 JE SHORT abexcm5.00401117
00401101 |. 6A 00 PUSH 0 ; /Style MB_OK|MB_APPLMODAL
00401103 |. 68 34244000 PUSH abexcm5.00402434 ; |Title "Error!"
00401108 |. 68 3B244000 PUSH abexcm5.0040243B ; |Text "The serial you entered is not correct!"
0040110D |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hOwner
00401110 |. E8 56000000 CALL ; \MessageBoxA
00401115 |. EB 16 JMP SHORT abexcm5.0040112D
00401117 |> 6A 00 PUSH 0 ; /Style MB_OK|MB_APPLMODAL
00401119 |. 68 06244000 PUSH abexcm5.00402406 ; |Title "Well Done!"
0040111E |. 68 11244000 PUSH abexcm5.00402411 ; |Text "Yep, you entered a correct serial!"
00401123 |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hOwner
00401126 |. E8 40000000 CALL ; \MessageBoxA
0040112B |. EB 00 JMP SHORT abexcm5.0040112D
0040112D |$ 6A 00 PUSH 0 ; /Result 0
0040112F |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
00401132 |. E8 22000000 CALL ; \EndDialog
00401137 |. C9 LEAVE
00401138 \. C2 1000 RETN 10
0040113B $-FF25 6C304000 JMP DWORD PTR DS:[<&KERNEL32.GetModuleHa>; kernel32.GetModuleHandleA
00401141 $-FF25 70304000 JMP DWORD PTR DS:[<&KERNEL32.lstrcatA>] ; kernel32.lstrcatA
00401147 .-FF25 74304000 JMP DWORD PTR DS:[<&KERNEL32.ExitProcess>; kernel32.ExitProcess
0040114D $-FF25 78304000 JMP DWORD PTR DS:[<&KERNEL32.lstrcmpiA>] ; kernel32.lstrcmpiA
00401153 $-FF25 7C304000 JMP DWORD PTR DS:[<&KERNEL32.GetVolumeIn>; kernel32.GetVolumeInformationA
00401159 $-FF25 84304000 JMP DWORD PTR DS:[<&USER32.EndDialog>] ; USER32.EndDialog
0040115F $-FF25 88304000 JMP DWORD PTR DS:[<&USER32.DialogBoxPara>; USER32.DialogBoxParamA
00401165 .-FF25 8C304000 JMP DWORD PTR DS:[<&USER32.wsprintfA>] ; USER32.wsprintfA
0040116B $-FF25 90304000 JMP DWORD PTR DS:[<&USER32.MessageBoxA>] ; USER32.MessageBoxA
00401171 $-FF25 94304000 JMP DWORD PTR DS:[<&USER32.GetDlgItemTex>; USER32.GetDlgItemTextA



Reversing :
-------------


Bon .. moi je sens bien poser un BPX sur l'api messageboxA, on fait donc un HALT+E, on selectionne le 
path de notre crackme, .. click droit 'view names', on se met sur USER32;MessageBoxA ..
click droit 'set breakpoint on every reference'..et on load par F9 ..

Le crackme s'est donc lancé, on rentre un serial a la con '123456789' .. et comme
par magie le soft break. YEah, on en croit pas nos yeux fatigués..ollydebug nous affiche le
serial !!

00401099 |. E8 B5000000 CALL ; \GetVolumeInformationA
0040109E |. 68 F3234000 PUSH abexcm5.004023F3 ; /StringToAdd "4562-ABEX"
004010A3 |. 68 5C224000 PUSH abexcm5.0040225C ; |ConcatString "6784-ABEX"
004010A8 |. E8 94000000 CALL ; \lstrcatA
004010AD |. B2 02 MOV DL,2
004010AF |> 8305 5C224000 >/ADD DWORD PTR DS:[40225C],1
004010B6 |. 8305 5D224000 >|ADD DWORD PTR DS:[40225D],1
004010BD |. 8305 5E224000 >|ADD DWORD PTR DS:[40225E],1
004010C4 |. 8305 5F224000 >|ADD DWORD PTR DS:[40225F],1
004010CB |. FECA |DEC DL
004010CD |.^75 E0 \JNZ SHORT abexcm5.004010AF
004010CF |. 68 FD234000 PUSH abexcm5.004023FD ; /StringToAdd "L2C-5781"
004010D4 |. 68 00204000 PUSH abexcm5.00402000 ; |ConcatString "L2C-57816784-ABEX"
004010D9 |. E8 63000000 CALL ; \lstrcatA
004010DE |. 68 5C224000 PUSH abexcm5.0040225C ; /StringToAdd "6784-ABEX"
004010E3 |. 68 00204000 PUSH abexcm5.00402000 ; |ConcatString "L2C-57816784-ABEX"
004010E8 |. E8 54000000 CALL ; \lstrcatA
004010ED |. 68 24234000 PUSH abexcm5.00402324 ; /String2 "123456789"
004010F2 |. 68 00204000 PUSH abexcm5.00402000 ; |String1 "L2C-57816784-ABEX"
004010F7 |. E8 51000000 CALL ; \lstrcmpiA



Bon c bien gentil tout ça ! mais bon.. j'aimerais comprendre un pe qd meme.

il y a cette api GetVolumeInformationA.. apparement il y ajoute "4562-ABEX"
et concatene le tout pour donner : "6784-ABEX". Ce qui semble etre une partie du serial.

ensuiste il y ajoute "L2C-5781". qu'il concatene avec "6784-ABEX", ce qui donne le serial valide et 
ensuite il y a la comparaison entre notre serial a la con, et le bon serial calculé.
de là. il JUMP si c bon ou pas vers la messageBoxA ...easy.

Le serial pour ma machine sera donc : L2C-57816784-ABEX


-|- C. Pour finir

voila, je pense que pour se remettre en jambe, c tout a fait ce qu'il nous fallait. Il est un
peut tard mais promis, je m'occupe de keygener le dernier prochainement.

bon reverse à tous.

thomas.