
Free Information Xchange presents:

Sin v1.05 - CD crack by Static Vengeance - May 21st, 1999

REQUIREMENTS:
Full game install
W32Dasm & Hex editor

	Sin is another first person shooter like Quake and so many others.  In fact Sin uses the
Quake II engine for it's 3D engine.  Like Quake II (early versions), Sin has a CD check and it's also
very much like the Quake II CD check.  So let's get right to work on this one.  First disassemble sin.exe
and go to the menu bar and select refs and then select "String data references" from the drop down menu.
From the refs box that comes up, grab the slider bar and scroll down looking for anything interesting.
Part way down you'll come across "\sin.exe" which is a ref to the game file.  Many times this can be part
of the CD check.  So double click this ref and let's see what it gets us.  Doing so puts you in the middle
of this routine:

* Referenced by a CALL at Address:
|:00465DE6                                                      <-- Called only once
|
:00465620 83EC50                  sub esp, 00000050
:00465623 8D442404                lea eax, dword ptr [esp+04]
:00465627 53                      push ebx                      <-- Store original ebx value
:00465628 33DB                    xor ebx, ebx                  <-- Zero out ebx for pass/fail flag
:0046562A 50                      push eax
:0046562B 6819000200              push 00020019
:00465630 53                      push ebx

* Possible StringData Ref from Data Obj ->"Software\Ritual Entertainment\Sin"  <-- Registry key
                                  |
:00465631 6894DB4800              push 0048DB94
:00465636 6802000080              push 80000002
:0046563B 881DD8045100            mov byte ptr [005104D8], bl   <-- Store lowest 8 bits of ebx in flag

* Reference To: ADVAPI32.RegOpenKeyExA, Ord:012Eh
                                  |
:00465641 FF1508C04700            Call dword ptr [0047C008]
:00465647 85C0                    test eax, eax
:00465649 0F85F1000000            jne 00465740                  <-- Have an error?  Jump to exit
:0046564F 8B442408                mov eax, dword ptr [esp+08]
:00465653 8D4C240C                lea ecx, dword ptr [esp+0C]
:00465657 56                      push esi
:00465658 51                      push ecx
:00465659 8D542418                lea edx, dword ptr [esp+18]
:0046565D 68D8045100              push 005104D8
:00465662 52                      push edx
:00465663 53                      push ebx

* Possible StringData Ref from Data Obj ->"PATH"                <-- Get the path of the CD
                                  |
:00465664 688CDB4800              push 0048DB8C
:00465669 50                      push eax
:0046566A C744242880000000        mov [esp+28], 00000080

* Reference To: ADVAPI32.RegQueryValueExA, Ord:0136h            <-- Get it from the registry
                                  |
:00465672 FF1504C04700            Call dword ptr [0047C004]
:00465678 8B4C240C                mov ecx, dword ptr [esp+0C]
:0046567C 8BF0                    mov esi, eax
:0046567E 51                      push ecx

* Reference To: ADVAPI32.RegCloseKey, Ord:0117h
                                  |
:0046567F FF1500C04700            Call dword ptr [0047C000]
:00465685 3BF3                    cmp esi, ebx
:00465687 5E                      pop esi
:00465688 0F85B2000000            jne 00465740
:0046568E 6A01                    push 00000001

* Reference To: KERNEL32.SetErrorMode, Ord:0213h
                                  |
:00465690 FF15C4C04700            Call dword ptr [0047C0C4]

* Possible StringData Ref from Data Obj ->"\sin.exe"            <-- The file to be checked for
                                  |
:00465696 6880DB4800              push 0048DB80
:0046569B 68D8045100              push 005104D8
:004656A0 8D54241C                lea edx, dword ptr [esp+1C]

* Possible StringData Ref from Data Obj ->"%s%s"
                                  |
:004656A4 6810694800              push 00486910
:004656A9 52                      push edx
:004656AA E8E1820000              call 0046D990
:004656AF 8D442424                lea eax, dword ptr [esp+24]

* Possible StringData Ref from Data Obj ->"r"                   <-- Read the file
                                  |
:004656B3 687CDB4800              push 0048DB7C
:004656B8 50                      push eax
:004656B9 E8B2770000              call 0046CE70
:004656BE 83C418                  add esp, 00000018
:004656C1 3BC3                    cmp eax, ebx
:004656C3 7475                    je 0046573A
:004656C5 8A0DD8045100            mov cl, byte ptr [005104D8]
:004656CB 50                      push eax
:004656CC 884C2408                mov byte ptr [esp+08], cl
:004656D0 C64424093A              mov [esp+09], 3A
:004656D5 C644240A5C              mov [esp+0A], 5C
:004656DA 885C240B                mov byte ptr [esp+0B], bl
:004656DE E8DD760000              call 0046CDC0
:004656E3 83C404                  add esp, 00000004
:004656E6 8D542404                lea edx, dword ptr [esp+04]  <-- Load the current drive to check
:004656EA 52                      push edx                     <-- Push current drive to check

