Lima alat lagi melawan penipu pada proyek seluler dengan DAU 1 juta pengguna

Dahulu kala, kami harus mengubah sepenuhnya perlindungan penembak PvP yang populer. Hasilnya adalah sejumlah alat yang kami persiapkan dan rilis secara bersamaan untuk mencegah penipu melacak pembaruan secara bertahap. 





ยซยป โ€” , , โ€”  . , : 





  • .





  • Photon Plugin.





  • .





  • .





  • .





, .





, , .





โ„–6.

, ( Android) ( iOS), .





(iOS)

Jailbreak Cydia , . ( *.plist), .





/Library/MobileSubstrate/DynamicLibraries/ ( ).





, Jailbreak, , .





string finalPath = string.Empty;
string substratePath = "/Library/MobileSubstrate/DynamicLibraries/";

bool bySymlink = false;

if (!Directory.Exists(substratePath)) //    (  xCon),          
{
	string symlinkPath = CreateSymlimk(substratePath);

	if (!string.IsNullOrEmpty(symlinkPath))
	{
		bySymlink = true;
		finalPath = symlinkPath;
	}
}
else
{
	finalPath = substratePath;
}


bool detected = false;
string detectedFile = string.Empty;

try
{
	if (!string.IsNullOrEmpty(finalPath))
	{
		string[] plistFiles = Directory.GetFiles(finalPath, "*.plist"));

		foreach (var plistFile in plistFiles)
		{
			if (File.Exists(plistFile))
			{
				StreamReader file = File.OpenText(plistFile);
				string con = file.ReadToEnd();

				string bundle = "app_bundle"; 

				if (con.Contains(bundle))
				{
					detectedFile = plistFile;
					detected = true;
					break;
				}
			}
		}
	}
}
catch (Exception ex)
{
	Debug.LogError(ex.ToString());
}
      
      



, (KernBypass, A-Bypass). , .





, .





KernBypass ( ):





