Copy Link
Add to Bookmark
Report

Alien World

(c) 1992 Hi-Tec

DrWatson's profile picture
Published in 
Amiga hacking
 · 17 Jun 2018
Alien World (c) 1992 Hi-Tec Amiga cover.
Pin it
Alien World (c) 1992 Hi-Tec Amiga cover.

Things you will need:

1. The original of "AlienWorld" (c) 1992 Hi-Tec. The CAPS (SPS) version (number 1398) is the one I've used here.
2. An Amiga or a copy o fUAE.
3. Action Replay 3 cartridge.
4. Asm-One, or your personal favourite assembler.

Today we're going to look at a horizontal shoot-em-up called "Alien World", that I must admit I don't remember at all from back in the day. It's going to be quite an easy crack, in fact this tutorial was so short that I decided to also crack the Atari ST version of the game (big mistake!). If you are interested, please check out the second part of this document. Anyway, back on-topic! The Amiga cracking tutorial law, Chapter 13 section 337, states that all tutorials must have a screenshot of an attempt to copy the disk with XCopy:

Illustration 1: XCopy Alien World
Pin it
Illustration 1: XCopy Alien World

A custom format disk - good! This gives us something to do at least, lets load the first track into memory using AR and check out the bootblock:

 
>>> rt 0 1 10000
>>> d 1000c
MOVEA.L $00000004.S,A6
MOVE.L #$7E000,$28(A1) ;load address
MOVE.L #$400,$2C(A1) ;disk offset
MOVE.L #$E00,$24(A1) ;length
JSR -$1C8(A6) ;DoIO()
JMP $0007E000 ;jump to loaded code


We have no need for this code, since we already read in the entire track (which is $1600 bytes long) we can just move the code into position with AR:

 
>>> trans 10400 10400+e00 7e000
>>> d 7e000

Illustration 2: Code relocated by bootblock to $07E000
Pin it
Illustration 2: Code relocated by bootblock to $07E000

So after going into supervisor mode and turning off DMA etc., the real code begins at $07E030. I've detailed in the picture above what everything means, but I'll quickly go over how I discovered all this.
If we examine the code at $07E046 to $07E054, and $07E07E to $07E090, we can clearly see that D0 must be the load address because currently there is nothing at the address it is about to JSR to. This also means that $07E1CA must be the loader, since the load address is passed to it and when it returns magically there is something there! Since we know D0 is the load address, that must mean A0 is something else... if we examine the address it points to before the first loader call ($07E87A) we see the null-terminated string "anim.prg", therefore A0 must be a pointer to the filename. This means that somewhere in memory there must be a filetable which includes filenames, but currently we don't know where that resides.
At this point we could disassemble all the loader code and see what it does, or we could reboot and let the game start loading then enter AR and have a look for the filetable. Since I'm lazy I took the second option, and simply reset and let the game begin loading then pressed the magic button and scanned RAM for ascii using the "nq" command:

Illustration 3: Filetable at $000200
Pin it
Illustration 3: Filetable at $000200

Well that explains 2 things - the address $200 points to some text, with the filetable starting around $290. If we check where the mfm buffer is pointed to ("e 20" to show $DFF020/DSKPTH) we see the value $600.
If you look back at the picture of the code loaded by the bootblock, the first 2 lines are clearly setting up loader variables to point to the load address for the filetable (d0=$200) and the mfm buffer ptr (d1=$600).
Now that we know what all the loader arguments are, it's time to rip some files!
There is no need to over-complicate anything here, a quick patch installed by a modified bootblock and patching the instruction at $07E046 to JMP to our patch will accomplish everything we need. By the time $07E046 is being executed, the filetable/disk-init stuff has been executed so this is the obvious place to hook. Insert a copy of the original, and lets start patching:

 
>>> rt 0 1 10000
>>> a 10446, "JMP 7F000" , < enter >, < esc >
>>> a 1002c < add code as per screenshot below >
>>> bootchk 10000
>>> wt 0 1 10000


The new bootblock looks like this:

Illustration 4: Modified bootblock to rip files
Pin it
Illustration 4: Modified bootblock to rip files

Everything is clearly commented above, so lets just look at the process for ripping all the files using our newly-modified copy:

1. Boot from copy, wait for green screen.
2. Swap disk to original, press LMB.
3. Screen goes red while file is loaded.
4. Screen goes blue when loading has finished.
5. Enter AR, "m7f004" shows current file name ptr (eg:0298), then "m0298" to see filename.
6. Save with "sm1:< filename >,20000< A0value >", a0 = end address of loaded file, all files begin at $20000.
7. Exit AR with "g" and press LMB to load next file, back to step 3 until all ripped (screen flashes).

