Loading of encrypted love files - closed source code.

Issue #1280 new
Triangle345
created an issue

I know for many years users have asked how to create closed source games. Whether it be for profit , anti cheat, intellectual property or whatever; they deserve to optional security.

I know some ideas from love2d community regarding this topic are:

  • Copyright your code. License is everything.
    • Copyright doesnt mean anything to cheaters or people from other countries trying to steal your hard work.
  • You can bytecode compile lua files.
    • This is easy to bypass via many lua de-compilers out there.
  • Obfuscation.
    • No better than a decompiler really.
  • Write logic on server while keeping the user client bare bones.
    • Sometimes we want heavy logic on client side for performance. Why should we need to do so much extra work with love2d to keep it secure if we want?

Now there is no 100% full proof remedy for reverse engineering lua code or even binary files, however you can make it damn hard; so that 99% of people trying would quit.

Lua's easy interpolation with C allows it to do just that. We can create custom loaders for lua (e.g table.insert(package.loaders, 2, load)) to handle encrypted love2d files. The key would be hidden away within love2d itself. When the love2d game is about to execute we read and parse all these encrypted lua files into memory; un-encrypting them and loading them into lua VM via the custom loader I mentioned previously.

We can create a simple "packager" that encrypts every file and stores this key; thus making the level to entry in recovering the user's hard work; non trivial.

I've been looking at the love2d code base a bit and i have some ideas where things might go but thought I would propose this idea to see what people think or if anyone wants to take a jab at it?

