Page 1 of 1

File Checksum Generator

Posted: Fri Jan 25, 2008 4:23 am
by localmotion34
After spending the better part of a year learning to reverse engineer, and unpack every major version of Armadillo and ASprotect, I am putting forth more knowledge of Anti-crack solutions. This is an IN-DEPTH solution that requires some thinking.

Your software WILL BE UNPACKED, even EXEcryptor users. Even if you use Armadillo custom builds, yes I have easily unpacked those too. The key is to outsmart the cracker in other ways. I have already posted about double subclassing, and procedure arrays, and my next part is regarding file checksums and hashes. My example uses JCV's hashlib, so proper credit goes to him for that.

If youe EXE/DLL are modified, the hash will change no matter what. Even inline patching changes the checksum. The point here i am trying to make is that using MULTIPLE types of checksums in MULTIPLE ways can be an extremely useful tool. "File Checksum Generator" takes whatever EXE/DLL files you ask it to, and generates 12 DIFFERENT types of hashes for EACH file. It then exports ALL those hashes FOR EACH FILE into an INI file, that can even be encrypted itself. It also will calculate the HEX CHECKSUM of each string hash (see below) as an additional method of protection.

Here's how it works:
1) Completely compile your program
2) Add the complied files to File Checksum Generator
3) generate 12 different checksums
4) Encrypt the filename and each hash with a password
5) export that data to a file

6) Now, from your program, you can read the INI file hash checksums, AT ANY POINT IN TIME and then compare them against a checksum that your program generates itself.

So you have SomeDLL.dll that has your registration check in it. Its pre-determined MD5 hash is 12345678901234567890123456789012. HOWEVER, your EXE file returns a DIFFERENT checksum. FLAGGED!. But you still have 11 more checks you can perform AT ANY PLACE IN YOUR CODE. If one is patched, then there are 11 more to find and patch as well.

This solution basically does the gruntwork FOR you, and gives you the option of calculating and/or storing your checksums. One possibility it to use a a data file for all your strings in your EXE, which are encrypted with the MD5 of your EXE itself. You could check the MD5 of your exe, and then use the returned result to decrypt all your window/button texts. If the MD5 is altered, then your program will be GARBAGE.

This solution is a great way to introduce hidden timebombs and integrity checks into your code. For every EXE/DLL you have, this gives you 12 hashes to use in any manner you choose. Im posting the source so you can modify the output of the hash data to suit your needs. You could even make this append the hash data to a DLL, use stenography to hide it into a bitmap or JPEG, or whatever.

For the "Sum" of the hash checksum, this is another way to verify that the file hash is correct without even comparing the two strings. Basically, you add the hex values of EACH hash character to get a final total. If 2 hashes are the same, then their sum character totals will be as well. Now, the same total can be reached by many hashes, but the possibility that will happen for 12 different hashes of a single file is about 1:trillion.

Code: Select all

Procedure SumChecksum(String.s) ;This is designed to sum all the Hex values of a character string into one final number
  For a=1 To Len(String); go through ALL characters of the string
    character.s=Mid(String,a,1); get a character
    Char=PeekC(@character) ;current character Hex value from calculated serial
    CharValue=CharValue+Char  ; add them together
  Next 
  ProcedureReturn CharValue ;return the TOTAL character Hex sum
EndProcedure 
THE MAIN POINT is that the more you cloak your integrity checks, and the more you use, the possibility of cracking your program CORRECTLY decreases dramatically. THIS IS A TOOL, which can be used by you in any way you see fit. I will post an example shortly of the full power of this method. For now here is the EXE, the source, 2 INI files, and a screenshot.


http://www.penguinbyte.com/apps/pbwebst ... 1/FCSV.zip

Posted: Fri Jan 25, 2008 6:31 am
by pdwyer
Why stop at 12?

Why not try to find a way to dynamically generate these so you can do 1000 or some developer specified amount?

Alternatively why not stop at 5? If the hash is good enough, are you improving much by having 2? We're certainly talking about numbers higher than 1 trillion. I'm assuming that you are wanting to put this all through the code as each place will be somewhere that needs to be patched so that it returns OK rather than NG at each check. But I can't see how 11 more hashes helps this. One hash can be hard enough to fool that it will be easier to patch the code around it rather than fool it.

I very much agree with the first sentence in your last paragraph. So much do I think that it's more important that I fail to understand the 12 hashes

The key problem that this still doesn't address though is that if it's broken once it's broken everywhere. The same problem that DVDs etc have (had).

Posted: Fri Jan 25, 2008 7:18 am
by localmotion34
I think if you combine this with double subclassing for some important gadgets (buttons that save ect.), procedure arrays (multiple procedures that do the same thing with their addresses stored in an array), and multi-part serials (i have posted this before), an app will be nearly impossible to crack CORRECTLY without major, major work.

