随笔 - 11  文章 - 0  评论 - 14 

仿《雷霆战机》飞行射击手游开发--防破解

本文将介绍一个简单的防破解版的方法,希望能跟大家一起讨论学习。

 

    目前最常见也是最简单的单机游戏破解方法就是直接反编译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,则提醒用户并直接退出游戏。

 

本游戏正式开放源代码啦~~

代码库https://git.oschina.net/thorqq/RaidenFree

Win版试玩http://pan.baidu.com/s/1hsbrUug

posted on 2017-02-14 15:15  雁惊寒  阅读(569)  评论(2编辑  收藏