http://www.xaudio.com/wplay - Webpage.
I think most reversers who read my page will be well aware of MP3 audio and have a significant quantity of such files on their HD's, in this next tutorial I'm actually going to break the habit of a lifetime and completely reverse engineer some mathematical algorithms. The author of WPlay (Justin Lenart) is evidently a Swedish student and if you really do use his program I urge you to send him a few $ for his efforts. The benefits of WPlay over any other MP3 players out there is likely to be minimal, they all seem to use xaudio.dll although this appears to be written in Delphi.
The protection scheme is a single registration key (processed on-line), we can most probably assume there are more than 1 good keys even though any single cracked key could appear in a deplorable serialz list. Cracking the scheme would be a matter of a lot of jump reversing, in fact its considerable effort to patch all the checks so I'll advise against it. Using the StringRef approach you'll easily locate the protection routine.
:0043BF28 CALL 0043BC18 <-- Call protection.
:0043BF2D TEST AL,AL <-- Use AL (1 = good).
:0043BF2F JZ 0043BF48 <-- Beggar_off.
Tracing inside here is where the problems begin, the first elementary check is
up at this code.
:0043BC51 CALL 00403860 <-- Get key length.
:0043BC56 CMP EAX, 1E <-- Was it 30.
:0043BC59 JNZ 0043BEAB <-- Beggar_off.
Obviously you can fix your input now and note the bad jump address :), keep
tracing and don't panic when you step through the next few EBX loops, lots of
nasty SHL's and CALL's you think, but none of this throws you out of the
scheme, don't investigate what the program doesn't force you too investigate.
Our first real test will be this code.
:0043BD9F CALL 0043BB70 <-- Store positions 19-22 in BX.
:0043BDA6 CALL 0043BB0C <-- Algorithm using positions of the code.
:0043BDAB CMP EBX,EAX <-- EAX holds result, EBX is a check value.
:0043BDAD JNZ 0043BEAB <-- Beggar_off.
You can trace this call and attempt to reverse the maths behind it which isn't
trivial at all, the result here must be equal to positions 19-22 of the
input code. The algorithm uses positions 1-4 and 6-9 inclusive in a complex
loop, if you actually trace through the entire scheme (reversing all the
obvious jumps) you'll realise several important facts, the first of which is
that the first 4 letters must be KAGI, the second being that positions 5 and 14
will be checked for hyphens (2Dh).
Knowing the first 4 letters will greatly help us fix our input (refer to the code below), EAX points to our converted input (I recommend you look at this live yourself), so an input code KAGI-1234ABCD.....in memory looks like this (note that the - is discarded):
4B 41 47 49 12 34 AB CD <-- Actual values that will be used. K A G I .. 4 .. .. <-- Data window display (.. indicates non-HTML chars).
At 0043BB25 the program uses the value of BL to calculate an offset position into a table of jumbled mess, on the first iteration the letter K is used, however subsequent XOR's at 0043BB19 ensure the next value of BL is changed, as we know that the first 4 letters must be KAGI we can depend on the value for at least the first 4 iterations, evidently you won't need to reverse the maths or reproduce the table because we can fix the value of BX (positions 19-22).
:0043BB0F MOV ECX,08h <-- Amount to loop.
:0043BB14 MOV EAX, 00469780 <-- Code.
:0043BB19 XOR EBX,EBX <-- Loop (clear EBX).
:0043BB1B MOV BL, BYTE PTR [EAX] <-- use BL.
:0043BB1D XOR EBX,EDX <-- XOR with EDX (initially 0).
:0043BB1F AND EBX,000000FFh <-- Polishes EBX.
:0043BB25 MOV EBX, DWORD PTR [4*EBX+00467CD0] <-- Offset into junk table.
:0043BB2C SHR EDX,08h <-- Shift right.
:0043BB2F XOR EBX,EDX <-- XOR result with EDX.
:0043BB31 MOV EDX,EBX <-- Store and loop again.
At this stage the code KAGI-1234ABCD-1234A9ED90ABCDEF passes through these
checks (A9ED is the result obtained from the above algorithm), the very next
check is very similar (again fix positions 23-30 to the calculated value of
EAX, in the example case here this is 78E0316D). All this hard work however will
transpire to nothing as the next code checks that positions 8 & 9 are 2 and 3
respectively, this means you'll have to recalculate the previous 2 checksums
again.
Sadly recalculation is the order of the day, you'll soon figure that positions 6-9 are actually defaults (3232), this means yet another recalculation of all the checksums. Positions 9-12 and 14-17 are used to determine those checksum results so they can be anything you chose providing your results then correspond. Finally I computed a good code, needless to say the KAGI-3232 will be the only dependable part.
Example Registration Code: KAGI-3232ABCD-12347A61AC5D3FD6
The code is written out to the file wplay.ini.