For example:

Illustration 5: Example of ripping files
Pin it
Illustration 5: Example of ripping files

Swap disks before saving file "lev1.prg", and everything will fit onto 2 blank disks (there is 1mb of data total, so it won't fit on a single disk).

Incidentally, if you look more closely at the original loader you will see it features an encoded table of 16 different MFM Sync values - this might have been annoying if you were dealing with a warped original but since we have the physical disk we can completely ignore this!

Now after 15 lines of code and a few minutes of loading/saving we have all the files successfully ripped to our workdisks, we can see that we're going to have to pack at least some files for our crack to be on 1-disk like the original. Thankfully there are no packed files on the original, so this won't really be a problem. I started by using Imploder to pack the 4 files loaded by the first piece of code at $07E000:

 
NAME ORIG SIZE PACKED
anim.prg 78,752 39,144
load.dat 48,032 N/A
intro.prg 294,736 184,094
alien.prg 48,102 20,424


Packing the loading picture "load.dat" only saved about 3k, so lets ignore that file. A quick calculation of the overall size if we pack the other 3 files gave me a total of about 850k. Since we know an Amiga disk holds 880k, this will be enough, there is no need to pack any other files.
At this point we know the first code loaded by the bootblock to $07E000 does the following:

1. Loads/execs "anim.prg", "Hi-TecPremier" animation.
2. Loads/displays "load.dat", loading picture - we need the copperlist + setup code for this in our crack.
3. Loads/execs "intro.prg", intro animation.
4. Loads/execs "alien.prg", the main game exe.

We also know that "alien.prg" probably contains another loader, since there are many other files in the filetable not referenced/used yet and after loading "alien.prg" it is jumped into directly, not called with JSR.
If we look at the loader code at $07E1CA we can see the first instruction is MOVEM.L D1- D7/A2-A6,-(A7). Reset and let the game load fully then enter AR and search for this instruction:

 
>>> f 48 e7 7f 3e,37820


We start searching from $037820 since this is the base address of "alien.prg", and we only find 1 match at $03FBFE. This is probably the loader, but to be certain lets look for references to it:

 
>>> fa 3fbfe 37820


The first hit is at $03F4BC, a quick look at the code around this location shows that this is indeed the loader and this time it's called to load "title.dat" to $01C600.
Now that we have enough information to produce a working crack (you can check out all the references to the loader and reassure yourself that all the files in the filetable are loaded via this loader) it is time to start coding!

I decided just to write my own code to replace the original code loaded to $07E000, ripping the pieces I needed such as the copperlist + setup code for displaying "load.dat", since we need to decrunch 3 of the files and we are using a different loader/filetable anyway. The code is in the file "alienstart07e000.s" in the attached archive, so I won't repeat everything here, but perhaps I should mention the differences from the original:

1. Loads/depacks/execs "anim.prg", "Hi-TecPremier" animation.
2. Loads/displays "load.dat", loading picture
3. Loads/depacks/execs "intro.prg",intro animation.
4. Loads/depacks/patches/execs "alien.prg", the main game exe.

We also check a flag controlled by the crack intro (not supplied, write your own!), if this flag is set to 1 then we will skip steps 1-3 above (all introduction stuff) and go directly to loading the main game exe.
The patching of "alien.prg" is simply a few NOPS (zap the filetable loading and loader init stuff) then overwriting the first instruction of the loader with a JMP MYLOADER before we begin, since after looking around a bit I discovered the initial code at $07E000 always remains in memory despite never being used once the main game file is executed - we just redirect it to our existing loader, and job done!

Our new filetable requires 12 bytes per entry (original used 16), and is simply the first 8 chars of the filename + a longword which is the disk offset. Since the minimum filelength of the original names was 7, and all names have a terminating null, only storing the first 8 chars of each filename is enough to identify them uniquely. To get the filelength for each load we simply subtract the diskoffset for this file from the diskoffset of the next file - this saves wasting another 4 bytes to store the filelength. As always, we add a little routine which converts the loader arguments used by the game into the arguments our replacement loader expects - this time I've chosen to use a byte-loader by Melon Design (ripped from the game "Naughty Ones") so that we don't waste any unnecessary disk space.

Once this code is assembled and written as binary to "boot07e000.bin", we can turn our attention to creating our crackdisk proper. All the code is contained in "aliencrack01.s", again I won't detail it too much here but basically all it does is load our new code to $07E000, and copy our filetable to $200 before any loading occurs (since there is no "load filetable" code anymore).

Illustration 6: Level 1 gameplay
Pin it
Illustration 6: Level 1 gameplay

And that seems to work!

next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT