So i've herd a lot of times from a lot of people that it's stupidly easy to decrypt anything made in bgt, like sounds etc. Most of you have probably herd of the BT sync folder called moresounds, which is basicly a huge ass folder full of different game sounds as well as some sounds ripped from libs like sfx kit amung other things. I was wondering if anyone could explain how people can do that stuff? I'm not trying to hack anything, i'm mainly just wondering if there's any way of protecting against that sort of thing.
Unfortunately, there's ways to rip sounds and data no matter how you encrypt it, you could package them in a dat file or something, or in the game's exe, it doesn't matter, there's ways around it.
I've entertained the idea of completely serverside sounds...
Contact information:email: [email protected]
Skype: Brennan Draves
I'm usually found on online games, chatting, and being warned bye admins for talking to much, f**k you admin!
#3 (edited by cartertemm 2019-02-26 19:41:54)
Admins, could you please watch this topic? I feel here lies the potential for a great deal of destructive information getting leaked, the last thing this community needs is the ability to rip assets out of games especially in these times.
I'll go ahead and skip to the second portion of your question, as I believe there's enough dishonesty to go around without a publicly easy-to-follow guide for everyone. This is done following standard disassembly. thus, I'd be lying if I said there was a good one fits all protection mechanism.
Redfox, sounds.dat can be broken. Serverside sounds are not only an insane usability sacrifice but false sensse of security. Let's not make our games suck because we're spending more time attempting to devise complicated algorithms to prevent someone from getting your sounds. That's what a license is for.
The short and generic answer, if someone is smart and determined they'll break your protection no matter what. If the computer is able to read it, so can a well skilled attacker.
However, you can make the process significantly more difficult. As someone who considers disassembly a hobby, I can only give a couple rough bits of information. It's then your job to combine them into as tight of a system as possible. If you would like me to give suggestions on a specific implementation, get in contact off forum. I'll try to put it as simply as possible without really getting into technical Intricacies.
Builtin functions are a partial issue. Given the ease of determining an address for a function in the BGT standard library, one can simply wait until it is called and get more information. Take string_encrypt for example.
The attacker would probably allow your game to execute until he found a call to the address of string_encrypt, obtainable with any decent disassembler. He could then examine the parameters or return values. Mathematical operations can be harder to track down however, since the computer is performing hundreds per second. Basically, try and avoid the call to builtin functions for encryption whenever possible. Stick to your own system. I personally recommend doing a bit of research into bitwise or ascii. I stress again, math is really helpful here. Try generic byte rotation/shifting. That way your in effect creating multiple layers to sort through. If the attacker gets the parameters to string_encrypt, they'll be encoded by your own method as well so he can't just throw the key into a 20 line extractor. As I'm sure you can tell, I'm being vague and purposely so. Most of the time it's really more trouble than it's worth and I hope people would eventually grow to understand that.
i agreed, please watch this topic,
I finded the thing called flm or something like that, can anyone tell me how this works?
I'm keeping an active eye on this topic. I definitely do not want to start seeing specific descriptions of how to break games, as BGT is still a language many devs use and we don't need them feeling as if they're going to be at risk by default.
https://www.dropbox.com/s/z8ls3rc3f4mkb … n.txt?dl=1
I am also watching this topic as well.
bgt/c# stuff can be unpacked using the data libraryes that any dev used to pack that thing, i know some ways around how to unpack that stuff, using tools, or even a code to unpack this data, and if you wonder, i would tell yo the key is incide the dat file or the .something
In case of BGT, this is very easy. General problem is, that algorithms for things like encryption, packages managing, sounds loading etc. are used by everyone, thus attacker exactly knows what to search for.
For example, if a game has sounds packaged in it, it is just a package pasted in the executable file. And because there is a high chance that developer used native BGT packages, there will be most likely the same data structure. So all you need to do is to grab a binary editor, or make one yourself, it is very easy with BGT. Check out header used by normal BGT packages and then search for it in executable file. When you find it, cut everything before and save the rest of file. Tada, there is a working BGT package, which you can browse, extract, or do whatever you want with it.
I have published this information because I don't consider it so dangerous. I just wanted to point out the biggest problems leading to sounds leaks.
I won't publish concrete steps, because I know there are kids waiting just to steal something. But things work very similar if you want to decript sounds. The biggest problems when decripting something are which algorithm was used, how was it implemented and how to know, if decripted result is correct or not, in other words if currently tried key is right or not.
When using BGT, all of these questions are answered.
So you don't even need a disassembler. I have a program which allows me to decrypt sounds from the most of BGT games just by few keyboard hits.
There are ways to go around this. however, as someone already mentioned, don't waste your time with this. Big games like NHL, World of tanks or GTA don't use encryption of sounds at all. Think more about your game structure. That's what makes your game unique, its performance and features. 99% of that kids who are just dealing with leaked sounds and source codes can't do so. So even if they get your sounds, they will be completely unable to use them.
#10 (edited by Ethin 2019-02-27 21:23:47)
@8 and 9, this is definitely untrue.
8: cryptographic keys are stored in the compiled bytecode of the executable, not in the encrypted pack file. If the keys were stored in the pack file, decryption would not be possible without opening the file, figuring out the key offset and reading from there.
9: Just because someone knows what algorithm to use for cryptography does in no way mean that cryptography is bad. It does in no way mean that an attacker can easily extract the key from the code of the application. Every good cryptography library has special functions that are used to securely generate, store, utilize, and wipe memory. The only reason people are able to extract keys from BGT so easily is because of one major problem with the way BGT works: the base address is always the same. There is no use of ASLR involved. Since ASLR is not used, it is ridiculously easy to figure out just where each function offset is and put a BP on it. If ASLR were used this would be far more difficult, as even disassemblers would not yield results that could be trusted. I also find it very hard to believe that you have written a program in BGT that is capable of figuring out the cryptographic key used to encrypt data without some kind of disassembler involved. That kind of technology is far beyond BGT's capabilities. Here's my reason why I doubt you: whenever a byte is added to a sequence of bytes, the amount of possible byte sequences grows exponentially. As an example, let's go with the ASCII table since that will be easy to understand. The ASCII has 128 characters, the NULL byte included. For this example, we won't assume that the NULL byte means the end of a character sequence as it does in C, because we don't know if Phillip may have found a way around that. Let's say your sequence of bytes currently is of size 1. That's 128 possibilities. Not hard to iterate through, eh? Let's add some bytes and I shall demonstrate the exponential growth:
2 bytes: 256-16,384 possibilities
3 bytes: 384-2,097,152 possibilities
18 bytes: 2,304-85 undecillion possibilities
Now, lets bring in the Python unicode table (0x0-0x110000). Now we start to get ridiculously large amounts of possibilities. For one byte of an unicode string we have 1,114,112 possibilities right there. Make that sequence 32 bytes long and you've got yourself approximately between 35,651,584 to over 3.1748503857632414... × 10^193 possibilities.
Granted, hackers do not guess keys like this -- the time, as you can see, would be astronomically unfeasible. However, hackers usually have debuggers, hex editors and other tools available to them to aid in the task of breaking encryption. BGT does not however provide such tools. I am perhaps over-complicating the problem, but unless you can provide proof to back up your claim, I certainly will not take you seriously. I doubt that if I gave you a pack file encrypted with a 1024-byte key your little program could crack it in a few minutes.
As for the pack file thing, yes, the pack file has a "known" header. However, remember that its possible to add encrypted sounds to pack files and then decrypt them when you need them and still include them in an executable. I have a program that can extract pack files but I still have to get the key(s) first, which does solicit a debugger. Perhaps I'm wong on what I've said, but I still have my doubts about your 'program'.
@Ethin: I didn't said cryptography is bad at all. Cryptographic algorithms themselves like AEs Rijndael or Serpent are fine. If you encrypt a string with bgt and store it somewhere, with good key it is impossible to decrypt it.
However problems appear when a program which is fully under your control works with encrypted data. I have played around with Hero's call some time ago trying to get its sounds. And I wasn't successful at this, because I didn't know the format in which they were saved.
Of course, if I invested more time to it, I might use disassembler to look how data are processed, which functions are called, etc. But it could take days, weeks, or even years of work if algorithm in c++ was complicated enough for me to find out what's happening.
That's a lot when compared with BGT, where all implementation details are known and you have tools to reproduce loading, you need just to find right key.
And if this key lies unprotected in memory of program, which you can easily access, then it is trivial even for a program in BGT to find it.
Of course this is not the case of modern good written apps, you can't even use this technique to get to macbooks anymore, after Apple's fix, but in BGT...
The key can be found in minutes, without guessing or disassembling.
Regarding packages yes, that's just one layer of 'protection' and you still need to get encryption key to be able to get playable sounds. That's the reason why I wrote exact steps how to do this. Even if some kid reproduces them, he / she will most likely to get just encrypted files. And it is still a good preview what are the risks of BGT's security. If I received an executable in C++ with packed sounds, I would need to use debugger to see how they are stored and how can I get them. If I received a program in BGT, I would already know, what to do.
#12 (edited by Ethin 2019-02-28 01:15:05)
@11, and again, I doubt your claim. BGT does not have the ability to read raw memory. I find it very hard to believe that you could easily figure out the key for any BGT game or pack file with BGT alone. If BGT had the ability to read and write raw memory I think someone like cartertemm would've figured that out long ago and we wouldn't need to delve into debuggers to figure out the decryption key for sounds.
It is completely in BGT. I just give it a memory dump of target process and the rest is analysis.
I have here a collection of decription keys to sounds of various BGT games, including popular titles like Redspot (did you know its key has about 170 characters?), The killer or Sbyw. None of them was revealed by debugger or disassembler, all I needed was memory dump of each game, which you can optain by few clicks in task manager.
#14 (edited by Ethin 2019-02-28 01:41:22)
@13, yeah... OK then... whatever you say.
ok, just for fun i tried this on my own game. I was in fact able to find my key in the ram dump, but this only works if it is your own game i think, because you don't know what is key and what not, so to efectively find it you need to know it before. Or is there a methot to find it directly in that file?
#16 (edited by Ethin 2019-02-28 12:09:56)
And again, I doubt this. Significantly. The header of an embedded pack file is known by practically everyone who's invested time into it. But using BGT itself to analyze memory dumps to discover keys... you know my opinion already. Please provide some actual evidence, either privately or publicly, instead of giving vague theories and information that doesn't prove anything.
well, i didn't with bgt. I red the dump with npp, and was able to find my key. But i was not able to deteckt any keys, exept i know exactly how they go. Because there is nothing like key=deckey or so, so it's almost impossible to find it using that way.
at Ethin, in my case i have a lot of was to look for the key, and i will say it again, bgt stuff can be easy unpacked in a way or an other
I think what Ethan was arguing is that you can't do it with bgt. He wasn't arguing the difficulty of decryption, he was simply saying that you can't decrypt BGT with BGT and asking for evidence.
What is hard is dynamic coding, coding that accepts different input at different times.
This is what truly takes a large amount of effort on a developer's part.
@19, that was generally what I was saying. You can encrypt and decrypt with BGT, but you can't just find a cryptographic key in a few minutes like Rastislav Kiss was claiming, with BGT. You can't "analyze memory dumps" with it, either -- not unless you know windows internalsvery, very well, and I really doubt the memory dump format was ever standardized, let alone written down in a specification. So unless evidence can be provided that you can suddenly find keys in BGT using BGT in less than 5 minutes, or whatever a "few minutes" is, I can't just accept that.
that's exactly why I marked BGT security as very vulnerable. To be able to decrypt german messages during world war II, allies needed to have working enigma machine first, so they could make a decryption machine based on it.
In BGT, you have everything to find out, if any key you are able to think out is correct or not.
And you have a dump file, which as you know contains the key, what is one continuous sequence of bytes.
And you know that it will probably contain upto 20 characters, possibly more like in case of Redspot.
So, how many continuous 20 bytes sequences can you get out of 100000000 bytes long dump file?
Yes, it's 5000000 possible sequences.
It may look many for a human, but this is actually nothing for a computer. Fast C++ program would do this in few seconds.
Another good thing is, that passwords with more characters have longer sequences, so there is even lower amount of possible passwords.
But BGT is generally very slow when you want to perform many operations involving use of strings. Searching the key in this way can take hours, if it's long enough. Of course, even hours is perfectly short time, when we want to decrypt something. But now, it's far from our C++ ideal right?
So, how to speed this up?
One approach is through a basic question. Why the decryption takes so much time?
Answer: because it's trying many sequences, which are obviously not our password.
For example, ascii values 1, 205, 51, 105 are even not printable, so it probably isn't what we want.
Of course, this isn't an absolute claim. If one uses password generator, it can involve such characters as well. It is rather psychological assumption. Why would one use a password generator, if he / she can easily write a password to quotes and it will work?
Based on this conclusion, we can easyly reduce size of the memory dump by filtering out all non-printable characters. We can go even deeper and start thinking, what characters has programmer probably used based on his language.
First option we have is to get all groups of printable characters out of the file and try, if our password wasn't surrounded by non printable characters. Because BGT has functions to get ascii code of a byte, it is capable of doing such filtering. or you can do some preprocessing on the file, there are programs to extract string out of binary files.
This method worked for all BGT games I have cracked, except myone.
If this don't work, then the password is probably surrounded by other printable characters.
So you can connect everything together and search with sequences selecting method.
If this doesn't work as well, then a password generator was probably used and thus you need to iterate through all bytes.
Length of this operation depends on the length of used password. From encryptions I broke, this is very unpredictable. For example, Samtupy used about 170 characters long password to protect sounds of Redspot, but only 4 characters longone to protect sounds of Sammycenter.
I saw games using about 10 character long password, few using 60 characters, so there are various approaches.
But they are crackable in general, and the most easy way is through the encryption tool, through BGT.
If you don't believe, try it out. it is that easy like this.
I personally have also nothing against publishing my source code here, but I think some people won't agree with that. It is bit embarrassing for me revealing it here as some super secret, when it is just a set of ideas, which you probably would invent easily yourself as well if you think about it a bit. But here it is, you have everything to successfully recover passwords of sounds from the most of BGT games. Trivial approach when compared to debuggers, disassemblers and so on, but it basically works and requires less technical skills and time.
For developers, as I said, there are ways to go around this. Not all of BGT games are crackable in this way, one of them is STW and I still don't know why.
I would like to see its password to check, what happened in memory so my program isn't able to detect it. One my theory is, that Samtupy loaded everything to memory first and then erased the password, but I can't think out the reason why he would to do so.
But that's not important anyway. There are more important and more enjoyable parts of coding, which are more worth of your attention.
#22 (edited by Ethin 2019-03-01 19:13:36)
@21, first, your not proving anything and making very wild assumptions about a lot of things. Your assuming that the key can be easily determined by picking random offsets in the core dump and just scanning from there. Sorry, buddy, not how that works. Your also making assumptions about key lengths.
Really, your just making claims that are very difficult to believe. Your making a claim that if I load a 500 MB file that's a BGT program, sounds and all, that I can just locate the decryption key in about a minute or so. That is not feasible. In a 500 MB program, there are 524288000 offsets. Let's assume that the base address is our starting offset. The base address is 0x400000. That would mean offsets 0x400000 to 0x1f800000. Since the game is loaded in RAM by the time you generate the dump, you can't exclude anything. I'm sorry but unless you actually provide code and provide a working PoC, I find your claim impossible to believe. I'll stick with the tried and true method of debugging the application to cut sounds and other pack data out of a BGT executable, which has been proven to work time and time again. It doesn't help your case when you make false assertions that the character sequence "1, 205, 51, 105" is not printable. Only byte 1 (SOH) is a non-printable character; that's an aSCII control character. Bytes 205, 51, and 105 is printable if your going with the extended ASCII table; otherwise byte 205 is not a valid byte. If your processing the dump in unicode/UTF-8, then the above assertion is still valid; only byte 0x1 is non-printable. 0xCD is Í; 0x33 is 3; and 0x69 is i.
#23 (edited by Rastislav Kiss 2019-03-01 20:11:40)
Memory dumps of BGT programs normally haven't 500mb. From 100 to 200, in special cases more, but it isn't very frequent.
Also I apologize for my mistake in calculation, in 100000000 bytes there are 99999980 possible 20 byte sequences, not 5000000. Still not much, but if we want to be exact, it's good to claim.
Also about the example sequence, one byte is enough to call password not printable, if we are supposing the password has been written on the keyboard without using characters generation. Or it may be more exact calling it not writable?
Not important anyway.
Your assuming that the key can be easily determined by picking random offsets in the core dump and just scanning from there. Sorry, buddy, not how that works.
Who's talking about picking random offsets? Let's describe the technique by offsets, okay. Then you pick starting offset 0, and increase it by 1 till you don't have enough bytes to get from that position to form a password.
This basically works, it doesn't matter how much you don't want to believe it.
But I know that some people aren't familiar with theoretical proves. While you can prove this practically yourself just by following what I said, I can save your time by sending you my code and a practical example of program where it works.
There are two versions. One takes a list of strings extracted from the memory dump by external program. it is fast, it can find the password in few minutes.
Secondone works directly with memory dump and doesn't use any filtering, trying every possible sequence in given range. How fast it finds the password depends on your initial setup. if password is long enough, it will take more than few minutes, but it will find it.
Which version would you like to try out?
@23, again, your missing the point. This technique doesn't work and if it did it would be horribly inefficient and makes far too may assumptions about the password. What if the password isn't a password within the ASCII table. What if its raw bytes. Again, I'll stick with the tried and proven method and not some phantom method someone's willing to just make up without evidence.
ok, @rasti i did what you said to test, didn't plan to abuse it. I made a thing that reads the dmp files and tries to set every single line as decryption key, then trys to play a sound, an if that checks if the sound is playing and if it is copy the key. It don't works. What do i do wrong, just asking? I don't plan to do any sound leaks or so.