This paragraph you read was written AFTER the crack was done. I'll mention a 'list of passwords' later in the tutorial that I address as 'useless'. It happens that the list DOES work if you can gain access to a 'registerable' stars!.exe, which is not the case of the demo version. I didn't know of the existence of a site that distributes those files, along with the demo version we crack here. The crack of the 'registerable' one, which pops a window prompting you to enter a registration code consists of tracking a message box, which should be fairly easy compared with cracking the demo, which is what we do here. Notice then that the purpose of this file IS NOT to let you use a cracked version of the game, which is ILLEGAL. If that's what you intend to do, please DO NOT contact me. The material that follows is intended to enlighten beginners in asmonautics on how to find their bearings in the black empty void of alien code.
Hello people. I have to fill a whole web site of lots of material, and I don't have much time. This document might have some minor inaccuracies/mistypings I overlooked. If you spot anything, you can bite my nose at email@example.com. Thank you.
Studying the protection of STARS! (what a game...). Before you start - Some of the memory addresses, especially segments, will probably be different on your computer. If you're new to asmonauting and find my explanation difficult to follow, at least you'll see some important concepts and tools mentioned. Having the ideas clear in your head is one thing, writing them while you're cracking is another. I don't think I'd write this file in some other opportunity really, so if you have a question, whatever it is, feel free to ask.
Comments :- We'll cover A LOT here... This is NOT a 'shortest
path to the crack' tutorial. I'm trying to comment each step I
took myself as I took it.
Protection type :- Disabled functions.
Tools :- SoftICE, W32Dasm, a resource editor, Hex Workshop, WIN32.HLP reference, Hutch's MASM pack.
1). VOODOO CRACKING - Needs luck and brains. The more brains you have, the faster the luck comes. You can stick some random needles in cursed programs at random to ban the evil spirits. It works many times. If it doesn't, you know in the end the spirit will be not a very easy one to deal with.
2). ZEN CRACKING - Needs experience. It's said you can 'feel' the code in the zen approach. The more you have visiting code, the faster you start 'feeling' what a certain piece of code does. Frowned upon by the people of Middle East for some obscure connection with alcohol-consumption habits. Yet it works well with Pepsi or coffee.
3). CHESS CRACKING - Needs patience, time and determination. Each MOV is important and has to be analyzed. It's the ULTIMATE cracking experience because you rip the whole program apart in the end. Very rewarding.
4). DONKEY CRACKING - Needs both extra- and intra- systemic stimuli to paralyze every synapse in your body, as to avoid the unwanted consequences of repeating a certain task MANY times in a row robotically. Thanks to the nature of modular programming used in large scanable code, this is rarely needed.
This AMAZING, AMAZING, game has no crack I am aware of. I did find a list of passwords once, completely useless (I'll come back to this one) and on another occasion I found a 'crack' that does not work. I wonder if this crack was really for the beautiful STARS!. So many things in this web have the word 'stars' in it... When I started to look in the program, I soon realized why there wasn't a crack in the market. The program is HEAVILY defended by a kind of protection called FUNCTION DISABLING. Let's see some detail.
1). You start a new game. You have the option to 'create a new race' or create an 'advanced game' (the real fun is here). 905 of the options in the various pages of these two sections are disabled. You can't click on 'HUGE UNIVERSE' or set the winning conditions, etc.
2). After 20 days, you get a very nice reminder popping at your face (sweetened with a system beep) saying you used it for more than 20 days. This all BEFORE you start the game. Then...
3). The game ends in turn 80 no matter what.
4). You can reach tech-level 10 in the demo (but 26 in the full version).
Well, I got all this from the help file. Guess what? I didn't crack it yet. I DID figure out some steps, but since this will be a looong journey, I decided to write while I travel through the STARS!. This started soon after I began studying WINDOWS programs. I barely knew a couple of tutorials (but wrote ASM programs for years...), but the main path was clear: the secret was in the API's. I'll explain.
I started from the start. Loaded the program in SoftICE, traced lots of lines, found some VERY weird API's (DOS3CALL comes to mind). When the protection is a password check, some of the job is already done for you. You KNOW what to look for more or less and it's a matter of setting some breakpoints. Sooner or later some API concerned with creating a MessageBox (to tell you 'Invalid Password'), or retrieving text (the password you typed), or other will be called. Our case is very different. Something somewhere in the code is telling the program NOT to let you do some stuff. We have to find it and change it somehow. Pure voodoo does not work here (but it helps). Some Zen and Chess cracking are also necessary. We start using voodoo thought.
Well, a good step is to read whatever documents come with the
game. In some situations they even tell you where the crack is,
or how the program is to be cracked, believe it or not. A little
bit of it happens in STARS!. When reading the following in the
'README2.TXT' file that comes with STARS! :-
EXCERPT FROM README2.TXT (comes with STARS!) ------------------------------------------------------------------- Uninstalling the Stars! Demo To uninstall the Stars! demo, simply delete the Stars! directory and all its files and the Stars.ini file from the Windows directory. Note: The game will end after 80 turns when you play the Stars! demo. If you wish to play a full game you must order the boxed version. --------------------------------------------------------------------
I decided to see what STARS.INI had to tell me. I found some unintelligible entries there, but this one was interesting :-
HistoryInfo=263 (You might have a different number)
HistoryInfo? what might that be? I changed it to 0, a typical voodoo procedure. I run the game and... surprise! :-
"You have been using this demo version of Stars! for more than 20 days. To continue using this game, see the ordering information available from the help menu."
Well, now we know HOW the program is counting days. But this is very little. I decided to give the file 'STARS!.HLP' a try. In the 'How to register section' they say you will be prompted to enter a password the very first time you run the RETAIL VERSION. This does not happen in the demo (or we would be dealing with the somewhat easier 'password check').
Still in the spirit of studying the habits of the prey, I loaded STARS!.EXE in a resource editor. (I hope you have your tools ready...) What do we see here? We have a heading saying 'BITMAP'. I take a look at each. Cute. Then a new heading 'MENU'. Following comes 'DIALOG'. When looking at the dialogs ready-made for this game, the second one in the series (with number 86) gives me a shock. It says 'REGISTER SERIAL NUMBER'. Wow! But... It NEVER appears in the game.
This must be the dialog that appears when the RETAIL VERSION is run for the first time. The writers must have taken out the code that causes this dialog to appear in the DEMO VERSION. What if we can find how? If we can access it, we transform the problem from a 'disabled functions' crack to a 'password check' crack. Well, I tried. While trying, the following possibilities ocurred to me :-
1). The code that controls what the RESULTS of the password
do might have been taken out of the program. The writers just
left the dialog there 'cause there was no reason to take it out'.
2). SOME part of the code MIGHT be there. Some missing.
3). It might be all there, but not easily accessible using the little I know.
4). etc. etc.
############################ # CRACKING STARS! PART ONE # ############################
All these 'might's' were frustrating. I thought of another option. RE-enabling by hand everything that was disabled. This requires more donkey work, is less elegant and less chess. The problem is that I might not have the time to pursue the chess approach in full. I decided for a mix in the hope I might learn more about the program. Who knows? Let's re-enable!.
STEP 1 - The radio buttons and check boxes.
Launch STARS! and click 'NEW GAME'. You'll notice that some RADIO BUTTONS are greyed out, disabled. You can't have a LARGE universe to play with, for example. These little 'things' are actually highly customized 'windows'. There's an API that disables/enables these 'windows' (making them look 'grey' if disabled). How I know this? Voodoo. I was looking over and over again inside the code in the hope a ShowPasswordWindow API existed there... (No, this API does NOT exist). I found many interesting API's in the process. One read 'EnableWindow'.
I open the WIN32.HLP file and read about it. It's an API used to enable AND disable windows. If called with a '0' and the handle of a window, the window gets disabled. If called with a '1', the window becomes enabled. I said Insha'Allah the guys are using this. Let's see. Load STARS!.EXE in SoftICE and press CTRL-D for the program to run. When in the main screen, we will click on 'NEW GAME' to see the first of a series of dialogs that pop with disabled stuff. First press CTRL-D again and enter this breakpoint BPX user!EnableWindow. Notice we're using the 16 bit version of the API. The 32 bit would be 'BPX user32!enablewindow '(If it exists! one times SoftICE seems not to make the difference, and I'm sure this is not SoftICE's mistake, but my ignorance).
STARS is a 16 bit program, and you can verify that by looking at the addresses at the left of the instructions. They come in the form 'xxxx:yyyy', where the 'yyyy', the address of each instruction in a 'xxxx' segment, is a WORD, 16 bits. If you're confused read the assembly tutorials. You'll need assembly, friend. Ready? Press CTRL-D again to go back to the game and then click the 'NEW GAME' button. SoftICE pops up in the start of a EnableWindow execution. Press F11 to make the whole call execute and SoftICE jump back to the line just AFTER the 'call EnableWindow'.
Scroll a little bit up and you'll see a PUSH 00 there. This is the program telling how the EnableWindow API will behave. We know that a 0 will cause a disabling. Let's change that to a PUSH 01 to see what happens. Enter 'a 5a6a'. We're telling SoftICE we want to 'assemble' (to program!) starting from the memory address '5a6a', where the PUSH 00 instruction is. Type PUSH 01 instead an press enter (to make SoftICE accept the code you typed) and the enter again (to tell SoftICE we don't want to code anymore).
If we are in the right track, these radios won't be disable anymore. Press CTRL-D a couple of times, because various 'windows' are being disabled, and your breakpoint will make SoftICE pop at each one. When all the window is drawn, all radio buttons are enabled, except 1. Why? This is the one that escaped us. It was disabled BEFORE we changed the PUSH 00 to PUSH 01 (there was a call to EnableWindow before, right? The one that we used to trigger the breakpoint). Don't worry. Press CTRL-D, and type 'bd *' in SoftICE. This means 'disable all breakpoints'. Press CTRL-D again. Click 'cancel' to go back to the main screen of the game. Click NEW GAME again. Heh, all the buttons are re-enabled. We typed the 'bd *' to stop SoftICE from popping for every EnableWindow'.
Well, There are two buttons in the 'New Game' window: 'Customize race' and 'Advanced game'. Each of these will show you there are a LOT of disabled radio buttons and others. Most follow the same 'EnableWindow' approach. I don't need to show you more details about them. CTRL-D, type 'be *' (this re-enables all breakpoints-we have only 1...) and repeat the approach for the remaining windows in both the 'customize race' and the 'advanced game' dialogs.
Well, are they all re-enabled? NO! You'll soon notice some buttons that seem to never call EnableWindow. They stay disabled, but don't worry about them now. The ones we have already enabled are ONLY ENABLED IN THE MEMORY OF YOUR COMPUTER! The original EXE file remained unchanged. If you wan't to check this out, quit STARS! (click the EXIT button in the main screen) and re-load the program in SoftICE. CTRL-D to run it and click 'new game'. The buttons are still disabled. We need to change the PUSH 00 to PUSH 01 in the file.
I'll use HEX WORKSHOP. First, we have to know WHERE the code is. Repeat the operation we did to find the first EnableWindow in SoftICE. Done? type 'CODE ON', so that the BYTES representing each memory location with the instructions are displayed. This is what we have starting from the PUSH 00 ... I wrote the bytes down.
6A00 PUSH 00 941410A717 CALL USER!ENABLEWINDOW 46 INC SI 81FEEC03 CMP SI,03EC 7EEA JLE 5A62 57 PUSH DI
So I get 6A 00 94 14 10 A7 17 46 8 FE EC 03 7E EA 57. This is what the code will look like in HEX inside our STARS!.EXE file. Or will it? Heh. WATCH THOSE API's! The 'code' for an API CHANGES once the program is loaded in memory. The safe side here is to rely and copy the hex data of non-API (actually non FAR CALL) code. The line starting INC SI (46) is ok. We're left with 46 81 FE EC 03.
These might be enough. We'll make the hex editor search for this byte pattern for us in the original file. After loading STARS!.EXE in Hex Workshop, click on EDIT then FIND. Make sure you check the HEX radio button, for we're searching hex data. Enter 4681FEEC03, then click FIND. The editor displays a match greyed out. We found it, right? well, maybe. What if THE SAME BYTE PATTERN OCCURS ELSEWHERE IN THE FILE? Let's check out. Press f3 to 'search again' (or 'continue the search'). oops. It jumps to another area WITH THE SAME BYTE PATTERN! This same byte pattern actually exists in 4 DIFFERENT places in the file (press F3 again to verify). What do we do? Well, we refine the search. Adding an extra byte or two will reduce he possibility of exactly the same code existing somewhere else. Let's try this, with the next 2 bytes added 4681FEEC037EEA.
Found? press F3 to check if there's another match. The 'wrap notification' tells us the end of the file was reached and no more matches were found. Now we got it. The code for PUSH 00 was 6A00. We will change that for PUSH 01, which happens to be 6A01. Locate the 6A00 a little before the greyed string and change it to 6A01. Just place the cursor there with the mouse and type. Your typing will replace the old values (DON'T DELETE BYTES! JUST OVERWRITE!). Click on FILE then SAVE. Create a backup if you want. It's a good idea actually to create backups ALWAYS BEFORE YOU START ANY cracking. But you surely have the original downloaded zip, so it's not a problem now.
Double click STARS!.EXE (or run it from SoftICE if you wish). The radio buttons in the NEW GAME window should be all enabled. Some interesting questions arise here.
1). Does the program respond to these newly enabled buttons?.
I didn't test it yet. It seems to create huge universes though.
2). If it does, is the game AI and are functions capable of handling the new setting?, we'll have to crack the rest to verify. I wonder...
As you can see, this 'disabled function' business IS fun. I'll let you finish part 1 of the tutorial yourself. there are more 8 windows with disabled stuff in them. Some with LOTS of radio/check boxes, some with only one. You'll notice that the 'EnableWindow' Approach used in this 'PART ONE' does not enable everything in these windows. We do it in PART TWO. I add here just in case the hex code of the other disabling parts I used to track where the 'PUSH 00' was. Notice further that a single EnableWindow was used to disable all windows in the NEW GAME window. Some of the windows that follow have several. Here's a couple of hints :-
Byte patterns used to locate all '6A00' (push 00) before the EnableWindow's in 'CUSTOMIZE RACE' dialogs.
dialog 1 4681FE16017EEAFFF (disables 2 items) E9C6FD8B4E0A (1 item) dialog 2 4681FE18017EEA6A (10 items) dialog 3 83FE0D7EB66A0168 (14 items) dialog 4 4681FE25017EEA6A (3 items) dialog 5 6A01682013569AD4 (1 item) dialog 6 4681FE20017EEA (18 items) 83C406E9A6FE (1 item)
Just look some bytes back once you find these (unique) patterns. You'll soon find a '6A 00'. Change the 00 to 01.
Byte patterns used to locate all '6A00' before the EnableWindow's in 'ADVANCED GAME' dialogs. Well, there are only 2 dialogs here. The first has some byte patterns that are repeated elsewhere, making the job a little harder. My approach was :- BPX in the first EnableWindow. Turn BPX off (type a 'bd *') and press F10 to check how the code behaves. The first EnableWindow is repeated a couple of times, so are the second and the third. Then 5 other follow, each for a window. Then I found an usable byte pattern that happens to be unique : 0Ff84D300BFE803. Once I found this I turned the previous 8 6A00's into 6A01's. The next dialog's EnableWindow can be found near the pattern 4683FE077CB66A01.
############################ # CRACKING STARS! PART TWO # ############################
I know. You're already in love with the game. Next step - the buttons that don't work in :-
Dialogs 4 and 5 of CUSTOMIZE RACE.
Dialog 3 of ADVANCED GAME.
I expected these buttons to be customized windows like the usual push buttons an others we see elsewhere. They being grey and disabled led me to think some missing EnableWindow would appear somewhere. It didn't. In order to acquire more info on what API's the program might be using, I launch W32Dasm, the only disassembler I have at the moment. The point is that STARS! is a 16 bit application and W32Dasm seems to work better with 32-bit stuff. But all I want to know now is if there's any API that can shed some light on the subject.
I load STARS! in W32Dasm, and click FUNCTIONS then IMPORTS from the menu. This nice feature shows us all the API's the program accesses. I scroll and scroll, but nothing really catches my eyes. I only see that the program uses a DialogBox API somewhere, then I have an idea. Let's try to penetrate the code responsible for the dialogs we are interested and take a look. I'll start with the last dialog of the ADVANCED GAME part. Load STARS! in SoftICE, Run. Click 'new game', 'advanced game'. Click 'next' twice and we're there. Saw it? good. Click 'back' to go to the previous dialog. CTRL-D and set a BPX DialogBox. CTRL-D and click next. Yess! Press F11.
SoftICE goes away... well, what actually is happening is that by pressing F11 we execute the call (to the DialogBox API) and then go back. This is exactly what SoftICE is doing. To bring SoftICE back to life, click 'back' in the game. There you go. We're stopped after the dialog was called. Think of the dialog as a 'separate' program that our main program calls for the moment. How do we get IN THERE? Well, I open WIN32.HLP and read that the first parameter pushed before DialogBox is called is the address of the dialog procedure - the code we want, in other words. But that is for 32 bit code. I wonder what is different in 16 bit... gonna need some voodoo here.
Well, Since the address of the proc IS most probably PUSHed somewhere, Know what? I set a breakpoint just BEFORE the CALL DialogBox. Disable breakpoints, CTRL-D and go back to the PREVIOUS DIALOG (Advanced game 2 of 3), CTRL-D, re-enable breakpoints, CTRL-D and click 'next'. SoftICE stops just one instruction away from the call, with all the pushes in the stack for us to see... type 'd ss:sp'. This will have some stuff there in the stack. A voodoo approach alright.
Now some zen : what there looks like the segment:offset address of a proc? My data window shows a promising 10 00 DF 45. That translates to 45DF:0010 in plain English. If your zen didn't let you see this, don't worry. You'll get there sooner than you think. You might always TRY each pair of numbers (don't forget to reverse the bytes...) by setting a BPX in each. When you execute the call, ONE will surely respond.
I set a BPX there then. F10 the call, CTRL-d after the first stop (which was caused by our old BPX user!DialogBox) to let it go. SoftICE stops again at 45DF:0010. A mov ax,sth, then a jump. Mmm. F10, F10, well, We are in an ENTER instruction. Looks just like the start of a procedure. We got there. This is the entry point of 'Advanced game - dialog 3 of 3'. I remember reading somewhere an excellent explanation about how procedures start and end. You usually find an ENTER followed by some PUSHes in the start of a proc. That's the procedure's prelude, the introduction, preface, you name it. Then we have code, code, more code and finally a series of POP's, followed by a LEAVE, RET, RETF, or whatever 'bye bye', instruction.
That's the procedure's cadence, the finale. I hope this helps improve your zen. Sooner or later a window-handling procedure (we just entered one) will start checking for the MESSAGES it was sent. It will start comparing if the msg sent matches any msgs it's interested in. Let's do some chess cracking and look closer at this proc. You may now clear all breakpoints. We don't need them. Just make sure you set a new BPX at the ENTER instruction. After some PUSHes, AX is loaded with a value which is heavily compared to lots of values. I guess AX has the message sent, and these values are messages our program cares about. Let's see :-
cmp ax,20 ; is message 20?
-- ja 7050
| cmp ax,19 ; is it 19?
| jz 70ba
| ja 7270
| sub al,f ;
| jz 706c ; msg= f?
| sub al,5 ; f+5=14
| jz 709a
| jmp 7270
-- sub ax,110 ; this is address 7050.
jz 712e ; was msg=110
dec ax ; no... 110+1=111
jz 7189 ; was it 111?
sub ax,f0 ; no,,,111+f=201
jz 724c ; 201?
dec ax ; 202
dec ax ; 203
jz 724c ; was it?
It seems that 7270 is where any invalid messages lead our proc to. We don't have to care about that. Lets' see what these 'message numbers' mean first, so that we can follow the ones WE are interested. Open the file WINDOWS.INC that should be in the INCLUDE folder of hutch's MASM 32 pack. Window messages come in the form WM_BLABLA. Search for the string WM_ (You might need to type capitals depending on your text editor). Here's a list of what I found :-
a). 20 WM_SETCURSOR
b). 19 WM_????? not found. (I'm going to annnoy someone on a certain channel).
c). 0F WM_PAINT
d). 14 WM_ERASEBKGND
e). 110 WM_INITDIALOG
f). 111 WM_COMMAND
g). 201 WM_LBUTTONDOWN
h). 203 WM_LBUTTONDBLCLK
I soon set a breakpoint on each of the jumps these messages led to. My fears were confirmed. The buttons were not 'windows' buttons, but custom made ones... My breakpoint on the WM_LBUTTONDOWN showed soon that the dialog itself was handling (heh, was NOT handling) the mouse clicks. I decided to pay the WM_PAINT message handler a visit as to change the default grey buttons STARS! has by default. This was easy. The PAINT message leads us to address 706C. Set a breakpoint there and let the program go.
You might need to click 'back' then 'next' for the program to re-paint the dialog. SoftICE pops. You'll be able to see a call to USER!BeginPaint, which initializes the paint process, some PUSHes, and a call 7278. Notice that we have then some more lines, and then a call to USER!EndPaint. The window will be painted at this time. We need to intercept the call 7278, which is the TRUE paint procedure for this window. Go there and set a bpx in the ENTER line (at 7278).
Another proc starting with another ENTER. Press F10 until some 3 or 4 lines are PAINTed in the dialog (you'll press F10 a couple of dozens of times). You'll notice that 2 CALL's are responsible for the button painting, a first call to paint the upper button and another call for the lower one. Taking a closer look, we notice that both calls are TO THE SAME ADDRESS - 4237:9CF0. I paid it a visit, and believe me, you don't want to see what's in there... I came back to the place where both calls are made.
You can notice a couple of pushes before each call right? Well, one of these pushes is telling the 4237:9CF0 procedure what is printed in the face of each button. I changed some values pushed and discovered that it's the second PUSH that carries the button-face value. STARS! has a couple of them in memory and each is accessed through a number. The second push for the first call is PUSH 00A4. The second push for call 2 is PUSH 00A5. I first changed the A4 (before call 1) to A5. Heh, all the buttons were then drawn with a disabled arrow down. We know now what the numbers for disabled arrow up and down are...
What about the ENABLED? Voodoo. Try. They happen to be A0 and
A1. But before you try... If you try to assemble PUSH 00A0, SICE
will take it as a PUSH A0... Instead you can edit the byte in
the data window. Type d cs:(address) . Now type 'e' and enter.
You're in the data window. Change the A4 and A5 to a byte of your
heart's desire and give 4237:9CF0 a run to see what the byte you
typed puts on a button. You're aware some values are meaningless
and put nothing, right? OK.
The rest sounds easy. (Hex Workshop again). There was a problem though. This is the pattern I used at first :-
68A400A1204903 -- near call 1. We change the A4 for A0.
68a500a1204903 -- near call 2. We change the A5 for A1.
But these had multiple matches all over the program. It took me some time, but the nearest byte pattern in the area that is unique is a little bit far up... almost 50 lines in the CODE window (FF46E68B46F2). After locating this pattern, go some lines down and THEN locate the two patterns A and B above and change the bytes accordingly. Save, run and now our buttons display their new enabled cheeks.
############################## # CRACKING STARS! PART THREE # ##############################
Well, REALLY enabling these buttons is another story. If you're patient enough to trace through different parts of the PAINT procedure, you'll notice our program is drawing every part of them. Worse, the program (and not WINDOWS) is also responsible for checking WHAT buttons are being pressed and respond accordingly. IF it can see a button was pressed. It can't right now. Heh.
The first place I went to (based on wishful thinking) was the WM_COMMAND handling part. I know that WM_COMMAND is the message sent to a window everytime a button or a menu item is clicked. I wasn't fortunate. WM_COMMAND has nothing to do with our custom made buttons. I knew what was ahead and went to sleep. In bed, I had a horrible nightmare. The WM_LBUTTONDOWN was responsible for the custom-button handling. It was all removed by the programmers (since the demo doesn't need it) and I would have to rewrite the whole code, if at all possible.
I set a bpx in the start of the WM_LBUTTONDOWN branch and I heard the voices of every cracked program crying from their tombs... Next day I set the BPX anyway, in 724C. Everytime I clicked the mouse anywhere in the dialog, SoftICE would pop. Again the only interesting thing there was this :-
a). The X coordinate of the mouse (at click time) comes in
b). The Y coordinate comes in [bp+8].
c). There's a call to 75CE.
On the pursuit. Let's see this 75CE. Again some code, a FAR CALL to 1907:17DE, from which ax might cause a jump (JGE 75EE). Let's see what this FAR call is about.
MOV AX, FFFF
This is it. A call just to put an 'FFFF' in ax. More important, when returning, the JGE will NEVER jump. The proc just pops si, di (pushed when the proc started) and then LEAVEs and RETurns, to wait for other meaningless WM_LBUTTONDOWN's. Let's see what happens when a, say, 1. Just 'r ax' then type 0001 AFTER the return from the far call. AX is ORed, the JGE works and the program jumps to 'mov si,ax'. CTRL-D and guess what happens? (you might not have noticed a little change...).
The down arrow button in the 'Owns 60%...of planets' just worked. It may go all the way down because the program might think the mouse buttons still pressed. You should make sure you understand what is going on by trying different numbers in AX after the call returns. Each number from 0 to 19 activates a button. As shown above, not ALL of the buttons handling was removed. It seems that only the part that checks IF a button was pressed (and which one...) was taken out. We could code it again easily right? Well, I was starting to do this :-
a). Set a BPX at the start of the WM_LBUTTONDOWN branch
b). Click at the LEFT UPPER corner of a button. SoftICE pops. Write down the x/y value.
c). Repeat 'b' clicking at the RIGHT LOWER corner.
This is all we need to check if a click was inside a button. But something occurred to me...
a). I'd need 4x20=80 WORDS to store my new array containing
the button co-ordinates
b). I have no idea how to add code to an already existing 16 bit exe file...
c). 'b' above made me stop thinking...
Then I remembered something... Remember the PAINT procedure? We saw that a value containing WHAT type of button to be painted was passed (the ones we changed to A0 and A1). Some PLACEMENT data MUST be passed somewhere... If we could locate it, there would be no need to create a new one. I wen't to the PAINT proc again. I started dumping (that's 'd xxxx' in SoftICE) every address that seemed meaningful until 4920 contained some data very similar to the 'button position table' I started to write a while ago (It served to something after all...).
We have our table of positions then. The rest is not very hard. Write some code to verify if the click was inside of these 20 sets pf co-ordinates. If so, put the coordinate number in AX and jump to the 'mov si,ax' part in the 75CE procedure. Things were not so easy though... space is scarce here. Some say that some high level languages leave a lot of space in their code. Other than a few NOP's scattered here and there, our space problem will require some virus writing enthusiasm... What do we need?.
We need a counter. We'll make that AX to keep in the safe side.
That's what the program was 'using'.
We need a pointer to the buttons co-ordinates address. that's BX.
DX and CX will hold the X and Y click co-ordinates.
The following code was my original idea :-
mov dx,[bp+6] ; mouse x
mov cx,[bp+8] ; mouse y
mov bx, ; buttons co-ordinates
We're ready. Notice that the WM_LBUTTONDOWN branch ALREADY has AX=0 when it's reached (It was a sub ax,0f/jz that brought us here, remember?), so we don't need to set ax to 0 and save our first line of code. A good place to do this 'initializing' is when the WM_LBUTTONDOWN just starts. We'll replace the lines :-
Until this line (that remains like the original). No need to mess with it.
push word ptr [bp+a]
Now everytime we click, the 75CE procedure will be ready to make calculations for us.You might need to re-read the above part before continuing, not to mention some experimenting...
Well, I managed to fit our new button handling code in the space from PUSH DI till the LEAVE and RET just before the NOP/MOV SI,AX/SAR SI,1. When I got things working, I was given a little surprise : That FAR CALL (the one that returns a FFFF) in the middle of our dear beautiful space IS A PAIN IN THE ASS to be taken away. I tried overwriting it in SoftICE and the code worked fine. When I replaced the original code the program would generate an error whenever the 'NEW GAME' button was clicked. Why? Heh, when the program is loaded, all FAR CALLs have the proper address inserted in them. It seems that the erased call brought the wrath of Allah upon us. What a mess.
I was happy with the small code I had, and would have to make it YET SMALLER! The far call was taking 5 bytes. 5 bytes, man. I don't want to go into the details of dozens of approaches to fit my code there. I got something that worked in the end. Some main features were :-
a). The call stole 5 bytes from me. My revenge was using the
3 bytes of the call (the 'mov ax,ffff').
b). The PUSH DI and PUSH SI can be taken out safely. A plus benefit is that the POP DI and POP SI yield extra welcome bytes.
c). I was some bytes short and needed a LEAVE and RET in case my click was NOT on a button. It happens that no harm is done if a value higher than 19 is passed to the MOV SI,AX part. I didn't check throughly, but leaving some voodoo traces won't harm if the program doesn't hang.
You're still reading this? Man, you're a born asmonaut. The original 75CE procedure will become :-
ENTER 20,0 ; Unchanged JMP 75DF ; Jump to start comparisons. I know, I know. But what else could I do?. 75D4 ADD BX,08 ; Point to next button co-ordinate data. INC AX ; Increase counter. CALL 4287:17DE ; The damn call. We'll have a CMP AX,14 there. JZ 75F2 ; Was last coor checked? :-( no button. Jump to button handling anyway. 75DF CMP DX,[BX] ; Is X coor of click LESS than button leftmost coor (i.e. outside range). JB 75D4 ; Yeah, it was. Increase counter and point to next button data. CMP DX,[BX+4] ; Is X too much to the right?. JA 75D4 CMP CX,[BX+2] ; Too much up?. JB 75D4 CMP CX,[BX+6] ; Down?. JA 75D4 75F2 MOV SI,AX ; OK! The click was inside a button. AX has button number. SAR SI,1 ; I wonder why, but I found a way of using it next line. JB 7602 ; If ax was EVEN it was an UP button. If ODD, a DOWN. This was lucky... MOV DI,0001 ; This line remains unchanged.
So you can see how I used the FAR CALL. We still have 2 changes to make :-
A). In the FAR CALL, change the 'mov ax,ffff' to 'cmp ax,14'. This will affect the 0 flag if 20 coordinates have already been tested. The flag remains set after the RETF, so that our main code can test it.
B). What did this part do before? Well, it PUSHed DI and SI, and POPed them. We took it all out, but there's another POP SI and POP DI at the very end of this proc (the part that deals with a valid button). Scroll some lines down. You'll soon see this :-
This is some code the DEMO version NEVER enters. We have to nop the POP SI and POP DI. It wasn't so hard to follow right? I'll give here the HEX code you have to change. As an exercise I'll let you figure out WHERE you should type the new code. Remember, search UNIQUE byte patterns. These might be a little farther up or down your target. Stay away from CALLs.
CODE CHANGE AT STARTING OF WM_LBUTTONDOWN BRANCH
CODE CHANGE AT PROCEDURE 75CE
XXXXXXXXXX ; WHATEVER THESE 5 BYTES ARE LEAVE THEM ALONE! THIS IS THE FAR CALL.
Don't forget to NOP the POP DI and the POP SI. Don't forget to replace the 'MOV AX,FFFF' to 'CMP AX,14' inside the FAR CALL. Why I have the impression this went all too fast?.
############################# # CRACKING STARS! PART FOUR # #############################
We're done with the 'ADVANCED GAME' dialogs. We turn our attention to the 'CUSTOMIZE RACE' ones. We have to deal with dialogs number 4 and 5. We'll start with 5 because it seems to be very similar to the last dialog we studied. It has only custom made buttons. Load the game in SoftICE, CTRL-D, 'NEW GAME', go to dialog 4 of 'CUSTOMIZE RACE', CTRL-D, bpx dialogbox, CTRL-D and click next to go to dialog 5.
SoftICE pops. Press F11, and then back (or next, any will do) to exit this dialog and make SoftICE terminate the DialogBox call, just like we did in last dialog. Look a little bit up and you'll see the pair DX:AX again being used to point to our dialog. Set a BPX in the PUSH DX or PUSH AX for SoftICE to stop there so that we can copy their values. Better, type 'BPX DX:AX' and CTRL-D. SoftICE stops there. F11 (if SoftICE stops at the USER!DialogBox - we still have a bpx 0), F10, F10 and we are in the ENTER instruction of our dialog procedure.
Changing the default buttons
With a glance you can see the 'SUB AX,0F'. That's the PAINT branch. Set a BPX there. Once SoftICE stops there, follow the call, F10 until the buttons are drawn. Again a 00A4 and a 00A5 are pushed to give us the default unabled buttons. Change them first. The A4 to A0 and the A5 to A1.
More buttons to activate
Another look at the beginning of the dialog proc reveals 1CF8 to be the start of the WM_LBUTTONDOWN handling branch. Let's see if we find familiar stuff. Mouse X and Y are got. Then a CALL 20CC. We follow 20CC. The only interesting thing is a CALL 17DE. Where did I see this number before... We follow.By the sword of Allah! It's that old FAR CALL (It's not FAR anymore here) that we changed from 'MOV AX,FFFF' to 'CMP AX,14'...
I already knew something was wrong actually. Did you try clicking on dialog 5? Sometimes it goes all blank, sometimes part of it. I actually expected some functions to be shared. We fix. We have in this dialog 14 buttons. The good news is that we have no FAR call to mess with, so we can re-write all our click-detection code in 20CC. 17DE will never be called from here. First we initialize our branch BEFORE it calls 20CC.
mov bx, ; check this address at the PAINT procedure...
The changes in the 20CC procedure will be :-
ENTER 0020,00 ; This stays like the original.
MOV DI,0001 ; This stays like the original too.
Don't forget to remove the POP DI and POP SI (NOP them) at the very end of the proc. You'll find them some 11 lines below in Hex Workshop. Look for 5E and 5F. As you can see, this second dialog re-enabling was made VERY easy by our previous study. Let's go back a dialog and see what the buttons in dialog 4 have to tell us. We have 3 different types of buttons here. 'square' ones with an arrow, 'rectangular' ones with 2 pairs of '<<' and '>>' signs on them, and a pair of up-down buttons just like the ones we've been re-enabling. I wonder if they'll really need multiple cracking. Let me see...
OK. The 'square' buttons are disabled by an 'OR AL,4' just before they are painted. I changed that to an OR AL,AL which seems to work here. I cross my fingers though, for this OR might have repercussions later in the game (remember that FAR CALL which surprised us?). The 'rectangle' buttons are initialized further down, where they are disabled by an OR AX,000C. I changed it to an OR AX,0008, and both types aof rectangles (the '<< >>' and the '>> <<') are drawn fine. Our old friend, the up-down, can be again re-enabled by changing the usual A4 and A5 by A0 and A1. You just have to F10 through the PAINT procedure to see where each button is drawn.
SoftICE helps you further by 'flashing' when a PAINT occurs. Be careful with the 'rectangle'. It uses the same CALL as the square, but initializes further down and re-uses the CALL that draws the 'squares' with a JMP 14D7 (taking us just below the 'OR AL,4' we will change for the 'square' buttons). Here are some hints :-
I used :-
83FF011BC0050300 to get near the 0c04 (or al,4). Change to
0ac0 (or al,al)
B87613EB03B88013 to get near the 0c0c (or al,c). Change to 0c08 (or al,8))
666A0068A400A120 to get near the 68a400/68a500 (push 00a4/push 00a3). You know what to do...
Now let's 11A6, the WM_LMOUSEBUTTON branch. First we see the usual setup as before, with the call directed to 17E2. In the 17E2 proc we meet our old friend being called, 17DE, the FAR CALL of the 'ADVANCED GAME' third dialog. I think we'll be very lucky if all these different buttons (14 of them) are receiving the same click-checking treatment. They might.
asmonaut checking....Yep. They do. Did I mention how many buttons are there? 6 squares, 6 rectangles and 2 up-downs. Well, The blue/red/green areas (gravity/temperature/radiation ranges) ARE BUTTONS TOO. That makes 17 buttons. They look a little scary right? (especially these 3 new unexpected 'buttons'), but they ALL react in the same fashion the old ones we saw. This is a bad, bad day for STARS! protection scheme. This time there are some little changes :-
1). SI seems to be needed as the button-number carrier inside
the button handler. We make it our counter this time instead of
2). Instead of DX and CX, we now use AX and DX to carry the mouse XY.
The rest is now trivial.
When entering the WM_LBUTTONDOWN.
mov bx, --> very consistent, this program.
xor si,si --> our new counter.
When entering the CALL.
skipping the ENTER 000020,00...
mov word ptr [bp-2],dx
and the rest remains unchanged.
I'd like to make a note here. A weird feature in the code allowed us some more swimming space. After the ORIGINAL MOV AX,SI we had :-
Then this follows :-
After a division, AX has the result and DX the remainder. The program is repeating (unnecessarily) the lines :-
DON'T FORGET TO NOP THE 'POP SI' AND 'POP DI' AT THE VERY END. They are FAR away below. Yes my friend. The SETUP stage of STARS! has just been cracked. I'm going to get some coffee.
############################# # CRACKING STARS! PART FIVE # #############################
We are now three main problems. The time limit (easy) the turn limit and the techno level limit. We will solve the time-limit problem last. Our task now is to hunt the turn limiting code. By the very nature of the problems left (limiting) any explorer's intuition will tell him a number is being compared to the limiting number. In the case of the turn limit we have to remove the limitation completely. Haha. you won't believe it. Took me less than 2 minutes. ANY newbie would have done it in less than 5 minutes using voodoo.
Heh. My first idea was this :-
1). get to window procedure
2). locate PAINT procedure
3). isolate area where a variable related to the turn number ('year' would be a probable choice) was painted
4). set a BPM on it (break on memory access)
5). keep breaking until some sensible CMP appeared
I ran the game and pressed F9 a couple of times (to end the turn). I wanted to see what would happen in turn 80. Because of a 'bug' in STARS!, it ends multiple turns in a row if you press F9 repeatedly. Getting to turn 80 takes just a few seconds (I wonder if I can fix this). Well, guess what? A message box pops. See? voodoo pays! I click OK in the message box and BPX messagebox. Press F9. SoftICE pops. Press F11 to show the msgbox, click OK to kill it and we're back in SoftICE where the box was called. It's in a little proc. press F10 3 times until we RET to the caller. Scroll some lines up and you'll see this :-
CMP WORD PTR ,50 ; Allah! look at this number!
CALL 5457:8DC2 ; This is the call to the dialog
OK. Since we better not mess with calls, just turn the 'JBE 009C' to 'JMP 009C' and I promise you'll never see that message box again. We still have a turn limit of 65536 though... Next. The techno levels. You played the tutorial? You should. This game IS fun, and the tutorial shows you what the tech levels are about. You're limited to 10 in the demo, but 26 in the retail version. The programmers kindly supply this information in the demo documentation.
Well, I think I did it some time after typing the last line. Click 'Commands' then research in the menu. Dialog pops with lots of info on research. On the right side under the 'Currently researching' heading, you can see the line 'Resources needed to complete'. Our crack's key is there. When reached level 10, You get the message 'MAXED OUT' instead of a resource number.
Set a BPX TextOut to make SoftICE stop whenever any text is painted to get a feel. When I found where this number/text is painted I looked for comparisons. Was anything like CMP xxx, A around? Instead I found this: CMP DWORD PTR [BP-16],-01, which IS when the MAXED OUT text appears. I deviated the jump and got a -1 printed as resources needed. It seems that if you can't go to higher tech levels, The resources needed calculation gives a -1. We have to find WHERE that -1 gets in BP-16 then. I typed 'd ss:bp-16' to keep an eye on that memory location while I trace.
This tracing could actually take HOURS because of the 'expected research benefits' part. It searches for lots of stuff. You'll have to set some 'zen' bpx in places after jumps that re-start the benefits string search. Press F10 trying to see WHERE [bp-16] is set to ff ff ff ff and you'll know what I'm talking about. Another approach is to set a BPX TextOut and memorize how many benefits a certain techno yields. When they are all painted, start F10'ing. Let me give you an estimate of how many F10's until [bp-16] changes to ff ff ff ff...hold on. Man... A LOT! I just found a better approach. Try this in SoftICE :-
s cs:0 L cs:ffff ff,ff,ff,ff
This will search the current code segment from 0 to ffff (the whole segment) for the bytes ff,ff,ff,ff (ffffffff=-1 in the dword world). The result will be in address BBB. The instruction MOV [bp-16],ffffffff is actually at address 0bb0. Look a little bit up and you'll see the line :-
Change that 0A(10) to 1A(26) and enjoy the new techno levels. (Fire some 'Jihad missiles' in the memory of the time limit we'll crack next). Do I need to tell you what to do? I'll just resume.
a). turn limit - look for the bytes A3C206833E820050. You'll
see a 78 byte next, Change it to EB (this changes the JBE to JMP).
b). tech limit - look for the bytes C00080B9CA580A. Change this last '0A' for '1A' (I wonder... what happens if we set a yet HIGHER level?).
The time limit. We already saw that the STARS.INI file has an entry called HistoryInfo that is used to count the days we've been using the demo. Quite protected this demo... Set that history to zero and a very nice message box pops at the very start of the game. Did I say messagebox?. The procedure is EXACTLY the same as for the TURN LIMIT message box. There's a line at 11F8 that decides the issue :-
test byte ptr [06e6],02
.....followed by a JZ that bypass the box. We'll change that 02 to 00. Find this string 'F606E60602' then change this last '02' to '00'.
############################ # CRACKING STARS! PART SIX # ############################
ALPHA TESTING THE RESULTS
When verifying all the fixings, everything seemed fine until my research seemed to stop when the techs reached level 10. The calculations for resources needed to completion seemed to be OK, for they reached 0, BUT NEW LEVELS WOULDN'T BE REACHED. This is deeper than the stuff we did before. That ffffffff flag only stopped resource calculations etc. but something else forbids level attainment, it seems. Let's see...
A couple of BPX during the PAINT proc (of the research dialog) quickly shows the address 58CA to be the start of a 6 byte buffer to store each current tech level. I changed these values before opening and closing the research dialog a couple of times and the value I enter in painted. However, I press F9 and the OLD, REAL values find their way back in 58CA. It seems the real values are stored somewhere else.
asmonaut away cracking...
Back. Man, this wasn't pretty...
Well, 58CA was being retrieved from 4C24. That was the easy part.
A BPM in 58CA showed the way. I then set a bpm in 4C24 because changing it manually was not changing the tech level for good when a new turn was generated. To end the whole bpm chain, heh, the values, along with LOTS of other values, are stored ENCRYPTED somewhere (memory or file in hard disk). The LAST thing I'd do is try to crack the encryption. I don't really think it's really 'encrypted'. Maybe just compressed, you never know. Even so, I decided to track the values when a tech increases in value. I disabled all bp's, pressed F9 (in stars!, heh, not in SoftICE) to generate new turns while checking the tech dialog to see if a tech had 1 year left to increase.
Now the donkey cracking part: set a bpm in BOTH 4C24 and 58CA to see when the tech value would increase (It was an increment from 5 to 6 in my experiment). In donkey cracking, some determined individuals (called professional crackers), not nice programmers that just like to scan code cynically like us will press the CTRL-D MILLIONS of times until a certain memory address changes the way they so long waited.
I didn't need millions (just a lower digit number). After a certain quantity of CTRL-D's, The value in 58CA (we didn't need to track 4C24 after all...) showed a 6. I started with an eye scan of the area. I was in an obscure proc that had some jumps to everywhere. My 6 appeared after an 'INC BYTE PTR [BX]', where I quickly set a BPX and (disabling all other BP's) run some turns of stars!. Every time a tech increased, SoftICE popped. I saved the game where tech's 10 stopped advancing before. I loaded it and set some zen BP's in the areas where a 'CMP' and a '0A' were in the same line. I don't like to change many lines manually to see the result. I usually change 1 or 2.
More than that can crash the prog and you may have to start again. I was close. I knew it. What decided the issue was not a CMP to a 0A though, but a CMP to a 1A! 1A is 26 right? I read this line in the proc :-
CMP BYTE PTR [BX],1A
And 2 lines below we see
CMP BYTE PTR [BX],0A
and AGAIN two lines below we see
CMP BYTE PTR [BX],0A
Heh. We KNOW what the program does with a tech level 1A. Nothing. This is seemingly done in 5040, the same place where a comparison with 0A sends us. Armed with that (and the knowledge [BX] had my tech level) I confidently changed the last 0A's we saw to 1A. This was an important first step. Some 6 or 7 or 8. I can't launch SoftICE now... I'm typing) lines below there's another cmp [bx],0A followed by a JL to somewhere near the inc [bx]. I changed this one too. This is actually the only change we did that might cause any harm. I mention this because I DON'T KNOW THE DETAILS OF THIS PROC. I've been tracing STARS! for 3 days and everybody at home now hates the game ('... that game that pops a black screen when daddy presses CTRL-D...').
We don't need to really understand all the code to crack it, but we are NOT crackers right? we're just asmonauts seeking more asm knowledge. This is the aim of changing existing code. With the 3 above mentioned changes, my game happily advances. tach level 11, 12, 13...
Here is what you do : Locate the bytes 803F1A0F8D0003. The 803F1A means CMP BYTE PTR [BX],1A' What we want to change is the CMP BYTE PTR [BX],0A which is 803F0A. Just change the 0A to 1A. When you locate the pattern mentioned above, you'll find the first 803F0A in the next line, the second in the second next and the third some 4 or 5 lines below. I'll go for more testing (and kick some alien ass).
############################## # CRACKING STARS! PART SEVEN # ##############################
My my, this is a long crack, friend. I noticed 3 'features' :-
1). When I choose a 'huge' universe size, I get a 'large'.
All other sizes work OK.
2). Slow tech advances -- seems NOT to be responding. These guys pay me a very early visit with heavy metal stuff before I memorize what the name of my planets are.
3). It is not so easy to 'kick some alien ass'.
Well, first I was playing happily in my LARGE univ. thinking it was a HUGE one. Then I again read the help file which mentions HUGE univs to be up to 1000 planets. If you choose a 'control 100% of planets' in the winning conditions dialog (ADVANCED GAME dialog 3), and start a game, click on REPORT, SCORE then SWITCH. The first line says 'OWNS xxx PLANETS' where xxx should be the number of planets in the game. It was NEVER anything near 1000.
Mmm. It was not hard tough. For some inexplicable reason (for me) somewhere in the code the programmers make LARGE be the largest option. I wouldn't be surprised if the maximum was SMALL, which is the largest radio button enabled in the original demo. I did the following :-
1). bpx user!CheckRadioButton -- explanation -- if you don't
know, this API is used to do what it says. Handy if you want a
dialog to appear with some buttons checked as default. Our original
default was small, I think. When the dialog is about to appear,
SoftICE pops in the middle of a proc that handles this stuff.
2). bpm ds:0074 -- explanation (without some boring details...) I finally found the UNIVERSE SIZE row of radios. Depending on what radio you click, a number from 0 to 4 is stored in that address. If it IS set to 4 when we first choose huge. It's set back again somewhere in the code to 3.
3). do a 'd ds:0074' to display our dear mem address in the data window and keep CTRL-D'ing until that '4' turns magically into a '3'.
4). we get it here :-
CMP WORD PTR ,3
MOV WORD PTR ,3
This really makes sure  NEVER gives us a huge univ. I even thought the 'huge universe' creation code did something different than the other 4 types. Since I knew I was NOT even going to think about writing it again (???) in case it was missing (heh. actually I thought of asking the programmers about it...), I decided the kamikaze aproach a woman called Pandora taught humanity. Change MOV WORD PTR ,3 to show the program who is the boss here!. I REALLY find it incredible that it worked... ( I was preparing myself to set the breakpoints again... I was SURE it would hang somewhere).
Now we have a 800 planet huge universe. Want to know how you get the 1000? This whole situation we just saw shed some light in some other features we might have overlooked. You have also the SPARSE/NORMAL/DENSE and PACKED options. It's here we get more than 800 planets IF THESE BUTTONS WORK. STARS! now can create the HUGE size, but no matter what density I choose, I got 'only' 800 planets. We fix again. The trick is now to track the 'density' family of 4 radio buttons. Using almost exactly the 'universe size' approach of a few lines ago, we find that the value is stored in the next word: . The change is actually a neighbour to our last change, few lines below :-
CMP WORD PTR ,1
MOV WORD PTR ,1
Notice that the above code makes sure density is NEVER 'DENSE' or 'PACKED'. I got a 936 planet universe after that change. What twisted mind would want to conquer all that without getting the hush-a-boom bomb from Mr. Mystery Trader?.
Good news. heh? Well, the not so good news is that this crack is over for me, except for the next changes...It's sensible to check for the rest of the buttons in this dialog... they were tampered with too. The 'PLAYER POSITIONS' is disabled to allow only option 1, MODERATE, in this line.
MOV WORD PTR [007C],01
We see a TEST BYTE PTR ,8 just above it. Heh, guess what? This will disable the first 2 options in the check boxes (Maximum minerals and Slower tech advances), with the AND FC (which happens to CLEAR bits 0 and 1 of a FF byte...). I think this was done so because the third check box is the first one you can check in the original demo (the other one is the 4th). The program seems to make sure things below the 3rd are not set. We make sure they CAN be set at will. Remove the nasty AND line.
I don't think I really have to explain how to do it right? If you RE-READ the above parts carefully, you SHOULD know what to do. It's all API hunting and then watching the byte in the data window. Just in case you STILL DON'T KNOW what to do. The whole set of comparisons come in a row. All we have to do is skip them. We change the first JLE 134F (comparison start) to a JMP 136E (line after comparisons). That easy. 833E7400037E06. This '7E06' in the end is the JLE 134f. Change it to EB25 (JMP 136E).
############################## # CRACKING STARS! PART EIGHT # ##############################
There's more you can change in case some of the other radio/checkboxes are limited to a certain range in the code. The point is that changing WINDOWS applications is trivial in comparison to custom made functions. You just have to compare this last part with the part where we hunted the custom made buttons. Windows DOES make the job easier to write a program, but most apps I have seen were VERY easy to crack compared to the more chiselled DOS ones.
I personally like this game a lot. It's only by playing the tutorial included that you can start to appreciate certain subtleties in the game. The programmers did a very good job implementing the strategy. This is a MUST if you like the gender. This is the only game I know where you can play against 15 computer controlled opponents. Some DEMO features still can be noticed in the now cracked version. It seems, for example, that some machinery is labelled 'unavailable' in the technology browser just because they require a tech level higher than 10 (but they are available now for our use, of course). I'll let it up to you if you feel the exercise is worth it. If you spot something you think I should know, or just have something to say, my current e-mail is :-
You might find some related material on my site http://asmonaut.tsx.org.
Some true facts :-
1). ANY idiot can unzip a zipped file. Worse, they say they
enjoy 'cracking', which is understood by them as downloading a
cracked file, patch or key-generator from the web.
2). ALMOST anyone CAN crack. No big deal. If I could, LOTS, LOTS of people can. Tracing some inner workings of a program is OK. Distributing the modified file is NOT.
3). SOME PEOPLE can write games. Most games I see today SUCK. They lack content. They DO have nice music, graphics, but very few are really worth it.
4). NOT EVERYBODY can be an artist, which is a very important part of being able to create art. Programming can be taken as a job or an art (or both, but this is rare...).
5). VERY FEW people are intelligent, imaginative, creative and talented and have the inner strength to be a part of a team able to put good art for us lesser mortals to enlighten our lives with.
6). NOBODY before the makers of STARS! created a space conquest game with such features and playability. I don't say this only because I love the game, just check the other similar software and you'll see what a pioneering work this is. Please don't distribute the cracked game. I only wrote this file for fellow seekers of knowledge and protectionists. Note : I'm a programmer. That's how I feed my kids. I bow to the genius of Jeff McBride and Jeff Johnson, the makers of STARS!.
Because I know you'll like the game, I just want to add this : It took me 3 days to figure out the changes you see. Most of what you see here was written during the study. I am doing this for the pleasure of expanding MINE and YOURS assembly horizons. The programmers took a much longer time to code it and attempting to make it a pleasant experience because they have to earn a living (I think they enjoyed coding it too). I don't need to tell you piracy is illegal do I? Even if it was not, this game deserves to be bought. Make sure you buy the game if you like it. You'll be able to hear some nice spacey music while playing with the original too :-).
PS. It took me 3 days to finish until part 6. I 'had' to play 3 more days, and finished part 7 in 10 minutes. Both '3 days' pair were much fun.
* A good place to download is :- http://crisium.com/stars/demo.htm (link from CrackZ).
This is where you'll probably find the DEMO version. This well documented game can be downloaded from many sites though. A kind of 'official' site seems to be 'STARS-R-US'. If nothing of this works, launch a web search program and try searching for strings like 'stars and strategy', and you'll find it in no time. If you're looking for the retail version, STARS-R-US is the place. Most STARS! sites have links to one another, so this wouldn't be hard to find.