[TMG - Official Trial Keygenme No. 4 ]
by Amenesia

 

To find where the Name / Serial is checked: bpx :GetDlgItemInt



So the name length has to be >= to 5... 

TMG_:0040124B                 lea     eax, [esp+1B4h+lParam]
TMG_:00401252                 push    eax             ; lParam
TMG_:00401253                 push    41h             ; wParam
TMG_:00401255                 push    0Dh             ; WM_GETTEXT
TMG_:00401257                 push    3F1h            ; nIDDlgItem
TMG_:0040125C                 push    edi             ; hDlg
TMG_:0040125D                 call    esi ; SendDlgItemMessageA   ; Name
TMG_:0040125F                 cmp     eax, 5
TMG_:00401262                 mov     [esp+1C8h+LongueurNom_Big4], eax
TMG_:00401266                 jnb     short ErrorSize


... then it checks if serial is composed of [0..9][A..F]

TMG_:004012AA FiltreSerial: 
TMG_:004012AA                 mov     cl, [esp+edx+1DCh+Serial]
TMG_:004012B1                 cmp     cl, 30h
TMG_:004012B4                 jnb     short loc_0_4012B7
TMG_:004012B6                 dec     esi
TMG_:004012B7 
TMG_:004012B7 loc_0_4012B7:                     
TMG_:004012B7                 cmp     cl, 46h
TMG_:004012BA                 jbe     short loc_0_4012BD
TMG_:004012BC                 dec     esi
TMG_:004012BD 
TMG_:004012BD loc_0_4012BD:                     
TMG_:004012BD                 cmp     cl, 39h
TMG_:004012C0                 jbe     short loc_0_4012C8
TMG_:004012C2                 cmp     cl, 41h
TMG_:004012C5                 jnb     short loc_0_4012C8
TMG_:004012C7                 dec     esi
TMG_:004012C8 
TMG_:004012C8 loc_0_4012C8:                     
TMG_:004012C8                                      
TMG_:004012C8                 inc     edx
TMG_:004012C9                 cmp     edx, esi
TMG_:004012CB                 jb      short FiltreSerial


Some big numbers initialization...

TMG_:004012F5                 push    0
TMG_:004012F7                 mov     dword ptr [edx+238h], 10h   ;base
TMG_:00401301                 call    CreatBigNum
TMG_:00401306                 add     esp, 4
TMG_:00401309                 mov     [esp+1DCh+Big1], eax
TMG_:0040130D                 push    0
TMG_:0040130F                 call    CreatBigNum
TMG_:00401314                 add     esp, 4
TMG_:00401317                 mov     [esp+1DCh+Big2], eax
TMG_:0040131B                 push    0
TMG_:0040131D                 call    CreatBigNum
TMG_:00401322                 add     esp, 4
TMG_:00401325                 mov     [esp+1DCh+Big3], eax
TMG_:00401329                 push    0
TMG_:0040132B                 call    CreatBigNum
TMG_:00401330                 add     esp, 4
TMG_:00401333                 mov     [esp+1DCh+Big4], eax
TMG_:00401337                 push    0FFFFFFFDh
TMG_:00401339                 call    CreatBigNum
TMG_:0040133E                 add     esp, 4
TMG_:00401341                 mov     [esp+1DCh+Big5], eax
TMG_:00401345                 push    0
TMG_:00401347                 call    CreatBigNum


'12C34484F6C34BB886EEE052ACC6247098BEDC3C'
'5A3884AF3E676F49470F441CBEEBE7C0B1D9DF66'
'902166CCF366300FAF8B1CCA939C1280E5450F40'
'C90FDAA22168C234C4C5D89F4F2DD72349EE61F7'
'AB6853BDD1100F57'
'1C341C34E32D5EC8F3DC83E7DA1A9DAC84E26624'
'C90FDAA22168C234C4C6628B80DC1CD129024E20'
'ADF85458A2BB4A9AAFDC5620273D3CF1D8B9C841'  are put in big numbers

TMG_:00401387                 push    offset ....
TMG_:0040138C                 push    edi
TMG_:0040138D                 call    putBigNum



The program computes  C90FDAA22168C234C4C6628B80DC1CD129024E20 - 1 

TMG_:004013B1                 push    edi
TMG_:004013B2                 push    1
TMG_:004013B4                 push    edi
TMG_:004013B5                 call    Sub



Then it performs an hash on the name...