* Reference To: KERNEL32.GetDriveTypeA, Ord:00DFh              <-- Commonly used in CD check routines
                                  |
:004656EB FF15C0C04700            Call dword ptr [0047C0C0]
:004656F1 83F805                  cmp eax, 00000005            <-- 05 is the value for a CD rom drive
:004656F4 7544                    jne 0046573A                 <-- Exit out if not a CD Rom drive
:004656F6 57                      push edi
:004656F7 BFD8045100              mov edi, 005104D8
:004656FC 83C9FF                  or ecx, FFFFFFFF
:004656FF 33C0                    xor eax, eax
:00465701 33D2                    xor edx, edx
:00465703 F2                      repnz
:00465704 AE                      scasb
:00465705 F7D1                    not ecx
:00465707 49                      dec ecx
:00465708 7425                    je 0046572F
:0046570A B32F                    mov bl, 2F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046572D(C)
|
:0046570C 80BAD80451005C          cmp byte ptr [edx+005104D8], 5C
:00465713 7506                    jne 0046571B
:00465715 889AD8045100            mov byte ptr [edx+005104D8], bl

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00465713(C)
|
:0046571B BFD8045100              mov edi, 005104D8     <-- Wasted code space
:00465720 83C9FF                  or ecx, FFFFFFFF
:00465723 33C0                    xor eax, eax          <-- Wasted code space
:00465725 42                      inc edx
:00465726 F2                      repnz
:00465727 AE                      scasb
:00465728 F7D1                    not ecx
:0046572A 49                      dec ecx
:0046572B 3BD1                    cmp edx, ecx
:0046572D 72DD                    jb 0046570C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00465708(C)
|
:0046572F 5F                      pop edi
:00465730 B8D8045100              mov eax, 005104D8     <-- Load pointer to flag location
:00465735 5B                      pop ebx               <-- Restore original ebx
:00465736 83C450                  add esp, 00000050
:00465739 C3                      ret                   <-- Return to caller

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004656C3(C), :004656F4(C)
|
:0046573A 881DD8045100            mov byte ptr [005104D8], bl   <-- Scramble flag location

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00465649(C), :00465688(C)
|
:00465740 B8D8045100              mov eax, 005104D8     <-- Load pointer to flag location
:00465745 5B                      pop ebx               <-- Restore original ebx
:00465746 83C450                  add esp, 00000050
:00465749 C3                      ret                   <-- Return to caller

	Well from what I gather about the above code it's a simple CD check.  The routine gets the path
of the CD from the registry and tries to read the sin.exe file.  If not found it stores a non zero value
at 005104D8.  There's some wasted code (from the compiler??) in there that seems to me to be a little
confusing.  If you check the code flow you'll see some registers are loaded or xor'ed for no real reason.
Then the code loops up a bit but will eventualy fall through and the registers that were loaded are either
reloaded with new values or restored by pulling the original value off the stack... oh well.  That's the
CD check, so let's check the surounding code of the call that runs the CD check routine above:

  -- Program Code --
:00465DD3 51                      push ecx
:00465DD4 A3741D5100              mov dword ptr [00511D74], eax
:00465DD9 E852FFFFFF              call 00465D30
:00465DDE 83C404                  add esp, 00000004
:00465DE1 E89A010000              call 00465F80
:00465DE6 E835F8FFFF              call 00465620                 <-- Call the CD check outlined above
:00465DEB 8B3D801D5100            mov edi, dword ptr [00511D80] <-- Load a secondary flag, CD drive parm?
:00465DF1 89442434                mov dword ptr [esp+34], eax   <-- eax is always returned with 005104D8
:00465DF5 85C0                    test eax, eax                 <-- Test for zero
:00465DF7 747B                    je 00465E74                   <-- Always fails!!, but where we want to go
:00465DF9 83FF7D                  cmp edi, 0000007D             <-- Value from the CD check
:00465DFC 7D76                    jge 00465E74                  <-- We want to get to 465E74 to continue
:00465DFE 33DB                    xor ebx, ebx
:00465E00 85FF                    test edi, edi
:00465E02 7E46                    jle 00465E4A
:00465E04 BDA01D5100              mov ebp, 00511DA0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00465E44(C)
|
:00465E09 8B4D00                  mov ecx, dword ptr [ebp+00]

