Search Unity

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,252
    For those who wish to try themselves at IL2CPP dumping protection or tricking, here are the C# sources of one famous IL2CPP Dumper from the China developer I found in open sources (no license was attached):

    http://codestage.net/dump/share/2018.01/Il2CppDumper-1.0.19-SrcCode.7z

    Studying how it analyses metadata and binaries may help to create additional obstacles for such tools for those who interested.
     
  2. friuns

    friuns

    Joined:
    Jan 14, 2016
    Posts:
    22
    they working on it :)
    public fields i guess cannot be obfuscated, so it makes them easy to find, if hacker make code injection and change those variables even they encrypted in memory with ACT? or does ACT detects code injection in il2cpp?


    how do i add extra layer with loader?
     
    Last edited: Jan 17, 2018
  3. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Yeah, they always working on something =)
    Actually this is not much better then one big cs file with names since it doesn't have IL bytecode inside, it's just a metadata in a nicer form which will not help at all if code will be obfuscated, so nothing to worry about.

    Public fields can and should be obfuscated as much as possible.
    Use Unity-friendly obfuscator so it will be careful with Unity messages and make sure you're properly managing obfuscation of the serializable stuff.
    You easily can make a total mess in decompiled code for the person who will try to reverse-engineer it.

    There are also different other obfuscation tricks and techniques which may make your code harder to analyse. But most of them are 100% reversible with automated solutions (deobfuscators).

    But the names obfuscation we're talking about here is a most common part of the obfuscation process and only one obfuscation part which just can't be reversed automatically and will require a lot of hand work and reverse-engineering process to guess the names back.

    Currently ACTk doesn't detects code modification.
    Anyways, it's much more efficient to make own code modification checks since there are lots of different environments and possibilities.
    E.g. if your game have a server, you may store sensitive data there (like hashes of the binaries) so all checks for the client code integrity may be done on the server side restricting some server features for the code which was not make it through the checks.

    You may hook into the loading process forcing to execute your code first. This can be used for cheating too so I'll not describe it in details here, just google for it and you'll find proper info more likely.

    That's why all this code protection topic is currently out of ACTk scope - it's pretty huge and needs serious work and individual solutions in many cases.
    And there are tools and solutions around which covers it though costing much more $30

    The good thing here is that most cheaters will not touch your obfuscated IL2CPP code without very strong motivation.
    And such motivation is usually starts to appear as soon as your game become very popular so cheater could earn some money on cheats sell etc.
    So in such case your game more likely will make enough revenue making expensive code protection solutions affordable.
     
    Last edited: Jan 19, 2018
  4. Jason_AppXplore

    Jason_AppXplore

    Joined:
    Jan 14, 2015
    Posts:
    11
    Hi. I've been using your prefs editor and it has been working very well for me. Then the string that I have been storing became too long and it started giving me "string too long" errors in the console. Recently I've updated to a newer version and I'm glad that issue is fixed, but now I cannot edit the string anymore.

    Since I use it to store my save data, it has been very convenient to copy from the pref editor and paste it in a text editor to debug, and after finish editing it I can paste it back in the pref editor to overwrite my save data. The current pref editor allows to copy the value into clipboard, so I was wondering if it is possible to add an option to paste from clipboard as well.

    Thanks in advance.
     
  5. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Hey, @Jason_AppXplore

    Thanks for your feedback and feature request!
    It will be added for the next release (it's already done in dev version, feel free to drop me your invoice in PM to get current dev version with this paste feature along with few other fixes).
     
    Jason_AppXplore likes this.
  6. RealMTG

    RealMTG

    Joined:
    Jul 27, 2013
    Posts:
    229
    Hello!

    I tried to build my game for UWP (with IL2CPP, if it matters) with your asset included and I got an error.
    The fix was simple though: I just moved the "IsCheckingForCheat" property in TimeCheatingDetector into the '#if !UNITY_WINRT' section below.
    Just thought you should be aware of this. :)
     
    codestage likes this.
  7. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Hey, @RealMTG

    Thanks for reporting it!
    This will be fixed with next update (already fixed in current dev version).
     
    RealMTG likes this.
  8. sunxinzhe

    sunxinzhe

    Joined:
    Oct 26, 2015
    Posts:
    3
    i buy the asset today,as this plugin contains time cheat protecter,but when i import it ,i found it must has internet connect,but i need offline protecter,has plan?tks!
     
  9. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Hey, @sunxinzhe !

    Thanks for your purchase and I'm sorry to hear you were mislead by the asset description, I'll try to state the Internet connection requirement more explicitly with next update.

    What kind of offline time cheating protection you would like to have?
    I mean, isn't manual local time change comparison \ propagation at OnApplicationFocus \ OnApplicationPause events helps in your case?
     
  10. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    208
    Just to pitch in, I would definitely benefit from an offline anti cheat as well... especially for single player games.
     
  11. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    That's nice!
    Could you please share a bit more info too on what you're expecting from the offline TimeCheating detector, @zKici ?

    Why standard OnApplicationFocus \ OnApplicationPause events are not enough to check how much time have passed while application was inactive?

    Also, just a reminder, SpeedHackDetector should be able to detect cases when in-game timers are cheated.
     
  12. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    208
    I haven't really looked into all your options etc. Just bought it a while ago for future use,

    My thing is to basically check if someone is trying to hack resources such as money, health, levels, etc. To catch those, when values are changed for example via ResHack etc.
     
  13. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Ah, in such case you're on the safe side, @zKici, the only one feature which requires an internet connection is a TimeCheatingDetector.
    All other features, such as SpeedHackDetector, obscured types and prefs - all are fully offline.

    Thanks for the purchase too BTW.
     
  14. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    208
    Great! Thank you,

    No problem at all, I haven't gotten around to leave a review yet. I have your other assets too like FPS counter, maintainer etc.

    Although, perhaps this isn't the scope of the counter, but maybe you could add a VR sample scene in there and thus expanding your market. Just a thought :)
     
    codestage likes this.
  15. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Wow, triple thanks then! =D

    Actually it's already kinda there, just enable this World Canvas object in example scene to view counter in VR.

    upload_2018-3-13_16-54-19.png

    But thanks for your suggestion, now I see separate scene with VR example would be more nice and explicit, will do in future updates!
     
  16. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    208
    No problem :)

    Make sure you advertise that on your description or title too. It will attract more buyers.
     
    codestage likes this.
  17. sunxinzhe

    sunxinzhe

    Joined:
    Oct 26, 2015
    Posts:
    3

    tks your quick reply,in my game,has a daily reward,it based system time,but if player modify phone time,will cheat time to get reward, is almost like this asset ,forum address:https://forum.unity.com/threads/time-cheating-prevention-in-offline-mode-ios-android.256735/

    but from the forum reply, the asset "Time cheating prevention" has bug and look like has no time to fix,so not purchase it.

    in that forum,has a reply:
    hi
    i have this asset and its great, but can you please add this :
    http://stackoverflow.com/questions/...ser-has-changed-the-clock-time-on-their-devic
    if you add this then your asset become bulletproof !
    this is really important because we can tell if user changed the time and we can reset game if user did that

    is also need,tks
     
    codestage likes this.
  18. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Thanks for the clarification, @sunxinzhe
    I think it's possible to implement something helpful, I'll make offline mode for the TimeCheatingDetector in future updates, stay tuned.
     
  19. sunxinzhe

    sunxinzhe

    Joined:
    Oct 26, 2015
    Posts:
    3
    okay,tks,expecting!
     
  20. Dman00Cman

    Dman00Cman

    Joined:
    Jan 23, 2013
    Posts:
    5
    Hi Dmitriy,

    Thanks for the great asset! On the subject of the TimeCheatingDetector, could you provide functionality to check if you have verified time correctly at least once since start?

    Right now in my application there is a race condition between the TimeCheatingDetector detecting the time cheat and the user claiming the time based reward in my application on startup.

    If I disabled the button for claiming the reward until you had verified time at least once, I could get around this I think.
     
  21. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Hey @Dman00Cman

    Yes this is totally possible to implement. Will add with next update.
    Thanks for the feature request!
     
  22. Dman00Cman

    Dman00Cman

    Joined:
    Jan 23, 2013
    Posts:
    5
    Cheers! Do you have an estimated release date for your next update?
     
  23. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Unfortunately no exact ETA at this moment.
    Some features are in progress now and I try to include some little thingies like your into the update too by the way. Expect it somewhere before mid of April, hope to see it online sooner.
    Also feel free to pm me with invoice if you wish to get dev version as soon as I'll add feature you requested.
     
  24. OreoSplitter

    OreoSplitter

    Joined:
    Oct 21, 2017
    Posts:
    28
    With this asset does that mean I can use playerprefs vs learning about binary files or is that still the route I should take?

    Lastly how do you deal with apps like luckypatcher or freedom? I assume this asset doesn't help out in that area? I've read on stack overflow checking signatures via server isn't even good enough though I'm just learning all of this so can't confirm. Just curious to hear your thoughts on how to tackle this issue.
     
  25. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Hey, @OreoSplitter

    For small portions of data you're free to keep using PlayerPrefs or ObscuredPrefs for sensitive small data. ObscuredPrefs has similar syntax to the PlayerPrefs so you don't need to learn anything new to use it.

    If you need to encrypt some big amounts of data you're free to use classic binary writing classes and APIs as usual, just encrypt and decrypt raw data bytes with ObscuredByte.EncryptDecrypt(byte[] value, byte key) when writing \ reading to make sure saved data is not naked to the cheater's eye.

    These tools alter the code and for now code protection is out of ACTk scope (see more info here).
    I'll be investigating them closer in future to try find something we could use from the ACTk side though to detect usage of such tools but now it's a low-priority since it's more about code protection in first place.
     
  26. OreoSplitter

    OreoSplitter

    Joined:
    Oct 21, 2017
    Posts:
    28
    ObscuredFloat.SetNewCryptoKey(666) read is for all new instances.

    Does that mean only new created obscured float variables. Even if original obscured float gets it's value updated it's till using the old key?
     
    Last edited: Mar 26, 2018
  27. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Hey, @OreoSplitter

    Yes, this API sets new default key for new ObscuredFloat instances.
    If you wish to apply this key to existing instance, you need to call ApplyNewCryptoKey() on that instance.
     
  28. Richardbmth

    Richardbmth

    Joined:
    Mar 5, 2016
    Posts:
    29
    Hi Dmitriy :)

    I've just been playing around with the TimeCheatingDetector in the context of a 'Daily Gift for a mobile game'. I found the ForceCheck() method which I initiate on OnApplicationPause - when a player comes back to the game after changing the time.

    However, I can't work out how you detect when the player has changed their device back to the correct time and is no longer trying to cheat. Ideally I want to disable the Daily Gift and enable again when they put back the time as it should be - without closing down the game or creating and destroying the TimeCheatingDetector (I'm assuming that it would reset the TimeCheatDetection status).

    Is there a way a I can do that with the current version, or would that need more functionality? Preferably ForceCheck() would provide a callback that provides a result of the time is correct within the threshold or incorrect (a time cheat).
     
  29. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Hey, @Richardbmth

    Thanks for your question!

    Yeah, currently detector doesn't allow to know if check went successfully and this is a known API design flaw (few customers already mentioned this before).
    The upcoming update will have the improvement at this area so you will be able to know about successful checks and act accordingly, so it should solve your issue.
     
  30. Richardbmth

    Richardbmth

    Joined:
    Mar 5, 2016
    Posts:
    29
    Thank you @Dmitriy-Yukhanov that's sounds great :) Also...I wasn't expecting a reply until at least Monday, so do please take the rest of the weekend off ;)
     
    codestage likes this.
  31. ChoYongGil

    ChoYongGil

    Joined:
    Jan 17, 2014
    Posts:
    9
    Hi Dmitriy.

    "Injection Detected" event is always occurring on android. What can I do? (unity 2017.2.0p2, turn on "enable injection detector)
     
  32. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Hey, @ChoYongGil

    Could you please let me know which ACTk version you're using?

    Also please take a look at the "How to fill user-defined whitelist" readme section, particularly at the part about "ACTK_INJECTION_DEBUG" flag.

    Try to enable it and search logs for the details about assembly which causes detection to add it manually to the whitelist.
     
  33. ChoYongGil

    ChoYongGil

    Joined:
    Jan 17, 2014
    Posts:
    9
    The problem is solved. I was using an older version (1.5.5).
    Thank you very much.
     
    codestage likes this.
  34. cabanel

    cabanel

    Joined:
    Sep 22, 2014
    Posts:
    40
    hi, thank you for your fantastic asset!

    I have a problem:

    I imposed in a script that is in MainScene ObscuredPrefs.CryptoKey = "xxx"

    the value I put in inspector as recommended by you.

    During development I happen to start from other scenes so I am forced to insert from code
    # if UNITY_EDITOR
    ObscuredPrefs.CryptoKey = "xxx";
    #endif

    when I have to publish the app if I forget to remove the code
    the CryptoKey is visible in the script

    Can you recommend a comfortable solution?

    thank you

    Flavio
     
  35. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Hey, Flavio (@cabanel)!

    Not sure I got your question correctly =\
    When you do any kind of the build, all code wrapped with UNITY_EDITOR conditional symbol is got skipped during the build process, so you should be safe if you're worried about that code will get into the builds.
     
  36. cabanel

    cabanel

    Joined:
    Sep 22, 2014
    Posts:
    40
    Thank you very much.
     
  37. cabanel

    cabanel

    Joined:
    Sep 22, 2014
    Posts:
    40
    I set in my MainScene on start ObscuredPrefs.CryptoKey = ValueInspector;
    and it works well

    but in the development phase I can directly execute another scene without going from MainScene and I have to insert in this scene in start
    # if UNITY_EDITOR
    ObscuredPrefs.CryptoKey = "xxx";
    #endif

    is there a centralized way to do this?

    I'm sorry for my english

    thank you
     
  38. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    @cabanel
    Ah, you may act just like with any other initialization code you need to execute in main scene only - there are different patterns for this, for example you could add Editor-Only object with same initialization code to each scene and not editor-only object with same code to the main scene, so when you'll make a build editor-only objects will be eliminated and only one object with initialization code in the main scene will remain.
     
  39. cabanel

    cabanel

    Joined:
    Sep 22, 2014
    Posts:
    40
    to set an editorOnly object just set the tag = editorOnly in inspector?

    thanks Dmitriy
     
  40. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Yes
     
  41. cabanel

    cabanel

    Joined:
    Sep 22, 2014
    Posts:
    40
    thanks
     
  42. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Hey guys!
    I'm glad to let you know ACTk 1.6.0 is live now!

    This update brings to the table lots of fixes, additions and improvements to the existing features.
    Here are few highlights:
    • TimeCheatingDetector got some more love - it's back to UWP (IL2CPP only), more stable now and easier to use for the manual time checks.
    • ObscuredDouble and ObscuredFloat types are now more secure and harder to cheat (there were a vulnerability which now is closed). This fix changed internal algorithms and all previously encrypted variables of these two types needs to be migrated. So there are 3 ways of migration were included with this update including automatic one (read more in readme.pdf, Troubleshooting section).
    • BehaviorDesigner and PlayMaker integrations updated and TimeCheatingDetector added to both
    • Lots of other fixes and improvements (see changelog for details)
    - TimeCheatingDetector got some more love:
    * enabled for Windows Universal Platform with IL2CPP
    * stability improvements (thx Nilooo & off3nd)
    * Error and CheckPassed events exposed in public API now
    * new ErrorKind enum for error events
    * added new callback for successful check passes
    * interval 0 is now supported for the manual ForceCheck() execution only
    * added ForceCheckEnumerator() for yielding from coroutine
    * added awaitable ForceCheckTask() for async methods (.NET 4.6+, no WebGL)
    * added LastResult and LastError properties​
    - all Detectors:
    * added new AddToSceneOrGetExisting() API (execute from Start phase or later)
    * exposed CheatDetected event for subscription
    * now you may have multiple listeners for the detection event​
    - added IComparable implementations to all native obscured types
    * now native obscured types are sortable and LINQ-friendly​
    - exposed double epsilon at the ObscuredCheatingDetector
    - added Paste functionality to the prefs editor
    - get rid of internals usage at editor scripts (allows asmdef usage)
    - improved ObscuredDouble/Float security, migration required (thx off3nd)
    - added ObscuredDouble/Float migration from 1.5.2.0 - 1.5.8.0 to 1.5.9.0+ :
    * auto migration at runtime with ACTK_OBSCURED_AUTO_MIGRATION flag
    * manual migration at all prefabs and opened scenes via menu commands
    * runtime API to migrate values got with GetEncrypted()
    * removed legacy pre-1.5.2.0 support for Obscured types migration​
    - now detector object is automatically selected in scene after creation
    - BehaviorDesigner integration package updated:
    * added TimeCheatingDetected conditional
    * fixed compatibility issues​
    - PlayMaker integration package updated:
    * added TimeCheatingDetected action
    * fixed compatibility issues​
    - updated InjectionDetector whitelist to match Unity 2018.2.0b3
    - switched to X.X.X version tracking format
    - fixed compiler errors on UWP platform (thx Wajdi)
    - fixed possible incorrect readout of string pref at PrefsEditor
    - fixed incorrect behavior when copying unobscured string pref
    - fixed incorrect behavior of InjectionDetector in editor in debug mode
    - fixed missing Reflection.Obfuscation attributes at TimeCheatingDetector
    - fixed compilation flags set/get code to avoid obsolete platforms
    - fixed duplicate flags setting for some platforms (cleanup needed)
    - fixes and additions in API docs
    - minor refactor
    - other minor fixes
     
  43. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Hey everyone,

    I'm glad to let you know new 1.6.2 version is live at the store!
    This update brings lots of the important fixes and one critical fix for the 1.6.1 version regression (Android compilation failed).

    Thanks to everyone who report bugs and issues, it's always highly appreciated.

    Also I glad to finally declare Speed Hack Detector now detects root-level speedhacks on Android, made with tools like GameGuardian. This addition is in beta stage now, and may not work for Android 8.0 and newer, but should work on older versions just fine (screenshot from Android 7.1):

    vmware_2018-05-18_23-22-58.png

    Stay tuned for more!

    1.6.2
    - fixed 1.6.1 critical compilation error for Android platform (sorry!)
    - fixed missing ObscuredVector2, ObscuredVector3 and ObscuredQuaternion migration
    - fixed WallHackDetector false positive when Linear color space is used (thx Fiete)
    - fixed wrong plugin path at Unity 2018 packages (thx Fiete)
    - fixed compilation error when enabling WALLHACK_DEBUG flag (thx Fiete)
    - fixed test scene null reference errors in some cases when cheats are detected
    - fixed exception when removing entry at the user-defined Whitelist window (thx Matt)
    - other minor fixes
    - minor refactorings

    1.6.1
    - SpeedHackDetector now able to detect root-level speed hack on Android (beta)
    - organized usings in all code to prevent ambiguity with third-party classes
    - TimeCheatingDetector:
    * ForceCheckEnumerator method execution slightly changed to improve stability
    * added force check examples to the ActTesterGui​
    - removed some legacy code
     
    Last edited: May 23, 2018
  44. Robotron18

    Robotron18

    Joined:
    Aug 15, 2010
    Posts:
    12
    Дмитрий, добрый день. Очень заинтересовал анти чит. Если можно, ответь на пару вопросов.
    1. Могу ли я объявлять защищенные переменные в пределах структуры? А в пределах сериализованной структуры?
    2. Как порекомендуешь работать со Scriptable Objects?
    Заранее благодарен за ответы.
     
    Last edited: May 23, 2018
  45. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Hey, @Robotron18, please check your PM inbox for reply.
     
  46. pinkpointer

    pinkpointer

    Joined:
    Feb 22, 2017
    Posts:
    4
    Hi,

    Is there a way to use the obscured types as optional parameters?

    Example:
    public void Damage (ObscuredBool expired = false) {
    }

    This returns an error:
    Optional parameter expression of type `bool' cannot be converted to parameter type `CodeStage.AntiCheat.ObscuredTypes.ObscuredBool'

    Thanks!
     
  47. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Hey, @pinkpointer

    Let me please shamelessly copy-paste my answer to the similar question asked about ObscuredInt few years ago:

    Unfortunately, it's a CLR design restriction. Optional parameters should be compile time constants and compiler don't know how to cast int to the ObscuredInt.

    So the only way is to use default keyword for 0:
    Code (CSharp):
    1. private void Test(ObscuredInt a = default(ObscuredInt))
    Or to use nullable declaration and default null for other values:
    Code (CSharp):
    1. private void Test(ObscuredInt? a = null)
    2. {
    3.     if (a == null)
    4.     {
    5.         a = 10;
    6.     }
    7. }
     
  48. pinkpointer

    pinkpointer

    Joined:
    Feb 22, 2017
    Posts:
    4
    Thank you, I got it!
     
  49. Paradoks

    Paradoks

    Joined:
    Oct 13, 2009
    Posts:
    424
    how can i define a const with obscuredString ?
    public const ObscuredString myString = "string";
    dont work.
     
  50. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,252
    Hey, @Paradoks

    Unfortunately it's not possible since constants in C# are compile-time but obscured types are calculated at runtime.

    So just declare it as read-only or use native type for the constant value (may be found in memory).