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 |