-3

I want to provide a binary-only program written in C or C++ where the user has to pass a valid code via command line to be able to use some extra features of the program itself. The idea is to implement some verification strategy in the program which compares the passed code against a run-time generated code which univocally identifies the system or hardware on which the program is being run.

In other words, if and only if the run-time check:

f(<sysinfo>) == <given code>

is true, then the user is allowed to use the extra features of the program. f is the function generating the code at run-time and sysinfo is an appropriate information identifying the current system/hardware (i.e. MAC address of the first ethernet card, Serial Number of the processor, etc..).

The aim is to make it as much difficult as possible for the user to guess or (guess the way to calculate) a valid code without knowing f and sysinfo a priori. More importantly, I want it to be difficult to re-implement f by analyzing the disassembled code of the program.

Assuming the above is a strong strategy, how could I implement f in C or C++ and what can I choose as its argument? Also what GCC compiler flags could I turn on to obfuscate f specifically? Note that, for example, things like MD5(MAC) or MD5(SHA(MAC)) would be too simple for evident reasons.

EDIT: Another interesting point is how to make it difficult for the user to attack the code directly by removing or bypassing the portion of the code doing the check.

Martin
  • 9,089
  • 11
  • 52
  • 87
  • You want asymmetric crypto. – SLaks Sep 08 '14 at 02:45
  • @SLaks can you elaborate? do you have a link to some resources? – Martin Sep 08 '14 at 02:46
  • 2
    possible duplicate of [How are Software License Keys generated?](http://stackoverflow.com/questions/3002067/how-are-software-license-keys-generated) – SLaks Sep 08 '14 at 02:47
  • 1
    So if the user changes the hardware configuration, e.g. by adding a new ethernet card, the software will stop working? My *solve-puzzles* and *build-systems-that-work* directives are in conflict... – Beta Sep 08 '14 at 02:50
  • suppose no eth card can be added, which is really true in my case. anyway it was just an example. – Martin Sep 08 '14 at 02:52
  • @SLaks my question is not a duplicate of the one you are suggesting because I am talking about offline verification rather online as in that question – Martin Sep 08 '14 at 03:00

1 Answers1

1

If you are on Windows, a standard strategy is to hash the value of the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\MachineGuid

If you're worried that a user might "guess" the hash function, take a standard SHA256 implementation and do something sneaky like change the algorithm initialization values (one of the two groups of these uses binary representations of the cube roots of the primes to initialize - change it to 5th or 7th or whatever roots, starting at the nth place, such that you chop off the "all-zero" parts, etc.)

But really if someone is going to take the time to RE your code, it's much easier to attack the branch in the code that does the if (codeValid) { allowExtraFeatures(); } then to mess with the hashes... so don't worry too much about it.

BadZen
  • 4,083
  • 2
  • 25
  • 48