Jump to content
Robin Withes

"Encrypting" Sqf scripts

Recommended Posts

I recently came across quite a few scripts that were just written like this:

 

call compile toString [loadsofnumbers];

After googling a bit i found out that this is just a easy way to encrypt sqf files. I also found out that apparantly it is really easy to crack.

 

Im quite curious how to do this myself and how this works,

I would really appreciate someone helping me out here.

Share this post


Link to post
Share on other sites

Wake up.

Join Forum.

Don't share...

 

Why join the forum then?

 

  • Like 9

Share this post


Link to post
Share on other sites

Every script can be "decrypted" if the "attacker" has the right tools. If you call "compile" with a useable version of your script then I can read it if I want. And you have to compile a useable version or else the game itself wouldn't understand it.
You can't encrypt at all. You can only obfuscate a little. But I don't see any point in doing that.

  • Like 1

Share this post


Link to post
Share on other sites

I would guess the opfuscators will have to be terrible conservative. Staying away from strings and global variables (including functions), lest you access it indirectly though a constructed string by same name. E.g.:

 

CanNotBeObfuscated = 14;

// Because

missionNameSpace getVariable (format ["%1NotBeObfuscated", "Can"])

 

Share this post


Link to post
Share on other sites
4 hours ago, Beerkan said:

Wake up.

Join Forum.

Don't share...

 

Why join the forum then?

 

I'm not against sharing. I'm against people who steal your stuff, rip it, and credit as their own. Without even asking makes it worse. I am willing to help and share if people just respect the time myself and other developers who put in their time and effort.

3 hours ago, dedmen said:

Every script can be "decrypted" if the "attacker" has the right tools. If you call "compile" with a useable version of your script then I can read it if I want. And you have to compile a useable version or else the game itself wouldn't understand it.
You can't encrypt at all. You can only obfuscate a little. But I don't see any point in doing that.

Obfuscation isn't about stopping them, as we know everything can be reversed engineered, etc... It is about slowing them down. If they really want to waste time and effort then that's up to them. You mention compile? Not sure what you mean. I run my files through my own app that obfuscates variables, file names, and everything else. It also obscurs the code in a weird way which isn't easily reversable by just adding the \n or \r back in. I then use Maverick's ObfuSQF tool which locks the .pbo file. I also have certain code server-side. I only really do this for big projects that are worth my time protecting, lol. I'm not saying all this I do prevents anyone. It slows them down for sure and hopefully puts them off. I haven't seen anyone or known anyone get into Maverick's ObfuSQF - not yet at least which imo is good. Mikero Tools on the other hand is a different story - which is unfortunate.

3 hours ago, Muzzleflash said:

I would guess the opfuscators will have to be terrible conservative. Staying away from strings and global variables (including functions), lest you access it indirectly though a constructed string by same name. E.g.:

 

CanNotBeObfuscated = 14;

// Because

missionNameSpace getVariable (format ["%1NotBeObfuscated", "Can"])

 

Huh?

Share this post


Link to post
Share on other sites
1 minute ago, HazJ said:

You mention compile? Not sure what you mean. I run my files through my own app that obfuscates variables, file names, and everything else. It also obscurs the code in a weird way which isn't easily reversable by just adding the \n or \r back in. I then use Maverick's ObfuSQF tool which locks the .pbo file. I also have certain code server-side. I only really do this for big projects that are worth my time protecting, lol. I'm not saying all this I do prevents anyone. It slows them down for sure. I haven't seen anyone or known anyone get into Maverick's ObfuSQF - not yet at least which imo is good. Mikero Tools on the other hand is a different story.

You have to pass a engine readable string into the "compile" or "compileFinal" script command to be able to use the script in game. So if an attacker can easily grab the string you pass into compile. All your prior protection is already useless. But yeah.. It increases the time investment.. Depending on how experienced the "attacker" is he might already have all his tools prepared and have a good workflow so that it doesn't take him longer than just extracting the PBO.

 

I am all for open-source. If you don't want people to be able to put their name onto their code. Publish your code so that people will easily be able to find it and see that you are the author.

  • Like 1

Share this post


Link to post
Share on other sites
3 minutes ago, dedmen said:

You have to pass a engine readable string into the "compile" or "compileFinal" script command to be able to use the script in game. So if an attacker can easily grab the string you pass into compile. All your prior protection is already useless. But yeah.. It increases the time investment.. Depending on how experienced the "attacker" is he might already have all his tools prepared and have a good workflow so that it doesn't take him longer than just extracting the PBO.

 

I am all for open-source. If you don't want people to be able to put their name onto their code. Publish your code so that people will easily be able to find it and see that you are the author.

I don't understand why anyone would try to protect their scripts/code with compile command. What if you want to run it on your own server. Get people to your server/community. Then they steal? Protection can also be a way to get players to your mission, etc... If it is good enough. Not the protection itself but having it uniquely on your own server for example. By only allowing it there. Protecting it to be there only. Etc...

Share this post


Link to post
Share on other sites
40 minutes ago, HazJ said:

Huh?

The obfuscator cannot convert, say obfuscate the variable "MyPrettyVar" in:

 

MyPrettyVar = 123  into

"HzaT34A = ((1148-41)/9); 

 

unless it can make sure all references to MyPrettyVar are changed to HzaT34A . And that is hard to do since, someone might have written:

_myNum = missionNameSpace getVariable [format ["%1%2%3", "My", "Pretty", "Var"]];

 

Or maybe I am misunderstanding, and obfuscation means something different for .sqf than elsewhere?

Share this post


Link to post
Share on other sites

Capture.png

These are local variables, obviously, as you can see. I do global variables manually, at least atm. As for file and folder names:

Image.png

Next page has options to sync variables, etc... Also to export .bat which renames all the defined above (none in that pic above) automatically, after running on the .bat file.

Previous pages allow me to obscur code and other stuff. The opened SQF file gets the correct variables to the first picture, obviously.

  • Like 1

Share this post


Link to post
Share on other sites

Very interesting tool. May I ask what you made the the GUI in, WPF?  The look feels quite unique :)

 

But to follow my example, it gives rise to the question: I notice you translate "_x" to "_grN3oo" in the image. How does that work in say:

{alive _x} count allPlayers

 

Share this post


Link to post
Share on other sites

That is actually a bug lol. I think I opened the wrong version as this was fixed. However, I noticed something that isn't. The __FILENAME shouldn't obfuscate. The tool was made in AS3 (Flash) by SPUn for me only. Idea was mine, etc... He is a genius in AS3 and many other code languages lol.

 

EDIT: I think I understand about what you was saying earlier with compile command. Did you mean obfuscating the commands? I did that a long time ago, very long time ago but it was such a pain and not ideal. I had them stored on server-side. Out of the mission folder.

 

EDIT 2: Just did a search for it. Here's a basic example. I do not recommend anyone to do this though. It's not ideal imo. Especially if it's out of mission, you have to use publicVariableClient for JIP (only to new client joining but still). If you don't have them server-side then this is pointless.

3FX3vwXs = compile "(_this select 0) setVariable [(_this select 1), (_this select 2), (_this select 3)];";
// This is extremely old as I stated above. Did it a very long time ago. I used the compile command then but thinking about it now... compileFinal would of been more suitable instead I think.
zgp9VbvK = player;
Uh2UzhfB = "Map_Marker";
wt6hB65a = true;
[zgp9VbvK, Uh2UzhfB, 0, wt6hB65a] call 3FX3vwXs;

 

Share this post


Link to post
Share on other sites

Also notices '_this' in the list - you probably already fixed that.

 

I never said anything about compile in this thread, that was dedmen.

 

My main point was just that you had to be very careful obfuscating, particular anything non-local, like commands, or global variables and functions, strings, and especially any use of string formatting to access variables. And that a universal tool for obfuscating would have to be very conservative, to not cause problems. But if you know the code, you can of course be more aggressive in obfuscating.

 

