Game protection suggestion...?

Archives Forums/Linux Discussion/Game protection suggestion...?

SLotman(Posted 2009) [#1]
Since I'm currently finishing my game, I'm now turning into implementing a copy protection method, not very elaborated, just something to prevent "casual copiers"

What I need is some way to lock the game to the computer where it's installed. Whoever buys it can install the game as many times as they want, on as many computer as they want - but after installed, it must somehow tie itself to that computer.

Why this? Mainly because the game will run in schools. So I want to prevent kids copying the whole path where the game is installed and taking the game home.

On Windows I can easily get the HD serial number and encode it somewhere... but I have no clue how to do that on Linux. Searching on google didn't help either :(

I thought to store the path where the program is installed, but that could be easily changed; storing the username could be an option, but still, if several users get access to the game, it won't work... and I have no idea how the Linux setup on those schools might be.

I also can't check anything online - most of those schools don't have internet, maybe not even a decent phone line.

Now, please, let's not start a discussion where protection is needed, useful, hated or what - I need something implemented, and would love to hear from you guys any ideas, of what could be done.


TaskMaster(Posted 2009) [#2]
When installing, write a hidden file somewhere else on the OS (or in the registry, or whatever). Then, to copy the game, the user (kids) would have to know where that file is and copy it as well to run the game.

Not fool proof, and could be circumvented fairly easily, but it will stop casual copiers.


xlsior(Posted 2009) [#3]
Finding hardware informatio programmatically is actually really, really easy under Linux: It's all stored in plain text files that you can read and parse by your program.

For example:
/proc/cpuinfo will contain information about the CPU
/proc/meminfo will contain information about the memory
/proc/partitions will contain info about HD partitions

there's similar files for other hardware components.
A combination of several of these component files will probably be enough to get a fairly unique profile.

for example, the cpuinfo file may contain the following:


processor : 0
vendor_id : AuthenticAMD
cpu family : 5
model : 9
model name : AMD-K6(tm) 3D+ Processor
stepping : 1
cpu MHz : 400.919
cache size : 256 KB
fdiv_bug : no
hlt_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 1
wp : yes
flags : fpu vme de pse tsc msr mce cx8 pge mmx syscall 3dnow k6_mtrr
bogomips : 799.53



the vendor_ID, model name, CPU family, model and stepping would be good things to check against. MHz may be less suited, since there are tiny fluctuations in the returned speeds which may vary over time. (e.g. the 400.919 listed in this example really is 400MHz)

Example of /proc/meminfo:
total: used: free: shared: buffers: cached:
Mem: 1050001408 1012899840 37101568 0 113672192 420950016
Swap: 2097434624 217985024 1879449600
MemTotal: 1025392 kB
MemFree: 36232 kB
MemShared: 0 kB
Buffers: 111008 kB
Cached: 279304 kB
SwapCached: 131780 kB
Active: 677908 kB
ActiveAnon: 487272 kB
ActiveCache: 190636 kB
Inact_dirty: 129164 kB
Inact_laundry: 23948 kB
Inact_clean: 15332 kB
Inact_target: 169268 kB
HighTotal: 131008 kB
HighFree: 2336 kB
LowTotal: 894384 kB
LowFree: 33896 kB
SwapTotal: 2048276 kB
SwapFree: 1835400 kB
Committed_AS: 1079884 kB



There's a bunch of stuff that it dynamic, but the total mem size and the total swap size should be fairly static. (Unlike Windows, Linux typically uses a swap partition, not a swap file, so sizes are unlikely to change after the installation)


xlsior(Posted 2009) [#4]
One more thing: Harddrive information can also be found under the branch, but I'm not sure about the exact path for those. It's likely in a subfolder somewhere... hda is the primary IDE drive, sda is the primart SATA/SCSI drive. (hdb, hdc, hdd are secondary etc., sdb, sdc, sdd, sde, sdf etc. are secondary SATA)... but as far as locking against hardware, you probably only need to look at the primary partition.

Look around, but it could be something like:
/proc/ide/ide1/hda/identify
or
/proc/hda/idenfity
/proc/sda/identify

there's config files containing info about capacity, settings, model, identification, and others.


Jim Teeuwen(Posted 2009) [#5]
To add to xlsior's post, extracting the info from the files for use is also really easy. This goes into the standard UNIX commandline tools you will find on every linux machine and may well be worth spending some time on to learn about them. These tools are absolute life savers when working with linux (with every unix system for that matter).

Let's say you only want the CPU model name from /proc/cpuinfo, you just do this in a command line (or through the _system() command in blitz:

cat /proc/cpuinfo | grep "model name" | sed sed -r 's/model name\s+\:\s+//g'


This will print "AMD-K6(tm) 3D+ Processor" once for every CPU/Core that is present in the machine (using the output xlsior posted.. this is of course different for your own machines).

- 'cat' simply prints the contents of the file /proc/cpuinfo to the standard output stream.

- '|' (pipe) sends that output to the next program, in this case 'grep'.

- 'grep' performs a regular expression search on the text it gets from the standard input stream and prints only the lines that match. In our case "model name : AMD-K6(tm) 3D+ Processor".

- '|' this pipe sends the output from grep and gives it to the program 'sed'.

- 'sed' also performs a regular expression search on the input text and replaces the bit in "s/.../" with the bit in "/.../g". In our case "model name : " is replaced by "" (nothing). The output is then printed to the standard output stream again for your viewing pleasure.

For my own computer, the output of that command is:

$ cat /proc/cpuinfo | grep "model name" | sed -r 's/model name\s+\:\s+//g'
Intel(R) Core(TM)2 CPU         E8400  @ 3.00GHz
Intel(R) Core(TM)2 CPU         E8400  @ 3.00GHz


It's printed twice, because I have a dual core CPU and /proc/cpuinfo lists all those cpu details once for each cpu/core on the machine.

If you want only 1 result for the first cpu/core, use the 'head' command to get only the first line.

$ cat /proc/cpuinfo | grep "model name" | sed -r 's/model name\s+\:\s+//g' | head -n 1
Intel(R) Core(TM)2 CPU         E8400  @ 3.00GHz


- 'head' lets you print the first N lines of an input stream's text. '-n 1' denotes 'print only 1 line'. Similarly there is a 'tail' command which does the same as 'head', but counts from the end of the stream/text.

This may all be a little more info than you needed, but it will help you get anything you might want from your linux machines in the future.


This concludes our short (and probably pointless) lesson in Unix Shell Commands 101 :)


xlsior(Posted 2009) [#6]
...Or he can just open the file from within Blitzmax like any other textfile, and not have to depend on 3rd party additions. :-?


Jim Teeuwen(Posted 2009) [#7]
They are all part of the Unix core. No need for extra installs. Every unix OS hsa them installed by default. Saves him having to manually parse the file in blitz.

But sure, opening it in blitz works to :p


xlsior(Posted 2009) [#8]
I know they are standard, but there's little point in external scripts or processes to pull data that you can easily obtain directly from within your own program -- any additional external dependency is an additional point of failure, after all.


Brucey(Posted 2009) [#9]
I'd tend towards using cat ... too, but then I guess it depends where you're coming from :-p


SLotman(Posted 2009) [#10]
Thanks everybody for all the suggestions! After reading all that, I looked around on google (much better knowing what to look for) - and then I found a simple solution, which I think will work well:

dir=ReadDir("/dev/disk/by-uuid")

If Not dir RuntimeError "failed to read current directory"

Repeat
	t$=NextFile( dir )
	If t="" Exit
	If t="." Or t=".." Continue
	Print t	
Forever

CloseDir dir


This lists all uuids for all drives, so it should be pretty safe to use those id's, right?