Universal Military Simulator v1.0
The Hard Way
by ytc_ [tNO '99]

Target Universal Military Simulator v1.0
URL Not available (but target can be found in ORCPAK3.ZIP at +Greythorne's website)
Tools used Softice v3.x (I'm using WinNT version)
Hex editor (I'm using my previously cracked PSEdit v4.4 ;-)
Protection Paper protection
Level Beginners/Newbies

Awright!! We're making progress ;-) Now to +ORC's third lesson, paper protections. You can never tell how long did it take me to come this far during my earlier times when I just started cracking. But at least we're showing some improvements now. Lets go!


I will assume that you have already set up your copy of Softice and know how to use it well, including knowing what the shortcut function keys are (F8, F10, F11 and F12). If not, I suggest you read some other essays on how to set up Softice first before continuing. I will also assume that you have a fair knowledge of assembly language.

Unlike my previous tutorials, we can't use the loop trick anymore. I'm not sure if you experience the same problem, but in my case, Ctrl-D'ing will always bring me to NT's hal! idle mode. And bpints still won't work! (grr.. somebody tell me why!!) So I have to use the hard way... single stepping right from the beginning of the game's code. Sometimes it is time consuming, but it works most of the time if the protection scheme pops out right at startup like UMS (can be used upon nag screens which just won't break on anything). But with experience, one can quickly filter out the 'useless' code (that is the startup code) and jump straight to the CORRECT call instruction (can be found easily by stepping over the call and see if the protection features pop out... if it does, you should place a bpx on it, run anew and trace into that call and run the same steps until you can isolate out the EXACT 'call prot_scheme' instruction). I used this method very effectively on some 'un-bpx-able' programs (Varicad is one.. this is the program which helped 'gave birth' to this method I used). So, in UMS, here is the first call you should be able to isolate very easily.

0529:00F2  FF366700            PUSH    WORD PTR [0067]
0529:00F6  FF366500            PUSH    WORD PTR [0065]
0529:00FA  FF366300            PUSH    WORD PTR [0063]
0529:00FE  FF366100            PUSH    WORD PTR [0061]
0529:0102  FF365F00            PUSH    WORD PTR [005F]
0529:0106  9A06009B05          CALL    059B:0006

Following the steps explained above, you should then be able to isolate out the next subcall.

059B:00BB  44                  INC     SP
059B:00BC  44                  INC     SP
059B:00BD  8916D6A1            MOV     [A1D6],DX
059B:00C1  A3D4A1              MOV     [A1D4],AX
059B:00C4  9A3036D320          CALL    20D3:3630

Got it yet? Good. Now I can tell you that this call is THE 'call prot_scheme' instruction. Looking into the call, you should approach this part of code.

20D3:36D2  1E                  PUSH    DS
20D3:36D3  B8E23B              MOV     AX,3BE2 <== "Hello, commande..."
20D3:36D6  50                  PUSH    AX
20D3:36D7  9A0200C832          CALL    32C8:0002
20D3:36DC  83C404              ADD     SP,04
20D3:36DF  1E                  PUSH    DS
20D3:36E0  B8F83B              MOV     AX,3BF8 <== "Please open the..."
20D3:36E3  50                  PUSH    AX
20D3:36E4  9A0200C832          CALL    32C8:0002
20D3:36E9  83C404              ADD     SP,04
20D3:36EC  8B46FE              MOV     AX,[BP-02]
20D3:36EF  48                  DEC     AX
20D3:36F0  3D0C00              CMP     AX,000C
20D3:36F3  7603                JBE     36F8 <== jump is taken
20D3:36F5  E9D701              JMP     38CF
20D3:36F8  8BD8                MOV     BX,AX
20D3:36FA  D1E3                SHL     BX,1
20D3:36FC  2EFFA70137          JMP     CS:[BX+3701] <== the 'pick_question' jump

Yep, we've found the part which displays the 'startup intro' of the protection scheme. The final jump instruction (JMP CS:[BX+3701]) will jump to the corresponding code which displays the question and prepares the CORRECT password for comparison. We're getting closer. Here's an example how that piece of code will look like.

20D3:382B  1E                  PUSH    DS
20D3:382C  B8303E              MOV     AX,3E30 <== "YOUR ANSWER"
20D3:382F  50                  PUSH    AX
20D3:3830  16                  PUSH    SS
20D3:3831  8D46C8              LEA     AX,[BP-38]
20D3:3834  50                  PUSH    AX
20D3:3835  9A36007D33          CALL    337D:0036
20D3:383A  83C408              ADD     SP,08
20D3:383D  1E                  PUSH    DS
20D3:383E  B8383E              MOV     AX,3E38 <== "YOUR QUESTION"
20D3:3841  50                  PUSH    AX
20D3:3842  9A0200C832          CALL    32C8:0002
20D3:3847  83C404              ADD     SP,04
20D3:384A  E98200              JMP     38CF

Next, we'll follow the jump, which will bring us to the comparison routine.

20D3:38CF  1E                  PUSH    DS
20D3:38D0  B8843F              MOV     AX,3F84 <== "Remember when..."
... grabbing your input ...
20D3:38FD  EB12                JMP     3911
20D3:38FF  368A4296            MOV     AL,SS:[BP+SI-6A]
... uppercasing your input ...
20D3:3911  16                  PUSH    SS
20D3:3921  73DC                JAE     38FF
20D3:3923  16                  PUSH    SS
20D3:3924  8D46C8              LEA     AX,[BP-38] <== correct answer
20D3:3927  50                  PUSH    AX
20D3:3928  16                  PUSH    SS
20D3:3929  8D4696              LEA     AX,[BP-6A] <== your input
20D3:392C  50                  PUSH    AX
20D3:392D  9A04009833          CALL    3398:0004 <== CALL compare
20D3:3932  83C408              ADD     SP,08
20D3:3935  8BF8                MOV     DI,AX
20D3:3937  0BFF                OR      DI,DI <== is it equal?
20D3:3939  740D                JZ      3948 <== jump if not
20D3:393B  1E                  PUSH    DS
20D3:393C  B8C23F              MOV     AX,3FC2 <== "Incorrect answer"
20D3:393F  50                  PUSH    AX
20D3:3940  9A0200C832          CALL    32C8:0002
20D3:3945  83C404              ADD     SP,04
20D3:3948  0BFF                OR      DI,DI
20D3:394A  7590                JNZ     38DC <== jump if wrong answer
20D3:394C  8BE5                MOV     SP,BP
20D3:394E  5D                  POP     BP
20D3:394F  5F                  POP     DI
20D3:3950  5E                  POP     SI

Enough, there is nothing else to say now. There are many ways where you can crack this scheme. +ORC gave one solution by changing 'JZ 3948' (line CS:3939) to 'JNZ 3948' and 'JNZ 38DC' (line CS:394A) to 'JZ 38DC'. But I have a quicker (and I think, more elegant) way, that is to change 'OR DI,DI' (line CS:3937) to 'XOR DI,DI'. This will make sure the check passes correctly at both conditional jumps at CS:3939 and CS:394A. So bring your hex editor out and make your necessary changes. The game will now accept ANY answer, but not if you don't enter anything.

Final Notes

Sometimes, this kind of 'hard ways' have to be used if other methods doesn't work. I've been pondering for quite a long time, thinking of a quicker solution, but without success. If only that damn bpint will work.


There's a lot of people that I know, so I'll just greet everyone, especially those in #tno, #win32asm, #cracking4newbies and #cracking at EFNet.

Email     : y_t_c@usa.net
Website : http://ytc98.cjb.net

please "