Shop OBEX P1 Docs P2 Docs Learn Events
Code protect? - Page 5 — Parallax Forums

Code protect?

12357

Comments

  • hippyhippy Posts: 1,981
    edited 2008-02-22 22:08
    @ Phil : Yes that agrees with me.

    I think I have 23 mappings done, 9 to go; the four conditional execution bits and five destination
    register bits. That said there is a problem somewhere because I can see the occasional instruction
    which doesn't make any sense, ie it uses the -1 at $1E5 as a destination ( and that is now a proven
    constant - and possibly the only one ! ). One problem is that variables are at $00x or $1Ex so that's
    a lot of bits either set or cleared and hard to determine the real underlying mapping. I have some
    'helpers' to cajole the software in the right direction and I suspect I may have mis-typed one. I
    need to go back without loosing too much of what I have an then go forward again.

    On the other hand, nearly the other instructions seem to make some kind of sense. I've identified
    where various parts of the interpreter are, the Fetch-Execute Loop, bytecode Constant Number
    loading ( the 'packed number' code solved a couple of mappings ), Push to Stack, and a few other
    odds and bobs.

    So the current verdict is "cracked", although not finished yet.
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-22 22:10
    Phil - stay confident. What you are doing is "standard procedure" for handling block ciphers. With such small sizes as 32 and a wealth of "texts" (500!) you and hippy are bound to succeed.

    However: All classic successful encryption of block ciphers is based on some "skill" to handle anagrams smile.gif Which on the other hand needs an expertly control of the language.

    So do not fear smile.gif
  • LewisDLewisD Posts: 29
    edited 2008-02-22 22:14
    referencing this code and others from Hippy...


    Encryptd  opcode zcri cccc ddddddddd sssssssss
    
    003C0DC0  011011 0010 ---- 000000010 000000001  IF_?  XOR  $002,$001
    063809C0  011011 0010 ---- 000000001 000000010  IF_?  XOR  $001,$002
    003C0DC0  011011 0010 ---- 000000010 000000001  IF_?  XOR  $002,$001
    00024D89  110000 --00 1111 0000--000 000000001        CMPS $0--,$001 {WC?} {WZ?}
    00064089  110000 --00 ---- 0000--010 000000000  IF_?  CMPS $0--,$000 {WC?} {WZ?}
    0008D9C1  010111 0001 1111 000000000 000000000        RET
    
    



    I get this for pins...


    
    Encrypted Bit / Actual Instruction Bit
    
    
    28    12
    26    1
    25    9
    24    2
    21    29
    20    23
    19    26
    18    10
    15    22
    10    0
    7     30
    6     27     
    3     31
    2     8
    
    
    
    
    The full Encrypted Bit to where it could be in Actual Instruction mapping -
    
     31           ------ ---- ---- rqponml-- ---------
     30           ------ ---- ---- rqponml-- ---------
     29           ------ zy-- ---- rqponml-- -----d---
     28           ------ ---- ---- --------- -hgfe----
     27           ------ ---- ---- --------- -hgfe----
     26           ------ ---- ---- --------- -------b-
     25           ------ ---- ---- --------j ---------
     24           ------ ---- ---- --------- ------c--
     23           ------ ---- ---- rqponml-- ---------
     22           ------ ---- ---- --------- -hgfe----
     21           --D--- ---- ---- --------- ---------
     20           ------ --x- ---- --------- ---------
     19           -----A ---- ---- --------- ---------
     18           ------ ---- ---- -------k- ---------
     17           ------ zy-- ---- rqponml-- -----d---
     16           ------ zy-- ---- rqponml-- -----d---
     15           ------ ---w ---- --------- ---------
     14           ------ ---- vuts --------- ---------
     13           ------ ---- ---- --------- -hgfe----
     12           ---C-- ---- ---- --------- ---------
     11           ------ ---- vuts --------- ---------
     10           ------ ---- ---- --------- --------a
     9            ------ zy-- ---- rqponml-- -----d---
     8            ------ ---- vuts --------- ---------
     7            -E---- ---- ---- --------- ---------
     6            ----B- ---- ---- --------- ---------
     5            ------ ---- ---- rqponml-- ---------
     4            ------ zy-- ---- rqponml-- -----d---
     3            F----- ---- ---- --------- ---------
     2            ------ ---- ---- --------- i--------
     1            ------ ---- ---- rqponml-- ---------
     0            ------ ---- vuts --------- ---------
    
    
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-02-22 22:22
    Hippy, if you can find the code for the random number routine than that might help.

    Edit: code is
    Paul Baker said...

    Heres the promised source for the ? operator
    ' z=1: ?x
    ' Z=0: x?
    
                      min   x,#1              '?var/var?
                      mov   y,#32
                      mov   a,#%10111
          if_nz       ror   a,#1
    :rndlp            test  x,a         wc
          if_z        rcr   x,#1
          if_nz       rcl   x,#1
                      djnz  y,#:rndlp
    
    


    I asked about the line tab file and he said the way the compiler is organized it wouldn't be a trival task to generate a line tab file.
    So there is some condition bits and a wc for you smile.gif

    Post Edited (stevenmess2004) : 2/22/2008 10:28:47 PM GMT
  • GadgetmanGadgetman Posts: 2,436
    edited 2008-02-22 22:29
    The copycats you've had to deal with until now have been able to copy the SB1/BS2 systems because they've been made using 'off the shelf' chips. Then it has 'just' been a question of reverse-engineering the interpreter and designing a small PCB.

    The Propeller, though... Has added a second layer of complexity; a completely new chip they can't source cheaper, and which can't be 'copied' without a lot of work.
    (Even more so if they want to make it different enough not to have rabid lawyers on their necks.)

    Frankly, I expect certain 'competitors' to launch ridiculously souped up versions of their products to try to compete with the Propeller.
    And they'll certainly try to enhance the 'multitasking' functionality they've built into their versions of BASIC.
    But no, they won't attempt to create a copy of the Propeller.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Don't visit my new website...
  • LewisDLewisD Posts: 29
    edited 2008-02-22 22:48
    stevenmess2004

    That code starts at address $19B
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-02-22 23:01
    So we can guess that
    x is in 000
    y is in 001
    a is in 002
    Condition bits for $19E are IF_NZ = %0101
    Condition bits for $1A0 are IF_Z = %1010
    Condition bits for $1A1 are IF_NZ = %0101
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-02-22 23:18
    Bits 21 .. 18 (the IF_xx bits) are pretty easy to find (I think), since they're almost always all set. Simply summing the bit usage of each bit and picking the four highest yields the following for these bits in the encrypted code:

    ····0, 8, 11, 14

    but not necessarily in that order. That's my best inference, anyway. Perhaps Hippy can confirm. At least they can be removed from consideration for the other fields with some confidence, thus reducing the search space.

    I'm not even sure that XORing these bits with a random constant would help to obscure them, since the usage sums would still deviate from 50% by a wider margin than most of the other bits.

    One problem with using a substitution cipher (which is all a bit permutation is, even if futher XORed with a constant) is that Propeller assembly code has a very distinct fingerprint, from which much info can be gleaned. It would be better, I think, to permute the bits and then XOR them with an LFSR. This would erase any position correlates, leaving the ratio of 1s to 0s in each bit position at roughly 50%. Of course, if one knew an LFSR was being used, it would still be possible to search through the finite number of possibilities until data with the Propeller's distinct fingerprint popped out. From there, we're back to decrypting a substitution cypher again.

    But, by far, the best approach would be to keep the secret parts of the ROM non-readable. This doesn't have to preclude verification though. The ROM code could include a small routine that produces a hash (fancy checksum) of the COG's entire contents, which could then be written to the HUB for comparison to the expected value. If the values didn't match, or if the code failed, you'd know that that portion of the ROM was defective. If they matched, you'd know, with an extremely high degree of confidence, that the ROM was okay. The hash itself, though, would not contain enough info to extract any code from it.

    -Phil
  • hippyhippy Posts: 1,981
    edited 2008-02-22 23:24
    @ stevenmess2004, LewisD : Thanks humongously. That helped a lot, now with 27 bit swappings
    identified and just 5 left, all in the destination register.

    Not withstanding that I've got the (destination?) addressing bits slightly screwed ( hence the
    erroneous 007 : COGID $1E5 ), the almost completely decoded interpreter as I think it should
    look is attached.

    I'm also very interested in Phil's method because it's entirely different to my "take a hammer
    to it" approach.
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-02-22 23:26
    hippy, what I did was tiny compared to what you have done smile.gif
  • LewisDLewisD Posts: 29
    edited 2008-02-22 23:30
    ditto!!!
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-22 23:31
    Phil Pilgrim (PhiPi) said...
    ...using a substitution cipher (which is all a bit permutation is, even if futher XORed with a constant)
    It is not very useful to consider this as mono-alphabetic substitution (though it is of course) as the alphabet is very large (2^32). It would not have been possible to crack this code with the limited texts available and only some "imagined contents" if not a kind of block cipher were used (permutation) enabling intuitive anagram techniques.
  • hippyhippy Posts: 1,981
    edited 2008-02-23 00:24
    Phil Pilgrim (PhiPi) said...
    Bits 21 .. 18 (the IF_xx bits) are pretty easy to find (I think), since they're almost always all set. Simply summing the bit usage of each bit and picking the four highest yields the following for these bits in the encrypted code:

    0, 8, 11, 14

    but not necessarily in that order. That's my best inference, anyway. Perhaps Hippy can confirm.

    That matches with my results - I'm amazed. That was really causing me suffering until the randomise routine was mentioned. I think you'll be surprised though when you reveal the code; nearly 50% of instructions are conditional ! I don't know what distribution of 1's and 0's though.

    I cracked the WZ and WC by spotting a MOV with only one spare bit not allocated, and it was hardly likely to be the WC.

    IF_C fell out by looking at the Packed Byte bytecode decoding routine, and that also revealed IF_NC but no others.
  • simonlsimonl Posts: 866
    edited 2008-02-23 00:30
    Hey, what an amazing job you guys have done smile.gif I've been watching this; can't say I understand it (!), but it's an intriguing read all the same!

    As for Chip actually releasing the code - that leaves me feeling slightly uneasy (dunno why, it just does). Perhaps he should only release it to those that pass him the full decryption? After all, it's most likely to be those (i.e hippy, phipi, et al) that could make best use of it, and perhaps share some more useful stuff as a result?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheers,

    Simon
    www.norfolkhelicopterclub.co.uk
    You'll always have as many take-offs as landings, the trick is to be sure you can take-off again ;-)
    BTW: I type as I'm thinking, so please don't take any offense at my writing style smile.gif
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-02-23 00:35
    Maybe he could release by email to those who ask nicely for it. I know that I would like to see it to see if there is anything I can use for DOL.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-02-23 00:40
    Hippy,

    I'm curious, now that you've had time to examine Chip's code in some detail, how similar is it to the interpreter you wrote? Did necessity dictate similar code, or was there sufficient latitude that your two designs could differ significantly?

    -Phil
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-02-23 00:44
    Actually, I'm much less interested in the result than in the process of obtaining it. If Chip never revealed his code, I'd still be satisfied by the experience.

    -Phil
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-02-23 00:46
    There probably isn't much difference. Hippy probably figured out how to decode the ROM when he was working on his interpreter and is just playing with us all now just for fun smile.gif


    All TIC of course smile.gif
  • hippyhippy Posts: 1,981
    edited 2008-02-23 02:51
    I haven't really had much time to examine the actual code but it is interesting, although much of it is just sequences of instructions I haven't tried understanding. My best attempt came in ( if I remember right ) at around 750 longs, Chip's really does fit in 496 longs, no LMM, no overlay trickery I can see.

    No obvious lookup or jump tables either, opcode selection is done by range testing and bit test and branch and by taking two opcode bits into C and Z and using various IF combinations to execute one of four. That keeps the code footprint small but (slightly) slower speed than alternatives.

    I've learned at least one trick; how to do something based on two arbitrary bits in a byte. TEST (or AND NR ) is fine for getting a Z flag, but for SHR etc C is only set from lsb. That always had me stumped. TEST on a bit though can set either Z or C, so two TEST's gets an easy four-way case statement. Maybe everyone knew this but it's a trick I'd missed.

    There are as someone earlier suggested ( apologies for forgetting who ), lots of IF condition sequences. Chip seems better at this type of programming than most of us are, certainly I don't usually think that way. One potentially issue with getting to understand the code could be that Chip seems to "carry Z and C bit flags around the place" but that could just be a false impression I have.

    The mystery of the missing RET's is answered; there really aren't many, it is very linear and in-line code albeit spaghetti like ( actually more untangled string like ). It may become more clearer and logical as it becomes labelled and program flow becomes clearer. Not as many MOVS, MOVD and MOVI as I'd have expected either.

    As to similarity between my Interpreter and Chip's; I haven't really found enough to compare. I failed to hit the Cog size constraint because I designed it modular with lots of sub calls with RET whereas Chip seems to have lots of conditional fall-through. I don't think there's a "GOTO's are Harmful" poster on Chip's wall. It may be more correct to call Chip's code elegantly efficient rather than elegantly structured. One can see the hand of an assembler wizard at work - "real programmers don't need subroutines" - just jump into another routine which already does the job [noparse]:)[/noparse] The flow does appear logical though, not just jumbled.

    Where Chip seems to have the upper hand is in being able to find highly compact code for various routines. Chip "thinks optimised" IMO. I reckon there are going to be quite a few "Huh ? Why that way ?" questions and "Clever!" exclamations. In the first few longs we have that double ADD of #$100 to increment a destination register, why not one ADD and a $200 constant ? No extra code and faster to execute. My guess is it's more suited to the code being re-used as working registers, and speed isn't everything.

    I think my main question, how did Chip do it in 496 longs when I couldn't has been answered; my jump table was a bad idea, but that was necessitated through not having thought of better instruction decoding and execution. I was probably also side-tracked by a subconscious refusal to accept that some code can be allowed to be slow(er). On top of that, Chip had a much longer timescale for design and optimisation ... and gets paid for it smile.gif

    I think my interpreter would win on speed, but Chip's actually fits in a Cog and slightly slower speed is the penalty.

    Apologies to Chip for pulling an uninvited public code review out of the hat, from someone who doesn't even understand a tenth of what's there yet, and I hope there's no offence caused. It's a great work of art no matter which way it's looked at.
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-23 02:59
    Phil Pilgrim (PhiPi) said...
    Actually, I'm much less interested in the result than in the process of obtaining it.
    Though you will hardly have another opportunity to exercise it: Mono-alphabetic encryption is "out" since around 1585 smile.gif
  • cgraceycgracey Posts: 14,155
    edited 2008-02-23 03:15
    deSilva said...
    Phil Pilgrim (PhiPi) said...
    Actually, I'm much less interested in the result than in the process of obtaining it.
    Though you will hardly have another opportunity to exercise it: Mono-alphabetic encryption is "out" since around 1585 smile.gif
    Don't be a spoiler, deSilva... I could do it again!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Chip Gracey
    Parallax, Inc.
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-23 03:20
    @Hippy,
    I think this is an excellent review you gave. And it is not unexpected. When you have learned to design circuits - en-masse or en-detail you tend to put things "upside down"...

    A commercial programmer is trained to work left-to-right: Transforming input to output, level for level...
    A hardware persons works right-to-left: What is needed to just get that specific piece of information?

    My pet example for this ist the way a decoder for 7 segment displays works. Have a look at the circuit! And than have a look at your software driver smile.gif
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-02-23 03:52
    Hippy,

    Thanks for the thorough response! I agreee with deSilva: it's an excellent and thoughtfull commentary. But it also revealed something else you may not have intended. You used "learned" instead of "learnt". Are you not a native Brit? Or were you just being sensitive to a predominantly Yankee audience? smile.gif

    Regarding the missing RETs: Chip seems to have a passionate fondness for coroutines. So beware: a JMPRET may well deposit a return address into something besides a simple RET!

    -Phil
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-02-23 10:40
    PhilPi said...
    Regarding the missing RETs: Chip seems to have a passionate fondness for coroutines. So beware: a JMPRET may well deposit a return address into something besides a simple RET!
    There is at least one coroutine in the graphics driver. Seems like a good way of saving space to me. Although, it can make the code hard to read. But when it is going into ROM and you can't really change it who cares? smile.gif

    @hippy: Going through your code I think like you said that some of the dest bits are still scrambled (for example 009 writes over itself). The first two bits look like their right though. Phil may be able to figure something out based on the first 8 or 9 longs which are used for variables and temps.

    Chips method of decoding the instructions is almost like a linked list. The method used would explain some of the different execution times. I'm just about to have a look for the missing $3C opcode...
  • Paul MPaul M Posts: 95
    edited 2008-02-23 10:53
    Phil

    learnt vs learned : you prompted me to look it up; there seems to be much opinion that one is an Americanism but strictly·learned is the preterite (or simple past) and learnt is the past participle. Therefore, ·"I learned to program..."· and "I have learnt to program..." are the correct forms. According to Partridge,E. ("Usage and Abusage") ·"Learnt is disappearing from general use, but some discriminating·writers and speakers retain it as past participle".

    I admit I used to use the forms interchangeably - Thanks for prompting a non propeller interlude.smile.gif
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-23 11:04
    Many people here like these interludes, as many come from even more exotic countries than USA or Australia...
    I am working with an international company where people have developed a more or less non-understandable dialect - not only due to French pronunciation habits. We have words, phrases, "false friends" close to national connotations that do not exist in Standard English.

    A British colleague once told me he had to attend courses for "Technical English" during his enginering training to enable him to shift from his native language to the "world language" - sometimes called "Simplified and Bad Spoken English" smile.gif

    --- End of OT ---
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-02-23 11:12
    @hippy: I reckon that line $019 should be a jmp and not a ret. Its just semantics as they are really the same. Also I reckon that line $016 should have line $019 as the dest. Also, line $00D to $019 look like they are playing with the opcode that was just obtained from line $009. To make this work the destination for line $009 would have to be $005 which is only 1 bit off what you already have (maybe a type smile.gif ). However, this will kind of muckup lines $013, $014 and $015.

    I don't know how you figured this out, its already making my head spin smile.gif

    Of course all of this is just speculation and so far that hasn't got'en me too far on the topic of this thread smile.gif

    oh, did you have to put in the bit about the end of OT deSilva? That sounds like something interesting to pursue. Okay I'll be quiet now smile.gif

    Post Edited (stevenmess2004) : 2/23/2008 11:17:41 AM GMT
  • CardboardGuruCardboardGuru Posts: 443
    edited 2008-02-23 13:06
    Great thread.· And a fantastic peformance by Hippy.· If I was trying this myself I'd have tried out XORs -·the bit shifts wouldn't have occurred as a likely method.

    I just thought I'd do a post hoc analysis of instruction frequency counts from Hippy's dissassembly.· Just to see whether a fitness test·to differentiate realk code from random numbers·would have worked.· It's attached.·

    Sure enough the most common operations are pretty much what you would expect from any code.
    jmp, mov, add, test,·jmpret/ret

    Also the top condition codes are what you would expect too.· IF_ALWAYS, IF_Z, IF_NC, IF_C, IF_NZ.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Play Defender - Propeller version of the classic game
    Prop Room Robotics - my web store for Roomba spare parts in the UK
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-23 14:07
    As the encryption (let's call it so, out of convenience) is bit based, the "alphabet" is just {0,1}. For a statistical investigation you generally approach by bigrams, trigrams etc.

    As a Propeller instruction is highly structured this can be easily expanded - at a last step! - to a "word" = "opcode" as you did. It is interesting that you say it looks "standard", in contrast to Hippy's description of Chips different programming style. Where does your reference come from?

    Note that a machine language with different instruction lengths would have complicated this decryption tremendiously smile.gif

    Post Edited (deSilva) : 2/23/2008 2:25:53 PM GMT
  • hippyhippy Posts: 1,981
    edited 2008-02-23 14:36
    Yes, I'm a native Brit, but admit I do sometimes drift between English and American and sometimes without noticing. I have no idea how to properly spell "grey" or "gray" these days without looking it up or having to analyse which it would be. One thing I cannot do is comprehend English or American dates, they both stop me dead; ISO <whatever> "YYYY-MM-DD" is all I use, and encourage everyone to adopt.

    I try and take care in what I write but know I frequently fail; typo's, brain out-pacing fingers, excitement induced dyslexia and dropped and repeated words, and then sometimes just straight-forward nonsense and even misused words. As to "learned" or "learnt", I'd have had no idea of correct use. I just go with the flow, what comes out gets written down. My principle has always been that if others can get the drift it's probably good enough.

    My use of apostrophe in contractions sometimes provokes debate or criticism; you'll see PC's and typo's from me not PCs or typos. Those are the ingrained rules I was taught and I haven't seen any vote on a rule change smile.gif

    On the Interpreter front ...

    @ Phil : Chip does have lots of JMPRET's in there ! I think you're right about co-routines.

    @ stevenmess2004 : Those are definite pointers to a bit-swapping being wrong. Thankfully not in the instruction opcode. In the early days it could have been hard to determine if an opcode sequence were right or gibberish. I've tried moving my code backwards but it's still throwing up the same answers.

    @ CardboardGuru : Thanks for the analysis. I too had expected at least XOR encoding. I looked at the long at $FFF4 a while ago. Couldn't see any obvious instruction there, gave up as more extensive analysis seemed too complex and not worthwhile.

    Not sure how much credit I can take in the decoding. The key had always seemed to be "getting inside Chip's head" visualising how he would have done it. I expected more complex encoding, and LFSR seemed the likely candidate to me. If it hadn't been for Chip's pointer to it being simplistic I'd have discounted bit-swapping alone. If it hadn't been for the 'lucky guess' of what the code would be doing early on and manual decoding matching for the first two longs I'd be sitting alongside Chip saying no one would get it done this year. As noted, I was still expecting to hit some second level of encoding.

    I've done bit-swapping and address line swapping in the days of 6800's and external Eprom to make PCB tracking easier, so it was not an alien concept. I also wrote a program once which let a PC solve "Mastermind" - the game where four or six coloured pegs are placed in holes and the player has to guess the colours and are told how many they got right - the bit-mapping detection here works in almost the same way; work out what it cannot be and what one's left with is what it must be. And I cannot claim any original idea there smile.gif

    My work on the bytecode disassembler, own Spin Interpreter and previous similar work all helped but it's hard to quantify how much. Much of that was based on the work of others and here too I haven't even powered up a Propeller or switched on WinXP, I used the ROM image someone else extracted and took the help in this thread when I hit a wall.

    Ultimately thanks ( blame ? ) must go to Chip for his "yes, you can do it !". I'll take credit for the good guess as to how it was encoded and the few hours it took on the first two instructions, but after that it was really just a coding exercise to see if the image matched the theory and luckily it did. PowerBasic (2.10) for MS-DOS under Win98SE if anyone is wondering what tool I've used.
Sign In or Register to comment.