Deep within the Internet lies a great game...Subspace, by VIE(Virgin) Having gone retail just recently, it was a matter of time till the protection came...And it did, quite well I might add. How do we fix a program that has CRC checks on itself and the memory it resides in (active checking)???
I won't bother with source since most people reading this won't have access to the target, thus it means nothing...The more interesting part, and the point of this essay, is how we get around the check...We could just patch it with HIEW and go on, but a CRC check stops us...We patch the crc check, and memory checksums get us...Hard to debug since Winice's breakpoints(0CCh) throw off the values...So what do we do?? Well, I looked into API Hooking (Which IS NOT a prostitute with a Computer Science Degree =) and it didn't look promising...Then I get a flashback, thinking back to my AsmEdit essay.. TSR Crack! But this isn't the good ol' DOS environment, there is not a AX=25XX, INT 21h function for Winblows...So where would our point of attack be...Windows ITSELF!
I got this idea while attempting to fix a nuker on my own that had spread on IRC...Messing with important Win95 files is dangerous, toying with the kernel is just crazy...So we know SubSpace's first call in its protection scheme is to GetDriveTypeA..This API returns a 2 for floppies, 3 for HDs, and a 5 for CDROM (Other values dont interest us)...So I get this idea that we will essentially attack this protection like a FAKECD program would...We would emulate the files needed on our HD somewhere while a TSR emulates a CD
But were going to do this runtime...In Winice, type:
U GetDriveTypeA
You will see the assembly code for the API..write a portion of the
code
so we will find it on disk in kernel32.dll
(I can't give my example because there are too many kernel32.dll's out
there)
But basically you have a short routine that does some weird compares and
then
goes on to another API with a JMP.....Like this:
:BFF777C4 57 push edi :BFF777C5 6A21 push 00000021 :BFF777C7 2BD2 sub edx, edx :BFF777C9 68EFE2F9BF push BFF9E2EF :BFF777CE 64FF32 push dword ptr fs:[edx] :BFF777D1 648922 mov dword ptr fs:[edx], esp :BFF777D4 8B7C2414 mov edi, dword ptr [esp+14] :BFF777D8 0BFF or edi, edi :BFF777DA 7407 je BFF777E3 :BFF777DC 2BC0 sub eax, eax :BFF777DE 8D48FF lea ecx, dword ptr [eax-01] :BFF777E1 F2 repnz :BFF777E2 AE scasb * Referenced by a Jump at Address:BFF777DA(C) | :BFF777E3 648F02 pop dword ptr fs:[edx] :BFF777E6 83C408 add esp, 00000008 :BFF777E9 5F pop edi :BFF777EA E9E5D4FFFF jmp BFF74CD4So we have this small routine..Where do we put our code?!? Well, lets set a BPX on that JE and see if it ever actually jumps... So BPX BFF777DA and run through Explorer or something that trips the BPX. You will see that nothing ever makes that damn JE jump! So we can assume (mainly because MS wrote it =) that this routine has little worth..So lets modify and optimize it:
(This routine is first called by SubSpace for the drive C:)
:BFF777C4 57 xor edx,edx ; the only instr. kept :BFF777C5 6A21 mov eax,[esp] ; get calling routine :BFF777C7 2BD2 cmp eax,413e6e ; is it SS CD-Check? :BFF777C9 68EFE2F9BF jnz BFF777EA ; if not, continue API :BFF777CE 64FF32 mov [esp+4],eax ; save return address :BFF777D1 648922 pop eax ; inc ESP by 4 :BFF777D4 8B7C2414 mov eax,5 ; we are a CDROM! :BFF777D8 0BFF ret :BFF777DA 7407 je BFF777E3 ; useless MS stuff :BFF777DC 2BC0 sub eax, eax ; HERE! :BFF777DE 8D48FF lea ecx, dword ptr [eax-01] :BFF777E1 F2 repnz :BFF777E2 AE scasb * Referenced by a Jump at Address:BFF777DA(C) | :BFF777E3 648F02 pop dword ptr fs:[edx] :BFF777E6 83C408 add esp, 00000008 :BFF777E9 5F pop edi :BFF777EA E9E5D4FFFF jmp BFF74CD4
As you can see, we have intercepted this API quite brutally...We are checking to see whether it was called by SubSpace everytime it runs...Simple enough! Now that we have fooled it to think C: is a CDROM drive, we move on to the Disk space free check:
(The original is similar to above, but with more garbage...Which helps, because this routine is a bit bigger...Heres the new and improved routine!)
:BFF778C5 2BD2 xor edx,edx ; All MS is good for? :BFF778C7 68B8E2F9BF mov eax,[esp] ; get calling address :BFF778CC 64FF32 cmp eax,491E22 ; is it SubSpace? :BFF778CF 648922 jnz BFF77900 ; if not, continue API :BFF778D2 8B4C240C add esp,14h ; Real API returns alot :BFF778D6 E302 mov [esp],eax ; return point :BFF778D8 8A01 mov [esp+18],eax ; where spacefree is ret. :BFF778DA 8B4C2410 ret ; go back... :BFF778DE E302 jcxz BFF778EA ; rest of MS stuff :BFF778E0 8B01 mov eax, dword ptr [ecx] :BFF778E2 8B4C2414 mov ecx, dword ptr [esp+14] :BFF778E6 E302 jcxz BFF778EA :BFF778E8 8B01 mov eax, dword ptr [ecx] :BFF778EA 8B4C2418 mov ecx, dword ptr [esp+18] :BFF778EE E302 jcxz BFF778F2 :BFF778F0 8B01 mov eax, dword ptr [ecx] :BFF778F2 8B4C241C mov ecx, dword ptr [esp+1C] :BFF778F6 E302 jcxz BFF778FA :BFF778F8 8B01 mov eax, dword ptr [ecx] :BFF778FA 648F02 pop dword ptr fs:[edx] :BFF778FD 83C404 add esp, 00000004 :BFF77900 E954D5FFFF jmp BFF74E59So, we intercepted this routine and forced it to return 0 for disk space free, like a CDROM...Now the only part left is the label check and the file check...
So simply, we label our C: drive SUBSPACE, and with a little asm program I stewed up, we make a file that is 37,433,486...Apply these patches to the KERNEL32.DLL and reboot... Cross your fingers and it will not crash!
This is indeed an interesting way of approaching a crack...I've never seen anyone use this method, probably because its so dangerous and has compatibility problems...I wanted to spread the idea I found to others so they may consider this technique in the future...The main problem with using KERNEL32.DLL is that MS has so many damn versions of it, its crazy to make a patch for em all...
Amazing, no matter how far DOS goes away, its roots still follow us in cracking! TSR cracking is kind of a hobby of mine =) It's different!
PS - If you play SubSpace alot, buy the game...It's like 30 bux or something. I did this because I wanted the challenge! =)