Add in using DLLs loaded from memory (PBOSL), cross verifying EXE and DLL integrity both ways, and it might take weeks for a cracker to find all the possible permutations of checks.

Crackers dont usually fully check a program for FULL functionality. I guess my main point is to have a nice serial routine, which can be keygenned, and give the "good boy" message.

Then using multi-part serials where the second and third parts of the serial arent checked until a week later. Say when a user clicks a menu item. If CORE keygens your app relying only on the "goodboy" message, they arent going to use it for a week before they release their keygen. A TRUE PAYING CUSTOMER would get a FULL serial, which the second and third parts could be checked a week after registration.

A user that keygens your serial will know NOTHING of the second and third parts, so a week later when you check to see if they are there, BOOM. Now you have him. Once you verify the 2nd and 3rd serial parts are missing, just change the callback for a particular gadget to do something completely nonsensical. He's been using your program a week thinking he got it free, and then all of the sudden, weird things start happening.

He then may try and patch it (if he knows cracking), and now you have procedural arrays with 25-100 possible permutations of checking. You also have the file hash routines too. So now that he has patched away, the hashes will catch him, and THEN he discovers he has YET EVEN MORE to patch.

If you are good, then once you have detected a stolen serial or patch, all you have to do is set the window procedure of the "Register" button to the address of a procedure that ALWAYS says "Thank you, your serial has been accepted".

This hash idea is part of a larger package that i am trying to get across.

Posted: Fri Jan 25, 2008 10:41 am
by PB
> [crackers] arent going to use it for a week before they release their keygen

Time delays before warnings are a good idea. "King's Quest V" did that.
You played about a third of the game (don't know how many hours or
days that was in those days) and THEN had to enter something from the
manual to continue. So crackers wouldn't know there was a check coming
unless they played the game for days first. :)

Posted: Sat Jan 26, 2008 2:52 pm
by superadnim
Yes, but ultimately even if you put 200 checks, if they are all the same - once you detect one in the assembly dump, you can pretty much replace them all afterwards...

That's why I think the checks should all be different, it doesn't matter how or when they are performed.. if all your checks are equal... then you've got a problem.

Also, I don't think that tampering with the application's functionality is a good idea, in case a bad serial was entered afterwards, because it might give a bad impression of your application, the actual illegal user might even talk crap about your program because it's not working as it was supposed to. (of course, you can tell your paid customers this is a known behavior for an illegal copy, but then - they'll know about the system and there you are... back to square 1).

Posted: Sat Jan 26, 2008 3:08 pm
by PB
> illegal user might even talk crap about your program because it's not
> working as it was supposed to

Unlikely. They know they're trying to use a bad serial, so they know anything
not working is a result of their illegal activity. And legit users know it works,
so they're going to defend it if the illegal user trashes it. I see it all the time.

Posted: Sat Jan 26, 2008 3:14 pm
by superadnim
How exactly?, I'm just saying, what if they don't know this is a normal behavior for a non legit user?... sure if your user base is big enough they might all agree in that it's either this guy's system or something else, because it works just fine on everyone else's system... however, if you don't have a community where people congregate to discuss this sort of things regarding your application/s, then what? - 10 illegal users get together and start writing crap about your tools, then you must go public about how this is a protection scheme, etc... Right there you opened a door to the crackers! (now they know what doesn't work on what situation, they can track this down... unless its 100% "random")

Posted: Sat Jan 26, 2008 3:23 pm
by PB
Well the first thing you do is when prompting for the serial, is have a message
stating for the user to enter it carefully as a wrong serial can cause the app to
malfunction. This lets both parties (legit and illegal) know that the app works
fine with a correct serial. So, no problem.

As for defending the app against cracker's badmouthing: I see posts all the
time on Usenet where they say "this app is crap" and others reply along the
lines of "buy a legit copy then" etc. The public are smart enough to know.
If the cracker just badmouths it to other crackers, and not to the public,
then so what? It'll just stop crackers from being interested in it, which is
a good thing! :)

[Edit] Also: if your app has a demo mode, then the people will know it does
work and what the expected behaviour is; so if they enter a bad serial later,
and the behaviour changes, they know why -- because they're pirates.

Posted: Sun Jan 27, 2008 11:00 am
by DoubleDutch
My "experimental" system has 2 checksums in the multipart "voucher" code:

The first checksum just makes sure it's a good key, if it is then it passes the key to my online system for verification.

If the online system says it's a bad key then the IP address of the user is then blocked for 48 hours (if it's been in the blocked list before then it goes up to 1 week).

The algorithm for the 2nd check is NOT in the program - it's online. The first checksum is just to make sure that any lame hacks don't even get to the server.

Then as you say, you can use patch checks in the main program, multiple times, all over.