Sanitarium (PC Game crack)
Title : Sanitarium (GAME)
Version : 1.0 (should work with any)
Protection : Cd Check
Producer : http://www.ascgames.com
Tools : W32Dasm, Hiew
Difficulty : Moderate
1) Install the game. Copy all 3 Cd's to your hard drive. Yes I know It would take aproximately 2GB to do this so if you do not have a big hard disk you can just copy Cd one and later when you are promted to insert Cd 2 or 3 you just copy the files from Cd 2 or 3 then save your game (in the new chapter) exit to Windows and delete the files from cd 1 or 2. When ready with copying go to Directory Data and remove the read only attribute to all files (especialy to file res.002). If you did not do this later you will experiance a problem with the sound and voices. Anyway if you have a problem with voices (this may happen when going from cd to cd for exmpl going from chapter 3 to 4) save your game then quit to Windows go to Data and delete the file res.002, then just load your saved game.
2) Now back to the crack. Run the game without the Cd. You see inbuild message "Pleas insert ... ". Back up sntrm.exe and load your backup in W32Dasm. Searching for the error message will lead us to nowhere so we look for GetDriveTypeA. Skip the first one. The second one is the right place :
* Reference To: KERNEL32.GetDriveTypeA, Ord:00DFh
|
:00430654 8B3574114400 mov esi, dword ptr [00441174]
:0043065A C605E070440041 mov byte ptr [004470E0], 41
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043069C(C)
|
* Possible StringData Ref from Data Obj ->"A:\"
|
:00430661 68E0704400 push 004470E0
:00430666 FFD6 call esi
:00430668 83F805 cmp eax, 00000005
:0043066B 7521 jne 0043068E
:0043066D A0E0704400 mov al, byte ptr [004470E0]
:00430672 6A00 push 00000000
:00430674 6868754500 push 00457568
:00430679 A268754500 mov byte ptr [00457568], al
:0043067E E86D750000 call 00437BF0
:00430683 83C408 add esp, 00000008
:00430686 85C0 test eax, eax
:00430688 0F8482000000 je 00430710
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043066B(C)
|
:0043068E A0E0704400 mov al, byte ptr [004470E0]
:00430693 FEC0 inc al
:00430695 3C5A cmp al, 5A
:00430697 A2E0704400 mov byte ptr [004470E0], al
:0043069C 7EC3 jle 00430661
:0043069E C605E070440041 mov byte ptr [004470E0], 41
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004306DE(C)
|
* Possible StringData Ref from Data Obj ->"A:\"
|
:004306A5 68E0704400 push 004470E0
:004306AA FFD6 call esi
:004306AC 83F804 cmp eax, 00000004
:004306AF 751F jne 004306D0
:004306B1 8A0DE0704400 mov cl, byte ptr [004470E0]
:004306B7 6A00 push 00000000
:004306B9 6868754500 push 00457568
:004306BE 880D68754500 mov byte ptr [00457568], cl
:004306C4 E827750000 call 00437BF0
:004306C9 83C408 add esp, 00000008
:004306CC 85C0 test eax, eax
:004306CE 7415 je 004306E5
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004306AF(C)
|
:004306D0 A0E0704400 mov al, byte ptr [004470E0]
:004306D5 FEC0 inc al
:004306D7 3C5A cmp al, 5A
:004306D9 A2E0704400 mov byte ptr [004470E0], al
:004306DE 7EC5 jle 004306A5
:004306E0 33C0 xor eax, eax
:004306E2 5F pop edi
:004306E3 5E pop esi
:004306E4 C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004306CE(C)
|
* Possible StringData Ref from Data Obj ->"?:\DATA\"
|
:004306E5 A1E0604400 mov eax, dword ptr [004460E0]
:004306EA 8A15E0704400 mov dl, byte ptr [004470E0]
:004306F0 8810 mov byte ptr [eax], dl
:004306F2 8A0DE0704400 mov cl, byte ptr [004470E0]
:004306F8 880DA8914500 mov byte ptr [004591A8], cl
:004306FE C7058491450004000000 mov dword ptr [00459184], 00000004
:00430708 B804000000 mov eax, 00000004
:0043070D 5F pop edi
:0043070E 5E pop esi
:0043070F C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00430688(C)
|
* Possible StringData Ref from Data Obj ->"?:\DATA\"
|
:00430710 8B15E0604400 mov edx, dword ptr [004460E0]
:00430716 8A0DE0704400 mov cl, byte ptr [004470E0]
:0043071C 5F pop edi
:0043071D 5E pop esi
:0043071E 880A mov byte ptr [edx], cl
:00430720 A0E0704400 mov al, byte ptr [004470E0]
:00430725 A2A8914500 mov byte ptr [004591A8], al
:0043072A C7058491450005000000 mov dword ptr [00459184], 00000005
:00430734 B805000000 mov eax, 00000005
:00430739 C3 ret
:0043073A 90 nop
:0043073B 90 nop
:0043073C 90 nop
:0043073D 90 nop
:0043073E 90 nop
:0043073F 90 nop
It took me a very long time to understand the check routine because it is much more complicated than it seems. First lets take a look at this part :
:00430661 68E0704400 push 004470E0
:00430666 FFD6 call esi < - getdrivetypea is called
:00430668 83F805 cmp eax, 00000005 < - is eax 5 (Cd drive)
:0043066B 7521 jne 0043068E < - no then continue checking
:0043066D A0E0704400 mov al, byte ptr [004470E0]
:00430672 6A00 push 00000000
:00430674 6868754500 push 00457568
:00430679 A268754500 mov byte ptr [00457568], al
:0043067E E86D750000 call 00437BF0
:00430683 83C408 add esp, 00000008
:00430686 85C0 test eax, eax
:00430688 0F8482000000 je 00430710 < - GoodGye This is our jump
So It seems very easy we just nope jne 0043068E and make je 00430710 to jump 00430710. For those of you who do not know how to do this I will explain now. First note the offset of 0043066B. We do not need the offset of 00430688 because it is very close to the other one and we will find it easily. So for me the offset was 2fa6b. Now open the file sntrm.exe with Hiew. F4 - decode. F5 - go to 2fa6b. F3 - write 9090 (we noped 7521). Now to change the je to jmp go to the line 00430688. Now count how many chars you have on this line 6x2=12. So how to transform this 0F8482000000 (je 00430710) to E983000000 (jmp 00430710). You see that E983000000 is only 10 bytes and we have to nope some part of 0F8482000000. GOLDEN RULE : Always nope (90) the last part of the code. So press F3 then F2 to write Asm and change je to jmp. Press Enter and you see that the code you have written is 10 bytes and the previous one was 12 so it mess up with the next line. Do not worry just type 90 at the begining of the next line and you have restored the previous code. You should have something like this :
:0043066B 90 nop
:0043066C 90 nop
:0043066D A0E0704400 mov al, byte ptr [004470E0]
:00430672 6A00 push 00000000
:00430674 6868754500 push 00457568
:00430679 A268754500 mov byte ptr [00457568], al
:0043067E E86D750000 call 00437BF0
:00430683 83C408 add esp, 00000008
:00430686 85C0 test eax, eax
:00430688 E983000000 jmp 00430710
:0043068D 90 nop
:0043068E A0E0704400 mov al, byte ptr [004470E0]
3) Now lets see what is at 00430710. We see * Possible StringData Ref from Data Obj ->"?:\DATA\". This is very bad. We have to change the ?:\DATA\ string to .\DATA\ so the game will look for the files in its install dir. Open sntrm.exe with your best hex editor. I use Ultra edit 32. Search ASCII for ?:\DATA\ . We find it and now we have to change it to .\DATA\ . Do you remember the Golden Rule. We see 3F 3A 5C 44 41 54 41 5C and this means ?:\DATA\ . Something to remember: 5c means \ , 41 means A, 2e means . . So we change 3f to 2e, 3a to 5c, 5c to 44, 44 to 41, 41 to 54, 54 to 41, 41 to 5c and finally 5c to 00 (this at last is our nope). So we have changed it to .\DATA\ and this new string will begin at the right offset. Now Save the file and run the game. No more inbuild messages "Please ..." and the game begins to load, then we watch the intro movie and ....... it crashes General Protection Fault Error. Shit. What now?
4) Open sntrm.bak (your backuped exe) in W32Dasm. Go again in Check routine and take a close look at :
* Reference To: KERNEL32.GetDriveTypeA, Ord:00DFh
|
:00430654 8B3574114400 mov esi, dword ptr [00441174]
:0043065A C605E070440041 mov byte ptr [004470E0], 41 < - Here 004470E0 gets a value of A
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043069C(C)
|
* Possible StringData Ref from Data Obj ->"A:\"
|
:00430661 68E0704400 push 004470E0 < - A is pushed
:00430666 FFD6 call esi < - Getdrivetypea is called with value in 004470E0
:00430668 83F805 cmp eax, 00000005 < - eax is compared to 5
:0043066B 7521 jne 0043068E < - if Cd is not found go to 0043068E
:0043066D A0E0704400 mov al, byte ptr [004470E0]
:00430672 6A00 push 00000000
:00430674 6868754500 push 00457568
:00430679 A268754500 mov byte ptr [00457568], al
:0043067E E86D750000 call 00437BF0
:00430683 83C408 add esp, 00000008
:00430686 85C0 test eax, eax
:00430688 0F8482000000 je 00430710
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043066B(C)
|
:0043068E A0E0704400 mov al, byte ptr [004470E0] < - Here al takes value of 004470E0. A at first
:00430693 FEC0 inc al < - Here it is increased.Becomes B then C and so
:00430695 3C5A cmp al, 5A < - Here is a check if all letters are passed
:00430697 A2E0704400 mov byte ptr [004470E0], al < - Here 004470E0 takes value of al. B at second
:0043069C 7EC3 jle 00430661 < - If there are more letters jump to 00430661
:0043069E C605E070440041 mov byte ptr [004470E0], 41 < - If not then 004470E0 takes value of A
Well this is really difficult to understand check routine. I will translate it very shortly. First Getdrivetypea is called with value at 004470E0. At first this value is A. Look at
:0043065A C605E070440041 mov byte ptr [004470E0], 41 < - Here 004470E0 gets a value of A (41 means A)
and you will understand why. Then getdrivetypeA returns value of eax. If eax is 5 then cd is found and we continue down where our cd letter is stored in al and then in 00457568. When we removed the check routine the value stored in al is A. And this is not the right path. This is why the game crashes. So lets change the value in :
:0043065A C605E070440041 mov byte ptr [004470E0], 41 < - Here 004470E0 gets a value of A
We want the game to search in the dir where we installed it so we have to change A with . . We know 41 means A and I told you that 2E means . . So we have to change the upper line with this one :
:0043065A C605E070440041 mov byte ptr [004470E0], 2E < - Here 004470E0 gets a value of .
Look for the offset. For me it was 2fa5a. Open sntrm.exe with Hiew. F4 - decode. F5 - go to 2fa5a. F3 - then F2 to write in ASM and change 041 to 02E. F9 - save. ESC - quit.
5) Run the game. Now it runs just fine. Phew, this one was not so easy.