1 ) A patching serial approach
1.1 ) Raw dump
1.2 ) Analyzed dump
2 ) The key generator approach
Winamp is surely one of the most famous MP3 player. but most people ignore what the protection is for.
I don't either. It's just a financial support , I guess. No actual protection.
I'm dealing with Winamp 2.091. but the protection is the same since Winamp 2.00
The program expects an integer as a serial.
There is no "Wrong serial" message box, so we can't break on that.
The other basic solution is to break on serial reading.
That's what we'll do.
1 ) A patching serial approach
Run Winamp. Click on "Enter Registration Info"
Type your name. Mine will be "Crashtest [tNO '99]"
Well. it's obvious that the prog is checking your serial everytime you type something.
So. let's put a breakpoint.
start typing some number.
Here, '6734'
Then fire Softice (ctrl+d, for instance)
type bpx hmemcpy and go back to winamp window. (F5)
type '1'
You are now in the winamp program. but it has called the user.dll...
Here is exactly what happened. directly dumped from Softice by the symbol loader.
Non newbies will automatically understand. but if you need comments, scroll down to 1.2 )
Break due to BPX KERNEL!HMEMCPY (ET=612.80 milliseconds) KERNEL!HMEMCPY 1787:1D5C PUSH DWORD PTR [SI+20] 1787:37B0 OR AX,AX 1787:3A18 OR AX,AX Break due to BPX KERNEL!HMEMCPY (ET=2.70 microseconds) 1787:0B45 PUSH WORD PTR [DI] 1787:27B9 SUB DX,DX 1787:0C0D POP DS 17BF:82E7 POP EDI 17B7:4BC0 RET 1797:2A05 JMP 2A16 (JUMP ) 1797:4697 POP CX 0187:0028 JMP 014F:BFF72964 014F:0040260B PUSH 00 :u cs:eip 014F:0040260B PUSH 00 014F:0040260D PUSH 00 014F:0040260F PUSH EBX 014F:00402610 PUSH EDI 014F:00402611 CALL [USER32!GetDlgItemInt] 014F:00402617 MOV ESI,EAX 014F:00402619 LEA EAX,[EBP-80] 014F:0040261C PUSH EAX :bl 00) BPX KERNEL!HMEMCPY :bd 0 :bl 00) * BPX KERNEL!HMEMCPY 014F:0040260D PUSH 00 014F:0040260F PUSH EBX 014F:00402610 PUSH EDI 014F:00402611 CALL [USER32!GetDlgItemInt] 014F:00402617 MOV ESI,EAX :? eax 0001070D 0000067341 "" 014F:00402619 LEA EAX,[EBP-80] 014F:0040261C PUSH EAX :u cs:eip 014F:0040261C PUSH EAX 014F:0040261D CALL 0041F6A6 014F:00402622 CMP EAX,ESI 014F:00402624 POP ECX 014F:00402625 JNZ 00402631 014F:00402627 CMP BYTE PTR [EBP-80],00 014F:0040262B JZ 00402631 014F:0040262D PUSH 01 :d eax 0157:006CE748 43 72 61 73 68 74 65 73-74 20 5B 74 4E 4F 20 27 Crashtest [tNO ' 0157:006CE758 39 39 5D 00 00 00 00 00-8F 36 98 77 57 01 20 77 99]......6.wW. w 0157:006CE768 07 02 A0 76 07 02 50 3C-A7 03 50 BB 07 02 00 00 ...v..P<..P..... 0157:006CE778 99 28 F9 BF 79 1A 39 45-00 00 00 00 00 00 4F 03 .(..y.9E......O. 0157:006CE788 EF 45 00 00 00 40 00 00-00 00 01 02 31 00 00 00 .E...@......1... 0157:006CE798 FF FF FF 40 FF FF FF FF-40 06 00 00 00 00 00 00 ...@....@....... 0157:006CE7A8 5F 20 EF 05 4E 78 DD 32-8F 04 39 BD 07 02 50 BB _ ..Nx.2..9...P. 0157:006CE7B8 07 02 00 01 F2 77 FF 40-00 00 00 00 0A 78 FF 40 .....w.@.....x.@ 014F:0040261D CALL 0041F6A6 014F:00402622 CMP EAX,ESI :? esi 0001070D 0000067341 "" :? eax 05BDB139 0096317753 "½±9" 014F:00402624 POP ECX 014F:00402625 JNZ 00402631 (JUMP )
Now, the 'analyzed' version.
of coz, I disabled the code and the data window, to show what's happening.
sometimes, I pressed F10, or function keys, but It's not shown here.
so I'll write it in square brackets ([])
Break due to BPX KERNEL!HMEMCPY (ET=612.80 milliseconds) [softice broke here. but I'm not in Winamp. so I press F12 until I'm in] KERNEL!HMEMCPY 1787:1D5C PUSH DWORD PTR [SI+20] [F12 Pressed] 1787:37B0 OR AX,AX [F12 Pressed] 1787:3A18 OR AX,AX [F12 Pressed] Break due to BPX KERNEL!HMEMCPY (ET=2.70 microseconds) [F12 Pressed] 1787:0B45 PUSH WORD PTR [DI] [F12 Pressed] 1787:27B9 SUB DX,DX [F12 Pressed] 1787:0C0D POP DS [F12 Pressed] 17BF:82E7 POP EDI [F12 Pressed] 17B7:4BC0 RET [F12 Pressed] 1797:2A05 JMP 2A16 (JUMP ) [F12 Pressed] 1797:4697 POP CX [F12 Pressed] 0187:0028 JMP 014F:BFF72964 [F12 Pressed] [So I pressed F12 12 times] 014F:0040260B PUSH 00 [now, the winice windows shows I'm in winamp, because ] [I can see WINAMP!.text+1609 in the middle of the window ] :u cs:eip ] U = unassembles functions. ] cs=code segment. ] eip = extended instruction pointer ] so cs:eip = the adress of current instruction. [I want to see what's happening now. so I ask winice to show me the code] 014F:0040260B PUSH 00 ] look at that. 014F:0040260D PUSH 00 ] it's exactly what I spoke about in 3.1.2 ) . 014F:0040260F PUSH EBX ] Push is used for passing parameters. 014F:00402610 PUSH EDI ] 014F:00402611 CALL [USER32!GetDlgItemInt] ] then the call is made. 014F:00402617 MOV ESI,EAX ] and the result seems received in EAX. 014F:00402619 LEA EAX,[EBP-80] ] 014F:0040261C PUSH EAX ] [U can see here that getwindowtexta won't work. that's why it's better to directly use HMEMCPY as a breakpoint :bl ] bl = breakpoint list 00) BPX KERNEL!HMEMCPY :bd 0 ] bd = disable breakpoint :bl 00) * BPX KERNEL!HMEMCPY [Now, I disable the breakpoint on hmemcpy, because I know that GETDLGITEMINT will call it. all GET... will call it. and I don't want it to happen. I want to have the control, now] [F10 pressed] 014F:0040260D PUSH 00 [F10 pressed] 014F:0040260F PUSH EBX [F10 pressed] 014F:00402610 PUSH EDI [F10 pressed] 014F:00402611 CALL [USER32!GetDlgItemInt] [F10 pressed] 014F:00402617 MOV ESI,EAX :? eax 0001070D 0000067341 "" [Surprise. My serial is exactly stored in EAX.] [F10 pressed] 014F:00402619 LEA EAX,[EBP-80] [F10 pressed] 014F:0040261C PUSH EAX :u cs:eip [I want to see what will happen] 014F:0040261C PUSH EAX ] we can see here another push/call 014F:0040261D CALL 0041F6A6 ] structure. 014F:00402622 CMP EAX,ESI ] and some comparison is made after. 014F:00402624 POP ECX ] 014F:00402625 JNZ 00402631 ] 014F:00402627 CMP BYTE PTR [EBP-80],00 ] 014F:0040262B JZ 00402631 ] 014F:0040262D PUSH 01 ] :d eax 0157:006CE748 43 72 61 73 68 74 65 73-74 20 5B 74 4E 4F 20 27 Crashtest [tNO ' 0157:006CE758 39 39 5D 00 00 00 00 00-8F 36 98 77 57 01 20 77 99]......6.wW. w ... [well. here, my name is used directly] [F10 pressed] 014F:0040261D CALL 0041F6A6 [F10 pressed] 014F:00402622 CMP EAX,ESI :? esi 0001070D 0000067341 "" ] here is the serial I entered. :? eax 05BDB139 0096317753 "½±9" ] here is the compared value. [F10 pressed] 014F:00402624 POP ECX [F10 pressed] 014F:00402625 JNZ 00402631 (JUMP )well. of course, I hope you understood that the value 96317753 is the correct serial for "Crashtest [tNO '99]"
so, as I wrote in 3.1.2 ), if you just want your serial, u have it this way.
if you want to make a patch, just delete the jnz. if you want to make a keymaker,
analyse the call, starting at cs:41F6A6
2 ) The key generator approach
Sorry, but so far, I wrote about 1000 lines for this tut. and I wonder if it worthes going on.
I'm not lazy. I will go on if people ask me (politely !), but nobody has written more than 1000 lines for nothing, I think.
So in other words, gimme feedbacks !
Crashtest [tNO '99]