仿《雷霆战机》飞行射击手游开发--防破解
本文将介绍一个简单的防破解版的方法,希望能跟大家一起讨论学习。
目前最常见也是最简单的单机游戏破解方法就是直接反编译apk,然后寻找三大运营商的计费函数调用代码,然后粗暴的将支付结果强制改为成功,然后用破解者自己的keystore打包发布。下面我们要介绍的防破解方法,就是检查keystore是否被更换,一旦发现更换,就直接退出游戏。
1、执行命令keytool -list -v -keystore thorqq.keystore , 其中thorqq.keystore改成你的秘钥库文件名。
将执行结果中MD5后面的一长串字符串去掉冒号并改为小写后保存下来(在这里是:3f8e70eea5bedb593525623c0c47822f)。
2、在android工程中新建MyApplication.java,增加如下代码获取apk包签名的md5值。
private static String FingerprintMd5 = ""; public static String getFingerprintMd5() { return FingerprintMd5; } public Signature[] getRawSignature(Context context) { PackageManager pkgMgr = context.getPackageManager(); PackageInfo info = null; try { info = pkgMgr.getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES); } catch (PackageManager.NameNotFoundException e) { return null; } if (info == null) { return null; } return info.signatures; } private static String FingerprintMd5 = ""; public String stringToMD5(byte[] string) { byte[] hash; try { hash = MessageDigest.getInstance("MD5").digest(string); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return ""; } catch (Exception e) { e.printStackTrace(); return ""; } StringBuilder hex = new StringBuilder(hash.length * 2); for (byte b : hash) { if ((b & 0xFF) < 0x10) hex.append("0"); hex.append(Integer.toHexString(b & 0xFF)); } return FingerprintMd5 = hex.toString(); }
@Override public void onCreate() { //MD5 fingerprint stringToMD5(getRawSignature(this)[0].toByteArray()); super.onCreate(); }
3、在cpp工程中增加检查指纹的函数,比较从java中获取的md5值与我们自己的md5是否一致,如果不一致,则认为指纹错误,返回false
bool checkFingerprint() { //check fingerprint JniMethodInfo minfo; bool isHave = JniHelper::getStaticMethodInfo(minfo, "org/cocos2dx/cpp/MyApplication", "getFingerprintMd5", "()Ljava/lang/String;"); //没有在java中找到getFingerprintMd5这个函数 if (!isHave) { return false; } else { //调用getFingerprintMd5 jstring jstr = (jstring)minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID); std::string ret = JniHelper::jstring2string(jstr); Analytics::getInstance()->event(AnalyticsEvent::FingerPrint, ret.c_str()); GameData::getInstance()->setValue(GAMEDATA::FINGER_PRINT, ret); //这里就是上面我们在keytool命令后保存的md5指纹。为增加破解难度,这里最好要对字符串进行加密处理 std::string a = "3f8e70eea5bedb593525623c0c47822f"; //判断指纹是否一致 if (a != ret) { return false; } }
return true; }
4、在上层业务逻辑中调用checkFingerprint(),如果返回false,则提醒用户并直接退出游戏。
本游戏正式开放源代码啦~~