if (File.Exists("/var/mobile/Library/Preferences/jp.akusio.kernbypass.plist") 
{
	StreamReader file = File.OpenText("/var/mobile/Library/Preferences/jp.akusio.kernbypass.plist"); 
	string con = file.ReadToEnd();

	if (con.Contains("app_bundle") 
	{
		//detected
	}
}
      
      



(Android)

โ€” , , ( Parallel Space). , root-. : , Application Info .





, . โ€” (dataDir applicationInfo) access ( ). , , Persistent Data .





C:





JavaVM*		java_vm;

jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    
    java_vm = vm;
    return JNI_VERSION_1_6;
}

int CheckParentDirectoryAccess()
{
    JNIEnv* jni_env = 0;
    (*java_vm)->AttachCurrentThread(java_vm, &jni_env, NULL);

    jclass uClass = (*jni_env)->FindClass(jni_env, "com/unity3d/player/UnityPlayer");
    jfieldID activityID = (*jni_env)->GetStaticFieldID(jni_env, uClass, "currentActivity", "Landroid/app/Activity;");
    jobject obj_activity = (*jni_env)->GetStaticObjectField(jni_env, uClass, activityID);
    jclass classActivity = (*jni_env)->FindClass(jni_env, "android/app/Activity");
    
    jmethodID mID_func = (*jni_env)->GetMethodID(jni_env, classActivity,
                                                      "getPackageManager", "()Landroid/content/pm/PackageManager;");
    
    jobject pm = (*jni_env)->CallObjectMethod(jni_env, obj_activity, mID_func);
    
    jmethodID pmmID = (*jni_env)->GetMethodID(jni_env, classActivity,
                                                      "getPackageName", "()Ljava/lang/String;");
    
    jstring pName = (*jni_env)->CallObjectMethod(jni_env, obj_activity, pmmID);
    jclass pm_class = (*jni_env)->GetObjectClass(jni_env, pm);

    jmethodID mID_ai = (*jni_env)->GetMethodID(jni_env, pm_class, "getApplicationInfo","(Ljava/lang/String;I)Landroid/content/pm/ApplicationInfo;");

    jobject ai = (*jni_env)->CallObjectMethod(jni_env, pm, mID_ai, pName, 128);
    jclass ai_class = (*jni_env)->GetObjectClass(jni_env, ai);
    
    jfieldID nfieldID = (*jni_env)->GetFieldID(jni_env, ai_class,"dataDir","Ljava/lang/String;");
    jstring nDir = (*jni_env)->GetObjectField(jni_env, ai, nfieldID);
    
    const char *nDirStr = (*jni_env)->GetStringUTFChars(jni_env, nDir, 0);

    char parentDir[200];
    snprintf(parentDir, sizeof(parentDir), "%s/..", nDirStr);

    if (access(parentDir, W_OK) != 0)
    {
         return 1;
    }
	else
	{
		 return 0;
	}
}
      
      



apk (Android)

apk- , . , . 





, root-, . - , .





# Java-:





Lazy<byte[]> defaultResult = new Lazy<byte[]>(() => new byte[20]);

            if (Application.platform != RuntimePlatform.Android)
                return defaultResult.Value;

#if UNITY_ANDROID
var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");

	if (unityPlayer == null)
		throw new InvalidOperationException("unityPlayer == null");

	var _currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");

	if (_currentActivity == null)
		throw new InvalidOperationException("_currentActivity == null");


            var packageManager = _currentActivity.Call<AndroidJavaObject>("getPackageManager");
            if (packageManager == null)
                throw new InvalidOperationException("getPackageManager() == null");

            // http://developer.android.com/reference/android/content/pm/PackageManager.html#GET_SIGNATURES
            const int getSignaturesFlag = 64;
            var packageInfo = packageManager.Call<AndroidJavaObject>("getPackageInfo", PackageName, getSignaturesFlag);
            if (packageInfo == null)
                throw new InvalidOperationException("getPackageInfo() == null");

            var signatures = packageInfo.Get<AndroidJavaObject[]>("signatures");
            if (signatures == null)
                throw new InvalidOperationException("signatures() == null");

            using (var sha1 = new SHA1Managed())
            {
                var hashes = signatures.Select(s => s.Call<byte[]>("toByteArray"))
                    .Where(s => s != null)
                    .Select<byte[], byte[]>(sha1.ComputeHash);

                var result = hashes.FirstOrDefault() ?? defaultResult.Value;
                return result;
            }
#else
            return defaultResult.Value;
#endif
      
      



โ„–7. Photon Plugin

Photon Cloud, . .





Photon Server , , . , Photon, Photon Plugin.





Photon Plugin Enterprise Cloud #. Photon , , : 













  • ;





  • http- .





, , (, , , , ), , .





, . .





โ„–8.

. , . .





:





  1. . .





  2. . .





, (, Android โ€” id ). 





/ . (, ) .





, , . , .





โ€” , , . .





id โ€” , . , , id .





, .









โ„–9.  

, , (, GameGuardian Android). . , , , .





ยซยป :





 internal int Value
{
	get { return _salt ^ _saltedValue; }
	set { _saltedValue = _salt ^ value; }
}
      
      



, . . , 0 1000 ( , , ).





private static int[] refNumbers;

internal static void Start()
{
	refNumbers = new int[1000];

	for (int i = 0; i < refNumbers.Length; i++) 
	{
		refNumbers[i] = i;
	}
}

internal static bool Check()
{
	for (int i = 0; i < 1000; i++) 
	{
		if (!refNumbers [i].Equals(i))
			return true;
	}
}
      
      



โ„–10.

devtodev Flurry. . .





. Data-Driven . ., , . , 500 - , 500 , โ€” . , , .





SQL- . ( , ), . , , - , 0. , - . . , , , - id . โ€” .





. , . 9999 โ€” , - . . , , 15 30, , , , . , . id , , , 1000 , โ€” . .





, , . , .





, . , , , . .





, . ยซ ยป , .





, , . , . .









โ€” . , .





, , .





. , .








All Articles