I’m continuing my series of posts where I simplify the copy protection schemes on my old Sierra games. This entry is different in two ways. First, this one is an AGI game: the original Leisure Suit Larry. Second, this isn’t a copy-protection, but rather an age-protection. The game half-heartedly attempts to make you prove you are old enough to play.

As a reminder: I don’t really want to bypass the copy protection. I like seeing it; it’s a nostalgia thing. I just don’t want to have to get the answer correct to get to the other side of it.

A patch of my final solution is provided at the end of the article.

Getting Started

As this is an AGI game, I’m using my own disassembler. By the way, in that repository is a Go version and a Clojure version in different branches. Soon there will be a Java version, because I’m a little crazy.

Anyway, I am looking for the “How old are you?” quiz that the game gives the player. I want it to issue questions and tell you if you are right or wrong, just like it always has… except I want it to let you through to the game no matter what happens.

So, to get started, I extracted all the logic scrips. Searching for strings revealed that the quiz appears to be run in logic.006.

The Protection Scheme

The questions themselves appear to live in logic.002 and logic.003, but are called from logic.006. Here’s the relevant part, where it grades your answer, in cleaned-up pseudocode:

IF (answer was correct) {
   say "Correct";
   v95 = 5;
   v66 = 8;
} else if(this is the first wrong answer) {
   say "You blew that one"
   remember the loss (in flag 200);
   v95 = 2;
   v94--;
} else {
   say "You are a kid!";
   quit;
}

… and here’s the actual disassembly:

(N.B.: if you are accustomed to the SCI decompilations from my last few posts, these will look extremely primitive. That’s partly because the AGI interpreter is much more primitive, and partly because this is more of a disassembly than a decompilation).

IF(  ;; FF
    OR(  ;; FC
        equalv(%v92, %v93) ;; 025C5D
        NOT(  ;; FD
            greatern(%v93, 0) ;; 055D00
        )  ;; (FD)
    )  ;; FC
) {  ;; FF
    set(%f15) ;; 0C0F
    ;; flg 15 = <'print'/'print_at'>
    print(%m8) ;; 6508
    ;; msg 8 = <Correct.>
    assignn(%v95, 5) ;; 035F05
    assignn(%v66, 8) ;; 034208
} else {
    IF(  ;; FF
        NOT(  ;; FD
            isset(%f200) ;; 07C8
        )  ;; (FD)
    ) {  ;; FF
        assignn(%v95, 2) ;; 035F02
        print(%m5) ;; 6505
        ;; msg 5 = <Oops. You blew that one! ... >
        set(%f200) ;; 0CC8
        decrement(%v94) ;; 025E
    } else {
         print(%m6) ;; 6506
         ;; msg 6 = <You're a kid!! ...>
         quit(1) ;; 8601
    }
}

So immediately I can see the most important thing is not to set flag 200. That may even be enough. There are differences in v95, v66, and v94 between the right and wrong paths, too, which I can smooth over if I need to.

Attempt One

So, let’s just avoid setting flag 200. Setting a flag is opcode 0x0C, while resetting a flag is 0x0D. We’ll just reset the flag instead of setting it. I find the opcodes above in VOL.1, and adjust it:

hex-edit screenshot

… and it kind-of works, but it keeps asking question-after-question as you get them wrong.

Attempt Two

So much for the minimal adjustment! Now let’s change all the variables so they match the correct-answer path. Of course it would be easier to just force the game to think all the answers are correct, but I’d rather get the right feedback from the game as I go.

So, this time I set v66 and v95 just like the correct-answer path. This byte sequence is 1-byte shorter than it was before, so I pull the FE 04 unconditional jump over one and update the distance to 05.

hex-edit screenshot

… and it works! I can get as many wrong as I want, and it just keeps giving me credit despite warning me not to miss another one.

Patch

Unfortunately AGI games don’t look for out-of-band patches like SCI games do. So, I had to patch VOL.1 directly. Here is an IPS patch file for it: vol1.ips. There is IPS patching software all over the internet (like here).

Alternatively, you can just use a hex-editor and patch the file as shown in the screenhot above. Or you can just concentrate and answer the questions correctly!