Various kinds of restriction-ware: ---------------------- Register-patcher: General idea: 0. Create a polymorphic engine. Use this on your program pre-release. 1. Create a data area encrypted with some well known theoretically safe cipher. (Say AES) 2. Pre-release, change this data area so that it'll patch the PE- modified executable correctly, and assign a code. Also, assign e(x, code) = "program ID" for public viewing, where x is a secret key only known to you. (That could also be done per user on the server) 3. At the registration window, the program shows the program ID. The user is supposed to input this program ID into a web server and get d(x, ID) = code back. As long as you're using a good cipher, it shouldn't be possible for the user to vary the code by one byte and get any idea of the key x. (You could even just use e(x,code) = md5sum(code) and store both program id and code on the server) 4. When the user inputs a registration code, the program tries to decrypt a small verification program from the data area. This verification program goes somewhat like "mov eax, 1917, exit". At the exit, the caller compares it to 1917. This should be run in a protected thread so that if it decodes to nonsense (which is what happens if an incorrect code is entered), the program doesn't crash. (One could also just have a value being decoded and compared. This value should be as long as the key; say the program ID.) 5. The program then uses this verification to see if it has the right code. True, this part can be hacked, but that'll only deprive the program of a means of knowing if the code is right, and will corrupt the system upon patching. One may argue that the verification program is too fast, but using a 256 bit key should make it impossible to brute-force. 6. If the verification fails, the process is canceled and the program says "incorrect code.". Otherwise, it unpacks the patch and patches the program. Because of the polymorphic changes, this patch won't be helpful for any other scrambled version of the program, unless the polymorphism is reversible (which it shouldn't be). ---------------------- Keygen-proof traditional registration: (This is not secure against tinkering, nor code swapping, but it is against keygens, unless the adversary is in possession of a quantum computer.) 0. Create a public/private key pair and hide the private key. 1. Include the public key in your program. 2. Set registration key code as follows: 2.1. Get code and data from user. 2.2. If publicKeyDecrypt(code) == md5(data) then good boy else bad boy. Since public key encryption is fundamentally asymmetric, there can be no keygens. (QC notice is because factoring is in BQP.) (Why isn't anyone doing this?) (If you want to discourage sharing, just do something like If publicKeyDecrypt(code) == data.SSN concat md5(data) then for step 2.2 and verify the SSNs on registration. Of course, this'd be a perfect weapon for someone getting hold of another's SSN and wanting to make his life miserable, so it's not without its faults.)