How to protect integrity of your application

Not so long ago one of my programs was modified in an unauthorized way - images were replaced and some texts in the program were replaced using a HEX editor. In effect, it was supposed to look like a program written for someone other than the original client. There are also other reasons to be unhappy with replacing texts with a HEX editor, such as SQL Injection.

An idea came to my mind in which the program would check its own MD5 checksum at the start, which would also be the key to opening the encoded SQLite database. In the absence of this database or in the case of failed connection of the encrypted database - the program would end its work with a message about a security breach.

The code below should (after being modified) be placed in app.Opening. The scenario is this:

  • build the program and run it (not in debug mode)

  • the program starts and calculates the MD5 checksum for itself

  • checks if there is a database file “security.rds” (any name, of course) in the same folder

  • if not, it checks if there is a file named “TriggerEncode.txt” in the same directory (any name, of course)

  • if present - the SQLite database “security.rds” is created, coded and closed. The program displays a success message and exits.

  • if there is no “TriggerEncode.txt” file - The program displays an error message and exits.

When everything went smoothly, we remove the “TriggerEncode.txt” file from the directory and now we have a ready product that takes care of its integrity.

Of course, the file name “TriggerEncode.txt” is an example and you should use your own - of course in an obfuscated version. NOT IN PLAIN TEXT :smiley: The same goes to some additional text glued to MD5.value.

#If not DebugBuild then
  var md5string as String
  var db as new SQLiteDatabase
  var dbf as new FolderItem
  
  var f As FolderItem
  f=GetFolderItem(App.ExecutableFile.NativePath,FolderItem.PathTypeAbsolute) 
  
  //below old piece of code from Kem Tekinay
  dim mdfive as new MD5Digest
  dim bs as BinaryStream = BinaryStream.Open( f )
  while not bs.EOF
    dim chunk as string = bs.Read( 1000000 )
    mdfive.Process chunk
  wend
  // Tim Tekinay
  
  md5string = EncodeHex( mdfive.Value )+"something more..." //just to avoid it being barebone md5.value in hex, obfuscate this
  
  dbf=dbf.Child("security.rsd")
  
  if not dbf.Exists then
    var dbtrigger as new FolderItem
    dbtrigger=dbtrigger.Child("TriggerEncode.txt") //obviously, obsfuscate this string in your project
    
    if dbtrigger.Exists then
      db.DatabaseFile=dbf
      call db.CreateDatabaseFile
      if db.Connect then
        db.ExecuteSQL("create table TestDB (test TEXT)") //just something to fill database file
        db.Encrypt(md5string)
        db.Close
        MessageBox "Security set up... will quit now."
        Quit
      else
        MessageBox "Something wrong... will quit now."
        Quit
      end if
    else
      MessageBox "Cannot open security.rsd database... will quit now."
      Quit
    end if
  else
    db.DatabaseFile=dbf
    db.EncryptionKey=md5string
    if not db.Connect then
      MessageBox "Security breach... will quit now."
      Quit
    else
      db.Close
    end if
  end if
#EndIf
1 Like

For macOS, just codesign the app and do a code sign verification inside your code (at random).
If the code singing it broken (or re-codesigned with another account) you can trigger protection stuff.
For Windows, you can check the MD5 of the.exe file and see if it is still the same when you distributed it.

1 Like

in my case it was Raspberry Pi app. In case of checking MD5 and comparing - how it may prevent someone from altering my app?

It will not prevent it (nothing can prevent it).
But if you can detect the app has been tapered with, you could trigger for example a timer that does all sort of (less) funny stuff.

I knew a music app that when cracked would play random 10 seconds high-pitch noises :laughing:

1 Like

You guys are missing the point - an application can generate MD5 check sum of itself but then to compare it - with WHAT? Code signed application can chevk integrity on MacOS but what about unsigned apps for any platform?

1 Like

if you create a new app (or it got changed) the md5 change and the database is invalid?

if someone would hack he would try
md5string = “” 'EncodeHex
if 1=0
if 1=1
replace Quit and other things with NOP

yes, md5 will change with every build. of course, disassembling and replacing whole part of code with NOP will do… but it is kind of higher lever approach, don’t you think? Someone smart who knows where to put NOP’s will handle any form of protection :wink:

any motivated enough hacker (with enough time) will handle any form of protection.
the idea is to random things by quitting somewhere in the app, at many random points
this can discourage them.

in my case it hardly was a “hacker” - just a guy with HEX editor…

So… create a JSON file that lists all of your image files and their md5 hashes, sign that file. Put the public key and the signature in your app using methods with chrb calls:

Chrb(45) + chrb(23) etc…

Sometime after launch (maybe a timer with a random period assigned to it) you load the file and check its signature. Once the file is loaded, periodically check the hashes of the images. I wouldn’t do them all at once as the hashing will take a non-zero amount of time to do, but you could probably do 1-5 at a time depending on sizes.

You might also want to use several layers of delegates so the method call stack isn’t the same every time.

I also suggest making the names of the methods unobvious and possibly cryptic so crash logs won’t give away what the app was doing at any given time. For instance, you could call the method MenuHandler, but shouldn’t call it CheckImageHashes.

Like any security system, the reality is that you’re not going to stop the most determined people, usually in high school or college, and usually with lots of time on their hands. The name of the game here is deterrence. If you can make hacking your app very time consuming, they may just seek out an easier target.

4 Likes

all good points!

I would calculate whatever hash you like in the build script after building.
e.g. a hash for the picture files or on Windows the exe file hash.

Please note that code signing on macOS changes the binary file of the app.
Then you may include those hashes as a file within the bundle.

then at runtime compare the hashes in that file to the hashes you have in the data file.

…so my solution is probably resistant to file signing - it takes into account the MD5 from the moment the program starts, after code signing.

Do this for Windows apps:

  • Compile the app
  • Codesign it (if needed)
  • Get the MD5 value of the .exe file
  • Put that MD5 value in a .ini file (or whatever).
  • When launching the app, read the MD5 value and test.

For macOS, as I already explained, check the codesign integrity. (declares are needed). You cannot check MD5 values for macOS apps for several reasons.

…and MD5 value will be readable / editable in .ini file. that’s why I wanted to avoid it - hence encoded database (database password vs editable .ini file).

True but you could hide it (cleverly).

Anyhow, if you need an uncrackable app, let me know if you found a way to do so. Spoiler alert … there isn’t a way.

You can just rule out bad or mediocre hackers at best.

That said, for macOS, code signing (and checking it) is a pretty good protection.

OK guys, anyway, I shared my approach :slight_smile: maybe someone will benefit from it.

1 Like

Just a question:
I always thought that for Linux, all users expect everything for free. Making and selling software for Linux is not really commercially interesting. Didn’t know there was also cracking involved. :slight_smile:

That’s what I was always told anyway.

I think your idea is good and you shouldn’t get discouraged by some of the responses. If you implement your approach, at the bare minimum the less enthusiastic hackers will give up and move to the app of one of the other posters that feel it’s useless to provide any sort of protection. So, there’s that…