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

Can Decompiler IL2CPP ?

Discussion in 'General Discussion' started by khaccanh, Aug 30, 2016.

  1. khaccanh

    khaccanh

    Joined:
    Dec 10, 2012
    Posts:
    12
    Dear All
    Pokemon Go made with Unity 3D and use IL2CPP. IL2CPP convert c# code to C++ and compiler to Assembly.
    But Pokemon Go is hacked. Is Pokemon go decompiled?
    Can deompiler a apk or ipa using IL2CPP ?
     
  2. Ostwind

    Ostwind

    Joined:
    Mar 22, 2011
    Posts:
    2,804
    Anything can be reverse engineered. IL2CPP just makes it more difficult compared to mono but its not a 100% protection.
     
  3. Andy-Touch

    Andy-Touch

    A Moon Shaped Bool Unity Legend

    Joined:
    May 5, 2014
    Posts:
    1,479
    How has Pokemon Go been hacked? Link?
     
    MrEsquire likes this.
  4. khaccanh

    khaccanh

    Joined:
    Dec 10, 2012
    Posts:
    12
    This is link to reverse Pokemon Go
    https://applidium.com/en/news/unbundling_pokemon_go/
    Although All app can reverse. But with IL2CPP you can not archive orgin code with name class and function, it is only assembly code . But someone said that they can reverse IL2CPP to orgin code with name class and function
     
    MrEsquire likes this.
  5. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    So much this. As long as the application gets executed on end users machine, people will be able to look inside.
     
    Ryiah likes this.
  6. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,964
    Whether the vast majority of those interested in it are capable of making sense of the decompiled code is another thing. This is one of those worry threads that hasn't any real basis because the people truly capable of making sense of the decompiled IL2CPP code are more than capable of building their own solutions. It'd have to be extremely valuable to be worthwhile.
     
  7. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    Sure. Nobody would do that for plagiarizing code. That'd be super ineffective. Did people really do that when they could just decompile C#, though? I would find that surprising...
     
    Brity likes this.
  8. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,554
    Depends on the project. It would require one heck of an amazing game to make people wade through machine code. I remember that original Doom was repeatedly disassembled, that there people who fan-translated snes and ps2 games, sometimes hacking through the engine code as well, etc. I also remember that someone managed to write script extender dll for oblivion/skyrim, that adds new functions to the game's built-in scripting language.

    In case of unity whoever is trying to reverse engineer the project would probably be trying to make some sort of mod or unofficial bugfix. That doesn't sound like enough motivation for me. Trying to steal the code is dead end route, anyone with a brain would understand that (at least I hope so).
     
    Ryiah likes this.
  9. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,227
    In the article you link to they only reverse engineered the java code, not IL2CPP.
     
    Brity and theANMATOR2b like this.
  10. khaccanh

    khaccanh

    Joined:
    Dec 10, 2012
    Posts:
    12
    https://www.assetstore.unity3d.com/en/#!/content/48919
    IL2CPP builds are much harder to reverse engineer but strings and member information (class, method names etc) are visible in the global-metadata.dat file.
    But Unity said that IL2CPP trip all class method name to number and very hard to understand.
    Who is right ? Any one have used that asset to obfuscator
    this is some class after decompiler Pokemon Go use IL2CPP. All class and function is meaningful.

    class HoloPokemonId
    {
    // Fields
    int value__;
    static HoloPokemonId POKEMON_UNSET = 0;
    static HoloPokemonId V0001_POKEMON_BULBASAUR = 1;
    static HoloPokemonId V0002_POKEMON_IVYSAUR = 2;
    static HoloPokemonId V0003_POKEMON_VENUSAUR = 3;
    static HoloPokemonId V0004_POKEMON_CHARMANDER = 4;
    static HoloPokemonId V0005_POKEMON_CHARMELEON = 5;
    static HoloPokemonId V0006_POKEMON_CHARIZARD = 6;
    static HoloPokemonId V0007_POKEMON_SQUIRTLE = 7;
    static HoloPokemonId V0008_POKEMON_WARTORTLE = 8;
    static HoloPokemonId V0009_POKEMON_BLASTOISE = 9;
    static HoloPokemonId V0010_POKEMON_CATERPIE = 10;
    static HoloPokemonId V0011_POKEMON_METAPOD = 11;
    static HoloPokemonId V0012_POKEMON_BUTTERFREE = 12;
    static HoloPokemonId V0013_POKEMON_WEEDLE = 13;
    static HoloPokemonId V0014_POKEMON_KAKUNA = 14;
    static HoloPokemonId V0015_POKEMON_BEEDRILL = 15;
    static HoloPokemonId V0016_POKEMON_PIDGEY = 16;
    static HoloPokemonId V0017_POKEMON_PIDGEOTTO = 17;
    static HoloPokemonId V0018_POKEMON_PIDGEOT = 18;
    static HoloPokemonId V0019_POKEMON_RATTATA = 19;
    static HoloPokemonId V0020_POKEMON_RATICATE = 20;
    static HoloPokemonId V0021_POKEMON_SPEAROW = 21;
    static HoloPokemonId V0022_POKEMON_FEAROW = 22;
    static HoloPokemonId V0023_POKEMON_EKANS = 23;
    static HoloPokemonId V0024_POKEMON_ARBOK = 24;
    static HoloPokemonId V0025_POKEMON_PIKACHU = 25;
    static HoloPokemonId V0026_POKEMON_RAICHU = 26;
    static HoloPokemonId V0027_POKEMON_SANDSHREW = 27;
    static HoloPokemonId V0028_POKEMON_SANDSLASH = 28;
    static HoloPokemonId V0029_POKEMON_NIDORAN = 29;
    static HoloPokemonId V0030_POKEMON_NIDORINA = 30;
    static HoloPokemonId V0031_POKEMON_NIDOQUEEN = 31;
    static HoloPokemonId V0032_POKEMON_NIDORAN = 32;
    static HoloPokemonId V0033_POKEMON_NIDORINO = 33;
    static HoloPokemonId V0034_POKEMON_NIDOKING = 34;
    static HoloPokemonId V0035_POKEMON_CLEFAIRY = 35;
    static HoloPokemonId V0036_POKEMON_CLEFABLE = 36;
    static HoloPokemonId V0037_POKEMON_VULPIX = 37;
    static HoloPokemonId V0038_POKEMON_NINETALES = 38;
    static HoloPokemonId V0039_POKEMON_JIGGLYPUFF = 39;
    static HoloPokemonId V0040_POKEMON_WIGGLYTUFF = 40;
    static HoloPokemonId V0041_POKEMON_ZUBAT = 41;
    static HoloPokemonId V0042_POKEMON_GOLBAT = 42;
    static HoloPokemonId V0043_POKEMON_ODDISH = 43;
    static HoloPokemonId V0044_POKEMON_GLOOM = 44;
    static HoloPokemonId V0045_POKEMON_VILEPLUME = 45;
    static HoloPokemonId V0046_POKEMON_PARAS = 46;
    static HoloPokemonId V0047_POKEMON_PARASECT = 47;
    static HoloPokemonId V0048_POKEMON_VENONAT = 48;
    static HoloPokemonId V0049_POKEMON_VENOMOTH = 49;
    static HoloPokemonId V0050_POKEMON_DIGLETT = 50;
    static HoloPokemonId V0051_POKEMON_DUGTRIO = 51;
    static HoloPokemonId V0052_POKEMON_MEOWTH = 52;
    static HoloPokemonId V0053_POKEMON_PERSIAN = 53;
    static HoloPokemonId V0054_POKEMON_PSYDUCK = 54;
    static HoloPokemonId V0055_POKEMON_GOLDUCK = 55;
    static HoloPokemonId V0056_POKEMON_MANKEY = 56;
    static HoloPokemonId V0057_POKEMON_PRIMEAPE = 57;
    static HoloPokemonId V0058_POKEMON_GROWLITHE = 58;
    static HoloPokemonId V0059_POKEMON_ARCANINE = 59;
    static HoloPokemonId V0060_POKEMON_POLIWAG = 60;
    static HoloPokemonId V0061_POKEMON_POLIWHIRL = 61;
    static HoloPokemonId V0062_POKEMON_POLIWRATH = 62;
    static HoloPokemonId V0063_POKEMON_ABRA = 63;
    static HoloPokemonId V0064_POKEMON_KADABRA = 64;
    static HoloPokemonId V0065_POKEMON_ALAKAZAM = 65;
    static HoloPokemonId V0066_POKEMON_MACHOP = 66;
    static HoloPokemonId V0067_POKEMON_MACHOKE = 67;
    static HoloPokemonId V0068_POKEMON_MACHAMP = 68;
    static HoloPokemonId V0069_POKEMON_BELLSPROUT = 69;
    static HoloPokemonId V0070_POKEMON_WEEPINBELL = 70;
    static HoloPokemonId V0071_POKEMON_VICTREEBEL = 71;
    static HoloPokemonId V0072_POKEMON_TENTACOOL = 72;
    static HoloPokemonId V0073_POKEMON_TENTACRUEL = 73;
    static HoloPokemonId V0074_POKEMON_GEODUDE = 74;
    static HoloPokemonId V0075_POKEMON_GRAVELER = 75;
    static HoloPokemonId V0076_POKEMON_GOLEM = 76;
    static HoloPokemonId V0077_POKEMON_PONYTA = 77;
    static HoloPokemonId V0078_POKEMON_RAPIDASH = 78;
    static HoloPokemonId V0079_POKEMON_SLOWPOKE = 79;
    static HoloPokemonId V0080_POKEMON_SLOWBRO = 80;
    static HoloPokemonId V0081_POKEMON_MAGNEMITE = 81;
    static HoloPokemonId V0082_POKEMON_MAGNETON = 82;
    static HoloPokemonId V0083_POKEMON_FARFETCHD = 83;
    static HoloPokemonId V0084_POKEMON_DODUO = 84;
    static HoloPokemonId V0085_POKEMON_DODRIO = 85;
    static HoloPokemonId V0086_POKEMON_SEEL = 86;
    static HoloPokemonId V0087_POKEMON_DEWGONG = 87;
    static HoloPokemonId V0088_POKEMON_GRIMER = 88;
    static HoloPokemonId V0089_POKEMON_MUK = 89;
    static HoloPokemonId V0090_POKEMON_SHELLDER = 90;
    static HoloPokemonId V0091_POKEMON_CLOYSTER = 91;
    static HoloPokemonId V0092_POKEMON_GASTLY = 92;
    static HoloPokemonId V0093_POKEMON_HAUNTER = 93;
    static HoloPokemonId V0094_POKEMON_GENGAR = 94;
    static HoloPokemonId V0095_POKEMON_ONIX = 95;
    static HoloPokemonId V0096_POKEMON_DROWZEE = 96;
    static HoloPokemonId V0097_POKEMON_HYPNO = 97;
    static HoloPokemonId V0098_POKEMON_KRABBY = 98;
    static HoloPokemonId V0099_POKEMON_KINGLER = 99;
    static HoloPokemonId V0100_POKEMON_VOLTORB = 100;
    static HoloPokemonId V0101_POKEMON_ELECTRODE = 101;
    static HoloPokemonId V0102_POKEMON_EXEGGCUTE = 102;
    static HoloPokemonId V0103_POKEMON_EXEGGUTOR = 103;
    static HoloPokemonId V0104_POKEMON_CUBONE = 104;
    static HoloPokemonId V0105_POKEMON_MAROWAK = 105;
    static HoloPokemonId V0106_POKEMON_HITMONLEE = 106;
    static HoloPokemonId V0107_POKEMON_HITMONCHAN = 107;
    static HoloPokemonId V0108_POKEMON_LICKITUNG = 108;
    static HoloPokemonId V0109_POKEMON_KOFFING = 109;
    static HoloPokemonId V0110_POKEMON_WEEZING = 110;
    static HoloPokemonId V0111_POKEMON_RHYHORN = 111;
    static HoloPokemonId V0112_POKEMON_RHYDON = 112;
    static HoloPokemonId V0113_POKEMON_CHANSEY = 113;
    static HoloPokemonId V0114_POKEMON_TANGELA = 114;
    static HoloPokemonId V0115_POKEMON_KANGASKHAN = 115;
    static HoloPokemonId V0116_POKEMON_HORSEA = 116;
    static HoloPokemonId V0117_POKEMON_SEADRA = 117;
    static HoloPokemonId V0118_POKEMON_GOLDEEN = 118;
    static HoloPokemonId V0119_POKEMON_SEAKING = 119;
    static HoloPokemonId V0120_POKEMON_STARYU = 120;
    static HoloPokemonId V0121_POKEMON_STARMIE = 121;
    static HoloPokemonId V0122_POKEMON_MR_MIME = 122;
    static HoloPokemonId V0123_POKEMON_SCYTHER = 123;
    static HoloPokemonId V0124_POKEMON_JYNX = 124;
    static HoloPokemonId V0125_POKEMON_ELECTABUZZ = 125;
    static HoloPokemonId V0126_POKEMON_MAGMAR = 126;
    static HoloPokemonId V0127_POKEMON_PINSIR = 127;
    static HoloPokemonId V0128_POKEMON_TAUROS = 128;
    static HoloPokemonId V0129_POKEMON_MAGIKARP = 129;
    static HoloPokemonId V0130_POKEMON_GYARADOS = 130;
    static HoloPokemonId V0131_POKEMON_LAPRAS = 131;
    static HoloPokemonId V0132_POKEMON_DITTO = 132;
    static HoloPokemonId V0133_POKEMON_EEVEE = 133;
    static HoloPokemonId V0134_POKEMON_VAPOREON = 134;
    static HoloPokemonId V0135_POKEMON_JOLTEON = 135;
    static HoloPokemonId V0136_POKEMON_FLAREON = 136;
    static HoloPokemonId V0137_POKEMON_PORYGON = 137;
    static HoloPokemonId V0138_POKEMON_OMANYTE = 138;
    static HoloPokemonId V0139_POKEMON_OMASTAR = 139;
    static HoloPokemonId V0140_POKEMON_KABUTO = 140;
    static HoloPokemonId V0141_POKEMON_KABUTOPS = 141;
    static HoloPokemonId V0142_POKEMON_AERODACTYL = 142;
    static HoloPokemonId V0143_POKEMON_SNORLAX = 143;
    static HoloPokemonId V0144_POKEMON_ARTICUNO = 144;
    static HoloPokemonId V0145_POKEMON_ZAPDOS = 145;
    static HoloPokemonId V0146_POKEMON_MOLTRES = 146;
    static HoloPokemonId V0147_POKEMON_DRATINI = 147;
    static HoloPokemonId V0148_POKEMON_DRAGONAIR = 148;
    static HoloPokemonId V0149_POKEMON_DRAGONITE = 149;
    static HoloPokemonId V0150_POKEMON_MEWTWO = 150;
    static HoloPokemonId V0151_POKEMON_MEW = 151;

    // VTable
    virtual boolean Equals(mvar obj); // 0 - 4d5e77c
    virtual void Finalize(); // 1 - 4da8e94
    virtual int GetHashCode(); // 2 - 4d5e794
    virtual String ToString(); // 3 - 4d5d9a8
    virtual String ToString(String format, String provider); // 4 - 4d5e61c
    virtual TypeCode GetTypeCode(); // 5 - 4d5b570
    virtual boolean System.IConvertible.ToBoolean(Boolean provider); // 6 - 4d5a9c0
    virtual byte System.IConvertible.ToByte(Byte provider); // 7 - 4d5aa78
    virtual char System.IConvertible.ToChar(Char provider); // 8 - 4d5ab2c
    virtual DateTime System.IConvertible.ToDateTime(DateTime provider); // 9 - 4d5abe0
    virtual Decimal System.IConvertible.ToDecimal(Decimal provider); // 10 - 4d5aca4
    virtual double System.IConvertible.ToDouble(Double provider); // 11 - 4d5ad68
    virtual short System.IConvertible.ToInt16(Int16 provider); // 12 - 4d5ae1c
    virtual int System.IConvertible.ToInt32(Int32 provider); // 13 - 4d5aed0
    virtual long System.IConvertible.ToInt64(Int64 provider); // 14 - 4d5af84
    virtual sbyte System.IConvertible.ToSByte(SByte provider); // 15 - 4d5b038
    virtual float System.IConvertible.ToSingle(Single provider); // 16 - 4d5b0ec
    virtual String ToString(String provider); // 17 - 4d5db8c
    virtual mvar System.IConvertible.ToType(Object targetType, Object provider); // 18 - 4d5b1a0
    virtual ushort System.IConvertible.ToUInt16(UInt16 provider); // 19 - 4d5b354
    virtual uint System.IConvertible.ToUInt32(UInt32 provider); // 20 - 4d5b408
    virtual ulong System.IConvertible.ToUInt64(UInt64 provider); // 21 - 4d5b4bc
    virtual int CompareTo(mvar target); // 22 - 4d5d838
    }
     
  11. khaccanh

    khaccanh

    Joined:
    Dec 10, 2012
    Posts:
    12
    In that link is the best that I can search through Google. It just decompiler java plugin of unity 3d by java tool. But someone must can revert IL2CPP if class and method name is stored in metadata.
    Do you think project should be obfuscator before release
     
  12. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    Hmm the "they be stealin my codez" circle jerk once again. Yes if your using the mono backend people can easily decompile it back to IL code again, or even back to any language that compiles to IL. Yes even with il2cpp you will never stop the dedicated ones from breaking into it as well. No you should not worry, or waste your time caring. No you cant stop it. Yes you must live with it.

    If someone made a straight up clones of your game, and you lose sales as a result, well that is just your fault, for not marketing it well enough, or monetizing off it well enough. Not to mention, people who have the skills to do the above, and market it better than you are most likely just going to build their own product.
     
  13. khaccanh

    khaccanh

    Joined:
    Dec 10, 2012
    Posts:
    12
    I just think unity should replace name class and method, varibles in metada by a random number .
    It is hard to understand a code with nonsense class method varibles. No one try to decompiler that code, it take more time than code by themself.
    You many time to imlement algorithm, test bug, ... But like mono backen just 5 minutes to decompiler .apk or .ipa to orgin C# code. It lead people steal code than code by themself.
     
  14. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    938
    I'd rather have UT devote development time to improving their own product than wasting time in the endless and lost battle of piracy and code protection
     
    Last edited: Aug 31, 2016
  15. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,964
    None of those functions are meaningful in the slightest.
     
  16. khaccanh

    khaccanh

    Joined:
    Dec 10, 2012
    Posts:
    12
    It is just virtual function. can be override
     
  17. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,964
    What does that have to do with my statement? Show me some functions and code stored within them and then I'll care.
     
  18. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    also even then you should not care
     
    Brity likes this.
  19. khaccanh

    khaccanh

    Joined:
    Dec 10, 2012
    Posts:
    12
    I am not person decompiler and hack pokemon go. So I can't show full code for you.
    I just confuse about if IL2CPP can be decompiled like mono.
    I am freelancer and use unity 3d to dev App. My customer need a native code, they don't want their opponent can decompiler in 5 minutes. So I need to sure IL2CPP can convert to assembly code. With Assembly code all name class and function is triped to random number. It is very hard to understand.
    But IL2CPP still store name class and name method in meta-data, so it is still reverted like mono.
    Although Pokemon Go is hacked but I think they just hack third-party plugin java language. And sniff packed to fake message with server. I don't think they can mod IL2CPP.
    But SomeOne show me the code they try to decompiler , and they said IL2CPP covert C# -> C++ but all name class and methed still store in meta-data.
    I think Unity can replace All name class and method in meta-data by random number. No one try to read an assembly code. It is good for all developer.
     
  20. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,964
    IL2CPP produces native code. Problem solved.

    Your customer is concerned about their code. Class and method names are not code.
     
    Deon-Cadme likes this.
  21. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,227
    But all our crash dumps and logs would be full or random named functions. We would have no hope in solving crashes/issues. Callstacks would be useless. If you have some super secret code then put it onto a server and communicate over the internet with it. You could also obsfucate the code yourself during the build process (https://www.assetstore.unity3d.com/en/#!/content/48919)
     
    Kiwasi and Ryiah like this.
  22. khaccanh

    khaccanh

    Joined:
    Dec 10, 2012
    Posts:
    12
    Thanks you.
    They don't have secret code. They just don't need their opponent decompiler easily. So I will recommend they use
    https://www.assetstore.unity3d.com/en/#!/content/48919
    I hope Unity will integrate Obfuscator like Visual Studio.
     
  23. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,964
    Except Unity never integrated Visual Studio. They integrated a third party asset that eased the process of using Visual Studio but the IDE itself is still very much a standalone program. That's likely how an obfuscator would end up too.
     
    Last edited: Aug 31, 2016
  24. Lostlogic

    Lostlogic

    Joined:
    Sep 6, 2009
    Posts:
    693
    From what I can tell, the main thing you could potentially worry about are API keys as they are exposed just like everything else.
     
  25. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Correct.

    Visual Studio doesn't have an integrated obfuscator (the exception is when compiling to UWP from .NET which uses .NET Native - this isn't an obfuscator but a native compiler much like IL2CPP). Visual Studio used to ship with a community edition of Dotfuscator, but it was a third party plugin for Visual Studio and not an integrated part of the IDE itself.
     
  26. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    This post is fairly obfuscated and hard to understand. Just code like you post and you'll be all good.

    :p ;)
     
  27. Le_Tai

    Le_Tai

    Joined:
    Jun 20, 2014
    Posts:
    442
    Or in another word, copy your code to Google Translate and compile the result :)
     
  28. Ostwind

    Ostwind

    Joined:
    Mar 22, 2011
    Posts:
    2,804
    I write all my private projects and tools in Finnish language and cause of the nature of the language and how long and complex compound words we can easily use combined with code/technical words it's sometimes as good as some obfuscation output to foreigner, or even harder if they try to use translators which get confused very fast :)

     
  29. tswalk

    tswalk

    Joined:
    Jul 27, 2013
    Posts:
    1,109
    if I saw code written in Finnish, I would personally throw my hands up and walk away... it was hard enough to just read the street signs there.
     
  30. ZandyLol

    ZandyLol

    Joined:
    Jul 25, 2016
    Posts:
    7
    I absolutely agree with you, IL2CPP will do nothing!
     
  31. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,646
    I remember back when we first released IL2CPP we received quite a number of bug reports where variables/fields/methods/properties didn't quite work if they had chinese characters in them. The repro project was all chinese. It was fun debugging.