
Resource Manager 1.0
Ripping code to create a Keygen 2
Written by Sphinx
Introduction |
Tools required |
Target's URL |
http://www.crackpltools.prv.pl
Essay |
First you ask. Why crack another resource decompiler when there are a lot
(and far better) out there? Yeah, coz I
used it and it's shareware ;-)
Anyway, let's snoop! Ahh, so it's coded in Delphi :-) So we might as well
use DeDe to
decompile our prey. But first, let's try running it. Whoa!
Nice anims ;-) Anyway, register via ? > Registration menu.
Ok.
So we see a couple (including the blinking $23) As the author said, to
register we must send him the "program id".
So we already got
a hint that this so-called program id is based on some infos on our (well, my)
PC, les, it's just stupid!
And mine is 1583. And we're only
interested with the "Input Code" button and disregard the rest...
hehe... and lo! We
only get a password field. So we know that the program
id acts as our "name." Nuff here and we'll goto DeDe. Goto the
"DCU" tab then right-click... bah! You know the drill don't you?
(and this ain't the full snippet of course ;-) Btw, I used
12345
as my fake password.
You see: (with ripped hexcodes!)
...(some crap)... * Possible String Reference to: "Input Password" | 00483A11 mov eax, $00483B68 ; move it's address then.. 00483A16 call 0044E5F0 ; draws the whole dialog 00483A1B test al, al ; what button? (al = 1 when Ok) 00483A1D jz 00483B17 ; so if 0, do nothing! 00483A23 lea edx, [ebp-$0C] ; dunno :) 00483A26 mov eax, [ebp-$08] ; after, eax = usercode 00483A29 call 00404FDC ; convert usercode to hex; ret to eax 00483A2E mov [ebp-$10], eax ; [ebp-10] = usercode (ie. 3039) 00483A31 call 004837E0 ; calls GetVolumeInformationA for getting our id below 00483A36 mov [ebp-$14], eax ; [ebp-14] = tempinfo for the id 00483A39 call 0040A230 ; calls MessageBeep (nonsense ;) 00483A3E cmp dword ptr [ebp-$0C], +$00 ; is usercode ALL numbers? 00483A42 jnz 00483A56 ; no? jump badboy, else... (now we know it's just numbers :) 00483A44 mov eax, [ebp-$14] ; eax = tempinfo for the id (to be use on the next call) 00483A47 call 0048377COk. The above call determines the real program id. Oh yeah, this call sucks coz it uses some FPU :-P Anyway, I
00483A4C call 00483720 ; calculate real passwoid (see below) 00483A51 cmp eax, [ebp-$10] ; compare realcode (eax) with usercode at [ebp-10] 00483A54 jz 00483A65 ; guess?So don't mind patching this jump coz you'll only get the goodboy message and when you restart, you're unregged again!
0137:00483720 PUSH EBX ; just save some 0137:00483721 PUSH ESI ; values coz we'll use 0137:00483722 PUSH EDI ; these registers 0137:00483723 PUSH ECX ; here... 0137:00483724 IMUL EDI,EAX,000186A0 ; id = id * 186A0 (edi = eax * 186A0) 0137:0048372A ADD EDI,EAX ; add that 62F to id (edi = edi + eax) 0137:0048372C XOR EBX,EBX ; clear ebx 0137:0048372E MOV ESI,0048C7E4 ; esi = data table! 0137:00483733 FLD REAL10 PTR [00483770] ; Ok. Here are the FPU (!) 0137:00483739 FLDLN2 ; but just noticing 0137:0048373B FXCH ST(1) ; (and not really understanding) 0137:0048373D FYL2X ; what's happening with these numbers (yep!) 0137:0048373F XOR EAX,EAX ; is that these produces 0137:00483741 MOV AL,BL ; some numbers with the pattern 0137:00483743 MOV [ESP],EAX ; (in dec) 1, 10, 100, 1000, 10000, etc. 0137:00483746 FILD DWORD PTR [ESP] 0137:00483749 FMULP ST(1),ST 0137:0048374B CALL 004029C0 0137:00483750 CALL 004029D8Ok. The above call converts that number to hex and ret it in eax. So 1st, eax = 1 (coz the 1st was 1).
0137:00483755 XOR EDX,EDX ; clear edx 0137:00483757 MOV DL,[ESI] ; dl = byte at the data table (1st, dl=07) 0137:00483759 SUB EDX,0A ; subtract a 0A (edx = 07 - 0A, so edx = FFFFFFFFD) 0137:0048375C IMUL EDX ; eax = eax * edx (eax = 1 * FFFFFFFFD, so eax = FFFFFFFFD) 0137:0048375E ADD EDI,EAX ; the CORE! (edi = 96F7D8F + FFFFFFFFD, so edi = 96F7D8C) 0137:00483760 INC EBX ; increment total counter (so now it's 1) 0137:00483761 INC ESI ; increment data table pointer 0137:00483762 CMP BL,0A ; is counter = 0A? (so we know it loops 10 times!) 0137:00483765 JNZ 00483733 ; no? loop (if done, edi has our REAL password!) 0137:00483767 MOV EAX,EDI ; eax = E7DB4902 (38899079?? in dec)So my real password is sniffed (heh!). If I were to sniff only I'd stop here. But since I won't I'll still have work to do ;-)
Code Segment
Assume CS:Code,DS:Code
Org 100h
.386p
Start:
mov ah, 9
lea dx, [intro]
int 21h ; display the header (and prompt)
mov ah, 0Ah
lea dx, [pid]
int 21h ; read the program id
; convert input to hex (ret to eax)
lea esi, [pid+2] ; don't point to the descriptors
xor eax, eax
xor ebx, ebx
xor ecx, ecx
mov bl, [esi]
next:
sub bl, 30h
lea eax, [eax*4+eax]
add eax, eax
add eax, ebx
inc esi
mov bl, [esi]
cmp bl, 0Dh ; have we reached the end?
jnz short next ; no? jump back
; serial calculation (ripped)
imul ecx, eax, 186A0h ; ecx instead of edi
add ecx, eax
xor ebx, ebx
lea esi, [table1] ; esi = those 1, 10, 100..
lea edi, [table2] ; edi = data table
_483733:
mov eax, [esi] ; move a dword
xor edx, edx
mov dl, [edi] ; move just a byte
sub edx, 0A
imul edx
add ecx, eax
add esi, 4 ; point to the next dword
inc edi ; increment data table pointer
inc ebx ; increment counter
cmp bl, 0Ah
jnz _483733
; convert to decimal
mov eax, ecx
xor ebx, ebx
lea edi, [serial]
xor ecx, ecx
mov ecx, 0Ah
not_yet:
xor edx, edx
div ecx
add edx, 30h
push edx
inc ebx
test eax, eax
jnz not_yet
again:
pop edx
mov byte ptr [edi+eax], dl
inc eax
test ebx, ebx
dec ebx
jnz again
mov byte ptr [edi+eax], '$'
; display the serial
mov ah, 9
lea dx, [reg_no]
int 21h
lea dx, [serial]
int 21h
mov ah, 2
mov dl, 13
int 21h
mov dl, 10
int 21h
mov ax, 4C00h
int 21h ; program terminate
; data starts here
Intro db 13,10,"Resource Manager 1.0 Keygen by Sphinx [05/27/01]",13,10
db 13,10,"Enter Program ID: $"
Reg_no db 13,10,"Registration no: $"
Pid db 06h, 07h dup (0)
Table1 dd 01h,0Ah,64h,3E8h,2710h,186A0h,0F4240h,989680h,5F5E100h,3B9ACA00h
Table2 db 07h,13h,03h,07h,0Bh,10h,01h,04h,08h,0Eh
Serial db 0Bh dup(?)
Code Ends
End Start
Final Notes |