[Android Apps and Games] scary alien:
Very nice obfuscation idea, appelflap.

I decided to try to implement something like this in one of my apps, but added a little twist on this same idea.

Since my app, AFV (free in the Market, btw), is at heart, a checksum app, I figured, why not add a checksum component to this validation check?

Here's what I ended-up doing:

protected String [COLOR="Blue"]calculate_string_checksum[/COLOR] ( String source_string, String algorithm )
{
MessageDigest md = null; // initialize
StringBuffer sb = new StringBuffer("");

try
{ // prepare the MessageDigest function
md = MessageDigest.getInstance(algorithm); // tell the function which algorithm we will be using
}
catch (NoSuchAlgorithmException e)
{
return "error: init MessageDigest (" + e + "); unknown digest type (" + algorithm + ")";
}

md.update(source_string.getBytes(), 0, source_string.length()); // calculate the checksum / digest
byte[] mdbytes = md.digest(); // convert the checksum to a byte array

// express checksum in hex
//
for (int i = 0; i < mdbytes.length; i++)
{
sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
}

return sb.toString(); // return the calculated checksum
}

private void [COLOR="Blue"]validity_check[/COLOR] ()
{
String s1 = "s"; // simple package name obfuscation
String s2 = "a";
String s3 = ".";
String s4 = "a";
String s5 = "f";
String s6 = "v";

String developer_email = "<your email address goes here>"; // feel free to obfuscate this string too

String digest1 = "acd858d735"; // simple digest obfuscation
String digest2 = "0840011d1d";
String digest3 = "4170034753";
String digest4 = "9d66034a26";

String validdigest = digest1 + digest2 + digest3 + digest4; // re-assemble for subsequent comparison

String myPackageName1 = getPackageName(); // who do I think I am?
String myPackageName2 = s1 + s2 + s3 + s4 + s5 + s6; // who am I really?

// lots of choices of digest algorithms available:
// MD5, SHA1, SHA224, SHA256, SHA384, SHA512
//
String mypn1_checksum = calculate_string_checksum (myPackageName1, "SHA1");
String mypn2_checksum = calculate_string_checksum (myPackageName2, "SHA1");

Log.i(TAG, "validity_check(): myPackageName1 = " + myPackageName1);
Log.i(TAG, "validity_check(): myPackageName2 = " + myPackageName2);
Log.i(TAG, "validity_check(): mypn1_checksum = " + mypn1_checksum);
Log.i(TAG, "validity_check(): mypn2_checksum = " + mypn2_checksum);
Log.i(TAG, "validity_check(): validdigest = " + validdigest);

if ( myPackageName1.equals(myPackageName2) &&
mypn1_checksum.equals(mypn2_checksum) &&
mypn1_checksum.equals(validdigest) )
{
// display_popup_message (" *** Info ***",
// "I have determined that this is a valid copy of my app. Thank you for using it!",
// "Continue");
}
else
display_popup_message ("*** Warning ***",
"It appears that this app has been tampered with and is not genuine.\n\n" +
"Please contact me, the developer, at\n\n" + developer_email +
"\n\nfor additional information." , "Continue");
}

private void [COLOR="Blue"]display_popup_message[/COLOR] (String w_title, String w_msg, String w_button)
{
AlertDialog.Builder alert1 = new AlertDialog.Builder(this);
alert1.setTitle(w_title);
alert1.setCancelable(false);
alert1.setMessage(w_msg);
alert1.setPositiveButton(w_button, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) { } });
alert1.show(); // display the alertdialog pop-up
}

Then, you can simply make a call to validity_check (); in the onCreate() function. You could also get a little trickier than what I showed about in obfuscating the comparison strings (i.e., define them out of order, partially, split and re-order the calculated checksum against a re-ordered comparison string, etc.)...I'll leave these details up to your personal choice.

Note: if you use the SHA512 algorithm, its a very long checksum / digest.

Hope this helps (and maybe this'll slow the crooks down a little bit ;), eh?).

Cheers!