I’m wondering whether this method would work (I don’t know the specifics of md5 hashes):
1: in code, have a constant defined with only zeroes (length would be equal to a md5 hash’s length)
2: have a mechanism to write the md5 hash to StdOut (or whatever way to show it)
3: build the app and run it. Now, you can know its md5 hash.
4: go back to code and replace the constant with the known hash. Since both are of the same size, the checksum should not differ.
5: build the app again.
had that idea, too. I mean, a copy of the main binary executable file to further compare. Then I have developed my solution which is kind of “self-signing executable file” approach. Removing encoded SQLite database file prevents application from start. Altering main executable binary or encoded SQLite database - has the same effect. The only real solution is to disassemble the executable and alter the code which is not trivial if you use smart obfuscating of strings etc. Further than this, you can move whole “check integrity” thing in other place of program run instead of opening, to make false assumption that altered version really works.
replace Quit and other things with NOP
If finding app.quit is easy, then setting app.AllowAutoQuit=true and then closing all the window in the loop will do the trick the same and will be harder to find…
Instead of using the whole app and doing a binary compare, read the app as a series of chunks, let’s say 32k each. Create a 32-bit checksum for each chunk, chain the checksums into a binary file and distribute that with the app, it will be significantly smaller and not obvious what it is.
Just to raise the bar against the hex-editor types, you could also XOR the checksums against a UUID extracted from the machine hardware mashed with the installed date and time, and the users email address, so its then unique and effectively locked to their CPU.
You could also incorporate this into a licencing mechanism whereby the app creates the .dat when first run, and they have to send you the .dat to obtain a licence key that unlocks the full functionality (and in the process you have captured their email).
Throughout the app check that it hasn’t been edited and is licensed, otherwise set app.AllowAutoQuit=true.
The other trick from long ago was to allow limited use of the app in various ways (enough for say “Try before Buy”) but cripple any way to save data or open files. You could even make it look like it did save/read the file, but encoding the data in some way with a corrupt key resulting in gibberish or even crashing the app when they try to read the file.
Rather than going the distance of that complex routine, I would suggesting doing executable signature and rely on authenticode on windows(and whatever code signing macos supports, i don’t have much experience ther). If the signature is off with the user doing gross tinkering with the code, windows and macos will flag the file as non-conforming, possibly blocking execution.
it was paint mixing application written for Raspberry Pi and electronic scale
the end user doesn’t have to bear with any licence etc.
the paint manufacturer delivers (apart from paints) Raspberry Pi with preloaded software and electronic scale - burden free for use
someone else selling the same products (under different brand name) just took the software, replaced graphics, changed texts in software and start offering this to his customers
So, since it was an app for Pi, what sandboxing, what signing etc… that’s why I had to find a solution not basing on signing of application.
Little chance there is a hacker reading this thread and now he knows about our tricks to avoid unauthorized changes after compiling.
My way is to have all resources, graphics, all texts, configuration etc, embedded in one encrypted sqlite_db, including a set of keys, and check the file md5 and the keys several times. Advantage of this is that you can distribute multilingual, different graphics per branche, different menu-configurations etc. Well, this is just my way and I have some classes and selfmade tools to accomplish this quick and easy in a new application.
I would like to point out that anyone that has the skills to modify your app and re-sign it will probably also have the ability to bypass the code that runs the authenticode verifications, so this may not be the overall win you think it is.
A minimum level of security is appropriate. So extra checking for code signing is certainly helpful.
If you don’t agree with this, I suggest you throw out Xojo’s security as well (including checking for the license key). Because according to your reasoning, that is redundant anyway.