Hacker Question
Hello hackers,
as some of you might know, I am supervising the work on converting games from TR-Dos or TAP to the +D or Opus disk format for our SCENE+ disk magazine. However, for the new issue I came across 6 programs that have a strange new loader. Maybe somebody can explain here.
First game I got here is RESCUE LANDER ( http://www.worldofspectrum.org/forums/discussion/50247/ )
The Basic loader looks very simple:
5 BORDER 1
6 PAPER 1
7 INK 7
8 CLS
10 CLEAR .: LOAD "" SCREEN$: POKE .,. : LOAD ""CODE: RANDOMIZE USR .
What annoys me are the dots (.) . There should be numbers, but somehow the numbers are invisible and therefore a dot is set. So now I cannot change the Basic Loader and insert disk commands, as the Basic Interpreter will not accept the command.
First question of course is WHY? And second question is how it is done (and how to convert it back).
Who can help?
Regards
Thomas
as some of you might know, I am supervising the work on converting games from TR-Dos or TAP to the +D or Opus disk format for our SCENE+ disk magazine. However, for the new issue I came across 6 programs that have a strange new loader. Maybe somebody can explain here.
First game I got here is RESCUE LANDER ( http://www.worldofspectrum.org/forums/discussion/50247/ )
The Basic loader looks very simple:
5 BORDER 1
6 PAPER 1
7 INK 7
8 CLS
10 CLEAR .: LOAD "" SCREEN$: POKE .,. : LOAD ""CODE: RANDOMIZE USR .
What annoys me are the dots (.) . There should be numbers, but somehow the numbers are invisible and therefore a dot is set. So now I cannot change the Basic Loader and insert disk commands, as the Basic Interpreter will not accept the command.
First question of course is WHY? And second question is how it is done (and how to convert it back).
Who can help?
Regards
Thomas
Post edited by rich_chandler on
Comments
'Solving' these isn't hard, open a debugger at around #5D00 and EXAMINE DOTS. You will see a value of #0E after each one, followed by the hidden 5-byte representation. This is mostly zeros but in the middle of it there's a 2-byte 'real value' ('FirstByte + 256 * SecondByte'). Here, we have
CLEAR 30311
POKE 23739,111
RANDOMIZE USR 48010
P.S. The same kind of 'WHY' can be found in 'why bother with a computer from 30+ years ago overall', I think
10 CLEAR 30311: LOAD "" SCREEN$: POKE 23739,111: LOAD "" CODE: RANDOMIZE USR 48010
I quite like the idea of adding this as well. :)
POKE 42785,75:POKE 42786,69:POKE 42787,77:POKE 42788,80:POKE 42789,83:POKE 42790,84
Sinclair BASIC holds numbers twice in two different formats: text and the number itself. If you look through the bytes, you see:
23806 253 046 014 000 000 103 118 000 058
253 = CLEAR
046 = dot
014 = number
...then five bytes, of which 103,118 is interesting, because that is 30311...
058 = colon
It is not unusual to find hidden numbers in BASIC loaders, as a form of protection. Usually it would be a false address that caused a crash, but one of the Magic Knight games actually included a false address that jumped to a "hello hacker!" screen.
I have never seen it with dots instead of a false number though. There is no point in protecting such a new game, maybe it is a way of saving bytes in the BASIC loader?
There are various special listing programs, but this is the only one I could find quickly on WoS:
http://www.worldofspectrum.org/infoseekid.cgi?id=0007948
gLoaderPayload.putdata(0x00); gLoaderPayload.putdata(0x0a); // line number 10 gLoaderPayload.putdata(BASIC_SIZE); // bytes on line (51) gLoaderPayload.putdata(0x00); // 0? gLoaderPayload.putdata(0xfd); // CLEAR gLoaderPayload.putdataintlit_min(gBootExecAddr-1); gLoaderPayload.putdata(':'); gLoaderPayload.putdata(0xf9); // RANDOMIZE gLoaderPayload.putdata(0xc0); // USR gLoaderPayload.putdataintlit_min(CODE_OFFSET); // 23759+basic size gLoaderPayload.putdata(':'); gLoaderPayload.putdata(0xf4); // POKE gLoaderPayload.putdataintlit_min(23739); gLoaderPayload.putdata(','); gLoaderPayload.putdataintlit_min(111); gLoaderPayload.putdata(':'); gLoaderPayload.putdata(0xef); // LOAD gLoaderPayload.putdata('"'); gLoaderPayload.putdata('"'); gLoaderPayload.putdata(0xaf); // CODE gLoaderPayload.putdata(':'); gLoaderPayload.putdata(0xf9); // RANDOMIZE gLoaderPayload.putdata(0xc0); // USR gLoaderPayload.putdataintlit_min(gBootExecAddr); gLoaderPayload.putdata(0x0d); // enterputdata('0'); putdata(0x0e); putdata(0x00); putdata(0x00); putdataint(n); putdata(0x00);http://goo.gl/q2j0NZ - make ZX Spectrum choose your own adventure games, no programming needed (release 3)
I'm spaniard, so I use the "Listador BASIC para +3" published in Microhobby 192, but I have another english counterpart (but I don't remember the name).
An' you know what they said?
Well, some of it was true!
I've mentioned 'the dots' because that is what they've swapped the actual numbers with in this particular loader. In other loaders these might be 0's, or even entirely fake numbers (let's say a RANDOMIZE USR 31336 that actually calls the address 25000). Generally, when you use a debugger you should look around these numbers/symbols that come after RANDOMIZE USR, CLEAR and so on.
#0E / 14 I think is the marker byte used by BASIC in this context to indicate a 5-byte format value following. It's not actually part of the value itself
I think Jmk above explained it better than me, and he also posted a pretty useful routine that lists the BASIC program with all the real values it uses automatically, you should check it out. I'm not sure if it has any limitations etc but it seems to work with this loader :)
253 = CLEAR
What is RANDOMIZE USR? POKE? I can of course use the software tht Jmk suggestest, but I want find out how it works, not just rewrite it.
I´ve already tried some other programms as now it seems very common to use this protecton. But I didn´t suceed. One demo (Down) had more pokes and RAND USR commands than a simple loader, because it uses RAM switching. So it get´s a bit harder, but that´s the point about when hacking, isn´t it?
Because USR is a function (and not a command) you need to add some command to fullfill the rules of Sinclair BASIC syntax. The most harmless command is RANDOMIZE, that is why it became a kind of standard.
There are several BASIC/code tables online like this one, you can look up the codes for each command there. But you don't actually have to remember all the codes in order to do it (E.g. I don't :) ).
As an example, this is the loader of Manic Miner. If your debugger has a memory view window like this (see the big blue window at the lower right), you can easily identify where the numbers are located, visually. Then just eventually compare that with the LISTing you get in the BASIC and you will see the way they correspond and what the actual commands are.
There are other cues that you can use, such as let's say you can typically identify the LOAD commands by sequences of "" in the memory, and #0D's indicating ends of BASIC lines, but that's more or less it