compileFinal is one alternative. You don't really need the compile though (unless you want it to be final):

3FX3vwXs = {(_this select 0) setVariable [(_this select 1), (_this select 2), (_this select 3);};

Share this post


Link to post
Share on other sites

Just adding my 2 cents - I am not a huge fan of obfuscation or encryption, but something that has helped prevent people from ripping off code is to have as much as possible in a server side add on.   You cant steal what you dont have.

 

Everything that's ran by the server only doesn't need to be sent to the client.   

 

For most of everything else to be ran by the client, remoteexec and publicvariables work well too, just don't forget the potential network impacts.  Security wise, I dont know if there is a method to export the contents of a remoteexec if your recieving (I'm not quite sure how the receiving engine handles it) and if your using a PV, anyone with console access during a live game could copy it.   Still, it makes the cost of effort vs reward high enough that if they get it, they kinda earned it lol.

 

Edit: I dont think asking for help on the community then not sharing the result is a good practice.  You dont have to armaholic everything, but at least "take a penny, leave a penny".   There is no way to learn code (without it becoming a second job) without a contributing community. 

Share this post


Link to post
Share on other sites
3 hours ago, Muzzleflash said:

Also notices '_this' in the list - you probably already fixed that.

 

I never said anything about compile in this thread, that was dedmen.

 

My main point was just that you had to be very careful obfuscating, particular anything non-local, like commands, or global variables and functions, strings, and especially any use of string formatting to access variables. And that a universal tool for obfuscating would have to be very conservative, to not cause problems. But if you know the code, you can of course be more aggressive in obfuscating.

 

compileFinal is one alternative. You don't really need the compile though (unless you want it to be final):

3FX3vwXs = {(_this select 0) setVariable [(_this select 1), (_this select 2), (_this select 3);};

I didn't think it would work like that? Though I've not tried.

3 hours ago, wyattwic said:

Just adding my 2 cents - I am not a huge fan of obfuscation or encryption, but something that has helped prevent people from ripping off code is to have as much as possible in a server side add on.   You cant steal what you dont have.

 

Everything that's ran by the server only doesn't need to be sent to the client.   

 

For most of everything else to be ran by the client, remoteexec and publicvariables work well too, just don't forget the potential network impacts.  Security wise, I dont know if there is a method to export the contents of a remoteexec if your recieving (I'm not quite sure how the receiving engine handles it) and if your using a PV, anyone with console access during a live game could copy it.   Still, it makes the cost of effort vs reward high enough that if they get it, they kinda earned it lol.

 

Edit: I dont think asking for help on the community then not sharing the result is a good practice.  You dont have to armaholic everything, but at least "take a penny, leave a penny".   There is no way to learn code (without it becoming a second job) without a contributing community. 

Of course. I understand that. Again, sharing/helping is fine. Obfuscating / protecting work that you don't own isn't acceptable. Though for me. It's mostly all my own code. I'm active on the forums and help people when I can. Even via Steam and other ways. Along as they are motivated to learn and try. I know I've explained this over and over. I just feel like, people automatically assume people who obfuscate (protect) their work are fronwed upon sort of, and seem like they don't share/help the community. That isn't the case always, at least not for me. Not for everyone either.

Share this post


Link to post
Share on other sites

lol dont worry about the code. Good ideas are always clone/copy, reproduce. You cant protect them.

 

there is a lot of story about this, where first inventors were totaly forget about the beneficit of others

https://fr.wikipedia.org/wiki/Nikola_Tesla

 

You cant expect a cipher protection will help you to protect any good idea

You cant expect to be first on something, and to claim this, will help you too

 

Just do the things when it s time to do, and do it with fun to attract the best guys in your community

  • Like 1

Share this post


Link to post
Share on other sites
8 hours ago, HazJ said:

