Reversing The Encoding Of Serial Numbers In PALs or GALs - Page 1
Forum section: electronics / projects

author: dexters_lab
author_rank: Unknown
timestamp: December 02, 2016, 08:56:17 am
content: I have a number of JEDEC files here for the PAL/GAL 20V8 that encode a serial number into the logic array and i would like to figure out how the serial number is encoded so i can create new ones with new serial numbers.These GAL20V8's are used in a 30 year old quantel paintbox to give each machine a unique serial number and i think it's also used to perform some kind of de-encryption of the software license keys. I found in a stash of these devices i acquired, that what Quantel call a 'SecurityPAL', it seems that someone at quantel was not doing their job properly and forgot to set the no readback fuse on them so i have several images of valid ICs.I should point out that Quantel (who don't even exist anymore as Quantel) stopped servicing these old machines decades ago & the industry does not use them anymore so i doubt this exercise will create any legal issues.The serial number is never any longer than 5 digits and there can be two serial numbers encoded.If anyone fancies a friday challenge, i have attached the read out data, the challenge now is for someone to tell me how they are encoding the serial number into the array!The filename is the serial number encoded into the IC and also printed on the label stuck to each IC.I have also attached a segment of the schematic showing how it's inputs are wired to the CPU address lines A1-A13, outputs are 8 bit onto the data bus. The system is a motorola 68k architecture.We're also tackling this from the software side too, disassembling the code that reads the PAL but that is work in progress.any thoughts would be appreciated!!

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 02, 2016, 09:30:58 am
content: ISTR you saying some units used a 20L8 - if so it has to be pretty simple as this device has no internal registersIf you look at the architecture of the device, the number has to be encoded as inputs, not outputs.e.g. for the simplest case, and assumomng a 16 bit number space it could be there are 4 'bit select' inputs, and it outputs one bit of the number, selected by the select inputs via one output.Obviosuly there could be some obfuscation by XORing etc., but it could NOT be something lie a LSFR shift-register.With a 20V8 it could be a little more complex, worst-case you may have outouts enabled by an obscure sequence, but from memory I don't think the 20V8 can have buried internal state that can feed back to the matrix.Of course it could be that there is no actual relationship between the number and the PAL contents and they had a database.If you can find something like a PAL disassembler it should be possible to figure it out.But as you have a working unit, it would be good to poke about the pins with a scope or logic analyzer to see if you can figure anything out, if only which pins are used.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 02, 2016, 09:40:22 am
content: Just noticed the schematic - it looks like it's just being used as a PROM.My guess is most of the address lines are a decode, and a subset will be a word select.As it isn't possible for it to be feeding back any state to internal registers (e.g. to read different things on multiple reads) I think simply cycling through all the addresses would reveal the PROM contents.In the absence of a JEDEC disassembler, You _could_ do it by manually decoding the JEDEC file, but would probably be quicker to read the devices like a PROM. If you have access to an EPROM programmer, make up a header to map the pins to an EPROM of suitable size. Or lash up some simple hardware to step through the addresses & spit out the data.

author: stj
author_rank: Super Contributor
timestamp: December 02, 2016, 09:57:08 am
content: there is an old dos program called "JED2BEQ",infact there are several versions of it - it was included with logic compilers like "PLAN"

author: dexters_lab
author_rank: Unknown
timestamp: December 02, 2016, 09:57:37 am
content: thanks Mikeyour probably right about the PROM thoughts, i have just burned one of those serials onto a new GAL and the machine picks the new serial number up just fine so i doubt there is a database of patternstime to have another play

author: CJay
author_rank: Super Contributor
timestamp: December 02, 2016, 10:51:15 am
content: Grab a copy of OPALJR21 from various places, it's got a nice command line utility which takes the .jed files you uploaded and spits out a .eqn file which should be simpler to simulate.Also worth a look, open two files in notepad, cut out the duplicated lines and you're left with what might reasonably be the serial number, it at least removes the deadwood.Attached the .eqn for 12360

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 02, 2016, 10:59:58 am
content: Quote from: CJay on December 02, 2016, 10:51:15 amUnless the number is blindingly obvious You'd probably want to compare all of them as you may gave 2 files with the same values in some bit positions

author: dexters_lab
author_rank: Unknown
timestamp: December 02, 2016, 11:36:08 am
content: having never touched PALs or GALs before this is out of my league now.A friend of mine is helping with this side of it, Ash... he's going to post in a momentmeanwhile i will look at trying to read one of them as a rom in the TL-866 and see what it spits out

author: OzOnE
author_rank: Regular Contributor
timestamp: December 02, 2016, 11:46:49 am
content: Hi, mike / all,(I still have that Photo-multiplier tube I bought from you on eBay btw. Still not sure what to build with it though. lol)I've been helping Mr Dexter to reverse the GALs / PALs, and already used OPALJR to convert the JED files to EQN logic equation files.(I may have been partly responsible for the current "snowball effect" of Quantel stuff, after I sent Mr Dexter my Quantel V-Series "Harriet" system in a swap for the NAC High-speed camera. lol)I translated the EQN file for one of the GALs (with the 12360 serial number) to Verilog, by just changing the logical operators to the Verilog ones.I then ran that on the DE1 dev board, since it's easier to just run the thing and debug via SignalTap rather than using that evil ModelSim simulator.It does indeed look like it's just using the GAL as a simple PROM, as the address bus from the 68000 very likely comes from an always-enabled buffer, so it's not doing anything fancy there.The /ALEC input is just an /Output-Enable by the looks of it, and the EQN files seem to confirm that theory.We're fairly confident that the schematic from the newer Paintbox uses the same GAL pinout for the GAL as the older "Harriet" style systems do.Mr Dexter has also read the GAL from the other similar Harriet system too, so that's a good confirmation that all the chips work the same way.When I ran through all the addresses on the dev board, the outputs hardly ever changed at all, so I'm thinking there may be an issue with just doing a direct translation to Verilog.I can't see why though tbh, as the logic terms only consist of rows of AND gates, and a few ORs in-between each row? It's also working on single-bit wide input signals too, of course.I've just tidied up the Verilog a tad, and it looks like a pretty simple ROM type layout...http://imgur.com/a/aJn3yI've attached the original EQN file for the "12360" serial GAL too, and that was converted using the OPALJR tool.The logic at least seems to tally with that newer schematic, and it doesn't look like it's using the registers nor registered-outputs at all.OzOnE. (ElectronAsh on YouTube.)

author: CJay
author_rank: Super Contributor
timestamp: December 02, 2016, 11:53:14 am
content: Quote from: mikeselectricstuff on December 02, 2016, 10:59:58 amMy bad, what I should have said was 'what might reasonably be the serial number or a portion of it', we only need to worry at the moment about the differences, if we can work on those and figure out how to alter the serial in a predictable way by changing the differing lines then we can expand that to the rest of the data and see if it 'fits' with the other files.Won't take more than a few iterations to see if it's a reasonable approach.

author: OzOnE
author_rank: Regular Contributor
timestamp: December 02, 2016, 12:00:13 pm
content: Just mentioned the PROM / TL866 thing to Mr Dexter before reading your post, Mike. Great minds. :pThe data output hardly seems to change at all when I run the Verilog on the dev board?If we can see the ROM reader output, it will confirm that I'm converting it correctly.I'm doubtful that I have tbh, as I would have expected the data output to change on almost every address?It's possible that was intentional though, or just the way their algo for the serial number works?While looking at the routines in the 68000 disassm (IDA Pro), it does look like it's doing some basic XOR stuff from a given input string and a "Copyright (c) Quantel...." string.I'll have a look to see where it reads the serial number too, as I don't think we've checked that code yet.Hopefully it just sends a fixed string to the "VerifySecurityPAL" routine, and then that spits out the serial number in the same way as it would scramble / de-scramble any other fixed string.That routine seems to be the only place where it ever reads from the PAL though, so there's hope.I did start to get the V-Series / Harriet 32K ROM monitor to boot by adding some skeleton code to MAME too.That allows me to step through the code and see what each routine does, so should come in handy.I did a similar thing for the older classic Paintbox about 3 years ago now...That DPB-7001 (from the BBC) is now in the possession of Mr Dexter too, as some of you have no doubt noticed. lolWe still have yet to get that damned thing to boot either.The only machine I had that was booting fully was the previous V-Series "Harriet" unit from over a year ago.The unit I sent to Mr Dexter was actually attempting to boot for the first two or three times I powered it up.I was then simply trying to get into the ROM monitor via the serial port to quickly note down the passwords in there.To do that, I had to lift the lid on the unit just a tad, flip the hex switch to the "0" position, then boot it up again.The damned thing then refused to boot into the "desktop" after that, and would only give a Bus Error.(#spoilers - Mr Dexter since found out that it was the video board causing that, so it must have just died due to old age / bad tant caps, or a bad buffer IC?)So then the "incident" with the original GAL chip occurred, and that's where we are now.OzOnE. (ElectronAsh on YouTube.)

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 02, 2016, 12:04:27 pm
content: Pretty straghtforward. Each line is a bunch of terms ANDED, with the lines ORed to produce the resultLooks like there are seven high-order addresses. Each line represents the output of that bit for each addressIt may be that they are effectively encoding an input function on some of the lower-order addresses, so there may be quite a few "valid" addresses within the address space, but for each data bit, there will only be seven addresses within the whole address space (ignoring duplicates from unused address bits) that return a '1'Each line will return a "1" for the address where Ax is '1' and /Ax is '0'e.g.Code:D0 = /A12 * /A13 * /A11 * A10 * /A9 * /A8 * /A7 * A6 * A5 * A4 * /A1 * A3 * A2 outputs '1' when Address = 0001000111110X+ /A12 * /A13 * A11 * /A10 * /A9 * /A8 * A7 * A6 * A5 * A4 * /A1 * A3 * /A2 outputs 1 when address= 0010001111100X+ /A12 * /A13 * A11 * /A10 * A9 * A8 * A7 * /A6 * /A5 * /A4 * A1 * /A3 * /A2 0010111000001X+ A12 * /A13 * /A11 * /A10 * A9 * /A8 * /A7 * /A6 * A5 * A4 * A1 * /A3 * A2 0100100011011X+ A12 * /A13 * /A11 * /A10 * A9 * A8 * /A7 * /A6 * /A5 * A4 * A1 * /A3 * A2 0100110001011X+ A12 * /A13 * /A11 * A10 * A9 * A8 * A7 * A6 * A5 * /A4 * A1 * /A3 * /A2 0101111110001X+ A12 * /A13 * A11 * A10 * /A9 * /A8 * A7 * A6 * /A5 * /A4 * A1 * /A3 * /A2 0111001100001X

author: OzOnE
author_rank: Regular Contributor
timestamp: December 02, 2016, 12:04:32 pm
content: Hi, CJay.Do you think my "translation" of the EQN to Verilog was a tad optimistic? lolIt literally only seems to change about ten bytes in the whole address range?All the other bytes stay at 0x00, so that's either the way the PALs worked in the first place, or I'm way off with my conversion?Do you know of any software which could just simulate the GAL chip outputs directly?It's strange though, as Mr Dexter has now written the JED file back to a blank GAL, and that is indeed reading the serial number just fine (whether directly, or via the usual VerifySecurityPAL routine, which I still need to double-check).The issue of course is that the serial on these working PALs no long match the passwords on the system (which IIRC, are stored on the HDD in the main OS file.)This is fun at least.I love investigating / reversing things like this.OzOnE. (ElectronAsh on YouTube.)

author: OzOnE
author_rank: Regular Contributor
timestamp: December 02, 2016, 12:08:09 pm
content: Mike - do you mean you would expect only several bytes to change at all in the address space (which is what I'm seeing so far)?All the rest on the Verilog run seem to output 0x00?The output data looks very sparse indeed, but that could be my simple conversion to Verilog was flawed...http://imgur.com/a/gxese

author: OzOnE
author_rank: Regular Contributor
timestamp: December 02, 2016, 12:12:22 pm
content: Actually, good point.I'll go through now, and just change the logic terms into something more readable.ie. change the input address bits into the Hex equivalents.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 02, 2016, 12:12:55 pm
content: See amended post above. Due to the architecture, each bit will only be '1' at seven addresses within the space.I suspect they are encoding data on the address bus. Just needs the common adddresses ( same for each bit & line) to be eliminated, then some turning inside-out ( reorder list by content) to make it look more meaningful

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 02, 2016, 12:20:12 pm
content: To clarify above turning inside out - once you have stripped the upper addresses, say you get a list like this ( abbreviated0'1' at the following adddresses :000 = 0010 = 2100 = 4111 = 7This would convert to the following for that bitAdddress / data0 1 ( '1' at address 0 position)1 02 1 ('1' at addr 2 position)3 04 15 06 07 1Once you do that I suspect you may get something that correlates to the number.You may be able to deduce something from how the system behaves - e.g. is it a case that it 'tests' a number coded into teh software and gets a yes/no answer, or can it actually read and ddisplay the number of the installe chip ? If the latter it would have to scan through the whole address space

author: OzOnE
author_rank: Regular Contributor
timestamp: December 02, 2016, 12:24:28 pm
content: Ahh - I see what you mean.I didn't spot that at all. lolOnly seven terms for each bit, so only seven possible addresses where that bit would go High.That does seem to confirm the Verilog then, and it only outputs a byte other than zero at a handful of addresses.From what I've seen of the Verify routine, it looks like it may be cycling through 0-9 while it's incrementing the address to the PAL (and doing a few other things which we're not quite sure about yet).My knowledge of 68K Asm is a tad lacking, so it's not intuitive yet, and takes me a while to figure it out.The last time I really got stuck into it was while trying to bypass a password on a certain airport X-Ray scanner.OK, I'm just converting all the rows of logic terms to binary (or hex)...OzOnE.

author: OzOnE
author_rank: Regular Contributor
timestamp: December 02, 2016, 12:27:25 pm
content: @Mike - yep, it's looking like the whole thing could be done with a fairly short list of terms, and that may mean the serial number really is just encoded onto a few bits.I was expecting it to do far more scrambling / checksum type stuff than that, but I guess they weren't trying to be super-secure?It has at least managed to cause us a few headaches already, so it did it's job. lolEDIT: Worth noting that the address bits on the "PAL" starts at A1, as in a lot of 68K-based systems (with no /UDS nor /LDS hooked up to the "ROM").So, if you read each address in turn with Byte instructions, the same output data would probably appear twice?When read in 16-bit Word mode, the output from the PAL should just be mapped to the lower 8-bits, of course.Although I believe the Byte and Word routines on the serial monitor do spit out the values correctly.We did try reading the PAL back via the serial commands yesterday, but it looked like it may have been locked out by another register? Or, Mr Dexter just had to hit the Enter key a few hundred more times. :pOzOnE.

author: amyk
author_rank: Super Contributor
timestamp: December 02, 2016, 12:28:04 pm
content: I've taken the 12360 equations and turned them into table in the following code which should reproduce what it looks like in the addres space of the CPU (except with every byte duplicated since A0 isn't connected). Each row represents a bit, each column represents an address at which that bit becomes 0.Code:#include <stdio.h>unsigned short btab[] = {{ 0x023E, 0x047C, 0x05C1, 0x091B, 0x098B, 0x0BF1, 0x0E61 },{ 0x0263, 0x04B2, 0x05B3, 0x0627, 0x0899, 0x090B, 0x0B80 },{ 0x0078, 0x03CD, 0x04E3, 0x0645, 0x06BE, 0x0732, 0x0991 },{ 0x0113, 0x0355, 0x0373, 0x0398, 0x03B9, 0x0627, 0x068D },{ 0x0162, 0x02AF, 0x02C4, 0x053C, 0x07AD, 0x081D, 0x0A86 },{ 0x0567, 0x0764, 0x087E, 0x0AE4, 0x0D4E, 0x0FB9, 0x1022 },{ 0x0207, 0x0470, 0x0683, 0x06F4, 0x096B, 0x0B88, 0x0DF2 },{ 0x0057, 0x00A8, 0x00A9, 0x0116, 0x0180, 0x01EB, 0x025A },};int main() {int i;for(i=0;i<8192;i++) {int j;unsigned char c = 255;for(j=0;j<8;j++) {int k;for(k=0;k<7;k++)c &= ~((i == btab) << j);}putchar(c);}return 0;}Attached is the output of the above code, it is indeed very sparse.

author: OzOnE
author_rank: Regular Contributor
timestamp: December 02, 2016, 12:30:36 pm
content: @amykThat was FAST.Superb work.I've only just started manually converting the logic rows to Hex, and only got the 0x023E one done. lol

author: OzOnE
author_rank: Regular Contributor
timestamp: December 02, 2016, 12:43:43 pm
content: @amykDid you see that address bit input A2 was inverted btw?I had to create an internal "wire" on the Verilog version to do that, but the EQN can do it directly on the input pin declaration.OzOnE.

author: amyk
author_rank: Super Contributor
timestamp: December 02, 2016, 12:47:43 pm
content: Quote from: OzOnE on December 02, 2016, 12:43:43 pmOops.Don't have any more time to play with this now but XOR'ing all the addresses in the table with 4 should fix it...

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 02, 2016, 12:55:48 pm
content: Quote from: OzOnE on December 02, 2016, 12:24:28 pmBut these addresses are almost certainly different for each number and maybe also for each bit. Needs some bit-twiddling to covert from address space to bit patterns on the address lines

author: OzOnE
author_rank: Regular Contributor
timestamp: December 02, 2016, 01:07:01 pm
content: No problem, amyk, it's still awesome. :pI should try using C more often, but I've been using FPGAs so much now that I do a lot of stuff in Verilog faster.(not that I'm an expert on either.)I'm just about to compile and run the Verilog again, but using your Hex values to compare with what I was getting before.It should match 100%, in theory.@mike - yep, there will be a fair few addresses where the output changes, and that's what I'm seeing so far.Still fairly sparse though, so their serial algo can't have been too complex after all.

author: OzOnE
author_rank: Regular Contributor
timestamp: December 02, 2016, 01:15:51 pm
content: Looks like the Hex version of the Verilog matches with what we're expecting from the EQN.It should do really, as it's just representing the addresses in Hex rather than binary / separate bits.http://pastebin.com/UDAPA52vOK, so, erm. lolI'll have a look at some other serial JEDs now, and try to figure out what that 68K routine is doing.Good progress though, as we could eventually implement this as either a simple ROM, or a PIC / AVR / CPLD / FPGA which can do any serial number.Although, that's obviously overkill if a simple PROM would do the job.This will be great for MAME use too - I'll try to get more of that working, but it will take a while.I never got the original Paintbox to fully boot on MAME, as although I had the full service manual with schematics, there were a fair few things I needed to test with the real machine in front of me.OzOnE.

author: OzOnE
author_rank: Regular Contributor
timestamp: December 02, 2016, 01:33:39 pm
content: OK, here's the main routine which seems to hash the PAL with that Quantel string...http://pastebin.com/dpjXhTL1EDIT: The "n" from the Quantel string is missing off the end, as IDA didn't seem to let me set it as an ASCII string properly?I'm fairly sure the string does just end with that "n" character though, as the 0x4E71 that follows it equates to a "NOP", and the 0x4E56 is an "RTS".Most of the comments in there are from another guy who has been helping to reverse this.If anyone could turn that routine into some C or even pseudo-code, that would be a huge help.As far as we can tell, it does look like the security PAL is simply mapped directly to 0xFD0000 in the 68K address space.I guess that when reading it using Word-addressing, the bytes would simply be output in the LSB of each access, with the upper bits floating (or tied High or Low)?

author: philpem
author_rank: Frequent Contributor
timestamp: December 02, 2016, 10:28:47 pm
content: Quote from: OzOnE on December 02, 2016, 01:33:39 pmNow I'm tempted to load that into a 68k emulator and see what it does...What specific 68k chip is on the main CPU board? I heard Dexter say "I've got 68040 CPU boards but they're for a later machine" in his videos, so I assume 68030 or earlier?Quote from: OzOnE on December 02, 2016, 01:33:39 pmThere's two ways I can think to do that in IDA. One is to change the length of the string array, the other is to mark the "nNqNV" as byte data. That'll split it into five bytes. Mark the latter four as code, then mark the three preceding as data.Is there any chance I could get a copy of the ROM which was disassembled to produce that code snipped, or the IDA file? (PM if necessary)Have you got some examples of input to that function? Ideally input and output when it's working?At cursory glance (two minutes) that looks more like it decrypts a licence string based on the PAL, not figures out the PAL's serial number.If I had a second machine and I had PAL source and licence keys, I'd just do a Three Musketeers attack on the thing. Clone a licence PAL from one machine to another, then copy the licence keys across.Quote from: OzOnE on December 02, 2016, 01:33:39 pmExcellent! Should be enough there to bash together an emulator. Just need a ROM image and/or IDA file.Cheers.

author: philpem
author_rank: Frequent Contributor
timestamp: December 02, 2016, 11:20:08 pm
content: Got bored, printed the code off instead, got a pencil. As you do.LOC_52EC..LOC_52F4 => this is a loop which clears *addr0 to $FFFF, word-by-word.52F8: Get the address of the input "crypto string"52FC: mustContain7777777 = '\0'. In other words, null terminate it at the 8th character. Leaving you with 7 characters/bytes... assuming it's a C string, and it's not filling it in with something else later.I wonder if this is the serial number.5300: Chuck the address of the PAL into A15306: D0 = $1FFF. 8191. Half the number of bytes in the PAL. The PAL is accessed in words and the address (A1) is auto-incremented. So this fits with 13 address bits.Clear D1(word) and D7(dword) on entryNow there's a loop which reads the PAL. The loop counter is D0At 5320, the code accesses addr0 -- it reads it, then writes back to it. What I'm not certain of from this code snippet is whether addr0 is a temporary buffer (i.e. the "data I read from the PAL" buffer), or some kind of encoding table used to decode the data in the PROM.So from this we can kind of deduce that the function works a little like this:int readSecurityPAL_ChecksumCrypto(uint8_t *inputCryptoString_len3F, uint16_t *addr0, void *addr1_mustContain7777777)inputCryptoString_len3F:Crypto string.On entry contains the encrypted crypto stringOn exit contains the decrypted (EOR'd) crypto stringaddr0:Accessed in 16-bit words.Seems to be a decoding table for the PAL (used to decode the addresses)addr1_mustContain7777777:8-byte byte arrayChecked after the PROM has been read.If this is not equal to {7,7,7,7,7,7,7,0}, then an error has occurred. (PROM not present?)Serial number?I'm still looking at what the inner loop does. It looks like the guys elsethread are on the right sort of track though. It scans up through the PAL addresses, then it processes a few bits which come out of the PAL.It's a bit of a headscratcher without seeing the rest of the code around it (or at least "seeing it running"). But hey ho.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 03, 2016, 12:23:54 am
content: Quote7 product terms in the PAL - coincidence..?

author: philpem
author_rank: Frequent Contributor
timestamp: December 03, 2016, 01:24:19 am
content: Quote from: mikeselectricstuff on December 03, 2016, 12:23:54 amProbably not...!I've been spending a few hours poking at the GALs. I've decoded all the GALs with JED2EQN, then converted the EQN syntax into C. My plan is to loop through and make a "security PAL emulator" I can bolt onto a 68K core. Watch this space.Curiously every single PAL has its outputs inverted. So normally, the data outputs will be high, unless you hit an address which interests it.Also, the data bits will probably read high if the outputs are disabled -- most systems I recall seeing have a pull-up resistor pack somewhere on the data bus.As Mike quite rightly says -- there are seven product terms, which probably corresponds to those seven bytes in the "Addr1" response.So based on the thinking that we have seven product terms, seven bytes in the "Addr1" return -- my bet is that "7777777" is a special return value which means "I can't find a security GAL, or it's broken".Anything else means the GAL responded to something.Looking at it another way, if we assume that's the maximum value, '7' is all bits set for a 3-bit value. A seven-bit array of three-bit values would get you 21 total bits encoded.Potentially, eight outputs times seven Pterms on the GAL gets you 56 bits.That's an encoding efficiency of 0.375... assuming these assumptions are right...

author: philpem
author_rank: Frequent Contributor
timestamp: December 03, 2016, 01:48:38 am
content: Some food for thought. This is a list of all the addresses which provoke a response from the "12360" GAL:Code:Addr 0x00AA -- value 0x7F -- inv 0x80Addr 0x00F4 -- value 0xFB -- inv 0x04Addr 0x0154 -- value 0x7F -- inv 0x80Addr 0x0156 -- value 0x7F -- inv 0x80Addr 0x0222 -- value 0xF7 -- inv 0x08Addr 0x0228 -- value 0x7F -- inv 0x80Addr 0x02C0 -- value 0xEF -- inv 0x10Addr 0x0304 -- value 0x7F -- inv 0x80Addr 0x03D2 -- value 0x7F -- inv 0x80Addr 0x040A -- value 0xBF -- inv 0x40Addr 0x0478 -- value 0xFE -- inv 0x01Addr 0x04B0 -- value 0x7F -- inv 0x80Addr 0x04C2 -- value 0xFD -- inv 0x02Addr 0x055A -- value 0xEF -- inv 0x10Addr 0x058C -- value 0xEF -- inv 0x10Addr 0x06AE -- value 0xF7 -- inv 0x08Addr 0x06E2 -- value 0xF7 -- inv 0x08Addr 0x0734 -- value 0xF7 -- inv 0x08Addr 0x0776 -- value 0xF7 -- inv 0x08Addr 0x079E -- value 0xFB -- inv 0x04Addr 0x08E4 -- value 0xBF -- inv 0x40Addr 0x08FC -- value 0xFE -- inv 0x01Addr 0x0960 -- value 0xFD -- inv 0x02Addr 0x09C2 -- value 0xFB -- inv 0x04Addr 0x0A7C -- value 0xEF -- inv 0x10Addr 0x0ACA -- value 0xDF -- inv 0x20Addr 0x0B62 -- value 0xFD -- inv 0x02Addr 0x0B86 -- value 0xFE -- inv 0x01Addr 0x0C4A -- value 0xF5 -- inv 0x0AAddr 0x0C8E -- value 0xFB -- inv 0x04Addr 0x0D02 -- value 0xBF -- inv 0x40Addr 0x0D1E -- value 0xF7 -- inv 0x08Addr 0x0D78 -- value 0xFB -- inv 0x04Addr 0x0DEC -- value 0xBF -- inv 0x40Addr 0x0E60 -- value 0xFB -- inv 0x04Addr 0x0ECC -- value 0xDF -- inv 0x20Addr 0x0F5E -- value 0xEF -- inv 0x10Addr 0x103E -- value 0xEF -- inv 0x10Addr 0x10F8 -- value 0xDF -- inv 0x20Addr 0x1136 -- value 0xFD -- inv 0x02Addr 0x121E -- value 0xFD -- inv 0x02Addr 0x1232 -- value 0xFE -- inv 0x01Addr 0x12D2 -- value 0xBF -- inv 0x40Addr 0x1312 -- value 0xFE -- inv 0x01Addr 0x1326 -- value 0xFB -- inv 0x04Addr 0x1508 -- value 0xEF -- inv 0x10Addr 0x15CC -- value 0xDF -- inv 0x20Addr 0x1704 -- value 0xFD -- inv 0x02Addr 0x1714 -- value 0xBF -- inv 0x40Addr 0x17E6 -- value 0xFE -- inv 0x01Addr 0x1A98 -- value 0xDF -- inv 0x20Addr 0x1BE0 -- value 0xBF -- inv 0x40Addr 0x1CC6 -- value 0xFE -- inv 0x01Addr 0x1F76 -- value 0xDF -- inv 0x20Addr 0x2040 -- value 0xDF -- inv 0x20Number of addresses which returned non-FF bytes: 55The C program which generated it:Code:#include <stdio.h>#include <stdint.h>#include <stdbool.h>int main(void){bool A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13;bool nD0,nD1,nD2,nD3,nD4,nD5,nD6,nD7;FILE *fp;unsigned int nNonFFs = 0;fp = fopen("quansec.bin", "wb");for (uint32_t addr = 0; addr < 0x4000; addr+=2){uint8_t ch;A1 = (addr & 2);A2 = !(addr & 4);// Every single GAL we have samples of seems to have A2 set as inverted in hardwareA3 = (addr & 8);A4 = (addr & 16);A5 = (addr & 32);A6 = (addr & 64);A7 = (addr & 128);A8 = (addr & 256);A9 = (addr & 512);A10 = (addr & 1024);A11 = (addr & 2048);A12 = (addr & 4096);A13 = (addr & 8192);#include "12360.c"ch =(!nD7 ? 128 : 0) |(!nD6 ? 64 : 0) |(!nD5 ? 32 : 0) |(!nD4 ? 16 : 0) |(!nD3 ? 8 : 0) |(!nD2 ? 4 : 0) |(!nD1 ? 2 : 0) |(!nD0 ? 1 : 0);if (ch != 0xFF) {printf("Addr 0x%04X -- value 0x%02X -- inv 0x%02X\n", addr, ch, ch ^ 0xFF);nNonFFs++;}fwrite(&ch, 1, 1, fp);}fclose(fp);printf("\n\nNumber of addresses which returned non-FF bytes: %u\n", nNonFFs);}And my cleaned-up equations file:Code:/*; JED2EQN -- JEDEC file to Boolean Equations disassembler (Version V063); Copyright (c) National Semiconductor Corporation 1990-1993; Disassembled from 12360.JED. Date: 12-2-116;$GALMODE MEDIUMchip 12360 GAL20V8A13=1 A12=2 A11=3 A10=4 A9=5 A8=6 A7=7 A6=8 A5=9 A4=10 A3=11 GND=12!A2=13 A1=14 D7=15 D6=16 D5=17 D4=18 D3=19 D2=20 D1=21D0=22 ALEC=23 VCC=24@ues 0000000000000000equations*/bool nD0 = (!A12 && !A13 && !A11 && A10 && !A9 && !A8 && !A7 && A6 && A5 && A4 && !A1 && A3 && A2)|| (!A12 && !A13 && A11 && !A10 && !A9 && !A8 && A7 && A6 && A5 && A4 && !A1 && A3 && !A2)|| (!A12 && !A13 && A11 && !A10 && A9 && A8 && A7 && !A6 && !A5 && !A4 && A1 && !A3 && !A2)|| (A12 && !A13 && !A11 && !A10 && A9 && !A8 && !A7 && !A6 && A5 && A4 && A1 && !A3 && A2)|| (A12 && !A13 && !A11 && !A10 && A9 && A8 && !A7 && !A6 && !A5 && A4 && A1 && !A3 && A2)|| (A12 && !A13 && !A11 && A10 && A9 && A8 && A7 && A6 && A5 && !A4 && A1 && !A3 && !A2)|| (A12 && !A13 && A11 && A10 && !A9 && !A8 && A7 && A6 && !A5 && !A4 && A1 && !A3 && !A2);//D0.oe = !ALECbool nD1 = (!A12 && !A13 && !A11 && A10 && !A9 && !A8 && A7 && A6 && !A5 && !A4 && A1 && !A3 && A2)|| (!A12 && !A13 && A11 && !A10 && !A9 && A8 && !A7 && A6 && A5 && !A4 && !A1 && !A3 && A2)|| (!A12 && !A13 && A11 && !A10 && A9 && A8 && !A7 && A6 && A5 && !A4 && A1 && !A3 && A2)|| (!A12 && !A13 && A11 && A10 && !A9 && !A8 && !A7 && A6 && !A5 && !A4 && A1 && A3 && A2)|| (A12 && !A13 && !A11 && !A10 && !A9 && A8 && !A7 && !A6 && A5 && A4 && A1 && !A3 && !A2)|| (A12 && !A13 && !A11 && !A10 && A9 && !A8 && !A7 && !A6 && !A5 && A4 && A1 && A3 && !A2)|| (A12 && !A13 && !A11 && A10 && A9 && A8 && !A7 && !A6 && !A5 && !A4 && !A1 && !A3 && !A2);//D1.oe = !ALECbool nD2 = (!A12 && !A13 && !A11 && !A10 && !A9 && !A8 && A7 && A6 && A5 && A4 && !A1 && !A3 && !A2)|| (!A12 && !A13 && !A11 && A10 && A9 && A8 && A7 && !A6 && !A5 && A4 && A1 && A3 && !A2)|| (!A12 && !A13 && A11 && !A10 && !A9 && A8 && A7 && A6 && !A5 && !A4 && A1 && !A3 && A2)|| (!A12 && !A13 && A11 && A10 && !A9 && !A8 && A7 && !A6 && !A5 && !A4 && A1 && A3 && !A2)|| (!A12 && !A13 && A11 && A10 && !A9 && A8 && !A7 && A6 && A5 && A4 && !A1 && A3 && A2)|| (!A12 && !A13 && A11 && A10 && A9 && !A8 && !A7 && A6 && A5 && !A4 && !A1 && !A3 && A2)|| (A12 && !A13 && !A11 && !A10 && A9 && A8 && !A7 && !A6 && A5 && !A4 && A1 && !A3 && !A2);//D2.oe = !ALECbool nD3 = (!A12 && !A13 && !A11 && !A10 && A9 && !A8 && !A7 && !A6 && A5 && !A4 && A1 && !A3 && A2)|| (!A12 && !A13 && !A11 && A10 && A9 && !A8 && A7 && !A6 && A5 && !A4 && A1 && A3 && !A2)|| (!A12 && !A13 && !A11 && A10 && A9 && !A8 && A7 && A6 && A5 && !A4 && A1 && !A3 && A2)|| (!A12 && !A13 && !A11 && A10 && A9 && A8 && !A7 && !A6 && A5 && A4 && !A1 && !A3 && !A2)|| (!A12 && !A13 && !A11 && A10 && A9 && A8 && !A7 && A6 && A5 && A4 && A1 && !A3 && !A2)|| (!A12 && !A13 && A11 && A10 && !A9 && !A8 && !A7 && A6 && !A5 && !A4 && A1 && A3 && A2)|| (!A12 && !A13 && A11 && A10 && !A9 && A8 && !A7 && !A6 && !A5 && A4 && A1 && A3 && !A2);//D3.oe = !ALECbool nD4 = (!A12 && !A13 && !A11 && !A10 && A9 && !A8 && A7 && A6 && !A5 && !A4 && !A1 && !A3 && A2)|| (!A12 && !A13 && !A11 && A10 && !A9 && A8 && !A7 && A6 && !A5 && A4 && A1 && A3 && A2)|| (!A12 && !A13 && !A11 && A10 && !A9 && A8 && A7 && !A6 && !A5 && !A4 && !A1 && A3 && !A2)|| (!A12 && !A13 && A11 && !A10 && A9 && !A8 && !A7 && A6 && A5 && A4 && !A1 && A3 && !A2)|| (!A12 && !A13 && A11 && A10 && A9 && A8 && !A7 && A6 && !A5 && A4 && A1 && A3 && !A2)|| (A12 && !A13 && !A11 && !A10 && !A9 && !A8 && !A7 && !A6 && A5 && A4 && A1 && A3 && !A2)|| (A12 && !A13 && !A11 && A10 && !A9 && A8 && !A7 && !A6 && !A5 && !A4 && !A1 && A3 && A2);//D4.oe = !ALEC;bool nD5 = (!A12 && !A13 && A11 && !A10 && A9 && !A8 && A7 && A6 && !A5 && !A4 && A1 && A3 && A2)|| (!A12 && !A13 && A11 && A10 && A9 && !A8 && A7 && A6 && !A5 && !A4 && !A1 && A3 && !A2)|| (A12 && !A13 && !A11 && !A10 && !A9 && !A8 && A7 && A6 && A5 && A4 && !A1 && A3 && A2)|| (A12 && !A13 && !A11 && A10 && !A9 && A8 && A7 && A6 && !A5 && !A4 && !A1 && A3 && !A2)|| (A12 && !A13 && A11 && !A10 && A9 && !A8 && A7 && !A6 && !A5 && A4 && !A1 && A3 && A2)|| (A12 && !A13 && A11 && A10 && A9 && A8 && !A7 && A6 && A5 && A4 && A1 && !A3 && !A2)|| (!A12 && A13 && !A11 && !A10 && !A9 && !A8 && !A7 && A6 && !A5 && !A4 && !A1 && !A3 && A2);//D5.oe = !ALECbool nD6 = (!A12 && !A13 && !A11 && A10 && !A9 && !A8 && !A7 && !A6 && !A5 && !A4 && A1 && A3 && A2)|| (!A12 && !A13 && A11 && !A10 && !A9 && !A8 && A7 && A6 && A5 && !A4 && !A1 && !A3 && !A2)|| (!A12 && !A13 && A11 && A10 && !A9 && A8 && !A7 && !A6 && !A5 && !A4 && A1 && !A3 && A2)|| (!A12 && !A13 && A11 && A10 && !A9 && A8 && A7 && A6 && A5 && !A4 && !A1 && A3 && !A2)|| (A12 && !A13 && !A11 && !A10 && A9 && !A8 && A7 && A6 && !A5 && A4 && A1 && !A3 && A2)|| (A12 && !A13 && !A11 && A10 && A9 && A8 && !A7 && !A6 && !A5 && A4 && !A1 && !A3 && !A2)|| (A12 && !A13 && A11 && !A10 && A9 && A8 && A7 && A6 && A5 && !A4 && !A1 && !A3 && A2);//D6.oe = !ALECbool nD7 = (!A12 && !A13 && !A11 && !A10 && !A9 && !A8 && A7 && !A6 && A5 && !A4 && A1 && A3 && A2)|| (!A12 && !A13 && !A11 && !A10 && !A9 && A8 && !A7 && A6 && !A5 && A4 && !A1 && !A3 && !A2)|| (!A12 && !A13 && !A11 && !A10 && !A9 && A8 && !A7 && A6 && !A5 && A4 && A1 && !A3 && !A2)|| (!A12 && !A13 && !A11 && !A10 && A9 && !A8 && !A7 && !A6 && A5 && !A4 && !A1 && A3 && A2)|| (!A12 && !A13 && !A11 && !A10 && A9 && A8 && !A7 && !A6 && !A5 && !A4 && !A1 && !A3 && !A2)|| (!A12 && !A13 && !A11 && !A10 && A9 && A8 && A7 && A6 && !A5 && A4 && A1 && !A3 && A2)|| (!A12 && !A13 && !A11 && A10 && !A9 && !A8 && A7 && !A6 && A5 && A4 && !A1 && !A3 && A2);//D7.oe = !ALECThis code doesn't bother with the least significant bit because... well... the "Read Security PAL" code accesses the PAL with a MOVE.W instruction and an autoincrement.That autoincrement adds two to the address.Also, as the PAL doesn't have UDS and LDS wired up, it can't tell what the least significant bit of the address bus is.I've a sneaking suspicion that a MOVE.B of (PAL_ADDR) and one of (PAL_ADDR+1) would result in the same value, but it would have complicated the original 68k code (would have required an ADD). Someone at Quantel knew their hardware and the 68k and decided to be a bit clever.In any case... The 68K only presents bits A1 through A13 to the PAL. There are definitely 13 address bits (8K address space), so that bounds the loop.(EDIT 0218: Modified the code; the PAL output makes a little more sense if you invert it like the Quantel code does before looking at it)

author: philpem
author_rank: Frequent Contributor
timestamp: December 03, 2016, 03:15:29 am
content: I've had a crack at transliterating the code into C, but I must have something massively wrong, because it doesn't work...Code:#include <stdio.h>#include <stdint.h>#include <stdbool.h>int main(void){bool A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13;bool nD0,nD1,nD2,nD3,nD4,nD5,nD6,nD7;uint16_t Addr0;uint8_t Addr1 = {7,7,7,7,7,7,7,0};uint8_t InputCryptoString;// LOC_52EE loop// Start by clearing Addr0 to 0xFFFFfor (size_t n=0; n<8; n++) {Addr0 = 0xFFFF;}// 52FC:InputCryptoString = 0;// some form of status response byte I guess?uint16_t m68k_d1 = 0;// some kind of loop counter?uint32_t m68k_d7 = 0;// check sum?for (uint32_t addr = 0; addr < 0x4000; addr+=2)// This is "LoopD0"{A1 = (addr & 2);A2 = !(addr & 4);// Every single GAL we have samples of seems to have A2 set as inverted in hardwareA3 = (addr & 8);A4 = (addr & 16);A5 = (addr & 32);A6 = (addr & 64);A7 = (addr & 128);A8 = (addr & 256);A9 = (addr & 512);A10 = (addr & 1024);A11 = (addr & 2048);A12 = (addr & 4096);A13 = (addr & 8192);#include "12360.c"// Read from PAL into D2uint8_t m68k_d2 =(!nD7 ? 128 : 0) |(!nD6 ? 64 : 0) |(!nD5 ? 32 : 0) |(!nD4 ? 16 : 0) |(!nD3 ? 8 : 0) |(!nD2 ? 4 : 0) |(!nD1 ? 2 : 0) |(!nD0 ? 1 : 0);// Invert the valuem68k_d2 ^= 0xFF;if (m68k_d2 == 0) {goto nextd0_d1plusplus;// TODO: Just put "d1++; continue;" here and leave that d1++ down below}for (uint8_t m68k_d3 = 7; m68k_d3 != 0xFF; m68k_d3--) {if (!(m68k_d2 & (1<<m68k_d3))) {continue;}//uint16_t m68k_d4 = m68k_d3 << 1;uint16_t m68k_d5 = Addr0;Addr0 = m68k_d1;// 005328 NEG.W D5m68k_d5 = -m68k_d5;// ADD.W D1, D5m68k_d5 += m68k_d1;// SUBQ #1, D5m68k_d5--;// CMPI.W #$800, D5if (m68k_d5 >= 0x800) {printf("CleanVarsAndReturn :(\n");return -1;}// BTST #$A, D5 --> and by 1024if (m68k_d5 & 0x400) {// >= 2KBInputCryptoString ^= m68k_d3;printf("More than 2KB; CleanVarsAndReturn :(\n");return -1;}// lessThan2KB:// 005344:uint16_t m68k_d6 = Addr1;if (m68k_d6 >= 7) {printf("Addr1 >= 7, CleanVarsAndReturn :(\n");return -1;}// 005350:if (m68k_d5 & 0x200) {// 005356: bset d3, (a0,d6.w)InputCryptoString |= (1<<m68k_d3);} else {// 00535C: bclr d3, (a0,d6.w)InputCryptoString &= ~(1<<m68k_d3);}// 005350:m68k_d6 <<= 3;m68k_d6 += m68k_d3;if (m68k_d5 & 0x100) {// 00536A:m68k_d7 |= 1<<m68k_d6;}// 00536C:InputCryptoString[m68k_d6 + 8] = m68k_d5;Addr1++;}nextd0_d1plusplus:m68k_d1++;}printf("DONE -->\n");printf("Addr0: ");for (size_t i=0; i<8; i++) {printf("%u ", Addr0);}printf("\n");printf("Addr1: ");for (size_t i=0; i<8; i++) {printf("%u ", Addr1);}printf("\n");}It looks like the code (ab)uses parts of the Crypto String for other things. The 8th character (which gets cleared at 0052FC) is some form of status code; 00533C flips a bit in that if something is wrong.First seven bytes of the Crypto String could well be the serial number.More when I've had some sleep.

author: dexters_lab
author_rank: Unknown
timestamp: December 03, 2016, 08:31:18 am
content: wow, thanks for all the help everyone.to answer some of your earlier questions, the system is a 68010The end result hopefully is to reprogram serial number 10352, because it's for this that i have a full set of license keys for a 'Harriet' system.i have placed a copy of all the files in question on my google drive as public:https://drive.google.com/drive/folders/0B24DgvumEJXibEgzRElOVjhCT1U?usp=sharingthe .JED files are the securityPALs that i managed to read. In the box of ICs i found there where a couple of duplicates these were 12360_A & B & 15462_A & B. I only included the copy to be complete. The JED files marked 17624_1, 17624_2 & 17624_N seem to be slightly different versions of 17624, they are marked like that on the IC label.I also included the i64 & asm files that Nicolas did of the EPROM disassembly, there are copies of the actual EPROMs there too.

author: philpem
author_rank: Frequent Contributor
timestamp: December 03, 2016, 11:45:35 am
content: After a little more playing... I've fixed my C version of the function:All those PALs seem to fail the "Read Security PAL" routine, or at least my C translation of it.I've attached the C versions of the PAL equations.I'm starting to suspect JED2EQN might have screwed up. To rule that out, I think my next step would be to make up an adapter and read one out as an EPROM -- that'd give a... what, 8K binary file?Have you got an EPROM programmer, Dexter? (I do, but I suspect you might not want to part with one of your security PALs!)The adapter you want to make would wire /OE to /ALEC, the address lines straight through (EPROM A0 to PAL A1, A1 to A2 and so on), the data lines 1:1, and VCC and ground straight through. That should allow an EPROM programmer to read the PAL as if it were a ROM.In the meantime -- I'll see if I can get the "checking routine" going in EASy68k.Cheers,Phil.

author: dexters_lab
author_rank: Unknown
timestamp: December 03, 2016, 12:34:02 pm
content: Yes i have a TL866, thats what i used to read the GAL/PALs.I can try wiring it up as a rom, a couple of people mentioned doing that beforeI can send you one of the ones i can read if you want, they are only useful to this exercise as i dont have the software keys for these serials anyway

author: philpem
author_rank: Frequent Contributor
timestamp: December 03, 2016, 02:14:49 pm
content: Quote from: dexters_lab on December 03, 2016, 12:34:02 pmHold off on that for the minute, I think. I've got Quantel's function running in EASy68k. There's definitely something up with my C code.For the 12360 PAL, whatever intermediate data you get out of said PAL, decrypted with the "Copyright Quantel" string, nets you the null-terminated string "HARRIET". Very interesting!It looks like the addresses of the bytes in the address map encode a text string (possibly encoded further by the serial number - I haven't got to the encryption yet), and the specific values (somehow) encode the serial number.It's sneaky, I'll give them that!

author: philpem
author_rank: Frequent Contributor
timestamp: December 03, 2016, 03:34:23 pm
content: Fixed it!After a couple of hours sat with EASy68k, I figured out what I was doing wrong. This little gem emulates the Quantel "Read and verify Security PAL" function.You get two things out of that function, by the way:* The "Crypted String" is a decrypted version of what's stored in the the PAL. The format of that is -- serial number twice, then a text string.* A return code, either "success" or "failure".Addr0 and Addr1 are just internal state, kept on the stack.There are two checksums: one on the encrypted string, one on the decrypted string. They're just additive, so nice and easy to recalculate.Reversing the encryption to get from a "decrypted string" to an "encrypted string" (or vice versa) is easy too: XOR is commutative.The only problem left to solve is figure out how the data in the PAL is encoded, then we can -- in theory -- make new PALs.But with what we have now, given a chunk of arbitrary PAL data (as if we read the PAL out in an EPROM programmer) or a set of PAL equations reformatted into C, we can answer the question "would a Paintbox accept this as a valid PAL?".EDIT: Now I've done some more mods to my tool... I can tell you what the PALs are for!12360: Harriet15462-E: PFrame Paintbox17624-1: Editbox17624-2: Editbox17624-N: Network

author: dexters_lab
author_rank: Unknown
timestamp: December 03, 2016, 03:51:22 pm
content: awesome work philpem!your results tie in to a couple of other small points i was about to make...firstly the two serial numbers. On these machines they have a machine serial number and a group serial number. I think so a group of machines can share a license key. But if there is no group then these two numbers are the same.secondly, during boot of the main OS just after it reports the serial numbers there is a description in caps, on machine 10352 it's 'PAINTBOX', it's quite possible this is the same text you found that said 'HARRIET'you can see a short excerpt from the console output here:Code:AFS V-series Diagnostics and Painting, version "V8-18-001 Paintbox"Built on 3-MAY-1994 at 11:21:28.09, file version V7.01Software generated for Paintbox 1-00NTSC standard 2133, 1940Serial number: 10352, 12742Description : PAINTBOXi am going to have a play wiring the PAL up as a PROM and see if i can get my TL866 to read the PAL that is coded with 12360

author: dexters_lab
author_rank: Unknown
timestamp: December 03, 2016, 04:00:09 pm
content: Quote from: philpem on December 03, 2016, 03:34:23 pmHarriet and Paintbox are essentially the same thing, a Harriet is a Paintbox with all the extras. Editbox is their non-linear digital editing machinemany paintboxes, editboxes etc had a network or other interface board fitted inside the machine, these have their own SecurityPAL on which is why there is a separate PAL for that. I am not sure why there are two PALs for the editbox though but i don't know too much about these systems so...

author: philpem
author_rank: Frequent Contributor
timestamp: December 03, 2016, 04:20:59 pm
content: Quote from: dexters_lab on December 03, 2016, 03:51:22 pmAhh - that makes sense. That sounds like what's known as a "floating licence" these days. You network a bunch of machines and buy, say, one licence for "advanced retouching" tied to the group. If someone's using it -- well, the other person who wants to use it has to wait until the other person finishes.It works fairly well, as long as the "pool" is reasonably sized.Quote from: dexters_lab on December 03, 2016, 03:51:22 pmWell, that looks like a smoking gun if I ever saw one.At a guess, the second instance of the serial number is probably the "group" serial number then, but without seeing an image of a PROM with a group serial number, I couldn't say for certain.Quote from: dexters_lab on December 03, 2016, 03:51:22 pmDefinitely do. I've attached a copy of the 12360 binary I generated from the equations.If you can get a good read from this one, it's probably worth trying to read out the other PALs you have -- even the ones with the security bit set should read out OK as PROMs. With that information, it should be simple enough to bash together a tool to create PAL equations for them.Or, indeed, feed them into QUAN_ALG and see what the contents are.Quote from: dexters_lab on December 03, 2016, 04:00:09 pmAt a guess - maybe Editbox needs two machines linked, and you have one PAL in each machine?Who knows.Cheers.

author: rstofer
author_rank: Super Contributor
timestamp: December 03, 2016, 04:51:20 pm
content: I don't see why the SecurityPAL couldn't implement some kind of FSM since there is a CPU involved. It could certainly be coded as an 8 bit wide LFSR with the CPU mangling the address lines based on previous output from the PAL.If I had a working system, I would be connecting a logic analyzer to the PAL. I would think that, given the possibility of a LFSR in uC code, trying to simply decode the PROM would be an exercise in futility.

author: philpem
author_rank: Frequent Contributor
timestamp: December 03, 2016, 05:03:41 pm
content: Quote from: rstofer on December 03, 2016, 04:51:20 pmYou're a touch late to the partyWe've got the PAL equations from a couple of unlocked chips and we've got a schematic -- those ruled out any register-related FSM shenanigans. The disassembly ruled out any similar foul play in the software.It's just a crazily-encoded ROM.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 03, 2016, 05:09:11 pm
content: Quote from: rstofer on December 03, 2016, 04:51:20 pmExcept that the limited number of product-terms available would limit functionality substantially, and it would be hard to generate a decent number space that was guaranteed to be fittable in the device.Later PLD devices, in particular the PEEL series would be a lot better as they can have buried internal registers to substantially obfuscate operation. Even the 22V10 can't hide the contents of its internal registers as far as I can recall, as feedback comes after the output-enable'd buffers, though there would be some scope to make it harder to figure out by making functions dependent on (visible) output states.With a 20L8 , you can't do anything more than make it act like a PROM with a finite number of either '1' or '0' outputs. The encoding of the address is at least as likely to be to make better use of the available capacity as for any kind of security.

author: dexters_lab
author_rank: Unknown
timestamp: December 03, 2016, 05:41:41 pm
content: philpem,attached is a .bin of the 12360 PAL as read as a TMS2764 EPROM, it does appear to be a match for your file but if you could double check?i am quite shocked my wiring worked TBH!

author: stfsux
author_rank: Contributor
timestamp: December 03, 2016, 06:20:01 pm
content: I've just quick questions about EQN.D0 to D7 are High-Z as long as ALEC is high, right?Code:/d0 = /a12 ...This means, d0 is low if the logic equation is true? But if it's not the case, there are High-Z?Or they have a default state when you declare them?

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 03, 2016, 06:26:03 pm
content: All output enables are controlled by pin 23 ( the .oe term)The equations are booleans - AND all terms on each line then OR the result. there may be an inversion on the output.

author: philpem
author_rank: Frequent Contributor
timestamp: December 03, 2016, 06:30:32 pm
content: Quote from: dexters_lab on December 03, 2016, 05:41:41 pmHarriet says hello!Looks good to me!Code:Loaded 12360_Read_As-ROM.binDONE -->Crypted string: --0H--0HHARRIET --------------------------------Hex crypted string:00 00 30 48 00 00 30 48 48 41 52 52 49 45 54 2020 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2000 00 00 08 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00Crypted string checksum (D7 loword): 5176Clear string checksum (D7 hiword): 1319AddrBitLastSeen aka Addr0 (internal): 3683 2946 2451 1679 2692 4128 3568 600BitActiveCounter aka Addr1 - should all be 7 (internal): 7 7 7 7 7 7 7 7I dare say you could swap in a couple of other PALs if you wanted to.I've been working on cleaning up and figuring out the PAL readback code too...* The decoder counts how many Pterms are associated with each bit -- that is, how many addresses it sees a bit respond to. The answer must be seven (not six, unless thou then proceedeth to seven, and eight is right out).* Overflowing this will cause the check to fail without any checksumming or decryption being performed.* In short: You have seven Pterms and eight bits, or 56 Pterms. Use them wisely.* "Commands" are encoded as the deltas between the bit addresses.* That is, every time an 'active' Pterm is seen, the decoder calculates the distance between this address and the last time it saw this bit respond.* The "last time" array is set to -1 (well, 0xFFFF but who's counting?) at the start.* A command (delta) of 0x800 or greater will cause an error.* Command AND 0x400? Inverts the current bit of Crypto String character 7.* Character 7 is zeroed at the start of the loop.* If this happens more than once, it's an error. TL/DR: you can set bits in character 7, but not clear them.* Char 7 is the last byte of the serial number...* Command AND 0x200? Sets the current serial number bit.* Command AND 0x100? Sets a bit in the checksum word.* This is done in a slightly peculiar way. Take the index of the Pterm bit in the PAL which triggered,* Oh, and for good measure, store the least significant 8 bits of the command in CryptoString[8+ ((NumberOfTimesIveSeenThisBit *+ BitNumber)]* BitNumber = 7..0 for bit mask 128..1In summary... it stores a bunch of data as delta-encoded commands, whose meaning changes depending on which bit they happened to be seen on.I've done a hell of a lot of commenting on this thing, results are attached. Phew.Next up is "How the bleeding hell do I make a PROM to satisfy this thing?!"

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 03, 2016, 06:43:25 pm
content: Quote from: philpem on December 03, 2016, 06:30:32 pmBrute force ?There are a lot of permutations but a lot of them can be eliminated.Looks like the scheme was designed to make it hard, but computing power has come rather a long way since it was designed.Obvious constraints :One bit at a time, obviouslyOnly 7 of 8192 possible addresses can be active.That's rather a big space, but I'm sure there must be ways to eliminate some based on other constraints.

author: philpem
author_rank: Frequent Contributor
timestamp: December 03, 2016, 07:27:43 pm
content: Quote from: mikeselectricstuff on December 03, 2016, 06:43:25 pmI think there are defined places where things need to go. In other words, if you want a certain block of PROM data, there are only a few ways to encode it.Ultimately what you're encoding in the address deltas are three command bits, plus the description. The command bits are effectively "subchannel" or "subcarrier" data: they're there so that in addition to those 56 bits which are used to say "This delta is the one which encodes the character code for this byte in the Description field", you can encode the serial number and checksum fields into the data too -- by increasing the space between some of the bits.56 characters to encode, 8 bits to stuff them in... 7 product terms... Lucky seven, again.I've got some ideas, mostly centred around a version of QUAN_ALG with the checksum tests disabled. Get the description encoding working, then start encoding other things.

author: OzOnE
author_rank: Regular Contributor
timestamp: December 03, 2016, 08:55:04 pm
content: Awesome work, Phil.I had Easy68K in my "Quantel Harriet" folder as well, but I've been stepping through the code in the MAME debugging instead.(I added a basic skeleton driver for the Harriet, but I'm not handling the serial stuff yet.)Due to my lack of 68K experience, I was finding it tough to work out which arguments were actually put on the stack for that SecurityPAL routine, so I didn't have an example string to go on.I also couldn't find a place in the code where it actually checks the serial number of the PAL?I need to get my head around the code you've produced. lolThe comments about the 777777 thing were added by another guy in Oz btw (no, not that one. :p )I was still working through that routine last night, but didn't make a huge amount of progress once I realised it was a fair bit more complex than I first thought.I did find the identical security routine in the main OS file btw (from the previous working Harriet that I had, which was sent to a friend some time ago).I'll send you the files from that, so you can have a look with IDA Pro etc.I'm still a tad baffled that the binary you posted doesn't match the one I generated from the EQN though?However, you file does indeed match 100% to the one that Mr Dexter read using the programmer, so that confirms that.Did you also spot that the /A2 input in the EQN was inverted? I guess you must have? :pHave you tried randomly changing a few bits in the binary / equations, to see how the output changes, or would that just completely scramble everything, or cause the routine to return with an error?I did a search through the main OS file for any addresses starting with 0xFD0xxx btw, and 0xFD0000 only appears in that same routine as in the ROM monitor.There are four or five other places in the raw hex that starts with 0xFD0xxx, but that's probably just random data.So, I think we can be fairly confident that all their crypto works through that same routine.Once we work out how to produce the correct response for the different serials, we should just be able to patch the code instead of generating a PAL each time (and therefore essentially "cracking" the Quantel OS).Now, I'll have to try to understand Phil's code now. lolOzOnE.

author: philpem
author_rank: Frequent Contributor
timestamp: December 03, 2016, 09:42:18 pm
content: Latest update: I now have a tool which can create PAL images, in "PROM-like image" form. I've just created a completely fake PAL with a description of "Hummingbird", which I'm quite sure never existed:Code:$ make && ./quan_enccc -g -ggdb -c -o quan_enc.o quan_enc.ccc -g -ggdb -o quan_enc quan_enc.oQuantel Paintbox Protection PAL builder.Serial numbers: 12345, 76543Description: HUMMINGBIRDRaw buffer:00 00 30 39 00 01 2A FF 48 55 4D 4D 49 4E 47 4249 52 44 20 20 20 20 20 20 20 20 20 20 20 20 2000 00 00 08 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00Raw checksum: 1649Enc checksum: 5212Encrypted buffer:43 6F 40 40 72 68 4D 97 3C 75 65 0E 60 6E 16 3728 3C 30 45 4C 00 6C 54 44 00 11 19 18 15 0E 0055 73 65 28 77 69 74 68 6F 75 74 20 70 65 72 6D69 73 73 69 6F 6E 20 66 6F 72 62 69 64 64 65 6E$ make && ./quan_alg ../quan_enc/enc.binmake: 'quan_alg' is up to date.Processing PAL image file ../quan_enc/enc.binaddr=0CEA, d2=0x02, testing bit d3=1, mask=0x02 SETaddr=1164, d2=0x02, testing bit d3=1, mask=0x02 SETaddr=1166, d2=0x02, testing bit d3=1, mask=0x02 SETaddr=144E, d2=0x02, testing bit d3=1, mask=0x02 SETaddr=193A, d2=0x02, testing bit d3=1, mask=0x02 SETaddr=1A22, d2=0x02, testing bit d3=1, mask=0x02 SETaddr=1B08, d2=0x02, testing bit d3=1, mask=0x02 SETCrypted string: Co@@rhM-<ue-`n-7(<0EL-lTD-------Use(without permission forbiddenHex crypted string:43 6F 40 40 72 68 4D 97 3C 75 65 0E 60 6E 16 3728 3C 30 45 4C 00 6C 54 44 00 11 19 18 15 0E 0055 73 65 28 77 69 74 68 6F 75 74 20 70 65 72 6D69 73 73 69 6F 6E 20 66 6F 72 62 69 64 64 65 6EDONE -->DeCrypted string: --09--*-HUMMINGBIRD --------------------------------Hex decrypted string:00 00 30 39 00 01 2A FF 48 55 4D 4D 49 4E 47 4249 52 44 20 20 20 20 20 20 20 20 20 20 20 20 2000 00 00 08 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00Crypted string checksum (D7 loword): 5212Clear string checksum (D7 hiword): 1649AddrBitLastSeen aka Addr0 (internal): 3402 3460 3418 2188 2948 2345 4609 1594BitActiveCounter aka Addr1 - should all be 7 (internal): 7 7 7 7 7 7 7 7There's only one thing that concerns me -- the eight bytes after the Description string seem to be used for "something":Code:Harriet #12360: 00 00 00 08 00 00 00 00PFrame Paintbox #15462-E: 00 00 10 00 04 00 00 00Editbox #17624-1: 10 00 01 00 00 00 00 00Editbox #17624-2: 00 42 01 00 00 00 00 00Network #17642-N: 00 60 00 00 00 00 00 00If the description string is meaningless to the machine (it could well be), this may well be a bitmask which says "unlock these features by default"... in which case, you'd need to know what the bits mean.I wonder how complex the "licence string" scheme is. Whether it just locks to serial number (in which case that's all you need to get right) or whether these bits matter too...Quote from: OzOnE on December 03, 2016, 08:55:04 pmThanksQuote from: OzOnE on December 03, 2016, 08:55:04 pmI'm not sure the monitor ROM would - at least I wouldn't expect it to. All I'd expect it to do is see if the PAL is there and maybe print the serial number. The main software would be what checked the serial number, read license strings, decrypted those, and decided whether you were worthy of advanced features and such.I'm guessing the thing boots from disk, and that there's more advanced licence checking in there.As regards the stack -- what it's putting on the stack are two pointers. "retcode_success_1" is a pointer to a variable which receives a return code from the function (ehh, the usual 68k calling convention is to use D0, but whatever). "inputCryptoString" isn't actually an input -- it's an output. It's a 64-byte buffer (not 0x3F -- the guy in Oz missed that a DBF loop loops n+1 times) which receives the decrypted version of the "cryptstring", which is actually the contents of the security PAL.That string encodes the serial number, description string (up to 24 characters, space padded) and 32 bytes of additional data which is usually 0x00 but some bits can be set to '1'.Quote from: OzOnE on December 03, 2016, 08:55:04 pmIt is... a bit heavy going. Or at least the decoder is. When you see the encoder it might click.Quote from: OzOnE on December 03, 2016, 08:55:04 pmExcellent! Thank youI did suspect the OS would be poking and prodding the security PAL. The question is, what does it do with the data from the PAL -- especially the data after the description?Quote from: OzOnE on December 03, 2016, 08:55:04 pmCould just be a typo maybe?I used a Python script to undo JED2EQN's word wrapping, then fed the output of that into a Sed script to rename the pins and convert the EQN code into C.Quote from: OzOnE on December 03, 2016, 08:55:04 pmYep! I read through the thread before I started hacking on this. Standing on the shoulders of giants, as it were!Quote from: OzOnE on December 03, 2016, 08:55:04 pmThat'd break the checksums on the PAL data (it checksums the encrypted and decrypted data).Quote from: OzOnE on December 03, 2016, 08:55:04 pmEhh. I prefer "no patches" fixes, myself.It's always nicer if you can run the original hardware and ROMs without having to patch the software

author: philpem
author_rank: Frequent Contributor
timestamp: December 03, 2016, 10:41:37 pm
content: And here's the PAL generator.Modify the constants at the top (serial numbers and product description string), compile it, run it, and it'll spit out two files.ENC.BIN is a "PROM-like" binary you can load into Quan_Alg to check the PAL.ENC.PLD is an Atmel-WinCUPL equation file which can be used to produce a GAL20V8.If you want to compile the PLD file, go into the WinCUPL options and set Logic Minimisation to "None" or "Quick". I found that at least with this file, Quine-McCluskey minimisation caused WinCUPL to crash during the CUPLM phase.There's also an example showing how to "fudge" the data bits which are nonzero in the Harriet PLD, so you can generate a functional duplicate of that.Enjoy!

author: dexters_lab
author_rank: Unknown
timestamp: December 03, 2016, 11:09:40 pm
content: O M Git's too late to play tonight, i'll have a proper look tomorrow

author: dexters_lab
author_rank: Unknown
timestamp: December 04, 2016, 09:06:29 am
content: thanks Philpem for all your worki nice little exercise for me would be to learn how to make a basic windows GUI or command line util to make it a bit more user friendlycan anyone recommend any tools to help?

author: OzOnE
author_rank: Regular Contributor
timestamp: December 04, 2016, 12:18:44 pm
content: @phil - I just sent you a big message via PM, but it didn't seem to appear in the Sent Items, so let me know if you received it OK.Luckily, I remembered to do a Ctrl-A, Ctrl-C, then paste the message into a text file.(The way this forum shows the previously sent replies on the Messages screen is a bit strange too.)Here's my Verilog of the 12360 PAL, but with the "binary" terms converted to Hex...http://pastebin.com/wx5nUghaIt's very possible I made a few typos in that one, but originally I was using the file I'd converted from the EQN.That was using NotePad++ to change the OR / AND / NOT operators though, and change the pin numbers to proper names etc.I got the same exact result when running the binary or hex term version on the dev board, but it still didn't match what you produced, or what Mr Dexter got from reading on the TL866, so I've obviously screwed something else up. lolI did invert the A2 bit input in the code, and also realise that the 68K doesn't hook up /LDS or /UDS, nor has A0 etc., but it should have produced the same result as reading the PAL as a "ROM". Oh well. It's not important now, just one of those things that's bugging me. heheI'll have a look now to see how to disassemble the whole OS file with IDA Pro. Unless anyone else knows?I managed it some time ago, but now can't recall how to just blindly dump the whole 68K binary back to an ASM file?Once we have enough of it disassembled, we should see exactly which routines are accessing that same PAL Security routine, and hopefully how it processes the passwords too.The passwords themselves seem to simply be written in cleartext at the start of the main OS file.The OS itself looks to be only 2 or 3 MBytes. The whole rest of the HDD image is just for storing the uncompressed video frames.(4:2:2 component, which the guy in Oz kindly converted back to RGB for us.)Here are a few example images from the Harriet unit I sent to Mr Dexter.http://imgur.com/a/uguw6Clearly, some of those images were from the BBC's "Airport" program. I remember it well. heheThat Harriet unit, and the previous one seemed to have been used right up until about 2002-2004. Amazing really.You can see how it stores the fonts and brushes as uncompressed, and even captures the palette box if it was enabled at the time.Kind of unsurprising, as the whole thing operates directly on the framebuffer(s), with only a certain amount of "hardware acceleration" for things like 3D rotations and scaling.The Harriet system uses the 68010, but also has the MC68450 DMA Controller.The classic Paintbox DPB-7001 used only the 68000, and virtually all of it's drawing functions were done using jellybean TTL logic, and some multipler chips etc. It stored the chosen brush shape on a separate RAM board, and would then do a Read-Modify-Write on the framebuffer contents, depending on the pressure of the stylus on the tablet / selected colour etc.It could also do "Copy 'n' paste" and masking effects between the two separate frame stores.Extremely impressive for 1981, especially since the 68000 CPU only got released in 1979 (IIRC).For anyone not familiar with the PB, here's the unit I'd been helping to get running for about three years (but sadly failed, as I'm 200 miles away from it. lol) This is the PB which is now in Mr Dexter's possession...And here's a demo of it's painting functions.Again, crude by today's standards of course, but absolutely groundbreaking for it's time...There were a number of copyright challenges by Quantel against Adobe over the years.It's clear that many of the techniques used in programs like Photoshop share a lot of similarities, but I guess we'll never know quite how much of it was "inspired" by the Quantel units.Right - back to trying to figure out Phil's (and amyk's) code. lolOzOnE.

author: OzOnE
author_rank: Regular Contributor
timestamp: December 04, 2016, 01:31:03 pm
content: I've started to find more routines in the main OS file now...It's interesting that it also has ASCII strings for different add-on options, like "HD Painting", "AV Painting" etc.http://imgur.com/a/wkY1hAs Mr Dexter said the other day, the Harriet isn't technically a "Harriet" unless it's linked to other units to make a more complete system.It should really be referred to as a "V-Series" unit, AFAIK?There are more routines for crypt / decrypt of files using the passwords (and serial number by the looks of it).I still haven't figured out how to force IDA to just disassemble the entire 2.11MB file, but I'm getting closer to finding which routines talk to the PAL, or use the serial number etc.OzOnE.

author: dexters_lab
author_rank: Unknown
timestamp: December 04, 2016, 03:41:28 pm
content: incidentally this is what the software keys look like:the first part is the key, then the option code it unlocks and then an expiry date, none means it's never expiresCode:AVE KMX BW3 LGG 2HM ZXM 33 NoneAZE 69T BW7 CGC WH9 VTR 69 NoneAVE KMT BW3 CGC 2HM ZTR 113 None

author: philpem
author_rank: Frequent Contributor
timestamp: December 04, 2016, 05:45:41 pm
content: Quote from: OzOnE on December 04, 2016, 12:18:44 pmGot it, I think. Links to a video about the DPB-7001?Quote from: OzOnE on December 04, 2016, 12:18:44 pmYou've got the logic a bit wrong.ALEC enables the I/Os.The data lines are normally high, but pull low if one of the Pterms detects a "hit".So if you scan through the address range, you should see a ton of 0xFF bytes, and 56 '0' bits scattered within that space.Quote from: OzOnE on December 04, 2016, 12:18:44 pmNice! I remember watching the videos of that on Youtube while Retrogamer was trying to get it up and running. I wondered what had happened to it.With regard to the OS... it looks like it's been loaded at address 0x0. I bet that isn't the load address.You need to know what address (in RAM) the boot ROM loads the OS into, and what address it starts executing from. If you give IDA that, it should get a long way into the disassembly.I think it might be stopping because the load/exec addresses are wrong.

author: dexters_lab
author_rank: Unknown
timestamp: December 04, 2016, 07:30:29 pm
content: OS is loaded at $400000

author: OzOnE
author_rank: Regular Contributor
timestamp: December 04, 2016, 07:34:20 pm
content: Hi,You should have a message with links to MEGA with the IDA stuff etc.?Quote from: philpem on December 04, 2016, 05:45:41 pmAhh, that probably explains it. lolI thought something might be inverted somewhere.I'm too used to Verilog, where you generally don't have inverted output pins unless you specifically code that.I forgot that PALs / GALs often have Active-Low outputs.I've just inverted the data bus on the Verilog, and it's now matching 100% with your 12360 binary.Quote from: philpem on December 04, 2016, 05:45:41 pmYep, I'm just trying to disassemble what I can atm, then work out where it normally loads the executables in RAM.I would imagine it loads the entire 2-4MB OS file(s) directly into RAM, as it does seem to point to routines in that range a lot.I did have the OS file for my older Harriet mostly disassembled in IDA, but the older IDA did have some bugs and glitches.So, I've started again with IDA 6.6 instead.I have nearly 50% of the code done so far, but I'm having to do a Ctrl-U to go to the next Undefined code, then hit C to convert to ASM.Most of the strings / data come before the routine of course, so I'm having to skip those manually too.Our guy in Oz did a superb job of figuring out most of the "Harriet" memory map btw.(hope this is OK to post?)...HW devices :CPU 68010DMA Controller MC68450 MC68450MFP MC68901 MC68901SCSI Controller WD33C93A WD33C93A x2 (found one only)2 Serial Ports + 8 I/O : MC68681 x2 MC68681 (found one only)SRAM + clock M48T02 x2 M48T023 rotary encoders move.w 0xFA0000, d0Optional Ethernet module is implemented on SCSI ID 6, with simple commandMapping addrs :0x000000 - 0x008000 ROM (32 KBytes)0x000100 - 0x0003FF RAM0x040000 - 0x0407FF NVRAM, default boot device0x040800 - 0x040FFF NVRAM20x400000 RAM do be verified0x7FD000 - … (seems used as RAM too : Input Console buffer)0x7FE000 - 0x7FFFFF RAM (4 KBytes) Initialized/tested during init0xF10000 - 0xF1001F : Serial Port MC68681 need To be verified (A0 = 1 for decoding)0xF100F1 : write on Serial GPIO : LED 7 segments front display (‘0’ to ‘9’)0xF20000 - 0xF2002F : MFP MC68901 (Serial Console)0xF30000 - 0xF300FF : DMA Controller MC684500xF40000 - 0xF4003F : SCSI Controller WD93C33A0xF60000 : Device with DMA transfer on 0xF60000 (DMA channel 2), 0xF60002 (DMA channel 3)0xF60007 : linked with burst write at 0xFE0004,8,A @sub3C0AF6 Memory Storage Board ?0xF96000 :one word write0xFA0000 : 3x Rotary Hex Switch : Word value0F00 => SW1400F0 => SW15000F => SW7sw14 SCSI Controller ID (normally 7 by default)sw7 BootID (0 DebugMonitor, F Boot from NVRam (Autoboot) else Printf “Autoboot From %d”, BootID)0xFB0000 : Leds ? Write 1 byte : 0x00 (init only) 0x1F or 0xFF (word) ; start and end of scsi cmds0xFB0001 : Read 12Bits (dip switch ?) used only in one place to index BootDeviceList0xFD0000 - 0xFD1FFF : Security PAL @sub52DCSecurity PAL store 2 flags, seems related to HW configuration/installation (like is a floppy drive present, serial number ….)0xFE0000 : ? @sub27260xFE0004,8,A : Writing word burst cmd 1,3,5,7,0 to these addr @sub3E8C0xFE device is a Floppy Controller ?I have found a few routines in the OS file which process the serial numbers, but they also appear to JSR to routines in RAM.Here's one example...ROM:00070D50 loc_70D50: ; CODE XREF: ROM:00070D48jROM:00070D50 adda.w #$44,sp ; 'D'ROM:00070D54 movem.l d0-a4,-(sp)ROM:00070D58 lea -$A(a6),a1ROM:00070D5C lea ($404100).l,a2ROM:00070D62 lea ($403CF2).l,a3ROM:00070D68 lea ($6362DE).l,a4ROM:00070D6E moveq #$C,d2ROM:00070D70 moveq #1,d5ROM:00070D72 subq.w #2,spROM:00070D74 pea -$4A(a6)ROM:00070D78 jsr $4710E8 ; <- Hard-coded to a routine in RAM.ROM:00070D7E addq.w #4,spROM:00070D80 tst.b (sp)+ROM:00070D82 bne.s loc_70DA0ROM:00070D84 pea aSerialNumberIn ; "Serial number invalid"ROM:00070D88 pea ($15).wROM:00070D8C move.l (sp),-(sp)ROM:00070D8E jsr $403FA4ROM:00070D94 adda.w d2,spROM:00070D96 jsr (a2)ROM:00070D98 jsr (a2)ROM:00070D9A clr.b -(sp)ROM:00070D9C jsr (a3)ROM:00070D9E addq.w #2,spOzOnE.

author: dexters_lab
author_rank: Unknown
timestamp: December 04, 2016, 07:39:20 pm
content: i should point out that the Harriet is actually working right now, when i get a moment i will go into a bit more detail here about what was done after philpem's code and of course i will be making a video in due course!just want to thank everyone for all of their help, it's certainly been an adventure getting this running!!

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 04, 2016, 08:04:41 pm
content: There has to be a Hackaday/EMFcamp/<insert favorite event> talk to be gotten out of all this....

author: SeanB
author_rank: Super Contributor
timestamp: December 04, 2016, 08:22:09 pm
content: Quote from: mikeselectricstuff on December 04, 2016, 08:04:41 pmI think more an Amp hour episode instead at first. Then a collaborative video with Mark and Dave about reverse engineering. We need the other collaborators in there as well at a minimum.

author: dexters_lab
author_rank: Unknown
timestamp: December 04, 2016, 09:34:06 pm
content: interesting thoughts therei will at least make a start to finish video about all the twists and turns and how it all came together

author: philpem
author_rank: Frequent Contributor
timestamp: December 04, 2016, 09:53:56 pm
content: Quote from: dexters_lab on December 04, 2016, 09:34:06 pmI'm looking forward to watching it(I may or may not be a bit of a sucker for Paintboxes...)

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 04, 2016, 10:12:49 pm
content: Now what to use to do graphics for the video....

author: philpem
author_rank: Frequent Contributor
timestamp: December 04, 2016, 10:18:09 pm
content: Quote from: dexters_lab on December 04, 2016, 07:30:29 pmI don't suppose you know where the monitor jumps to after it's loaded the OS, do you?

author: dexters_lab
author_rank: Unknown
timestamp: December 04, 2016, 10:21:08 pm
content: AFAIK it jumps directly to $400000

author: philpem
author_rank: Frequent Contributor
timestamp: December 04, 2016, 10:28:39 pm
content: Quote from: OzOnE on December 04, 2016, 07:34:20 pmYep!Quote from: OzOnE on December 04, 2016, 07:34:20 pmIt was in the EQN file - "/D1 = ..."Quote from: OzOnE on December 04, 2016, 07:34:20 pmQuote from: OzOnE on December 04, 2016, 07:34:20 pmYou've loaded the OS in at address zero, but the monitor loads it into RAM -- so IDA can't make head nor tail of the addresses.What you need to do is either reload it with the offset set to 0x400000 (not the "in paragraphs" one -- the one below it), or you might be able to get away with opening View -> Segments, then right clicking "ROM", selecting "Move Segment", then entering 0x400000 in the box.Needless to say, save your IDB file and take a backup before you try this.

author: philpem
author_rank: Frequent Contributor
timestamp: December 04, 2016, 10:37:53 pm
content: Quote from: dexters_lab on December 04, 2016, 10:21:08 pmSadly I don't think it is... that address is full of MOVEs, ORs with zero and BTSTs, which doesn't look like valid code

author: dexters_lab
author_rank: Unknown
timestamp: December 04, 2016, 10:39:08 pm
content: Quote from: mikeselectricstuff on December 04, 2016, 10:12:49 pmlol, yea i am sure i can use it somehowwill be nice to get the ramcorder working, it connects to the paintbox using CCIR601 so it can do animation, all 12 seconds of it!

author: dexters_lab
author_rank: Unknown
timestamp: December 04, 2016, 10:44:08 pm
content: Quote from: philpem on December 04, 2016, 10:37:53 pmoh, erm... dunno thenit could be different when it autoboots, i will check and let you know

author: technix
author_rank: Super Contributor
timestamp: December 04, 2016, 11:21:47 pm
content: Quote from: mikeselectricstuff on December 03, 2016, 06:43:25 pm8192 is not a big address space at all if you can code your brute force program to fully utilize the computing resources of your modern computer, especially GPU. It is a few seconds of run time at most on a R9 380 running OpenCL, less if you bump the GPU up to GTX 1080.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 04, 2016, 11:42:19 pm
content: Quote from: technix on December 04, 2016, 11:21:47 pmActually it is, if you can't ia lot of it.The number of permutations of seven '1' bits within that space is 8192x8191x8190x8189x8188x8187x8186, which is 2.46x10^27 , a rather large number to brute-force.If you did one test per microsecond, it would take 7.8^13 years

author: technix
author_rank: Super Contributor
timestamp: December 05, 2016, 05:14:03 am
content: Quote from: mikeselectricstuff on December 04, 2016, 11:42:19 pmThe key is on a modern GPU there are thousands of processing cores. For that kind of address space we can write a brute force searcher in OpenCL, break the entire address space up into chunks, and mount a distributed effort of brute forcing it. Although if someone can figure out a mathematical model to reduce the address space it would be nicer.

author: np
author_rank: Newbie
timestamp: December 05, 2016, 07:10:06 am
content: QuoteThank youI was quite busy these days/weeks but I see that you (all) did a good job.If any further help is required send me a PMNicolas

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 05, 2016, 09:26:20 am
content: Quote from: technix on December 05, 2016, 05:14:03 amOK say 1000 cores on a million years. Now down to 78,000 years

author: OzOnE
author_rank: Regular Contributor
timestamp: December 05, 2016, 11:26:02 am
content: @phil - I'll have a look at some of the other EQN files now, because the one I produced first using OpalJr doesn't have inverted "data" bus outputs?The only inversions were on /A2, /ALEC, and the logic terms themselves?Again, not important now, just one of those brain-teasers. lolThanks for the tip about IDA btw - it looks like moving the seg worked perfectly.I did Google about that yesterday, but the IDA site itself said that it was impossible to move the segments without adding them from scratch again.I guess they really need to update their docs, as it worked fine in IDA 6.6. heheI'll add the other segs / references for the hardware regs now, like Nicolas did for the ROM monitor disassem.At some point, I'll start adding more stuff to the FPGA Harriet, and see if I can at least get the serial monitor going.I had the ROM monitor for the classic DPB running on the dev board before, and translated a lot of the schematics into Verilog, but to actually get it running fully would require either adding lots of external RAM, or writing an SDRAM controller for the frame stores, disk store etc. The main RAM just uses the SRAM chip, so that should be fine.Interestingly, I believe that all of the main code on the classic Paintbox is stored on PROMs.One of the spare boards has the full 512KB of PROMs on it, IIRC. The floppy disks and giant HDD are only for storing uncompressed frames / fonts / brushes / cutouts etc.@np - Thanks, Nicolas - Some great work you did on the ROM code.What you did in only a few days would have taken me about 4 months. :pAs said in the last few posts, it doesn't look like the ROM monitor jumps directly to 0x400000 after loading the main OS, so it will be interesting to find out where it gets the vector from.Ahh - @philm - this may be very important to mention - when I grabbed those OS.BIN and OS2.BIN files from the HDD image of the first Harriet unit, I simply copied them out of the HDD image.It looked like that was the only 4MB chunk on the whole drive which actually contained any data, and the two "files" seemed to be almost the same apart from the "header"...http://imgur.com/a/QvgtAWe know now that you can simply list the files on the HDD using the serial monitor, and it returns the proper offsets for the files on the HDD.The old OS and OS2 files were from many years ago though, and from when I was just eager to start disassembling some code.We'll sort all of this out soon. lolNow that Mr Dexter has that new hoard of Quantel goodness, it's brought back a lot of the fun of working with them again.I think a Hackaday article would be great, and even better if there was a collab vid between Mr Dexter and Mr Jones.OzOnE.

author: technix
author_rank: Super Contributor
timestamp: December 05, 2016, 11:37:30 am
content: Quote from: mikeselectricstuff on December 05, 2016, 09:26:20 amThat is one GPU. Each machine can have more than one GPU, and in a distributed project there can be a lot more computers in general. Now if we can get 80k volunteers, it is already down to less than a yaer. And it is more likely than not some of them have dual GPU or more (Cards like AMD R9 295X2 count as two GPUs, and there are gaming rigs that have dual, tri or quad GPU setups), this just reduces the total search time further. Even better if some of us have Playstation 3 consoles that still had the older firmware revision (or hacked) that can run Linux.Such a problem is embarrassingly parallel as each tested case is independent of each other, hence you can just pile hardware onto the problem, and the time reduction is linear.

author: OzOnE
author_rank: Regular Contributor
timestamp: December 05, 2016, 12:09:13 pm
content: I think I see what's going on with the OS disassem now...It does look like the first 0x400 bytes (two sectors?) is just the AFS header for the file.Then, at offset 0x400 (which would normally be loaded to the start of RAM at 0x400000), the first instruction is a JMP 0x40003C.The instructions at offset 0x43C in the file (which will be at 0x3C when the header is removed) are then...ori #$2700,srresetWhich is pretty much what we see in the ROM monitor at it's reset vector of 0x5D0.Although, in the ROM monitor, the instructions at the reset vector are...nopresetori #$2700,srmove.w #$FF,($FB0000).letc...So, I'm just re-loading the OS file into IDA, but with the 1K "header" removed, and also loading it at the start of RAM (0x400000).Hopefully the hard-coded addresses for the serial number routines will then point to the right places.OzOnE.

author: technix
author_rank: Super Contributor
timestamp: December 05, 2016, 08:10:05 pm
content: Quote from: OzOnE on December 05, 2016, 12:09:13 pmIf we can get the key checking algorithm, we can rewrite it into OpenCL and start firing up GPUs.

author: philpem
author_rank: Frequent Contributor
timestamp: December 06, 2016, 06:16:28 pm
content: Quote from: technix on December 05, 2016, 08:10:05 pmThe problem is already solved. Look back in the thread.EDIT: This post:https://www.eevblog.com/forum/projects/reversing-the-encoding-of-serial-numbers-into-pals-or-gals/msg1083933/#msg1083933It was solved by running the algorithm in reverse, and the solution runs in under a second on a modern PC. Heck, it'd probably run in under a second or two on an 8MHz Z80 with enough RAM, it's all shifts, rotates, loops and moves.

author: technix
author_rank: Super Contributor
timestamp: December 06, 2016, 09:22:29 pm
content: Quote from: philpem on December 06, 2016, 06:16:28 pmNow can we figure out the meanings of each valid key?

author: dexters_lab
author_rank: Unknown
timestamp: December 14, 2016, 09:27:06 am
content: @PhilpemJust trying to dot the Is and cross the Ts while this is still fresh...I have read out all of the SecurityPALs as TMS2764 EPROMs and attached them, would you be able to run these through your decoder and reveal the contents?It might give us a clue to the use of the other 'spare' bytes after the description you mentioned before

author: philpem
author_rank: Frequent Contributor
timestamp: December 15, 2016, 01:23:41 am
content: Quote from: dexters_lab on December 14, 2016, 09:27:06 amHere you go!Some new description strings in this one:* 10311 Picturebox identifies as "GV SERIES"; the entire "spare" area is set to zeroHarriet:* 12360 Harriet - "00 00 00 08" in both copiesHAL:* 12875 & 11907: ID string is "HAL". First serial number in the ROM is 11907, second is 12875 (I'm curious which is the group one). Mystery bytes "00 04 00 00"* 14201: "HAL", mystery bytes "00 04 00 00"Editbox:* 13784_1, 13822_1, 15719_1, 16109_1, 16134_1, 16138_1, 16161_1, 17624_1dup1, 17624_1dup2: "EDITBOX". Mystery bytes "10 00 01 00"* 13784_2, 13822_1, 15719_2, 16109_2, 16134_2, 16138_1, 16161_1, 17624_2dup1, 17624_2dup2: "EDITBOX". Mystery bytes "00 42 01 00"Editbox Platinum (only the description text has changed though, possibly just different software keys):* 16450_1, 16879_1, 16980_1: "EDITBOX (PLATINUM)". Mystery bytes "10 00 01 00"* 16450_2, 16584_2, 16879_2, 16880_2: "EDITBOX (PLATINUM)". Mystery bytes "00 42 01 00"Edit Seat? -- possibly some special kind of Editbox:* 14340_1, 14491_1, 14691_1: "EDIT SEAT", Mystery bytes "10 00 00 00, 00 10 00 00"* 14340_2, 14491_2, 14691_2: "EDIT SEAT", Mystery bytes "00 42 00 00, 00 10 00 00"Domino?:* 13923 Dup 1: "DOMINO", Mystery bytes "00 00 20 00"* 13923 Dup 2: "DOMINO", Mystery bytes "00 00 04 00"Snetcom / Remote Mag Opt:* 14768, 17811: "REMOTE MAG OPT", Mystery bytes "00 00 00 00 10 00 00 00"PFrame Paintbox:* 15462 E dup1, 15462 E dup2: "PFRAME PAINTBOX", Mystery bytes "00 00 10 00 04 00 00 00"Paintbox:* 15546: "OPTIONS", Mystery bytes "00 00 00 08"Picturebox:* 70579: "PICTUREBOX", Mystery bytes "80 00 00 00"Henry:* 15671_1: "HENRY", Mystery bytes "10 00 00 10"* 15671_2: "HENRY", Mystery bytes "00 42 00 10"Network cards:* 13464 (HAL): ID string is "NETCOM". Mystery bytes "00 60 00 00" which is a network card* 15671_N, 15719_N_EB, 16879_N_ED, 16880_N_ED: "NETWORK". Mystery bytes "00 60 00 00"PMAN / GRID:* 15929 GRID: "PMAN". Mystery bytes "00 00 08 00"Bridge Processor:* 70579 BP: "BRIDGEPROC". Mystery bytes "00 60 00 00" -- yep, same as a network card. Maybe 00:60 just means "expansion card".At a guess, I'd say the mystery bytes encode the machine/card type. Dual-CPU machines at least have a PROM with encoding "10 00" for CPU1, and "00 42" for CPU2.There doesn't seem to be any other pattern to it, other than "specific machine types have specific values". A bit like the Gestalt values on old Macs, maybe?Cheers,Phil.

author: dexters_lab
author_rank: Unknown
timestamp: December 15, 2016, 09:16:09 am
content: QuoteGV?, hmm no idea on that one!Quotegood, this one could be importantQuoteyea i don't know that much about Editbox, it had a long life so probably went through many versions, there could also be custom products.QuoteDomino was Quantels 'movie' editor, it was a film scanner and setter. For restoring or editing movie film. Scan a frame, edit, then write frame back to film.Quote1U rack device with a MO drive connected to the network so other things could access the images on the disk it has a Snetcom board inside which seems to be the same as the Snetcom board installed in the v-series chassis.QuotePictureFrame, i have heard it mentioned before but no idea what it actually is.Quotethese could be significantQuoteearlier version of Editbox IIRCQuoteThese install inside the V-Series chassis for network connection through the SCSI port, they have their own 68k on boardQuoteno idea!Quotei am wondering if the BridgeProcessor is just an earlier version of the Netcom or SnetcomQuotei've attached one last PAL image, it's from my other v-series chassis and i thinks it's a picturebox.. if you could decode that one as well?

author: philpem
author_rank: Frequent Contributor
timestamp: December 16, 2016, 12:41:30 am
content: Quote from: dexters_lab on December 15, 2016, 09:16:09 amWell this one is a touch on the odd side...ID string is "COMBO", magic bytes are 00 00 00 00 02 00 00 00So who knows what that is... only way to tell is probably to boot it and see what it says on power-on.Cheers.

author: dexters_lab
author_rank: Unknown
timestamp: December 16, 2016, 07:21:44 am
content: Quote from: philpem on December 16, 2016, 12:41:30 amyes nobody is sure what it is!it's a much newer system from 1998, with SDI (serial) digital video, the later 68040 CPU card and snetcom (network), the sticker on the back says it's a Picturebox Express. It does boot but i can't seem to get a working keyboard or tablet on it. But just boots to a blank screen with the crosshairsI was told it's possibly a 'Combo' machine as in it's a Picturebox and a Paintbox in one which is quite possible as the licensing system from quantel certainly allowed that the hardware could run just about any configuration of softwarewish i knew what all the option codes that unlock parts of the software meant as it would help unravel itaccording to the list it has option 33, 69 & 113my older working one has 10001, 7, 30, 10002, 1, 5, 18 & 44here are some snippets from the bootlogCode:PAL standard 2103, 2300Serial number: 71335Description : COMBOOptions : 4000000000 39