TMG_:00401C90 HashInit        proc near
TMG_:00401C90 
TMG_:00401C90                 mov     eax, [esp+arg_0]
TMG_:00401C94                 xor     ecx, ecx
TMG_:00401C96                 mov     [eax+14h], ecx
TMG_:00401C99                 mov     [eax+10h], ecx
TMG_:00401C9C                 mov     dword ptr [eax], 67452301h
TMG_:00401CA2                 mov     dword ptr [eax+4], 0EFCDAB89h
TMG_:00401CA9                 mov     dword ptr [eax+8], 98BADCFEh
TMG_:00401CB0                 mov     dword ptr [eax+0Ch], 10325476h
TMG_:00401CB7                 retn
TMG_:00401CB7 HashInit        endp



... and compute Hash(Name)^3 mod AB6853BDD1100F57 ( we recognize the signature of Miracl function )

TMG_:00401440                 push    ebx
TMG_:00401441                 push    esi
TMG_:00401442                 push    3 
TMG_:00401444                 push    ebx
TMG_:00401445                 call    Power



We can see that the program use points so we can guess that it uses curves... so i seek for curve initalization...

TMG_:00401474                 push    1                 ; MR_EPOINT_NORMALIZED
TMG_:00401476                 push    edi              ; C90FDAA22168C234C4C6628B80DC1CD129024E1F
TMG_:00401477                 push    ebp             ; ADF85458A2BB4A9AAFDC5620273D3CF1D8B9C841
TMG_:00401478                 push    eax             ; 0FFFFFFFD
TMG_:00401479                 call    ecurve_init



Set 3 points 
pointA =  ( 902166CCF366300FAF8B1CCA939C1280E5450F40, 
1C341C34E32D5EC8F3DC83E7DA1A9DAC84E26624)

pointB =  (12C34484F6C34BB886EEE052ACC6247098BEDC3C,
5A3884AF3E676F49470F441CBEEBE7C0B1D9DF66) 

and an other using serial and VCode value ( <<The integer co-ordinates x and y of the point p. If  x and y are not distinct variables then x only is passed to the function, and lsb is taken as the least significant bit of y. In this case the full value of y is reconstructed internally. This is known as “point decompression” >> )  (pointC):

TMG_:004014B4                 push    ebp
TMG_:004014B5                 push    0
TMG_:004014B7                 push    eax  
TMG_:004014B8                 push    ecx  
TMG_:004014B9                 call    epoint_set

TMG_:004014E0                 push    eax   
TMG_:004014E1                 mov     eax, [esp+1E0h+Big3]
TMG_:004014E5                 push    0
TMG_:004014E7                 push    eax
TMG_:004014E8                 push    ecx
TMG_:004014E9                 call    epoint_set

TMG_:0040150B                 push    edx
TMG_:0040150C                 push    eax      ; VCode  
TMG_:0040150D                 push    esi      ; Serial  
TMG_:0040150E                 push    esi      ; Serial  
TMG_:0040150F                 call    epoint_set


Perform some operations ( read Miracl doc to be able to recognize signatures ):

 Hash(Name)^3 mod AB6853BDD1100F57 * pointA

TMG_:004015EE                 push    eax
TMG_:004015EF                 push    ebp
TMG_:004015F0                 push    ebx               
TMG_:004015F1                 call    ecurve_mult
 

Hash(Name)^3 mod AB6853BDD1100F57 * pointA - pointB

TMG_:004015F6                 mov     ecx, [esp+1E8h+var_1CC]
TMG_:004015FA                 mov     edx, [esp+1E8h+SizeNom]
TMG_:004015FE                 add     esp, 0Ch
TMG_:00401601                 push    ecx
TMG_:00401602                 push    edx
TMG_:00401603                 call    ecurve_sub

pointA + pointA
 

TMG_:0040160B                 push    ebp
TMG_:0040160C                 push    ebp
TMG_:0040160D                 call    ecurve_add
 

pointC + pointA + pointA

TMG_:00401619                 push    eax
TMG_:0040161A                 push    ebp
TMG_:0040161B                 call    ecurve_add

Then pointC + pointA + pointA = Hash(Name)^3 mod AB6853BDD1100F57 * pointA - pointB

TMG_:0040162B                 push    ecx
TMG_:0040162C                 push    edx
TMG_:0040162D                 call    epoint_comp

So the keygen is valid if :
pointC  = Hash(Name)^3 mod AB6853BDD1100F57 * pointA - pointB - pointA - pointA
 



 
Name   Amenesia
VCode 0
Serial 4ACDF68CC3EAEA998E420BF9A7DEFCC8DE86FEA2