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. Zeblote

    Zeblote

    Joined:
    Feb 8, 2013
    Posts:
    1,102
    Well you can reference the unityengine.dll and all the other required things when compiling it again. It will work with obfuscated code - that's the point of using a deobfuscator! It should replace all invalid characters and you can compile it. If it still doesn't work for whatever reason, you can always compile your code seperately and use ilmerge to put it in the original assembly, and then make an existing script call a setup function or something.
     
  2. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Yeah, de4dot made this too easy, too much people now can deobfuscate stuff =) But again - you need to repeat all actions on every app update in case of code-based injection, which may be too tediously for cheater. There are lot of ways to mess up existing .NET app, bytecode is so vulnerable =(
    And it is really not the topic for this thread - it's too wide to fit =P
     
  3. Zeblote

    Zeblote

    Joined:
    Feb 8, 2013
    Posts:
    1,102
    It's just a few clicks to put your cheat in the new update if you're doing it right :p Even if they rename all the classes (use reflexil to change them back to the names your cheat needs), as long as the code doesn't get completely restructured, it should work
     
  4. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Most obfuscators will make every build names different, and after deobfuscation such names may differ from build to build. So why bother with recompiling, renaming (reflexil is worst option for editing obfuscated IL btw - it re-assemblies file, so you need to deobfuscate it first - reflexil uses Mono.Cecil which hates obfuscation and buggy at all), etc. if you could just write your dll and injecting tool once and use it without any additional efforts until developer change something related to injected code, regardless of obfuscation, etc.?
    Damn, we went too far from the thread topic! =P
     
  5. Zeblote

    Zeblote

    Joined:
    Feb 8, 2013
    Posts:
    1,102
    Reflexil doesn't actually suck at all - you gonna run the assembly through de4dot, and then just overwrite the old one, works perfectly
     
  6. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Yep, de4dot may easily fail on custom obfuscation or on some newest version of known obfuscator though. Why add extra layer of possible bugs generator if you may easily evade it using proper tool?
    Actually IL allows us to have numerous ways to reach our goal, and it's not so important which one will be chosen.
    Once again, this is not best place for our discussion, we just frighten happy Unity developers =D
    Please, feel free to chat with me in skype or in some obfuscation / deobfuscation thread on forums - I will be really glad to speak with someone skilled in IL RE, we made too much too hacky posts here already =P
     
  7. bjohyea

    bjohyea

    Joined:
    Nov 24, 2013
    Posts:
    4



    Well um frium part of the problem is unity web player hosting options. Without https retrieving the download file to your game is simple as a F12 in Google Chrome and Right Click in firefox. Your game is hosted on multiple unity portals that don't protect the html code. $screenshot_2.png the highlighted bar contains the link to the .unity3d file where any person with a very basic knowledge of being a script kiddy (like me) with a little research can get the source code for your game, assets and textures used, pretty much your whole work. I learned the whole process of doing all the above with 15 mins of google searching and browsing websites. The point of this is that it makes it hella easier to create hacks to your game. Https solves this whole problem buts it is expensive, I'm currently making a unity fps and I knew I would need to fight hard against cheaters and protect my game. So I put myself in their place and eagerly learned from the evil-doers perspective. So im now just releasing on stand alone, despite the ad-revenue from webplayer. "Know your opponent, Be the enemy."
     
    Last edited: Mar 9, 2014
  8. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Https doesn't solve a problem - both your whole .unity3d file and separate .net assemblies - all can still be dumped from the memory. Releasing it stand alone still not prevents hackers from accessing your code and assets (still can be unpacked \ dumped).
     
  9. Zeblote

    Zeblote

    Joined:
    Feb 8, 2013
    Posts:
    1,102
    https will encrypt the transfer of the data. It will still be decrypted on the client side, and you can just as easy view the html code.

    Releasing standalone will only make it even easier.
     
  10. Tinytouchtales

    Tinytouchtales

    Joined:
    Dec 30, 2013
    Posts:
    23
    Hi Dmitriy!

    First of all thanks for the great tool! For me as a non programmer this makes life so much easier.

    Question: With the new updated 1.2.0 you changed PlayerPrefsObscured to ObscuredPrefs. I have a version of my iOS game in the App Store that uses the old system. What happens if i make an update and have exchanged all the old PlayerPrefsObscured to ObscuredPrefs. Will the App be able to read out all the old saves or will they be broken? Also what happens if i change the system and the new prefs overwrite the old prefs save?
     
  11. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, Tinytouchtales!
    Thanks for your feedback.

    Swapping PlayerPrefsObscured with ObscuredPrefs should work smoothly - all your data, saved with PlayerPrefsObscured will be accessible via ObscuredPrefs. All old variables, saved with PlayerPrefsObscured will remain in prefs though. New almost-ready-for-release version of plugin will also remove keys, written with legacy PlayerPrefsObscured while reading them with ObscuredPrefs.
     
  12. Tinytouchtales

    Tinytouchtales

    Joined:
    Dec 30, 2013
    Posts:
    23
    Ok cool, than i will upgrade everything for my next release, thanks!
     
  13. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey guys!
    Finally, new version got sent for the Asset Store review!
    It is already available for existing customers (just send me invoice and I'll send you latest version back!

    Here is new version changes:
    1.2.5
    - SpeedHackDetector introduced! Allows you to react on Cheat Engine's speed hack
    * some other speed hack tools may be detected too
    * use GameObject->Create Other->Code Stage->Speed Hack Detector menu item to add detector in scene
    * use any public SpeedHackDetector API to automatically add it to scene
    - added cheating detection to the ObscuredInt and ObscuredFloat (use Obscured*.onCheatingDetected)
    - migration from PlayerPrefs to ObscuredPrefs became super easy: just replace PlayerPrefs with ObscuredPrefs
    and read \ write any data as usual, no more manual PlayerPrefs to ObscuredPrefs conversion!
    * all data saved with regular PlayerPrefs will be automatically encrypted with ObscuredPrefs on read and
    original PlayerPrefs data will be deleted
    * Set ObscuredPrefs.preservePlayerPrefs to true to prevent original PlayerPrefs data deletion
    - migration from legacy PlayerPrefsObscured to ObscuredPrefs became smoother: data, written with PlayerPrefsObscured
    now converts to the new format while readed with ObscuredPrefs (previously - old legacy keys were left untouched
    after migration).
    - ObscuredPrefs.unobscuredMode implemented
    * allows to write all data unobscured, for testing purposes
    * thus it works in Editor only
    * breaks PlayerPrefs to ObscuredPrefs migration (reminder: in Editor)
    - ObscuredVector3 and ObscuredBool implemented!
    - data saved in TestScene now cleans up on application quit
    - ObscuredPrefs overfill in Web Player no longer breaks entire game process (and logs error in such case)
    - added selftests and performance tests code to the example scene (disabled by default) for debugging and
    making wise choices ;)
    - fixed compilation error of WP8 build
    - fixed initialization of some Obscured types
    - fixed ObscuredString equality operator implementation
    - minor fixes
    - minor docs fixes

    Online API docs will be updated after approving plugin on Asset Store, will send it to you with plugin itself on demand for now.
     
  14. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    amazing awesome work, the price should be higher :)

    thanks
     
  15. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Thanks, zKici!
    I'm thinking about raising price a little bit with next update, since it will add some new functionality again and plugin became pretty far from its first version (I didn't changed price of this plugin at all yet).

    This is not a final decision though (too far from next update yet).
     
    Last edited: Mar 18, 2014
  16. Emirk

    Emirk

    Joined:
    Nov 26, 2012
    Posts:
    17
    Great job on the plugin Dmitriy! I've been reading though this thread and I'm going to purchase ACT as soon as 1.2.5 hits the Asset Store.

    You should definitely raise the price.
     
  17. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Thanks, Emrik!
    Hope you'll have smooth experience with plugin!
     
  18. killa187420

    killa187420

    Joined:
    Dec 13, 2013
    Posts:
    10
    can i use this in js and how would i write it i bought tried import Assets/Javatest.js(2,8): BCE0021: Namespace 'CodeStage.AntiCheat.ObscuredTypes' not found, maybe you forgot to add an assembly reference? is error i get or if using obscured i get error that comes after not having ; that symbol at end
     
  19. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey there!
    Plugin written in C# and it supports usage from C# in first place.
    There is workaround to use it in JS though: you may place plugin code into the Assets\Plugins folder thus it will be compiled before any other code in project and it will be available from JS. And make sure to move plugin's Editor folder to the Assets\Editor since it won't work inside Plugins folder.

    Such workaround is not officially supported though so it may require some additional hand work, but it should work after all (some other customers were able to successfully use it in such way).

    Hope it helps!
     
  20. killa187420

    killa187420

    Joined:
    Dec 13, 2013
    Posts:
    10
    thank you i will try
     
  21. killa187420

    killa187420

    Joined:
    Dec 13, 2013
    Posts:
    10
    worked do u know if they got obscured int to work playerprefs save perfect though thank you again
     
  22. killa187420

    killa187420

    Joined:
    Dec 13, 2013
    Posts:
    10
    var totalCoins : int = 500;
    var collectedCoins : ObscuredInt = 100;
    var coinsLeft : int = totalCoins - collectedCoins;
    Debug.Log("Coins collected: " + collectedCoins + ", left: " + coinsLeft);
    // will print:
    // Coins collected: 100, left: 400
    } gets this error Assets/JavaTest.js(18,35): BCE0051: Operator '-' cannot be used with a left hand side of type 'int' and a right hand side of type 'CodeStage.AntiCheat.ObscuredTypes.ObscuredInt'.
     
  23. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, killa!
    Damn, I got no e-mail notifications for your posts for some reason =\
    I'm sorry for this delay.

    D'oh! Looks like JS doesn't support implicit types conversion =(
    You may workaround it using explicit type conversion (casting) though:

    int coinsLeft = totalCoins - (int)collectedCoins;

    This is really sad to see how many great features are not possible to implement smoothly in JS. I'd like to suggest you try switch to C#, it's easy to learn and it's lot more powerfull / flexible comparing to JS.
     
  24. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    I'm glad to tell you guys new version finally released in Asset Store!
    So, go grab it if you still didn't get it!

    And I'd like to let you know I'm going to raise a price a bit with next update (I'm working on it already), so hurry and buy it now if you still didn't! =D
     
  25. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    Wonderful work, a must have asset for this price was a rip off to you.

    Glad you are raising the price, hopefully not too many get this at the current steal price, and pay the extra in the future :)

    great work
     
  26. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Thanks for your support! :)
     
  27. emergki

    emergki

    Joined:
    Oct 15, 2007
    Posts:
    421
    I bought it yesterday :)
     
  28. killa187420

    killa187420

    Joined:
    Dec 13, 2013
    Posts:
    10
    yes iam in process learning c i can read some and have tried changing small stuff here there and after done this app iam going to switch so learning at same time thank you for the workaround :) and already using with my apps google cloud save it controls leaderboard so yea wanted make least hackable as possible and yes i agree for what u can do it for sure worth and more the price
     
  29. dceevp

    dceevp

    Joined:
    Mar 4, 2013
    Posts:
    19
    I think that my comment is some late, but this update is amazing. I need to implement this today!!
     
  30. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Thanks guys, damn notifications still not work for me =(

    And I glad to let you know next tiny update just went to the AssetStore review team:
    1.2.6
    - flash build support for SpeedHackDetector implemented
    - ObscuredVector2 and ObscuredQuaternion implemented
    - Cheating detection added to the ObscuredByte
    - SpeedHackDetector now awaits Action delegate instead of MonoBehaviour and method name. Please, read API docs for details
    - ObscuredPrefs.readForeignSaves field introduced
    * allows to read saves locked to other device and onPossibleForeignSavesDetected action still will be fired
    - deprecated PlayerPrefsObscured was removed completely, use ObscuredPrefs instead
    - ObscuredFloat slightly optimized
    - ObscuredDouble slightly optimized
    - all default arguments were replaced by methods overloading for additional compatibility with UnityScript (again)
    - minor fixes in API docs

    This update is going to raise the price up to $25, keeping Anti-Cheat Toolkit cheapest complex anti-cheat solution on the store!

    I also glad to let you know I still have lot of sweet features in my TODO list, so stay tuned!
     
  31. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    Amazing work Dmitriy, thank you.

    Keep doing what you do, simply great.
     
  32. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, guys!
    I'm here to let you know I'm about to remove IntegrityChecker from next Anti-Cheat update.
    There are few causes for that:
    - it is actually broken since 1.2.0 or 1.2.5 update (and I just recieved first bug report about it)
    - almost no one uses it (since I received first bug report only now)
    - it is incompatible with editor conditions (#if UNITY_EDITOR) since such conditions lead to different assemblies in editor and in build, so I can't calculate final assembly signature while in editor, it needs more complicated approach breaking regular build pipeline and allowing to take signatures after compilation assemblies to the target platform, but before resources were compressed, if it possible at all - it needs additional research
    - it was fun experiment in first place and its practical use do not provide too much benefit, since if cheater will reach assemblies altering phase, he will be able to rip IntegrityChecker off as any other integrity checks as well, so it was some kind of additional trap for lazy cheaters in first place, not something solid as variables obscuration

    And I'm going to use experience and knowledge I have gained while working on IntegrityChecker in new InjectionDetector module, which is in early research phase now and will help you to detect foreign managed (and prolly unmanaged in future) DLLs injected into your application.

    Please, let me know what do you think about it.
     
  33. kurayami88

    kurayami88

    Joined:
    Aug 30, 2013
    Posts:
    493
    Hi~

    Thanks for the great product... but there was a flaw though...
    please read my review about it on the asset store page... thx :)
    ** posted as Kura Studios**
     
  34. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, kurayami88!
    Thanks for your review.
    This is a known issue and it will be resolved in one of the next updates, it is impossible to implement right now since it needs some black magic from upcoming Unity release to implement it. I even have working prototype: http://i.imgur.com/YqBdUaz.png (* pssst *)

    I hope it is not super urgent for you, so you could wait for it for some time.
     
  35. kurayami88

    kurayami88

    Joined:
    Aug 30, 2013
    Posts:
    493
    wow... how did you get it working in the prototype then if you can't implement it now?
    i'll be eagerly waiting for it...
    until then, game sensitive data are exposed since i use them to control/set the game environment via the inspector... and since ACT doesn't harmonize at the moment, hackers can change the environment as they please (or so to speak)
     
  36. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Well, I can't talk about it on public, I hope you'll guess it though ;)

    I see, yeah this is one of the gaps I'm going to fill in future. For now the only way to prevent such cheating - avoid exposing sensitive variables into inspector.
     
  37. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey everyone!
    Anti-Cheat Toolkit 1.2.6 just got approved on Asset Store raising plugin's price to the $25.
    I posted earlier what's new in 1.2.6, here these changes once again + 1.2.6u1 and 1.2.6u2 service updates changes as well:

    1.2.6u2
    - fixed possible false positives of cheating detection in Obscured types
    - minor API docs fixes

    1.2.6u1
    - extra traces in ActionScript code were commented out

    1.2.6
    - flash build support for SpeedHackDetector implemented
    - ObscuredVector2 and ObscuredQuaternion implemented
    - Cheating detection added to the ObscuredByte
    - SpeedHackDetector now awaits Action delegate instead of MonoBehaviour and method name. Please, read API docs for details
    - ObscuredPrefs.readForeignSaves field introduced
    * allows to read saves locked to other device and onPossibleForeignSavesDetected action still will be fired
    - deprecated PlayerPrefsObscured was removed completely, use ObscuredPrefs instead
    - ObscuredFloat slightly optimized
    - ObscuredDouble slightly optimized
    - all default arguments were replaced by methods overloading for additional compatibility with UnityScript (again)
    - minor fixes in API docs

    Please, note: 1.2.6u1 and 1.2.6u2 are not released to the Asset Store, you may grab them directly from me, or wait until 1.2.7 release.
    I work hard on 1.2.7 update, bringing brand new Injection Detector module for PC (including WebPlayer), iOS and Android (allows to detect managed DLLs injection through Cheat Engine's Auto Assemble script or any handwritten mono embedding tools).

    I also removed IntegrityChecker from 1.2.7 as silence on my question regarding it tells more than any words =)
    IntegrityChecker in 1.2.6 and in few previous versions doesn't work, so avoid using it please.

    1.2.7 should be ready to be sent for review this week and it will take another ~1 week for approval, stay tuned!
     
  38. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    I'm very glad to let you know new version 1.2.7 already available on Asset Store! It was blazingly fast this time!

    What's new in 1.2.7:
    - InjectionDetector introduced
    * allows to detect if someone injects any managed dll into your app
    - ObscuredShort and ObscuredUShort with cheating detection implemented
    - IntegrityChecker removed (see my considerations here: http://forum.unity3d.com/threads/196578-Anti-Cheat-Toolkit-RELEASED/page7?p=1577548&viewfull=1#post1577548)
    - significant changes and fixes in API documentation (should be prettier and more detailed now)
    - DeviceLockLevel enum moved into the ObscuredPrefs class, thus now it should be reached as ObscuredPrefs.DeviceLockLevel
    - SpeedHackDetector's StartMonitoring methods were renamed to StartDetection ones
    - minor improvements in flash implementation of SpeedHackDetector
    - ObscuredUint was renamed to ObscuredUInt
    - minor files structure changes, please, make clean update (completely remove previous version before updating)
    - minor fixes and optimizations

    Please, note, this update has some changes in file structure thus I suggest to remove previous version from your project before updating to avoid any extra head pain!

    Injection Detector is an experimental module so far: please, test it on target platform before releasing.
    Have fun!
     
  39. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey again!
    New Anti-Cheat Toolkit 1.2.8 version just arrived to the Asset Store!
    What's new:

    1.2.8
    - New obscured types with cheating detection implemented
    * ObscuredSByte
    * ObscuredChar
    * ObscuredDecimal (Flash Player is not supported, use ObscuredFloat instead)
    * ObscuredULong
    - cheating detection added to these existing obscured types
    * ObscuredUInt
    * ObscuredLong
    * ObscuredDouble
    * ObscuredBool (except Flash Player: bug in exported pool manager code doesn’t allow to use nullables)
    - minor public API changes for few obscured types
    - fixed SpeedHackDetector error while playing test scene in editor with Flash Player target
    - fixed possible false positives of SpeedHackDetector in Flash Player
    - fixed Flash Player implementation of the ObscuredUShort.GetHashCode()
    - another minor improvements in flash implementation of SpeedHackDetector
    - other minor fixes and optimizations
     
  40. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    Amazing work ! We can't keep up with all these new releases and updates :)

    Thank you very much for this wonderful asset,

    I hope that all these new things such a: SByte Char etc. do not slow down my app, I do not use these and I hope it doesn't affect performance because its included.

    Thanks :)

     
  41. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, zKici!
    Thanks for your support!

    New obscured types won't hurt your game performance at all =)
     
  42. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    Even more better!

    Thanks amazing asset, a must get.
     
  43. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    Hey Dmitriy,

    I have a character that uses unity's navmesh,

    is it a good idea to have an Obscured bool to check whether the character is walking or running?

    ex Obscured bool walk

    or is this a bad idea, should I only use obscured for things such as purchases, level saves, etc.

    maybe you can explain it better to me so that I am careful of what I'm creating

    thanks :)
     
  44. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey again, zKici!
    Feel free to use ObscuredBool for your char walk flag if your game scores or any other sensitive values depend on player state. It's all up to you what to protect and what to leave unprotected - it completely depends on game specifics and weak places.
     
  45. Rustam-Ganeyev

    Rustam-Ganeyev

    Joined:
    Jul 18, 2011
    Posts:
    29
    Hi Dmitriy,

    I used Anti-Cheat toolkit in my project and yesterday I updated from (1.0.1.2) to the latest(1.2.8).

    Now I'm stuck with a following problem: I can't get old obscured data.

    Code (csharp):
    1.  
    2. PlayerPrefsObscured.lockToDevice = true;
    3. var data = PlayerPrefsObscured.GetString(key);
    now I changed to
    Code (csharp):
    1.  
    2. ObscuredPrefs.lockToDevice = ObscuredPrefs.DeviceLockLevel.Soft;
    3. var data = ObscuredPrefs.GetString(key);
    And now I'm unable to get old data from the same key.


    Please help me to handle problem. I can't release an update just because it will break datas on old users.
     
    Last edited: Apr 22, 2014
  46. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, Rustam!

    PlayerPrefsObscured uses ObscuredString with default encryption key under the hood. And that default key was changed in one of previous updates.
    But it's really easy to fix it in your case. Just find this line of code in the ObscuredPrefs EncryptKeyDeprecated() method:

    key = ObscuredString.EncryptDecrypt(key);

    and replace it with this line:

    key = ObscuredString.EncryptDecrypt(key, "4444");


    Please, let me know if it helps!
     
  47. Rustam-Ganeyev

    Rustam-Ganeyev

    Joined:
    Jul 18, 2011
    Posts:
    29
    I'm afraid it didn't help. It gives me a string, but it isn't what was saved. Maybe I should try another encryptionKey or should to change something DecryptValueDeprecated method?
     
  48. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Oh, sorry, forgot to mention PlayerPrefsObscured used "e806f69e7aea3ee30fe27a6abfae967f" as default crypto key. So you could try to set it via ObscuredPrefs.SetNewCryptoKey() as well to make it read old values.

    Please, let me know if it works for you.
     
  49. Rustam-Ganeyev

    Rustam-Ganeyev

    Joined:
    Jul 18, 2011
    Posts:
    29
    I did CodeStage.AntiCheat.ObscuredTypes.ObscuredPrefs.SetNewCryptoKey ("e806f69e7aea3ee30fe27a6abfae967f") on monobehaviour start method, now ObscuredPrefs.GetString(key) returns empty string, as in the first case.
     
  50. Rustam-Ganeyev

    Rustam-Ganeyev

    Joined:
    Jul 18, 2011
    Posts:
    29
    The reason I updated anti-cheat toolkit is a problem with iOS builds(not released yet), while android builds(released on google play) are ok.
    If I don't find any acceptable solution, I'll put different versions into Plugins/Android and Plugins/iOS folders, and will make an adapter for them.