* Possible StringData Ref from Data Obj ->"cddir"
                                  |
:00465E0C BEF46E4800              mov esi, 00486EF4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00465E2F(C)
|
:00465E11 8A01                    mov al, byte ptr [ecx]
:00465E13 8AD0                    mov dl, al
:00465E15 3A06                    cmp al, byte ptr [esi]
:00465E17 751C                    jne 00465E35
:00465E19 84D2                    test dl, dl
:00465E1B 7414                    je 00465E31
:00465E1D 8A4101                  mov al, byte ptr [ecx+01]
:00465E20 8AD0                    mov dl, al
:00465E22 3A4601                  cmp al, byte ptr [esi+01]
:00465E25 750E                    jne 00465E35
:00465E27 83C102                  add ecx, 00000002
:00465E2A 83C602                  add esi, 00000002
:00465E2D 84D2                    test dl, dl
:00465E2F 75E0                    jne 00465E11

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00465E1B(C)
|
:00465E31 33C9                    xor ecx, ecx
:00465E33 EB05                    jmp 00465E3A

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00465E17(C), :00465E25(C)
|
:00465E35 1BC9                    sbb ecx, ecx
:00465E37 83D9FF                  sbb ecx, FFFFFFFF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00465E33(U)
|
:00465E3A 85C9                    test ecx, ecx
:00465E3C 7408                    je 00465E46
:00465E3E 43                      inc ebx
:00465E3F 83C504                  add ebp, 00000004
:00465E42 3BDF                    cmp ebx, edi
:00465E44 7CC3                    jl 00465E09

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00465E3C(C)
|
:00465E46 8B442434                mov eax, dword ptr [esp+34]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00465E02(C)
|
:00465E4A 3BDF                    cmp ebx, edi
:00465E4C 7526                    jne 00465E74

* Possible StringData Ref from Data Obj ->"+set"
                                  |
:00465E4E C704BDA01D5100E02A4800  mov dword ptr [4*edi+00511DA0], 00482AE0
:00465E59 47                      inc edi

* Possible StringData Ref from Data Obj ->"cddir"
                                  |
:00465E5A C704BDA01D5100F46E4800  mov dword ptr [4*edi+00511DA0], 00486EF4
:00465E65 47                      inc edi
:00465E66 8904BDA01D5100          mov dword ptr [4*edi+00511DA0], eax
:00465E6D 47                      inc edi
:00465E6E 893D801D5100            mov dword ptr [00511D80], edi

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00465DF7(C), :00465DFC(C), :00465E4C(C)
|
:00465E74 68A01D5100              push 00511DA0          <-- Getting here continues the game!!
:00465E79 57                      push edi
:00465E7A E8C1F2FBFF              call 00425140
:00465E7F 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"0"
                                  |
:00465E81 68CCF24700              push 0047F2CC

* Possible StringData Ref from Data Obj ->"usegh"
                                  |
:00465E86 6850DD4800              push 0048DD50
:00465E8B E84078FDFF              call 0043D6D0
:00465E90 A35C055100              mov dword ptr [0051055C], eax
:00465E95 83C414                  add esp, 00000014
:00465E98 D94014                  fld dword ptr [eax+14]
:00465E9B D81DA4C24700            fcomp dword ptr [0047C2A4]
:00465EA1 DFE0                    fstsw ax
:00465EA3 F6C440                  test ah, 40
:00465EA6 750B                    jne 00465EB3
  -- Continuing Program Code --

	Well we don't want to run the CD check and as long as eax is always returned with a value of
005104D8 we'll overwrite the call with mov eax, 005104D8.  Then change the conditonal jump to a non
conditional jump to continue with the game.  Seems easy enough, the actual steps to crack this one are:

1.  Do a full game install
2.  Download the Sin v1.04 patch / CTF upgrade and install it
3.  Download the two Sin v1.05 upgrades and install them
4.  Make the following edits:

For v1.04, edit sin.exe
=============================================
Search for: E8 35 F8 FF FF  at offset 414,006
Change to : B8 C8 04 51 00

Search for: 74 7B           at offset 414,023
Change to : EB --

For v1.05, edit sin.exe
=============================================
Search for: E8 35 F8 FF FF  at offset 414,182
Change to : B8 D8 04 51 00

Search for: 74 7B           at offset 414,199
Change to : EB --

5.  Enjoy the game.

	Thus, another tutorial comes to an end becuase we FiX'ed one more game!

Static Vengeance - FiX
