basic copy proection

Started by
34 comments, last by DaBookshah 18 years, 1 month ago
I have a game im getting ready to sell, this is my first attempt to sell a game. I've read up on a number of software protection schemes and they all seem to be crackable. So i've decided i may as well see if i can just do something basic to deter any n00bs. So this is what i've thought of: 1) write my own vector interrupt for int 3 to stop debuggers. i dont know how to do interrupts in windows or if this will even work, if any one has any suggestions/links to articles 2) for online play, send the users key to the server, if the key s valid, the client recives a list of servers. This fails when the user joins by ip. This also fails with LAN and single player. I could force the user to be online to play (ala battlefield 2, and you buy online anyway) but then hackers can just bypass the online check. 3) one idea i had was to send the clients cpuid to a server, the server will then encrypt it and send it back to the client, this will then verify the player when they play offline (ie. you have to be online to install the game only). This should stop random copying of my game, but the hackers could probably just remove the code that checks the key is valid... plus i dont like the idea of cpu locking... any other ideas ? currently im just thinking 1 and 2, but it would be nice to stop simply copy for those people that play offline
Advertisement
1) everything can be cracked, the only thing you can hope for is deterring the less determined crackers.
2) the commercial solutions are written by experts. If they cannot make something watertight, don't even try to do it yourself.
3) what to do when a pirated version sends a valid key (not unheard of, key generators are common and a lot of people will give out their keys to friends and friends' friends etc. etc.)?
4) not all machines set a CPUID, or anything else that can uniquely identify them on their own. Other things like MAC addresses can be changed. And what procedures would you have in place to reset valid customers who change their hardware?
4a) what procedures do you have in place for people who aren't connected at all?
5) I doubt you can stop debuggers, there are just too many advanced ways that are (virtually) undetectable. The most determined cracker will have access to kernel debuggers, remote debugging facilities, and will also be able to intercept the data you send to your server for verification and change it on the fly.
This link might help:

http://www.activelocksoftware.com/
Anything can be cracked. Its just a matter of time, and the patience of the cracker.

As for antidebugger, Eldad Eilam in his book "Reversing: Secrets of Reverse Engineering" has a couple of good tricks to detect a debugger. This one here was the best, as its good for any debugger (kernel / user mode), and prolly won't raises a false positive.
bool bExceptionHit = false;__try{  _asm  {	pushfd	or dword ptr [esp], 0x100 //set the trap flag	popfd	nop  }}__except(EXCEPTION_EXECUTE_HANDLER){	bExceptionHit = true;}if(!bExceptionHit)	printf("A debugger is present");


Pretty much, if a debugger is present, it'll swallow the exception. So if the exception is hit, no debugger. I've yet to try this myself, but the author is brilliant, so I don't see why that souldn't compile.

GL!
Quote:2) the commercial solutions are written by experts.

Bwahaha.. I refer you to the recent Sony/First4Internet debacle. Not only is the entire design of their rootkit/"protection" a security hole, but it also contains pretty stupid bugs. And this in a kernel mode driver..


_Sigma: ooh, a productive tip! Nice :) These type of threads usually end up a silly discussion of whether or not to add copy protection, instead of valuable information on how to do so.
Why don't I chip in too, then:

Ways to detect debugger:
1) IsDebuggerPresent. Trivially dodged by debuggers (need only change flag in PEB)
2) timing. Impossible to avoid - single-stepping or handling lots of debug events will inevitably slow things down (unless remote debugging)
3) detecting *installation* of debugger. This is always an arms race and actually not nice to users because they might need a debugger for other tasks and may not be trying to hack your program.
4) trap flag method mentioned above

Misc. tips on how to annoy reversers:
1) scatter around (slightly different) inlined routines that wipe out all debug regs. This makes placing breakpoints across large regions of code infeasible (at least unreliable).
2) do not make it easy/desirable to spread a single cracked version. In more detail: if it's break-once run-anywhere, your protection isn't that good. Idea: compile a version for each customer that includes their name prominently displayed somewhere.
3) update frequently to invalidate simple patch-byte-here instructions and require reanalysis.
4) read in a recent BlackHat presentation about a way of protecting your memory from external analysis. Awesome!

Further reading: gold mine; also search for "Fravia".
E8 17 00 42 CE DC D2 DC E4 EA C4 40 CA DA C2 D8 CC 40 CA D0 E8 40E0 CA CA 96 5B B0 16 50 D7 D4 02 B2 02 86 E2 CD 21 58 48 79 F2 C3
I come bearing good news! There is nothing you have to do anymore, from a technical standpoint, to protect your games! There is this new thingy, called copyright law, and it enables you to sue anyone who copies your game without permission! Neat huh?
Quote:Original post by Anonymous Poster
I come bearing good news! There is nothing you have to do anymore, from a technical standpoint, to protect your games! There is this new thingy, called copyright law, and it enables you to sue anyone who copies your game without permission! Neat huh?

Wow. That is the most useless suggestion that I've ever had the misfuture to read.

IsDebuggerPresent isn't worth your time :P Unless your code is packed, its so damn easy to pass. You just search the imports for it, then if present, bp on it, once you hit, change the first OP to a 'ret' or 'ret 8' Can't remeber off the top of my head. And bam. Its defeated. See how easy? So put it in there, but don't rely on it.

*BUT* There is a way around this, again described by Elad. Just impliment your own 'IsDebuggerPresnt' code.
//Taken from Elad's book.mov eax,fs:[0x18] //fixed a small error heremov eax,[eax+0x30]cmp byte ptr [eax+0x2], 0je RunProgram ;jump to the main program code here;inconspicuously kill the app here.

Now thats way harder to pick out.

As Jan Wassenberg, timing is a really good way to defeat a debugger as well. Just set up another thread that monitors the first thread, and if it detects that the other thread is suspended, it terminates the app. Again, Elad's book is brilliant, so I'd grab a copy of that if you can.

Quote:
_Sigma: ooh, a productive tip! Nice :) These type of threads usually end up a silly discussion of whether or not to add copy protection, instead of valuable information on how to do so.

I know eh? Ah well. I just hope it helped him/her.

I don't recommend looking to see if a debugger is installed, as that will just piss people off. I have a few apps that won't run with SoftIce and what not installed, which is just plain annoying, so I've had to go in a disable that crap myself. Just not worth pissing off your customers.

Hope this helps.

[Edited by - _Sigma on March 4, 2006 9:25:29 PM]
Write your app in malbolge and ship a malbolge interpreter with it. There is no way anybody would be crazy enough to even bother cracking it.

Something that is similar to the malbolge way of protection: code morphing
You'ld have to be absolutely insane to try writing anything in that ridiculous language.

A couple more random tips:

* Do a checksum of the exe to detect modification.

* Don't check your key in a single spot. Use different code in both spots. Make the second check later on (in the middle of the game) and do something mean if it fails, such as:

rdtsc
push eax
ret

Have fun tracking that one down ;)

This topic is closed to new replies.

Advertisement