Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Anti-Cheat Toolkit: stop cheaters easily!

Discussion in 'Assets and Asset Store' started by codestage, Aug 20, 2013.

  1. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, @Cybertiger.
    It looks not normal, it shouldn't take up so much memory. I'll try to repeat it on my Mac OS vistual machine and will get back to you with investigation results or with reproducable case request (in case I'll not be able to reproduce it myself).
    Thanks for your report!
     
  2. Cybertiger

    Cybertiger

    Joined:
    Dec 19, 2013
    Posts:
    35
    I have investigated it a bit further. It didn't happen with a new empty project.
    Then i noticed that this memory problem only happens with prefabs.
    My Gamemanager is a prefab and has a couple of Obscured Variables on it.

    Here are my test results:
    If i add Obscured variables on a non prefab gamemanager class the memory problem doesn't happen.
    If i add Obscured variables on a prefab gamemanager class which has changed from it's origin the memory problem happens again.
    If i add Obscured variables on a FRESH prefab gamemanager class the memory problem doesn't happen.

    I can work around this for now.
    I hope this helps your investigation. I feel like it might be a Unity bug after all.

    Many thanks for your great support.
     
  3. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Oh, it became even more weird, thanks for your addition, it'll help for sure.
    I'm still not sure this bug on my side or Unity side. I'll continue investigation and will report results here.
     
  4. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey again, @Cybertiger!
    I did tried to repeat your case, but with no luck.
    Could you please describe few more details?
    - where do you measure memory usage (in profiler or in any other external tool)?
    - whan exactly do you see the memory usage increase, in Play mode, in Edit mode, after prefab instantiation or at any other point?

    Thanks in advance.
    P.S. Thanks to your report I noticed modified Obscured vars in prefabs are not marked bold, it will be fixed in further updates (added to the TODO).
     
  5. Cybertiger

    Cybertiger

    Joined:
    Dec 19, 2013
    Posts:
    35
    Hi Dmitriy,
    I am measuring the memory usage with the activity monitor on Mac OSX. You can see a clear spike when i select the gameManager with the obscured variables. And sometimes Unity crashes with a "Memory exception".
    I see the memory increase when i am in edit mode and select a modified prefab object.

    Many thanks for your effort.
     
  6. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, @Cybertiger!
    Thanks for your detailed explanation.
    I just tried to reproduce it on both Windows 8.1 using Unity 4.5.5 and Mac OS X 10.9.5 using Unity 4.5.4 with no luck.
    It really seems like a Unity bug, but would be great to have a look at your project (support email should be mentioned in plugin's readme.pdf) and get a bit more information about your environment (OS X version, Unity version) before making this conclusion absolute.
     
  7. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, guys!
    I'm glad to let you know about recent tiny update:

    Anti-Cheat Toolkit 1.3.3
    – Flash Player support deprecated, lot of ugly code removed
    – Unity 5 fully supported
    – plugin project updated to the Unity 4.5 (still can work in earlier Unity versions with few restrictions)
    – obscured fields are now bold in inspector if values changed in prefab instance (mimics regular behavior)
    – minor refactorings
    – some fixes and additions in the readme

    I also wish to let you know I have huge TODO list and I'm going to move over it further, lot of great things ahead (some of them are already in research / prototype state)!

    Grab latest version at the Asset Store, as usual: http://u3d.as/59N
     
  8. Keitaro3660

    Keitaro3660

    Joined:
    May 20, 2014
    Posts:
    86
    hello, i just watched the video overview. looks cool!
    but my problem is, i think 90% of my variable i created is by using Playmaker Global Variable, and not using C# script....
    and for playerpref, i also use playmaker playerprefs action.
    so can i still use this asset?
     
  9. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
  10. Keitaro3660

    Keitaro3660

    Joined:
    May 20, 2014
    Posts:
    86
    cool, looks like i'll need this asset :D
    i'll buy it now, and please add more tutorial in next update especially the one that support playmaker :D
    thank youuuuu
     
  11. RoTru

    RoTru

    Joined:
    Jun 5, 2014
    Posts:
    37
    Nice I'm in the middle of developing a photon based network game using Playmaker, if you could also check obsfucation on photon networked synced variables on instantiated objects that'd be awesome!!

    hopefully using arraymaker also wouldn't break it
     
    Last edited: Oct 29, 2014
  12. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, @RoTru!
    Added this to the TODO, thanks.
     
  13. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    What is the proper upgrade procedure from an older version to the newest one?
     
  14. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, @TokyoDan!
    I'd recommend completely remove previous version and import new version after that.
     
  15. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    Thanks. I just did that now I'm getting lots of errors from ActOptions.cs. The 1st one is:
    Assets/CodeStage/AntiCheatToolkit/Editor/Scripts/Windows/ActOptions.cs(32,45): error CS1502: The best overloaded method match for `UnityEditor.EditorPrefs.SetBool(string, bool)' has some invalid arguments
     
  16. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Oh, it looks weird. Could you please share your Unity version number and your OS name and version number as well?
    Also, are you sure you completely removed CodeStage/AntiCheatToolkit folder before upgrade?
     
  17. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    Unity 4.5.5. Building to Web, and yes I completely removed everything. I'll give it another try and also change my build platform to Mac.
     
  18. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Thanks. Still weird enough =(
    Could you please share your project or any other repeatable case to let me check it out?
     
  19. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    That fixed it. I don't know what happened. I can even change the build back to Web and it is OK. Sorry for the scare. (But it is Halloween here in Tokyo. hahaha).
     
  20. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    Thanks for your help.
     
  21. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Boo! =D Haha, thanks for letting me know it's gone now. Please, feel free to scare me again next time you'll encounter this issue!
     
  22. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    I got a stupid question... Is it possible to mix ObscuredPrefs and PlayerPrefs in the game project?

    I have some preferences that need to be encrypted and other preference that don't need to be encrypted.

    So when I need encryption I do:
    ObscuredPrefs.SetInt(aKey, anInt);
    ObscuredPrefs.Save();

    And when I don't need encryption I do:
    PlayerPrefs.SetInt(aKey, anInt);
    PlayerPrefs.Save();

    Is it OK to max and match like this?
     
  23. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, @TokyoDan!
    Yes, it is absolutely OK and should work fine.
     
  24. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    Then I have one more question. If I am mixing ObscuredPrefs and PlayerPrefs, then what is the difference between ObscuredPrefs.DeleteAll() and PlayerPrefs.DeleteAll() ?

    Do I need to do something like this:

    if (UsingEncryptedPrefs){
    ObscuredPrefs.DeleteAll();
    } else {
    PlayerPrefs.DeleteAll();
    }

    Will ObscuredPrefs.DeleteAll() delete just the encrypted ones and leave the non-encrypted ones untouched (and visa versa) ?

    Or will both ObscuredPrefs.DeleteAll() and PlayerPrefs.DeleteAll() delete all prefs settings no matter if they are encrypted or not?
     
  25. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
  26. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    Great. So to confirm...

    If I want to get rid of my mixed PlayerPrefs file all I need to do is call PlayerPrefs.DeleteAll() and there is no need to ever use ObscuredPrefs.DeleteAll().
     
  27. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Yes, this is correct.
     
  28. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey guys, while I'm working on next update, I did small research about JSON serialization of the Obscured variables.
    As you may already knew, all obscured variables are possible to serialize using BinaryFormatter as-is. But you also may use other serialization techniques using ISerializable implementation in your serializable class. It allows you easily control how to serialize obscured variable (either in obscured or unobscured form). Let me show you an example.
    This is how your serializable class could look like:

    Code (CSharp):
    1. using System;
    2. using System.Runtime.Serialization;
    3. using CodeStage.AntiCheat.ObscuredTypes;
    4.  
    5. [Serializable]
    6. public class ClassToSerialize: ISerializable
    7. {
    8.     public ObscuredString obscuredString;
    9.     public ObscuredInt obscuredInt;
    10.     public float regularFloat;
    11.  
    12.     public ClassToSerialize() { }
    13.  
    14.     private ClassToSerialize(SerializationInfo info, StreamingContext context)
    15.     {
    16.         obscuredString = (string)info.GetValue("obscuredString", typeof(string));
    17.         obscuredInt = (int)info.GetValue("obscuredInt", typeof(int));
    18.         regularFloat = (float)info.GetValue("regularFloat", typeof(float));
    19.     }
    20.  
    21.     public void GetObjectData(SerializationInfo info, StreamingContext context)
    22.     {
    23.         info.AddValue("obscuredString", obscuredString.ToString());
    24.         info.AddValue("obscuredInt", obscuredInt);
    25.         info.AddValue("regularFloat", regularFloat);
    26.     }
    27. }
    Please, note it has two Obscured vars and one regular one.
    ISerializable implementation includes both private constructor ClassToSerialize(SerializationInfo info, StreamingContext context) and public GetObjectData(SerializationInfo info, StreamingContext context) method.

    In GetObjectData you fill the SerializationInfo with all your serializable variables and in private constructor you simply read them back.

    And this is an example of the Json.NET used to serialize and deserialize such class:

    Code (CSharp):
    1. using Newtonsoft.Json;
    2. using UnityEngine;
    3.  
    4. public class SerializationTests : MonoBehaviour
    5. {
    6.     void Start ()
    7.     {
    8.         ClassToSerialize testClass = new ClassToSerialize();
    9.         testClass.obscuredString = "some string";
    10.         testClass.obscuredInt = 1234;
    11.         testClass.regularFloat = 5678.11f;
    12.        // prints "Before serialization: some string, 1234, 5678.11"
    13.         Debug.Log("Before serialization: " + testClass.obscuredString + ", " + testClass.obscuredInt + ", " + testClass.regularFloat);
    14.         string output = JsonConvert.SerializeObject(testClass);
    15.  
    16.        // prints "Serialized to: {"obscuredString":"some string","obscuredInt":1234,"regularFloat":5678.11}"
    17.         Debug.Log("Serialized to: " + output);
    18.         testClass = JsonConvert.DeserializeObject<ClassToSerialize>(output);
    19.  
    20.        // prints "After deserialization: some string, 1234, 5678.11"
    21.         Debug.Log("After deserialization: " + testClass.obscuredString + ", " + testClass.obscuredInt + ", " + testClass.regularFloat);
    22.     }
    23. }
    Thus, you're able to easily serialize any Obscured vars on your own.
    Some other serialization libraries respect the ISerializable implementation as well as Json.NET.

    added
    Here is an example of JSON.NET's JsonConverter usage by @mcmorry:
    https://forum.unity.com/threads/anti-cheat-toolkit-stop-cheaters-easily.196578/page-12#post-2642699

    added #2
    Here is Unity's JsonUtility example usage:
    https://forum.unity.com/threads/anti-cheat-toolkit-stop-cheaters-easily.196578/page-25#post-7114072
     
    Last edited: May 6, 2021
  29. dr.hell

    dr.hell

    Joined:
    Nov 6, 2014
    Posts:
    1
    I bought this one for anti-speed-hack.

    But anti-cheat-toolit don't detect infamous android cheat-engine "SB Game Hacker"'s speed hack.

    Could you please test SB Game Hacker?
     
  30. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, @dr.hell!
    Thanks for your report.

    I did tried to use SB Game Hacker's speed hack on rooted device and made small investigation.

    TL;DR
    Looks like we have absolutely no chance to detect it from Unity apps without using native plugins, GPS or Internet connection.

    More details
    SB Game Hacker speeds up absolutely all timers for specific application using root privileges. Thus any timer I can reach from Unity app is hacked and can't be trusted.

    Options we have:

    1. Write native plugin for low-level timers usage (we have a chance to find a timer not touched by SB Game Hacker).

    Pros:
    - doesn't depends on device capabilities

    Cons:
    - requires Unity Pro for Unity < 5
    - may not work at all without root-level privilegies (needs prototyping before development)
    - not cross-platform

    2. Write native plugin for suspicious processes detection (by signature).

    Pros:
    - 100% working solution
    - doesn't depends on device capabilities
    - may be used widely to detect any running hack tools

    Cons:
    - requires Unity Pro for Unity < 5
    - not cross-platform (some core code could be cross-platform though)
    - requires frequent updates to keep in sync with latest hack tools versions
    - advanced in development
    - will produce false positives (running cheat tool is not cheating yet)

    3. Write native plugin to detect rooted device

    Pros:
    - 100% working solution
    - doesn't depends on device capabilities

    Cons:
    - requires Unity Pro for Unity < 5
    - not cross-platform (some core code could be cross-platform though)
    - may be harmful for legit players (having rooted device is not cheating yet)

    4. Use Internet connection to retrieve trustable timestamps.

    Pros:
    - doesn't depends on device capabilities
    - 100% working solution
    - cross-platform

    Cons:
    - requires constant internet connection during gameplay
    - requires internet connection permission for app
    - may be not accurate enough on slow connection

    5. Use GPS location service to obtain timestamps.

    Pros:
    - 100% working solution
    - cross-platform (at least for mobiles)

    Cons:
    - not accurate enough (too high delays)
    - drains battery faster
    - depends on device capabilities (requires GPS)
    - requires GPS permission for app
    - advanced in development

    All of them require some significant work to implement.
    For now I'm going to keep "detect root-level speedhack" in my TODO. I'll get back to this in future and will try to implement something helpful, perhaps I'll start from adding Internet connection timestamps since it's the most reasonable solution from my point of view.
     
    Last edited: Aug 6, 2015
  31. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Just to let you guys know: some ObscuredPrefs goodness for Play Maker users is coming with next Anti-Cheat Toolkit update!



    I'm also going to introduce SpeedHackDetected Action in that update as well + some other detection actions may be added in future updates.
    And I wish to send my many thanks to the @kreischweide for his first attempt on ACT integration with Play Maker, it really helped me a lot to get started.
     
  32. Kiori

    Kiori

    Joined:
    Jun 25, 2014
    Posts:
    161
    Hi there, does the obscuredPref mean that we dont have to save to a file? is the data serialized by default on save?
    Do you also have encryption? I can save to other files if I want right?
    I'm not sure i understand this feature fully.

    How is the performance on mobile currently, based on your current customer feedback?

    Thanks, great work!
     
  33. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, @Kiori!
    ObscuredPrefs saves all data to the same location as PlayerPrefs. All data saved with ObscuredPrefs get automatically encrypted and decrypts back on read.
    Currently ObscuredPrefs doesn't support custom path to the data file.
    But you already can use obscured types to encrypt any data for your custom saves engine. See Encrypt \ Decrypt and GetEncrypted \ SetEncrypted methods of the obscured types in the API docs.

    About performance - ObscuredPrefs are definitively slower than PlayerPrefs because of additional resources consumption for encryption \ decryption. But not slow enough to make any troubles on mobile while being wisely used (outside of the huge loops and Update(), OnGUI, etc. functions).
     
  34. lend

    lend

    Joined:
    Aug 7, 2014
    Posts:
    13
  35. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, @lend!
    No, unfortunately PlayMaker doesn't allow to add new types at all. The only way to do it - via FsmObject and custom proxy class. And this is not a way to go with Obscured types since it will be too slow and dangerous (in terms of GC).

    Nearest ACT update will have actions for ObscuredPrefs and SpeedHackDetector.
    I still have "full PlayMaker support" in my TODO, so I might make edited PlayMaker assembly with included Obscured types or like so in future updates, not sure yet (need to make research first).
     
  36. cabanelContship

    cabanelContship

    Joined:
    Apr 28, 2014
    Posts:
    5
    Hi,
    before you buy this product, I would like to ask you if
    to avoid duplication of the value of a key in another, saved with ObscuredPrefs.SetInt,
    i can use:

    ObscuredPrefs.SetNewCryptoKey(nameKey1);
    ObscuredPrefs.SetInt(nameKey1, 100) ;

    ObscuredPrefs.SetNewCryptoKey(nameKey2);
    ObscuredPrefs.SetInt(nameKey2, 200) ;

    when long and different, to be the key? to be sure that it is not possible to copy values from one key to another?

    sorry for my english
    thanks
     
  37. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, @cabanelContship!
    Yes, you can change crypto key at any time, but remember to change it same way on load those variables.
    And I'd suggest to not use only nameKey* as crypto key (it's better to add some constant to it to avoid any weird collisions).
    If I understood you correctly %)
     
  38. cabanelContship

    cabanelContship

    Joined:
    Apr 28, 2014
    Posts:
    5
    I tried the keys like 343566, 888684567 or 534536467

    but very often by copying the values are read correctly or turned into other integers

    You can make an example of good key and as different from each other

    thanks
     
  39. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Ah, looks like I understood what you trying to implement finally.
    You wish to lock values to the keys, to prevent copy-paste of same value to the different keys, am I right?

    If so, it's not currently implemented, but it will be done in one of the nearest updates. So I'd suggest to wait for the next update or implement it by hands for now (add encrypted with ObscuredString.Encrypt() key to the value for reverse decryption and comparison after loading).
    Thanks for your questions.
     
  40. cabanelContship

    cabanelContship

    Joined:
    Apr 28, 2014
    Posts:
    5
    thanks,
    another question
    how you can add ObscuredInt in script of Editor?
    if I insert it as integer value is changed
     
  41. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey again.
    Why do you ever need Obscured vars in editor scripts?
    I'm not sure I understood you correctly =\
     
  42. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey guys, first tutorials are ready!
    I'll add some more tutorials, examples and best practices videos in future.
     
  43. cabanelContship

    cabanelContship

    Joined:
    Apr 28, 2014
    Posts:
    5
    I would like to customize my inspector where there are ObscuredInt.
    To make visible nell'ispector my variable ObscuredInt I have to add in the script editor:

    myTarget.myNumerObscured = EditorGUILayout.IntField("Description", myTarget.myNumerObscured);


    but after run unity, in inspector the value of MyNumerObscured is changed
    (I think is the encrypted value)
     
  44. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    @cabanelContship I see now. It should work fine (I tried to repeat it without success).
    Are you sure you call serializedObject.ApplyModifiedProperties() ?

    Here is an example I used to check it:

    Code (CSharp):
    1. using CodeStage.AntiCheat.ObscuredTypes;
    2. using UnityEngine;
    3.  
    4. public class Tester : MonoBehaviour
    5. {
    6.     [HideInInspector]
    7.     public ObscuredInt someInt;
    8. }
    9.  
    And editor for this class:
    Code (CSharp):
    1. using UnityEditor;
    2.  
    3. [CustomEditor(typeof(Tester))]
    4. public class TesterEditor : Editor
    5. {
    6.     public override void OnInspectorGUI()
    7.     {
    8.         serializedObject.Update();
    9.         (target as Tester).someInt = EditorGUILayout.IntField("Description", (target as Tester).someInt);
    10.         serializedObject.ApplyModifiedProperties();
    11.     }
    12. }
    And it works fine for me (I change value in inspector and it remains the same after application start).

    If you still have this issue - feel free to send me your repeatable case to let me check it out.
     
  45. cabanelContship

    cabanelContship

    Joined:
    Apr 28, 2014
    Posts:
    5
    ok work fine!!!
    thanks
     
  46. PhobicGunner

    PhobicGunner

    Joined:
    Jun 28, 2011
    Posts:
    1,813
    Hello,
    I think I read somewhere that the DLL injection detection was not for use in production code?
    Be curious to know why - experimental feature, known bugs, etc ...?

    It's really the one part of Anti-Cheat that I really want. Just about everything else is handled server side (we're going with an authoritative server), so I don't need to worry about ammo, health, wallhacking, etc.... just mostly want to catch a few ESP and aimbotters if possible.
     
  47. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, @PhobicGunner!
    InjectionDetector actually can be used in production code, but with extra caution. I have no any feedback on it from customers yet, that's why I can't say it perfectly works for everyone. It works fine for me though.

    Just carefully read DLL Injection section of the readme for some insight on how it works and on possible issues.
    Main possible issue - false positives. But InjectionDetector can be easily checked for false positives - just run it on target device and see if it reports any foreign assemblies. After that you can add that assembly to the whitelist as described in readme.
     
  48. PhobicGunner

    PhobicGunner

    Joined:
    Jun 28, 2011
    Posts:
    1,813
    Neat. Good to hear.
    It's cool that there's a callback for detection - I'm using Playfab as the backend for the game, and they have a nice proper matchmaking service available. I'm planning on seeing if I can separate players into separate matchmaking pools, and if so when a DLL injection is detected the user isn't outright banned, just flagged and placed into a separate matchmaking pool with other cheaters ;)
     
  49. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Haha, it should be fun, cheaters vs cheaters =D
    I'd be glad to know if it will have any false positives for you if possible, feel free to report them to me.
    And have fun! =)
     
  50. PhobicGunner

    PhobicGunner

    Joined:
    Jun 28, 2011
    Posts:
    1,813
    My artist and I had some other fun ideas too, although I probably won't implement them. One of them was replacing one out of every few words in a cheater's chat with a random dictionary word, madlibs style. Oh the hilarity that could ensue...

    "I'm not cheating, I swear. You're just mad 'cause I'm better than you" -> "I'm not cheating, taste swear. You're just mad earthquake I'm better than minute"
     
    asecretspot likes this.