I don't understand why anyone would try to protect their scripts/code with compile command. What if you want to run it on your own server. Get people to your server/community. Then they steal? Protection can also be a way to get players to your mission, etc... If it is good enough. Not the protection itself but having it uniquely on your own server for example. By only allowing it there. Protecting it to be there only. Etc...

Not protect with it. But you have to use "compile" to be able to run scripts in Arma. You can't call strings.

 

7 hours ago, HazJ said:

EDIT: I think I understand about what you was saying earlier with compile command. Did you mean obfuscating the commands? I did that a long time ago, very long time ago but it was such a pain and not ideal. I had them stored on server-side. Out of the mission folder.

No.
Let's say you have your script in a "encrypted" string.
You decrypt that string and then compile it to be able to call the function. Kinda like so
`call compile (call decryptFunction)`
Your decrypted code will only exist between the "compile" and your "(call decryptFunction)" and most people think that is secure. Because no one could grab the string inbetween there.

 

4 hours ago, wyattwic said:

Security wise, I dont know if there is a method to export the contents of a remoteexec if your recieving.

There is one.

Only real protection is to only have the Code serverside. You can even keep your serverside only scripts fully encrypted (real encryption.. AES or whatever) inside your mission.pbo if you use Intercept(Shameless advertising) on the serverside to decrypt and run them.

  • Like 2

Share this post


Link to post
Share on other sites
1 hour ago, HazJ said:

Of course. I understand that. Again, sharing/helping is fine. Obfuscating / protecting work that you don't own isn't acceptable. Though for me. It's mostly all my own code. I'm active on the forums and help people when I can. Even via Steam and other ways. Along as they are motivated to learn and try. I know I've explained this over and over. I just feel like, people automatically assume people who obfuscate (protect) their work are fronwed upon sort of, and seem like they don't share/help the community. That isn't the case always, at least not for me. Not for everyone either.

 

It was a general statement my friend.  I say that because of all the Altis Life people I see asking about the same thing.  :)

Share this post


Link to post
Share on other sites

Anyway, a lot of things are possible

 

here some possibilities to protect your code:

  • host main of your code on server side and dont share it with client << no cipher usage (security is relative to your server)
  • host main of your code on server side and send the minimun of code to client << no cipher usage (security is relative to your server)
  • using external dll on client and server side to uncipher files in memory, external tool to cipher all your files  << (security is relative to debug / network tools on client side)
  • using an external tool to cipher and internal script to uncipher all your files << (security is relative to debug / network tools on client side)
    • I did it with oo_cipher script. Import a full ciphered code through a sqf file, uncipher it through the game, and execute it.

 

helloworld.sqf content:
3C426F2C19662FBEAC94C8B26C2E640C40480B
init.sqf content


	private _cipher = "new" call OO_CIPHER;
	private _key = "WilliamShakespeare";
	private _data = loadFile "helloworld.sqf";

	_data = ["uncipher",[_key, _data]] call _cipher;
	call compile _data;
output

will hint "hello world";

Concerning the cipher usage, bascally its possible to hardcode the (symetric) secret key directly in .dll, but it requires to generate new one often.

 

Its not really a solution so you should use network exchange, the master piece is to think how the first handshake will be done between the client and server, cause the first step is to create a secure layer to share the key.

 

 

Share this post


Link to post
Share on other sites
18 minutes ago, code34 said:

Anyway, a lot of things are possible

 

 


init.sqf content


	private _cipher = "new" call OO_CIPHER;
	private _key = "WilliamShakespeare";
	private _data = loadFile "helloworld.sqf";

	_data = ["uncipher",[_key, _data]] call _cipher;
	call compile _data;

That's exactly what I meant with my first answer here. "_data" contains the decrypted code.
People can just write the string you pass to "compile" to a file and get the decrypted script.
This would only be somewhat secure with Battleye everywhere.

Share this post


Link to post
Share on other sites

yes it was a simple example to show it works :) In this case, the key exchange must be done through a secure layer across the network (not directly into the init.sqf like above)

 

and it doesnt avoid against debuger tools

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×