Obfuscating Code

What are some best practices for “hiding” sensitive code?

I was quite surprised to find a key gen for my app. I’m pretty sure they didn’t reverse engineer the serial number algorithm but instead found the relevant code.

I include function names in the build because they are needed for crash reports. However, all code related to serial generation uses non obvious Class and Method names. I assume that variables, properties and comment names are not visible in built apps.

I assume my Achilles heal is somewhere in my app I have

If not ModuleThatMakeSerials.ValidSerial(SerialNumber) then // obviously named better MsgBox "This text should be easy to search for" End If

and someone can, with some tools that I don’t know about, step through the assembled code at key points and then extract it out with the appropriate life support equipment.

I usually don’t give them the right names, but more random character sequences for the name.

I don’t think there is a way you can prevent this, so after taking reasonable precautions, add a blacklist of usernames (obfuscated, of course) that brings up a stern warning about the cost of piracy. Mine does that, erased the “registration”, then takes the user to the web site to purchase.

Well, there is not a definitive solution. You can control some aspects of the problem, but not all.
For your particular problem (a keygen) you can make it harder to decode using the advice from Christian or Kem, and also not relegating a license validation to a method which simply returns a boolean (very easy to track with a debugger).

A better method to avoid a keygen is to adopt AquaticPrime. I did this in past exactly for this problem and therefore I started a Xojo/RS port of the AquaticPrime which then Thomas Tempelmann completed and updated and wrote a nice tutorial on his web site (http://www.tempel.org/UsingAquaticPrime). You can find the repository for AP here: https://github.com/bdrister/AquaticPrime

With AP, a license is tied to an email address or the user name or whatever personal data you want, so no more keygens (due to the complexity of breaking the AP algorithm and low chances to have some user which give away his license.
And you can still blacklist some licenses, if needed.

AquaticPrime is a good way to verify license codes. Just make sure you are encrypting/obfuscating/encoding the public key somehow. Otherwise a cracker can just sub in their own public key then sign a fake license with their own private key.

My tool Arbed can obfuscate all strings in Xojo projects right now, though I hope to also add method name obfuscation on day. When? Well, I’m like Xojo in this regard: I want to have it tomorrow but it’ll probably take one or two years :wink:

Not to spoil Arbed, which is a really nice tool that every Xojo developer should have, here it’s an IDE script which makes a very basic string obfuscation.

Just select the string to obfuscate in code editor and run the script.

  // simple string obfuscation
  dim selectedText as string
  dim obfuscatedText as string
  dim obfuscChar as string
  dim obfuscLineLen as integer
  dim selectionStart as integer
  dim currentCode as string
  dim ascValue as integer
  dim i, n as integer
  const MAX_LINE_LEN = 80
  if selLength > 0 then
    selectedText = selText
    selectionStart = selStart
    if selLength > 1 and left(selectedText, 1) = """" and right(selectedText, 1) = """" then
      selectedText = mid(selectedText, 2, len(selectedText) - 2)
    end if
    n = len(selectedText)
    for i = 1 to n
      if obfuscLineLen > MAX_LINE_LEN then
        obfuscLineLen = 0
        obfuscatedText = obfuscatedText + " _" + endOfLine
      end if
      if obfuscatedText <> "" then
        obfuscatedText = obfuscatedText + "+"
        obfuscLineLen = obfuscLineLen + 1
      end if
      ascValue = asc(mid(selectedText, i, 1))
      if ascValue < 128 then
        obfuscChar = "chr(" + str(ascValue) + ")"
        obfuscChar = "encodings.UTF8.chr(" + str(ascValue) + ")"
      end if
      obfuscLineLen = obfuscLineLen + len(obfuscChar)
      obfuscatedText = obfuscatedText + obfuscChar
    selText = obfuscatedText
    currentCode = Text
    i = selectionStart
    while i > -1
      if mid(currentCode, i, 1) = endOfLine then
        if mid(currentCode, i-1, 1) <> "_" then
        end if
      end if
      i = i -1
    currentCode = left(currentCode, i) _
    + "// obfuscated string = " + selectedText + endOfLine _
    + mid(currentCode, i+1)
    Text = currentCode
  end if

Encrypting strings really want help. Most crackers will run your program using a debugger, they will create a breakpoint
on the routine that asks for the registration info. They will then find the algorithm that verifies the information then
copy this code and create a key generator.

Good crackers understand assembly language very well, programs like OllyDbg do a real good job of giving them the code
which they can extract or just patch.

If your program is popular there is nothing you can do. All the big companies have tried, Microsoft, IBM, intel… all have been cracked
or have key generators.

Ultimately the point is to drive more revenue, not necessarily stop people who were never going to buy anyway.

I can see encrypting strings for API keys and whatnot. How would it help with a serial generator?

Looks like the best bet is, as George mentioned, to not have a single routine that returns a serial. Or, switch to Aquatic Prime.

And, as Phillip said, reasonable precautions should be taken but the focus should be on the product, not the protection.

I suggest reading an old article about this topic: http://tidbits.com/article/6752

Just adopt some fair protection to avoid casual piracy and sharing of licenses (which again feeds casual piracy).
And fon’t get wrong in thinking that all people using a pirated copy of your product would buy it if you protect it enough. Most of them would not buy it in any case.

Then stop thinking to this and invest your time enhancing your product, not the protection scheme.