Cracking Open the Propeller (Original Page) - rosco-pc/propeller-wiki GitHub Wiki
Decoding the Spin Interpreter
Chip Gracey (Parallax) : Can anyone out there figure out how to get the proper binary image of the current Spin interpreter from ROM?
Harley Shanko : Did I just hear a challenge?
Chip : Yep! Maybe it hasn't been pursued, out of consideration to Parallax, but if someone posts the correct binary, I'll post the original source code.
Original thread : here
Overview
The Spin Interpreter along with the bootloader is stored in ROM, according to the Propeller Memory Map between byte addresses $F002 and $FFFF. Although this ROM area can be easily read by a Spin or PASM program ( as other data in ROM can be, character bitmaps and trigonomic tables ), the data returned is encrypted. This data is decrypted by on-chip and unknown hardware as it is loaded into a Cog for execution. As Chip has written ...
"The booter is at $F800 and the interpreter is at $F004. You will not be able to disassemble these programs, though, since the data is scrambled and only gets unscrambled by the HUB during launching. This is the only 'code protection' that the chip has and it's designed to slow down others from making me-too Propeller-like chip products".
Original thread : here
Encryption Mechanism
The encryption method used is not known but the Propeller chip does contain an LFSR which is used during program download and it very possible that an LFSR is used as apart of the decryption process. The LFSR taps used are documented.
A reversible LFSR is also used to randomise Spin variables. Although this is most likely implemented as code within the interpreter itself ( there are no LFSR related Cog opcodes ) there may be similarities between that and any LFSR used for ROM decryption. The randomisation algorithm can be found here
Chip has referred to the ROM image as "scrambled" rather than "encrypted" so the mechanism used could be quite simple, even if not easy to determine. Obvious "scrambling" mechanisms would be simple XORing, bit rotation, bit reversal and address bit re-ordering ( PASM code stored non-sequentially ). Any number of these methods, plus LFSR could be applied together, along with decryption being accumulative, the previously decoded value affecting the decoding of the next.
The encyption could be byte, word or long oriented. While loading Cog is usually talked of in terms of loading 512 longs, it could equally be the loading of 2K bytes.
Approaches to Decoding the Spin Interpreter
Although the Spin Interpreter reads Ram to initally configure the start address and stack, then reads Ram to interpret the bytecode, the program counter, stack pointer and related registers are all held within the Cog. There appear to be no Spin bytecodes which can extract data from within the Cog nor be subverted to do so. Trying to create a 'buffer overflow' type of attack to leave code in a Cog which could dump its contents out does not look possible.
The Spin Interpreter is launched by a CogInit of the PASM code held at $F004 with the PAR register pointing to a 12-byte block of memory ( $0004 at first Spin Interpreter boot-up ) which defines where the Spin bytecode to execute and stack is. By executing a CogInit of the assembler code above $F800 it may be possible to load a PASM program held low in Hub Ram which would be loaded as part of the 496 long load into Cog ( through address wrap-round ) leaving that PASM program plus some decrypted ROM in the Cog, and with a fair wind, see that PASM code executed and reveal the decrypted bytecode. Although the decrypted PASM code is not the actual Spin Interpreter ( it's the bootloader ) it would help in verifying any decryption algorithm determined. Whether such PASM code ( at the end of Cog memory ) would ever get executed is debatable and the odds would seem to be against it.
The best approach would appear to be to dump the ROM between $F000 and $FFFF and attempt to decode that either on chip or off-chip using a PC.
Spin Interpreter ROM Image
An extracted Spin Interpreter ROM Image ( in its encrypted form ) is available here as SPIN.ZIP ( in both a .BIN and a .HEX form ) from Peter Jakacki and a program to extract a ROM image is provided by dartof.
Die Images
A - COG RAM - (view of the ISDR Word Line drivers) B - HUB RAM - (view of the Column Address Decoder) C - HUB ROM - (view of the 4-16 Decoder driver)
Possible Helpers
The Spin Interpreter needs to know where the information is from which it initialises its program counter and stack pointer. This is provided by way of the PAR register set through a CogInit and thus the Interpreter should use the PAR as a source register fairly early on in its execution.
It would not be surprising to find an early 'rdbyte', 'rdword' or 'rdlong' using PAR and, as PAR is read only, a 'mov' from PAR and subsequent 'rdbyte', 'rdword' or 'rdlong' using the register PAR is moved to. It would not be unreasonable to expect the first Cog instruction to be a 'mov'. Concentrating on just the early part of the interpreter code could make a brute force attack on the encryption more feasible.
Given that there would seem to be only a limited amount of run-time data storage used within the run-time interpreter, it would seem unlikely that the initialisation code would be within an area later in the code which would subsequently be re-used for data storage. If that were the case, it would seem likely that a 'jmp' or 'jmpret' would appear early in the code.