Comments (44)

  1. Raidho

    I will just reiterate key points everyone worth their salt would bring up in this type of threads:

    0) Open source doesn't precludes commercial sale of the software
    1) Closed source doesn't stops piracy
    2) Closed source doesn't prevents ripoffs from existing
    3) Closed source doesn't makes it harder to cheat in the game

    You can sell open source software. The only thing different from closed source selling process is that you also provide source code along with the finished product, or anywhere really, it doesn't matter.

    If you have anything worth protecting, protect it legally. Use copyrights for assets and patents for software. Otherwise, if anyone gets their hands on it somehow, then you're shit out of luck. You're betting on people not caring enough to go all the way to do it. In other words, you're trying to protect something not worth protecting. If people aren't willing to tear through your game to rip out its contents to start with, what makes you think it's a good idea to invest time and effort into stopping them from it?

    People have been very successful in creating ripoffs over the years without any access to source materials. Having such access wouldn't make it any easier. In fact, if it was a direct copy and paste job, it would be a no-brainer to sue the offender into extinction because it would be piss easy to prove it's a copyrighted software and/or assets.

    Existence of software such as Cheat Engine and ArtMoney makes the cheating point completely moot. And that's not to mention more sophisticated tools that can go as far as to monkey-patch the game to execute arbitrary code. Cheaters don't even need to have access to the binaries, it's enough that the game is loaded into computer memory and running.

    Now regarding your suggestion, there's a reason why encrypted files don't have their own encryption key in any sort of vicinity. That sort of protection will never work. Also, if we go by your numbers, then if your game is only owned by 1000 people, there should be about 10 people savvy enough to dig right right past all protection it and upload everything online. Now consider how many sold units warrant cracking full-on DRM, and how little sold units don't warrant bothering with using it because impact of it getting compromised would be insignificant anyway.

    Finally, I'd like to address this basic misunderstanding:
    high degree of code obfuscation is not a desired property of conventional video game binaries, it's a byproduct of the way they are produced. Machine code is naturally not very readable, but that is not a feature, that's a problem that has to be sidestepped through use of compilers. As you should know, in heyday of assembly, x86 family processors greatly increased amount of instructions just so it was easier for humans to read and write assembly - not the opposite way. Today, many games opt in scripted languages despite them being pretty much source code in plain sight, leaving to the C++ side only the heavy lifting within the engine. You do not need to follow the unspoken cargo cult, as you do not need to rationalize all the quirks you may encounter as something meaningful or helpful.

  2. Gabe Stilez

    I wrote up a gigantic block of text as my answer, but Raidho more or less said the same things i wanted to point out, and even more.

    But to add a bit more to it, you talk about hiding stuff within Löve; but since it is an open-source project (at the very least in the fact that the source code is there for all to see), so there's nothing you could "hide" inside it in the way you'd want to; especially not a key to some magical encryption or obfuscative (totally a legit word) algorithm/function.

    If you want to do something like this, then that's your perogative, of course; feel free to load in C libraries, use the FFI to munge data and functions, and specifically addressing your last point with server authentication, implement that in a solely singleplayer game, to appease the likes of Ibusoft and AE, that people already loathe for such shenanigans. :3

    Also, just to point out something, server-side data verification for multiplayer games tend to not compute too much stuff there, only logic related things; client sends server input, server sends client good data, like position, etc. Your comparison would mean that the server would need to actually render each viewport, and stream the graphics and sound to each client, as an extreme example.

  3. Triangle345 reporter

    I understand and 100 % agree with what you guys are saying.

    My rationale is this: Think of your game as your house. You have a door that locks, windows that lock, etc. Now on your front door most people have more than 1 lock. What is the point of having more than one lock, an experienced enough robber can pick any lock. Or hell just kick down the door. Now let me ask you something, if you were a "casual" non expert home robber would you go for a house with the door wide open, or go for a steel closed door with an ADT security sticker. Even though the security sticker is fake and the door is actual made of wood, the robber would probably hit the open house.

    What you guys are saying is kind of analogous to "hey lets leave the door wide open and hire a security person with a gun to stand in front 24/7".
    Sure I understand it is not full proof, but just like the locks of your house or car; it is meant for the illusion of safety with minimal cost. All we can do is raise the barrier to entry.

  4. Gabe Stilez

    I think i will paste my block of text after all, since i believe i also tackled this point of view in it... may be wrong though, still, should be an interesting read. :3 I also edited it since when i wrote it, i was a bit more salty, as Raidho put it, than i am now, so hopefully it won't feel personal, because it's really not.

    Deserve is an interesting word you chose to use here. Let me offer some rebuttals, in the form of a /short/ novel:

    • Copyright:

      Some entities (companies or individuals) produce programs (games or otherwise) worthwile to rip off. Unless you're <"anich">, all those ripoffs will do is copy the mechanics at worst, something you can't copyright... and if they are stupid enough to steal your assets, their copy will 1. suck enough for people not to care about, and 2. won't be marketed anywhere but <"anich">.

      And let's be honest, unless you're one out of, i don't know, a million, you probably won't invent the next Pong or Fez.

      Also, those that do belong in such categories usually have enough finances to back them in legal proceedings, with regards to copyright infringement... though many times, a simple notice is enough to, pardon the profanity, scare them shitless.

      Sometimes this is a good thing, you /really/ don't want the kind of cesspool to build itself up what steam greenlight's deeper bowels have become; numerous exceptions notwithstanding, of course.

      That said, it can also be sad, like how a really talented group just wants to add a different perspective, like the Chrono Trigger 3D game that was made by a few hobbyist... before Nintendo sent them a C&D, /after years of progress/.

      So yeah, the worst thing that usually happens is that someone rips your mechanics off and releases a game quicker than you, better or worse in any regard, it doesn't matter; they'll almost never will copy your assets... unless you yourself found them on free art asset sites, or bought them from the Unity ASset Store;... :3

      ...unless you want to be part of the very oversaturated mobile/handheld market, asset stealing might be a tad bigger there.

      Oh, and those that create free games (whether opensource or not) won't really be negatively impacted by such things, though it's still a douche move.

    • Decompilers:

      Let me reiterate: "Some entities (companies or individuals) produce programs (games or otherwise) worthwile to rip off."

      People, individuals or groups, have decompiled tons of code, and there's no stopping them.

      Whether they do this for the challenge of it, or for fame, for monetary gain, or just because they can, doesn't matter; it will be done eventually, if enough interest exists on part of the perpetrator.

      Besides, compiling löve related lua files to bytecode literally does not accomplish anything, since the speedup is only for loading the code, after it's in memory, it will take the same amount of time to execute it if you had loaded a plain lua file.

    • Obfuscation:

      I find it a bit weird that you devalue obfuscation and compare it to decompilation, moreso since this one -can- prolong people's attempt at understanding -source code-, which is available if one uses löve to distribute games.

      I do agree though, that if it's already compiled, then unless the obfuscation is functional instead of just variable name mangling, it won't matter, since people search for what things do in the decompiled stuff, not what their names were... usually.

      What i mean by the above?

      playerHealth = playerHealth - enemyDamage

      and

      qw = qw - jk

      are practically the same, whereas

      result = first * second

      is far more easier to comprehend as a simple multiplication than

         result = first
         result = third - 53
         second = second + first + 22
         first = result + 31
         result = (first - second + 53) * second
    

    ...and the above is most certainly wrong, and i did that on purpose; sane people don't shoot themselves in the foot like this... and there are plenty of instane devs out there still, who do. :3

    • Server-based:

      Yes it's extra work, but there are a few things one should realize:

      There ain't no such thing as a free lunch, as the saying goes;

      Really, you don't even need to do heavy logic on the server side, you just need to send inputs, and the server passes back valid data about your client's world; Calculating sprites, stuff specific to your own viewport into the world, even inverse kinematics in a 3D game (where that's just eye candy).

      And we're not even talking about MMO-s, which are their own kind of horribly complex monstrosities of code and data(bases) combined. I myself used "community"-developed Lineage II servers; i saw the code, i saw the amount of data needed... and it still was missing A LOT of things.

      And of course, here's this: Multiplayer games have the luxury of server-side verification, but for single-player games, this kind of thing becomes a gigantic nuisance when the person that bought your game wants to enjoy it however -they- please, including cheating and all the works. Why? Because for them, it's more fun that way. You disagree? Well, then they won't buy the game, or if they will, they will hate your guts. Look no further than Ubisoft, that's a prime example pushing always-online checks as DRM... not that that reduced the amount of pirated games from them.

    Now on to your idea:

    • table.insert(package.loaders, 2, load)

      And where do i have the option to not override a perfectly valid loader?

    • The key would be hidden away within love2d itself.

      Löve is opensource software, so whatever you wanna push into it, it'll never be "secret" nor "hidden".

    • When the love2d game is about to execute we read and parse all these encrypted lua files into memory; un-encrypting them and loading them into lua VM via the custom loader I mentioned previously.

      First of all, you need to first decrypt them after loading them in, but before letting lua/JIT parse the files.

      Second, cheatengine. It's a neat little thing that reads memory locations for data, and can create scripts that, for example, after the human found where the code starts to decode into memory, it'll simply just copy the data over to a private memory location, and then maybe dump that to a file.

    • We can create a simple "packager" that encrypts every file and stores this key; thus making the level to entry in recovering the user's hard work; non trivial.

      Stores the key how? What kind of packager? Is it a separate program? One way or another, if you don't supply the key to a decryptor, it won't work, and the moment you do, the key is out in the open, no matter how little time it'll spend on the device the client's on.

  5. Triangle345 reporter

    Thx for the informative post. Definitely appreciate the time you took to explain.

    I agree with all your points. There is no need to convince me. All i'm stating is that it is a thin layer that will add some security to people who so choose. What ever their reasons might be. I'm not saying we have to rewrite the entire love loader. Only at the expense of a new package handler.

    We do not have to override any handler it was simply an example. This can be just an extra handler for , I dont know, ".d2evol" encrypted files. Etc. The key can be dynamically made at request and "stuffed" dynamically into the love.exe executable memory. Think of "char lovekey[32]" memory space.

    When you mention CheatEngine, you have to fire that up and start doing analysis. This can be quite a pain trying to determine which variables to what. Whats in memory and where, etc. It may not be worth it for you, especially if your running low on time. However; if I give you a javascript file you can easily view all the source code with no tools except a notepad. There is definitely a barrier to entry.

    This will also separate love2d amoungst other game frameworks such as unity, libgdx, phaser, etc. All those engines essentially have 0 focus on security. They may have some minimal obfuscators built in but nothing like what im proposing. What I'm proposing is more involved, to another level which someone would actually have to fire up "CheatEngine" to analyze the code. They would need to be comfortable with a different set of skills rather than the normal script kiddie type stuff.

    However; both of you made valid points and I agree with you. If you guys feel this feature is not for Love2d, I totally understand why. Just throwing this out there because of the unique nature lua has with c and the ability to force people to go more lower level to crack something.

  6. Triangle345 reporter

    Also if one wanted we can make it extremely easy to move this keyspace to any memory space within the application this making it extra annoying for anyone using CheatEngine.

  7. Bart van Strien

    Regardless of whether you'd want to encrypt your game or not, I don't feel like love (the project, not the binary) is the appropriate place to do so.

    For such a packager to work the key needs to be stored in a known location, i.e. you can extract it from there and decode. And basically any solution suffers from the same problem.

    Worse, since love is first and foremost a program that wants to run lua code, what prevents me from writing an unencrypted lua file that uses your custom loader to get the bytecode of the encrypted (then decrypted) files? Do you then also need code signing? And what enforces that? Can I bypass it by injecting code that calls the lua API directly?

  8. Triangle345 reporter

    Well we could have a "finalized" setting for love which takes a "snapshot" of the current state of the game. For example if you have 3 files, love can be aware that the game is finalized for deployment and no more extensions can be added (unless the user adds some exception to this).

  9. Triangle345 reporter

    Another thing, we could set a love flag that only uses one loader, the decryption loader for a "finalized" deployment. That should prevent casual introspection.

  10. Triangle345 reporter

    So just in case we need it I found an example of Love replacing the loader:

    wrap_filesystem.cpp

        // The love loaders should be tried after package.preload.
        love::luax_register_searcher(L, loader, 2);
        love::luax_register_searcher(L, extloader, 3);
    
  11. Alex Szpakowski

    LÖVE doesn't remove any of Lua's own loaders, they're still there and if you use require it will still try them if LÖVE's loaders fail to find a file.

    You can add your own or remove existing loaders without ever touching LÖVE's source code (inside a plain Lua file or inside a C dll loaded with Lua, if you want) FWIW.

  12. Raidho

    You did mention that other engines have basically zilch worth of technology and features in that department. You think that's for a reason?

    You brought up a house analogy, in which you missed the point. I'll bring up a different analogy, more to the point:

    You have a house, and you want people to use that house. But also you don't want strangers to barge in and take photos so you lock it up. And since people need to be able use the house, you leave the key hanging on a nail by the door. That highlights the core problem with this sort of approach. It just won't protect anything.

    Lastly, it's not that there are reasons not to attempt this. It's that there's no reason to do so. On top of being meaningless to start with, it's not even technically feasible and will accomplish nothing.

  13. J.W

    The "high-barrier" idea is good, either for anti-cheat or anti-copycat (not anti-copyright-infridgement), or just for hiding your crappy code :P Adding to the house analogy: you cook for the guests but you don't want them to know your recipe; you invite your friends but only allow them to play in the living room. (Do you want to see Dwarf Fortress open-sourced? The authors say NO.)

    I can feel the hostility of some people here, and I think @Triangle345 just wants to add this optional feature. Those who are really enthusiastic about open-source can just ignore this funtionality. So my first question is: does this project force any OS ideology upon game developers? Or do you think this feature will place a big burden on this project?

    Edit: fix grammar

  14. Gabe Stilez

    @J.W Löve using lua is already "high-barrier" enough in terms of anti-cheat; i feel like i should use the FFI /more/ just because C variables would retain their memory locations, unlike those in the lua part of the code.

    Anti-copycat can't be avoided either, since they'll rip off the mechanics at a glance, or at the worst, your assets; "they" don't need your code.

    As for your analogy, your guests are actually 6-year-old shits who won't listen to you, and would rather break everything including the kitchen sink in your house.

    By the way, i don't think anyone was hostile, just that the opinions were expressed pretty bluntly; nor that the project forces any kind of ideologies... i mean, even Unity which is more of an engine for commercial releases, doesn't have this kind of thing in it, for reasons detailed above; If @Triangle345 wants to obfuscate/encrypt, they're free to do so on the lua side, it won't be better or worse than making the Löve devs integrate it on the C++ side.

  15. J.W

    @Gabe Stilez If I can just unpack the package and seach for some keywords in the script, that is not enough.

    I understand all your points about "useless encryption", but you just over-simplified the matter. So I threw out Dwarf Fortress for example (it has been there for years but yet no one makes an excellent similar game, not to mentioned other big commercial games). Everyone should have his/her choice to accomplish some purposes, at least before the game is fully hacked.

    Anti-copycat can't be avoided either, since they'll rip off the mechanics at a glance, or at the worst, your assets; "they" don't need your code.

    That depends on what type of game you are developing, and how much you can copy, and who plays your game. Only a glance cannot give you all the details of the mechanism. How many years do you need to master the ideas? Are you afraid of being acused of plagiarist in the community? Will that affect the ecosystem badly (regards to innovation and economy)?

    As for your analogy, your guests are actually 6-year-old shits who won't listen to you, and would rather break everything including the kitchen sink in your house.

    It is interesting to see what they can do. There are so many games in the world, and how many are hacked into the core? How many Dwarf Fortress clones do you see? What if my game is only for a small circle and I just don't want to share the source code?


    If people keep oversimplifying this idea, no doubt I would wonder whether some OS guys are preaching here.

  16. Alex Szpakowski

    I threw out Dwarf Fortress for example (it has been there for years but yet no one makes an excellent similar game, not to mentioned other big commercial games). Everyone should have his/her choice to accomplish some purposes, at least before the game is fully hacked.

    Most game code is fairly useless without the broader context of the rest of the game. Clones don't usually clone code, just a (perhaps modified) version of the idea. Dwarf Fortress is notorious for being very tough for new players to get into, which is why you don't see many direct clones, not due to source code readability. There are many DF-inspired games which have more accessible UX. And many addons which make its UX more accessible.

    To me, this sort of idea just gives a false sense of security while adding a burden to myself (a LÖVE developer). I don't think it actually does anything really useful. I speak from experience in the open source community, experience as a solo indie commercial developer, and experience from within a team at an 80-person game development studio.

  17. Triangle345 reporter

    To me, this sort of idea just gives a false sense of security while adding a burden to myself (a LÖVE developer)

    Isnt all security just obscurity. Yes given enough time, any security context can be cracked. AES gives a pretty good sense of security but eventually it can be cracked. MD5 collisions are now easier than ever to create. Everything is relative.

    Dwarf fortress is insanely popular. However I guarantee you that if it were written in javascript no obfuscation we would see a lot more mods for it. In particular, graphic mods. And extensions, things that extend the base game.

    The kind of security that @Alex Szpakowski and others want is not achievable without extreme amounts of work. I'm proposing a simple idea that would make it a magnitude better for security conscious people to sleep at night.

    And no one was hostile, dont worry. I fully understand that hardcore open source advocates will hate this idea. But forcing people to use open source is just as bad as forcing people to use proprietary. People want different rewards, people gotta eat, who knows the reasons. Let the developers choose what they want for their game.

  18. Gabe Stilez

    @Triangle345 :

    Isnt all security just obscurity.

    Not at all; AES, or more precisely, all cryptographical algorithms under the "AES" moniker are well-known, what guarantees security is the fact that the key sizes are big enough, and that those are the only things you don't share with anyone. There's also Public-key Cryptography, which can be also useful; neither of these techniques are obscure.

    Also, MD5 and SHA-1 (now also cracked) are hash functions, you can't get back the original data from them, so they're kinda pointless in our source code encryption discussion.

    Obscure would be me doing weird undisclosed stuff on bytes or words of data, mirroring chunks, flipping bits, etc. You don't know the algorithm for what i'm doing.

    That said, for both AES/Pub-key and my obscure method, you (that is to say, the client) need a key (or the algorithm itself, in the case of the last one), in order to un-encrypt/un-obscure the code, so it can be executed.

    Dwarf Fortress is, as was said before, also insanely complex, for what it is. Let me give you another example, Notch obfuscated variables in minecraft, which was written in java. It didn't stop people from creating modding APIs (plural) over time, and even on the forums, people tend to refer to code snippets with the variable names still obfuscated, since they literally grew accustomed to reading it that way.

    The kind of security that Alex Szpakowski and others want is not achievable without extreme amounts of work. I'm proposing a simple idea that would make it a magnitude better for security conscious people to sleep at night.

    Don't take this one too personally, but to me, the above read like this: "Real security measures are too hard, but implementing something that has no real world use-case other than letting uninformed people sleep better at night would be worth it."

    @J.W : Calling people "Hardcore Open-Source Advocates" is a bit unjustified... and besides, no one's forcing you to do anything. Also, do explain what you find wrong with "false sense of security"? Implementing something that doesn't help with security is like that, i don't see the reason for the quotes.

  19. J.W

    @Gabe Stilez Note: I just said "really enthusiastic", not "hardcore". And I apologize for impatiently mislabeling just for the lenthy discussion around the oversimplified matter.

    and besides, no one's forcing you to do anything. … Implementing something that doesn't help with security is like that, i don't see the reason for the quotes.

    I know, I just want to make it clear if the project members can support this idea. But before that I also want to point out the oversimplification in your opinions. Do you mean "no encryption is perfect so no need to do that"? And I just need "high-barrier to modify/copy the game", not absolute security. We have different needs.

    Also, do explain what you find wrong with "false sense of security"?

    The DF game is an obvious example. Not just because it is complicated. If you don't get the source code, you just continue to do some dirty hack. Even if @Alex Szpakowski don't feel like close-source protection, the effect is "real" to the normal players/hackers. No matter how imperfect the game looks, you cannot change much.

    Notch obfuscated variables in minecraft, which was written in java. It didn't stop people from creating modding APIs (plural) over time, and even on the forums, people tend to refer to code snippets with the variable names still obfuscated, since they literally grew accustomed to reading it that way.

    So can you explain the case for DF? Just because Java is easier to hack? Aside from games, there are all kinds of softwares without that complexity. You may change some bytes but never get the source code, that's all about it.

  20. Raidho

    I will bring up again the

    false sense of security

    Emphasis on "false". None of these measures, nor any concievable ones, will actually improve security. The only "benefit" is that you can feel that it's secure when it actually isn't. With same exact results, you can simply pretend that it's secure when it actually isn't.

    Save your game on flash drive and sink it in holy water, that'll make a better protection than any software methods.

    Also,

    No matter how imperfect the game looks, you cannot change much.

    How is that a good thing. How permanently poor implementation is a good thing. How complete lack of modding support is a good thing. How reduced sales due to poor implementation and lack of modding support is a good thing. Just how. That doesn't makes any god damn sense. And so is the whole idea of obfuscating and encrypting game content.

    The only place where this might hold any weight is inside of DRM engine, but even then one can argue that you don't need DRM to start with because it's the same type of feelgood useless thing as content access prevention.

  21. J.W

    How is that a good thing. How permanently poor implementation is a good thing. How complete lack of modding support is a good thing. How reduced sales due to poor implementation and lack of modding support is a good thing. Just how. That doesn't makes any god damn sense. And so is the whole idea of obfuscating and encrypting game content.

    @Raidho Unless you can hack any game to any form you like, those are your sour grapes. My emphasis (and @Triangle345's) is just intended to set high barrier, now you ask for some holy reasons for not open-sourcing the game? That's weird.

  22. Triangle345 reporter

    what i'm talking about has nothing to do with game play, game implementation or even performance. I'm talking about a new feature for LOVE that few engines have. GoDot has script encryption and people use it. Unity does not. This will set us apart from the pack even having a feature like this. The fact that it is encrypted will already turn 90% of people off from hacking/cheating/cracking. The fact that the key is in some random memory location will turn off another 5 percent. The next 5 percent you can simply ban from servers/account ban if multiplayer

  23. Gabe Stilez

    @J.W:

    Apologies, my last post with the "hardcore open-source advocates" was meant for @Triangle345, not you.

    . But before that I also want to point out the oversimplification in your opinions.

    I don't feel like i oversimplified things, then again, that's subjective.

    Do you mean "no encryption is perfect so no need to do that"? And I just need "high-barrier to modify/copy the game", not absolute security. We have different needs.

    I meant that the kind of encryption both of you want is either not of use for any reason, and can be done on the lua side, resulting in the exact same amount of protection than if it was implemented in löve itself.

    The DF game is an obvious example. Not just because it is complicated. If you don't get the source code, you just continue to do some dirty hack. Even if Alex Szpakowski don't feel like close-source protection, the effect is "real" to the normal players/hackers. No matter how imperfect the game looks, you cannot change much.

    I'm feeling like there's at least two issues going on here in paralell; one would be regulating hacked clients in multiplayer, and the other being a way to not even allow people to touch the client itself.

    Again, for multiplayer games, you do server-side checks; that's the only way to ensure that modified clients won't pollute the multiplayer experience; for singleplayer, you shouldn't care at all.

    @Triangle345:

    what i'm talking about has nothing to do with game play, game implementation or even performance. I'm talking about a new feature for LOVE that few engines have. GoDot has script encryption and people use it. Unity does not. This will set us apart from the pack even having a feature like this.

    As was previously stated, maybe there's a good reason why Unity and the like don't have it. And as was previously stated, people stealing your code should be the least of your concerns.

    The fact that it is encrypted will already turn 90% of people off from hacking/cheating/cracking. The fact that the key is in some random memory location will turn off another 5 percent. The next 5 percent you can simply ban from servers/account ban if multiplayer

    Okay, so now you're talking about 1. hacking, which means modifying the client, which has no repercussions on the multiplayer parts, since the server should be authoritative, as i already said; 2. cheating, which the previous point covers, and again, you should not care if people cheat in single player... it's already hard to use CheatEngine with löve because it uses lua, which again, is something i already said; 3. cracking - not sure if you mean like, copy protection here, like those older games had, e.g. Red Alert 2, that needed a "CD key" for it to work; those can again, be implemented in lua if you'd prefer, though nowadays, you could just give out a loader, and if the server accepts whatever key you give your buyer, it will download the actual game... and if it doesn't, it won't download anything.

    The next 5% is moot, since if the client is already decompiled by hackers (it needs to be unencrypted at the execution stage anyway), the memory location can be found easily.

    Finally, that last 5% will include one person who will write a quick and dirty unencrypter that will work 100% of the time, making all this effort basically worthless, as it was stated before.

    tl;dr: The best you can do is to give people loaders, that require a key to download the actual game; Use authoritative servers to filter out people with modified clients.

  24. Triangle345 reporter

    I'm not sure how a loader that downloads the game will verify the client is legit? They can simply spoof the tcp/ip connection to be a fake loader. They can simply dump all the traffic out and analyze it. If it is encrypted and written in lua, this traffic can also be dumped out from lua.

  25. Alex Szpakowski

    LÖVE will not implement DRM for you. I believe you can use Steamworks to do that on PC.

    For networked multiplayer games, you need your server-side code to verify that any data the client is sending is legit. It's not the client's responsibility.

  26. J.W

    Ok, if you think Encryption = DRM (yeah, DRM includes encryption), then I have nothing to oppose. I just mean "high barrier", regardless of copyright infringement. I don't think Love2D developers want to call the lawyer on my behalf.

  27. J.W

    Just to make it clear you don't misuse the word "DRM". From what @Triangle345 said, I think encryption is an important part for the client, though it seems that he only wants to apply this technique to online games.

  28. Alex Szpakowski

    The fact that it is encrypted will already turn 90% of people off from hacking/cheating/cracking. The fact that the key is in some random memory location will turn off another 5 percent.

    You don't need to use the key to decrypt it, you only need to modify things just enough to get the program to output the decrypted source code. From there it might be trivial to load your own arbitrary raw code. (for example, modifying a string filepath in the executable file to point to a slightly different location may allow you to bootstrap your own Lua code which the game will execute. Said code may change the game's own code in order to get it to output its own source after decryption).

    I have done this before in a real commercial networked multiplayer game. If you are a developer patting yourself on the back for having 'encryption' in the client and a malicious user does such a thing, the only thing that will prevent other users' online experiences from being ruined is if you have server-side verification and protection against invalid data sent by a client.

    Your game is not secure at all if you use encryption that allows what I described above.

    If you have a non-networked game there's not much to worry about because the only experience that can be ruined is the hacker's own experience, therefore modification of singleplayer game state is not very harmful and trying to prevent it is not a particularly good investment of LÖVE's development resources.

  29. Raidho

    I know a few ways to implement such encryption, with cracking difficulty ranging from trivial to jawbreaking, and so can @Alex Szpakowski no doubt. I'm arguing against it because I'm being intellectually honest. I will say upfront that no asset protection will stop anyone industrious enough to dig into the package, and once it's compromised it might as well never been there.

    I can, and maybe even will, implement something like that. But it will not be the great solution to developers' woes, because it is always crackable. Simply letting such feature exist however would be a deliberate dishonesty to LÖVE users. Because it implies such ideas that simply do not connect with reality, and cognitive bias will make people ignore all statements about its inherent weakness. It will only lead to delusions at best, and dissatisfaction with the engine at worst.

    And besides, I don't want to encourage people to clam up and decay over their precious assets like some greedy villain. I want to encourage people to be free and open, to tinker and improve other's work and better their own selves.

  30. Triangle345 reporter

    Can you provide a few of your ideas. I'm intrigued to hear them. It will be informative to this thread and future endeavors if people ever reopen this. Nothing too detailed but just a general gist of what you would do.

  31. Bart van Strien

    Anyway, if there was an inbuilt method you could easily enable by writing a key somewhere (as was suggested), then the location of the key would have to be known. Which means anyone can extract it from the same place. And of course that's provided it's easy to build such a tool in the first place.

    If you want to be able to hide your key somewhere, odds are you'll have to recompile love anyway. And at that point you may as well build (or find) the protection solution that fits your exact security model. In a sense the "safest" solution is to have a non-stock love, as defeating your protection could entail more than decrypting it and running it on a stock love build.

    It's not really a priority for me, but if someone wants to build a good solution and upstream it, I'd definitely consider it. And a good solution wouldn't be an XOR, and probably not even AES. I think the best solution for use cases like these is asymmetric encryption, as you also get "free" code signing and it's harder to modify the game even after decryption, since you might have to re-encrypt it, yet the encryption key doesn't need to be distributed.

  32. Raidho

    One very basic approach is to make it encrypt the .love package with the key hidden within the same package. The LÖVE app will know where to find the key but it will be impossible to open the package otherwise. It will run on any LÖVE executable with appropriate functionality. Another basic approach is something similar to what Godot is doing, a compiler-supplied key that produces a game-specific executable only work with the package encrypted with the same key. It has a downside of having to manually compile the LÖVE app for every platform, chances are you will not be assed to support anything but Windows even though bare .love package can run on any OS. The distinction between the two method is key location, one contains key in package and the other in executable, both are equally easy (difficult) to crack, so security-wise there's no difference, but second method is clearly more cumbersome to use. Other "more sophisticated" methods are usually the variants of above, they are not harder to crack.

    I'd yet again would like to state that encrypting content is probably not a very good idea anyway. Maybe you'll take argument from authority: navigate to your Steam games folder, browse contents of any game. You'd normally find game content packaged, but not encrypted. Chances are content is not even packaged, and is simply stored as raw files. Which is to say, professional game studios big and small don't use game content encryption. If these people think content theft is not of any concern, maybe you should too.

  33. Bart van Strien

    I do not readily see how asymmetric encryption would work in any advantageous way over symmetric encryption. You still need a decryption-capable key stored in direct vicinity of encrypted file.

    Yes, but you cannot re-encrypt. Of course if someone can decrypt your game and run on stock love that won't help you. An additional benefit is that you get code signing pretty much for free.

    One very basic approach is to make it encrypt the .love package with the key hidden within the same package. The LÖVE app will know where to find the key but it will be impossible to open the package otherwise.

    How would love know where to find it, without having other software (or even a modified love version) also able to find it? And do you mean the contents of a .love, or the .love itself? Because in the latter case.. isn't the key encrypted? And it also becomes very difficult to implement.

  34. Triangle345 reporter

    I do not understand what you meant by "key in the same package". Do you mean that with any love program you would distribute a second binary with a key hidden inside that only love runtime would be able to "find"?

  35. Raidho

    @Bart van Strien I simply mean that key is inserted somewhere in cyphertext. Of course you cannot decrypt a cyphertext with a key that was inside plaintext and is now inaccessible. I know it's not truly secure but neither is Denuvo.

    Also, should it even matter if even a simple XOR is used? Shouldn't it be impervious to cryptographic attacks since it's the single instance of cyphertext encrypted with this particular key to exist and would-be attacker has no means of delivering attack anyhow?

    @Triangle345 Not sure I follow your quesiton. But the idea is that you'll produce same .love packages, except they're encrypted and thus cannot be simply renamed to .zip and opened.

  36. Triangle345 reporter

    Going back to the "loader" idea a few threads ago.. what if there was a binary loader which would grab the lua files from a safe location and give them to LOVE, which would load lua code from memory only? Then you wont really need to encrypt anything but just provide a framework for secure distribution. This safe location could be an encrypted archive, from online, etc.

  37. Log in to comment