CRYPTON Beta test version 0.95 Brief Instructions The current trend with shareware programmers at the moment is to utilise a keycode registration scheme for their software to enable certain functions within their program for registered users. The trouble with this method is that it is very easy to hack in to the program code and work out the keycode. Crypton provides a means to encrypt program code using a method which is extremely difficult to crack. Normally the user's name is combined in some way with a keycode and this in turn produces a magic number which the program examines to determine if it is correct. This is where the problem arises, the program must know the value of the magic number and therefore a copy of it must be stored somewhere within the program code. Once a hacker has found the magic number, it is easy to reverse the encryption method and crack the code. With Crypton there are no magic numbers to find, once a magic number has been generated from the user ID and keycode combination the number is used as a key to decrypt the program code. The program has no idea what the magic number should be and so it tries to decrypt the program using the key, if the key is wrong then the program will crash when the code is executed. Crypton will attempt to recover from the crash but will not always be successful since the code produced is completely random. If the key is correct the program will, of course, run normally. To avoid GEMDOS destroying the encrypted data with fixup data it is essential that the encrypted code be completely relocatable (i.e. PC relative (DEVPAC opt a+)) and the end of the code must be marked with two ILLEGAL instructions and the LONG value $DEC0DE. e.g. Here is some code that you might have in your program which should only be available to registered users. * the decrypt function expects to find the following values * on the stack. * * 4(sp) = keycode pointer pointer to the 10 char keycode * 8(sp) = ID pointer pointer to the user ID string * 12(sp) = coded_data_start pointer to code (save_file) * 16(sp) = coded_data_end pointer to code end (test_end) * 20(sp) = dummy routine pointer to test routine * 24(sp) = mode flag 1=check code, 0=dont check * * Lattice C prototype: * int __stdargs decrypt( char*,char*,void*,void*,void*); * * Sample C function call: * registered=decrypt(keycode,user_id,save_file,test_end,testcode,mode); decrypt incbin "decrypt.inl" return d0=0 on error * a0 -> data buffer * d0 = file length save_file move.l d0,d7 save file length move.l a0,d6 save buffer pointer lea filename(pc),a0 pointer to path string clr.w -(sp) move.l a0,-(sp) move.w #60,-(sp) fcreate() trap #1 addq.l #8,sp tst.l d0 bmi.s .exit move.w d0,d5 move.l d6,-(sp) move.l d7,-(sp) move.w d5,-(sp) move.w #63,-(sp) fwrite() trap #1 lea 12(sp),sp move.l d0,d6 move.w d5,-(sp) move.w #62,-(sp) fclose() trap #1 addq.l #4,sp cmp.l d6,d7 disk full? .exit rts testcode nop dummy code which performs cmp.l d0,d0 no real function but can beq.s .j2 be executed to see if the .j1 rts decryption was successful .j2 nop test_end bra.s .j1 illegal opcode = $4afc illegal dc.l $DEC0DE end All you need to do is include the code in your program and assemble/compile it as normal with debug symbols, then use Crypton to select the function to be encrypted. The master code is a hex code which should be known only to you. Each program you write will have a different master code. After entering the master code, you enter a user ID, which would be the user's name for example. Now click the Encrypt button and choose the function to be encrypted from the symbol chooser window. The file will be encrypted and a ten digit keycode will be generated which you can send to your registered user to enable them to unlock the encrypted functions. NOTE: The decrypting code temporarily replaces all system exception vectors if mode is TRUE. Since it is possible that this may interfere with some systems, the mode flag can be cleared and the decrypt code will not take these vectors and can therefore not check the test routine.