It is packed with FSG (PEiD)...
seg001:0041C306 loc_0_41C306:
seg001:0041C306
dec byte ptr [esi]
seg001:0041C308
jz near ptr dword_0_401000
seg001:0041C30E
push esi
So we just have to replace the "jz OEP" by an infinte loop, then dump
and rebuild the import table...
Looking for interesting API ( GetDlgItemText, GetWindowTextA,...
) , we find:
seg000:00401B1B
push 64h
seg000:00401B1D
push esi ; Buffer <=
Information entrée
seg000:00401B1E
push ebx
seg000:00401B1F
GetWindowTextA
seg000:00401B05
push ebx
; hWnd
seg000:00401B06
call GetWindowTextLengthA
seg000:00401B0B
cmp eax, 0Ah
seg000:00401B0E
jbe loc_0_401BF0
So the length of the KEy has to be >= 10...
seg000:00401B24
xor ebx, ebx
seg000:00401B26
xchg eax, ecx
seg000:00401B27
lea edi, [ebp+var_DC]
seg000:00401B2D
seg000:00401B2D loc_0_401B2D:
seg000:00401B2D
movsx eax, byte ptr [ebx+esi]
seg000:00401B31
cmp al, 23h
; car == "#" ?
seg000:00401B33
jz short loc_0_401B3B
seg000:00401B35
mov [ebx+edi], al
seg000:00401B38
inc ebx
seg000:00401B39
jmp short loc_0_401B3D
seg000:00401B3B loc_0_401B3B:
seg000:00401B3B
jmp short loc_0_401B3F
seg000:00401B3D loc_0_401B3D:
seg000:00401B3D
loop loc_0_401B2D
seg000:00401B3F
Here we can see, that the KEy is composed of 2 parts separated
by a "#". The first part is copied...
seg000:00401B3F loc_0_401B3F:
seg000:00401B3F
xor al, al
seg000:00401B41
mov [ebx+edi], al
seg000:00401B44
mov [ebp+var_E0], ebx
seg000:00401B4A
push offset dword_0_4042C8
seg000:00401B4F
push ebx
; 1st part length
seg000:00401B50
push edi
; 1st part
seg000:00401B51
call MD5
Then, the 1st part is 'hashed' using a modified-MD5 ( just rip it :)
)
seg000:00401B56
mov eax, ds:dword_0_4042C8
seg000:00401B5B
xor eax, ds:dword_0_4042D4
seg000:00401B61
and eax, ds:dword_0_4042CC
seg000:00401B67
imul eax, ds:dword_0_4042D0
seg000:00401B6E
mov [ebp+var_E4], eax
Then the 160 bits result is used to create a new number:
K = ( ( hash[0] xor hash[3] ) and hash[1] ) * hash[2]
seg000:00401B74
lea ebx, ds:4042B8h
seg000:00401B7A
mov edx, [ebx+8]
seg000:00401B7D
push edx
seg000:00401B7E
push eax
; key
seg000:00401B7F
call bigCreat
Input a big-number (Big1) from K. ( It seems to be roy's biglib...
)
seg000:00401B84
mov edi, esi
seg000:00401B86
add edi, [ebp+var_E0]
seg000:00401B8C
inc edi
seg000:00401B8D
mov edx, [ebx+0Ch]
seg000:00401B90
push edx
; Big
seg000:00401B91
push 10h
; base
seg000:00401B93
push edi
; 2nd part
seg000:00401B94
call bigIn
Input a big-number ( Big2 ) from the second part of the KEy (base 16).
seg000:00401B99
push dword ptr [ebx+0Ch] ; > BigR
seg000:00401B9C
push dword ptr [ebx] ; < DB10266AB0FD5B
seg000:00401B9E
push dword ptr [ebx+0Ch] ; < Big2
seg000:00401BA1
push dword ptr [ebx+4] ; < CC3183A81DF91
seg000:00401BA4
call bigPowMod
It's quite easy to recognize bigPowMod ( comparing code with roy's biglib
src )
So: BigR = CC3183A81DF91^Big2 mod DB10266AB0FD5B
seg000:00401BA9
push dword ptr [ebx+0Ch] ; < BigR
seg000:00401BAC
push dword ptr [ebx+8] ; < Big1
seg000:00401BAF
call bigCmp
seg000:00401BB4
or eax, eax
seg000:00401BB6
jnz NOTREGISTRED
In other words, the serial is valid if Big1 == CC3183A81DF91^Big2
mod DB10266AB0FD5B
We can't reverse the hash-part so to find a valid serail we have to
solve the discret logarithm problem
The order of the generated group is DB10266AB0FD5A = 2*9D*9C7*1244426C27...
so we can use Pohlig-Hellman algorithm ( Pollard rho algorithm takes
15min ) to find quickly the solution. ( read "Handbook of Applied
Cryptography" )
Key |
Amenesia//tkm!#779EE69AD541C3 |
|