Jump to content


Photo

The Common Atrocities Of Execute_string()


  • This topic is locked This topic is locked
163 replies to this topic

#1 Smarty

Smarty

    GMC Member

  • GMC Elder
  • 7522 posts
  • Version:GM:Studio

Posted 20 August 2007 - 04:52 PM

Every once in a while when I look around on the Q&A forums, be it Novice or Advanced, I stumble upon queries where someone comes up with a solution that advertises the use of the command execute_string(), or it's more voluminous brother execute_file(). This is a shame because these commands pose a few considerable drawbacks and pitfalls. It is also a shame because there are often solutions in straightforward GML - but apparently not everyone sees them.

Why should you try to avoid execute_string() and execute_file(), in Game Maker?
  • They make execution of your game slower. When Game Maker starts, it converts all scripted GML into a byte-coded representation, by verifying the syntax, checking the parameters and converting them into something that GM can execute much faster. Your game runs faster because this first step of interpretation of your programming takes place the start of the executable, and not while it is actually running the game. But execute_string() and execute_file() always apply this parsing during the game, when these commands are called. This can introduce a performance drop in your game, especially when used in continuously (step, draw) and semi-continuously (key, collision) triggered events.
  • It is a bad programming practice for beginners. The two commands make GML scripts self-modifying: GML scripts can modify or add code 'on the fly'. But this is not possible in all programming languages (because the result would have to carry an interpreter or parser around). You would face a drawback in understanding and using languages such as C++ and Delphi if you are unaware of the alternatives to self-modifying code.
  • They allow malicious script injection. Where execute_string() is used to parse user input, or execute_file() to run an external script, a user may introduce their own script and retrieve a great number of it's resources from your game and / or introduce cheats to their merit. To make your solution safe to malicious script injection you would need to strip it from all commands that could possibly allow for injection. And that is harder than you may think.
So why are these commands here? Well, some of the more valid reasons in Game Maker would be:
  • Rewriting pieces of script to optimize or finetune them to runtime circumstances. One could argue whether this is necessary and whether the parser interpretation is faster than a well-adjusted script to begin with, but this can be tested on a per-case basis.
  • Parsing expressions from the user. For example, including a calculation to plot a path. Parsing expressions is complex and may be slow, so it's better left to the built-in parser.
  • Allow building of modifications such as levels, plugins and fixes as separate scripts without redistributing the game. There are few (if any) alternatives to this apart from building a custom parser or interpreter.
If anyone has another valid reason why it cannot be avoided, feel free to point that out. I do not try to be exhaustive, but I do wish to keep a good perspective.

Unfortunately, these are not always the reasons why people advice using them in the Q&A forums. They are promoted because:
  • You want to get away with doing less. Some of the alternatives may require a little more programming effort, or an overal redesign of particular concepts of your game (we can argue that your game may require a rewrite should it become dependent on these methods).
  • People simply do not know better. Sadly, this is more often the case in the Q&A forums. I'll be as blunt as stating, if you do not know an alternative (not counting the valid reasons above), don't consider yourself expertised enough to answer the question.
The points that I raise are not new - many of the better-informed GM users occasionally have jumped into the fray, trying to save the day, but it still happens. So it may be time for a different approach, and that's the goal of this topic: breaking down that wall of execute_string() abuse.

We'll make it a bit of a game (without a prize, apart from the usual glorification). You give your piece of execute-infected script (provided it does not fall into the list of valid reasons). Others are welcome to reply and invent alternatives, by trying to eliminate execute_() (obviously) while keeping its functionality intact. As this often requires a different approach in the game, feel free to elaborate.

First we need a script. :blink:
  • 2

#2 gymnastdaniel5

gymnastdaniel5

    Roboleader

  • GMC Member
  • 1018 posts

Posted 20 August 2007 - 04:59 PM

Wow... I never noticed this... Well I can't disagree with an admin!
  • 0

#3 FredFredrickson

FredFredrickson

    Artist

  • Global Moderators
  • 9225 posts
  • Version:GM:Studio

Posted 20 August 2007 - 05:01 PM

Funny that you should write this up Smarty, I was just having a discussion with another friend of mine about how the inclusion of execute_string() in a GM application opens up quite a large hole as far as security goes. By using execute_string() in your GM-made program, you are essentially taking out the hard part for anyone willing to try to steal your game's resources (or cheat) via script injection, and I think that if your solution to a problem relies on this function, you should do whatever you can to try to work around its use.

Obviously, sometimes it is inevitable to need execute_string() or execute_file(), but when it can be avoided, it should be. Anyway, good read. :blink:
  • 0

#4 Nuble

Nuble

    United We Stand

  • New Member
  • 1741 posts

Posted 20 August 2007 - 05:01 PM

O... I guess I'm guilty of a few of those... I learned about it here and have been telling other people to use it since... The only reason that I use it is in situations like in that topic.

my code was this
instance_create(x,y,string(create_object))
and later turned into this
execute_string( "instance_create(x,y," + string(create_object) + ");" );

  • 0
QUOTE (Jimmy Wales - founder of wikipedia.org)
Imagine a world in which every single person on the planet is given free access to the sum of all human knowledge.

#5 BBGaming

BBGaming

    Programmer

  • GMC Member
  • 2478 posts
  • Version:GM7

Posted 20 August 2007 - 05:08 PM

Wow... I never noticed this...  Well I can't disagree with an admin!

<{POST_SNAPBACK}>


And that is exactly how I think this topic is going to go. Anyone can disagree with a regular member, but noone dares cross the cold, heartless Smarty. :blink:
http://gmc.yoyogames...dpost&p=2263869

Obviously, sometimes it is inevitable to need execute_string() or execute_file(), but when it can be avoided, it should be.

That is exactly what I was trying to think up to write, but a little more extended. Sometimes it's just plain stupid not to use execute_string(). As long as you don't call it in an event like step (like you said) I have never noticed any signifigant speed drop, or any speed drop. Calling execute_string once or twice in your game has no noticable effects. I often use execute_string() for menu buttons' parent objects, and just call their clickaction on left mouse. It's alot easier if you want to try to have any sort of decorative menu options.

Feel free to shoot me down.

Edited by B&B_Gaming, 20 August 2007 - 05:18 PM.

  • 0

Posted Image
Game Widgets
- Your pure-GML solution to API DLLs. Featured in Markup Magazine!

My Portfolio - All my good games and resources
Moved away from the forum - e-mail me if you need quick contact (hi_146@hotmail.com).


#6 BrandMan211

BrandMan211

    GMC Member

  • New Member
  • 597 posts

Posted 20 August 2007 - 05:17 PM

Hmm...

Let's say I WANT to make a game in which a user types in code, and it is executed. Is there an alternative other than storing it as a string and executing it?

Also, let's say I have one object that's properties are based on a variable defined by the object that created it. It stores many strings in another object, that are based on it's element. Instead of:

if variable = grass
{
  grassinfo = "It is grass.";
}

I would do:

execute_string(variable + "info = 'It is " + variable + ".';");

This is an extremely fake example, but still, would there be a better alternative?
  • 0
All the best,
Brandon Evans

#7 paul23

paul23

    GMC Member

  • Global Moderators
  • 4147 posts
  • Version:GM:Studio

Posted 20 August 2007 - 05:29 PM

well another "valid" reason.. at least I think, is for allowing "triggers"..

You just make an object and then at the collision event:

execute_string(triggerstring);


and at the object creation event IN THE ROOM you put something like:

triggerstring = "with(obj_bullet){instance_destroy()} instance_destroy();"


This will let the code only be executed once and it allows you to have plenty of triggers while only having 1 object. (opposed to the about ~10 objects I would have in my game) Which makes level design much easier, and later on also allows an easier way to create your own map editor..

ow and 1 more reason:

if you want to create an object editor (like the one of WCIII) it's hardly possible to do it antoher way round (apart from making your own interpreter, which I think is even more slowly). - but this falls I think already under the point 3 of valid reason you saw..



I myself often use the execute string command though, it's because whenever I create a program, I want it to be as dynamically as possible, allowing users to modify everything to their liking...
  • 1

#8 BrandMan211

BrandMan211

    GMC Member

  • New Member
  • 597 posts

Posted 20 August 2007 - 05:32 PM

paul23,

I'm not sure I get what you mean by triggers. Do you just mean code that is executed by multiple objects? Isn't that what scripts are for?
  • 0
All the best,
Brandon Evans

#9 Yourself

Yourself

    The Ultimate Pronoun

  • GMC Elder
  • 7352 posts
  • Version:Unknown

Posted 20 August 2007 - 05:34 PM

BrandMan211:

Clearly grass has some well defined value since you're treating it as a variable. If it has an integer value (say that you defined as a constant), you could use an array. However, in this case the following code indicates that the value of the grass variable is a string (by the way, a variable named grass holding the value "grass" is pretty pointless). So, in this case it would be better to use a ds_map (assuming you've created one and stored its index in the info variable):

ds_map_add(info, variable, "It is " + variable + ".");

This will easily expand to handle any value of variable (although if variable is a real value you'd have to modify the third argument) and will also allow you to see which values have been set. This is a much better approach because, not only is it faster, it's much more expandable as well.
  • 0

#10 hpapillon

hpapillon

    GMC Member

  • GMC Elder
  • 3020 posts
  • Version:Unknown

Posted 20 August 2007 - 05:37 PM

paul23 - I'm not entirely sure what you're talking about with your triggers idea, but I'm pretty sure you could do it with scripts and script_execute.

Which is what I use for button objects so that I can have just ONE button object - when the object is created, it gets its script assigned to it, and when it's clicked, it executes the associated script. This is also preferable in general because you can SEARCH in scripts to find things when you need to edit them later. It's much easier to find things done in a script than done in an object or room.


Of course, I'm making a huge game that depends vastly on execute_string, but Smarty and I have already argued over it. ;) I'm doing it because GM's internal editors are inconvenient for working with really huge amounts of code-and-text (I've got about a meg's worth of text scripting files that the game reads from during execution.) Even if it weren't a pain in the butt to work with this much information in the little bitty script editor, I'm not sure the gm source file would appreciate the bulk. We usually tell people to externalise huge resources, after all! :P
  • 0
Yes, making games is my day job.
Anime Games
Gaming blog

#11 Polystyrene Man

Polystyrene Man

    Fake Plastic Fun

  • New Member
  • 702 posts

Posted 20 August 2007 - 05:46 PM

paul23, you would be better off using a script as a "trigger". You could also stick the code in a user-defined event.

I wasn't aware of this problem at all. Then again, I don't frequent the Novice Q+A boards as much as I used to. I will say that I've only had to use execute_string() once.

Edited by Polystyrene Man, 20 August 2007 - 05:47 PM.

  • 0

#12 BrandMan211

BrandMan211

    GMC Member

  • New Member
  • 597 posts

Posted 20 August 2007 - 05:48 PM

I've never used ds_map_add, so I'll check it out. Thanks. But I'll clarify this again, that example was completely made up.
  • 0
All the best,
Brandon Evans

#13 Potnop

Potnop

    GMC Member

  • GMC Member
  • 3103 posts

Posted 20 August 2007 - 05:56 PM

Heh, yeah. I remember I used execute_file() to load levels and it took like 15 seconds when the level got big. For all the objects I would save something like

myObj = instance_create(obWall,0,0);
myObj.x = 4;
myObj.y = 17;
myObj.terrain = 2;

I then redid my saving format and isntead have it save liek this.

4
17
2

Well that's not exactly how GM saves real numbers in a text file, but yeah. Then I read the file after openeing it and stuff. It's like thousands of times faster this way. OK IDK about thousands, but it takes like 1 second instead of 15.

I only use execute_file in a little utility I made for myself to generate the ini file for the level editor's object layer thing.
  • 0
Vegeta! What does the scouter say about his powerlevel?!? It's ovER 9000!!!!!
I ownt read da script, script reads me.


Link To The Super Crew Topic / Link To Colonial Commando Topic
Platform Pathfinding Example Download it here!
Editable Early Version Level Editor(Nice @$$ stuff, check it out) Download it here!

#14 paul23

paul23

    GMC Member

  • Global Moderators
  • 4147 posts
  • Version:GM:Studio

Posted 20 August 2007 - 05:56 PM

paul23,

I'm not sure I get what you mean by triggers. Do you just mean code that is executed by multiple objects? Isn't that what scripts are for?

<{POST_SNAPBACK}>



nah the code is very specific, all instances have different code..

I only have 1 object, and then I want to let it do different things depending on it's possition and map...




@hpapillon: well I don't use scripts for it as it's very small pieces of code I putted there, mostly just the code to destroy itslef + another instance. (or create an instance, or change the speed of an instance.. simple things like that). The problem with using scripts to execute the code is that again I would need lots of scripts, basicly 1 for each "action" it can perform (letting things move, destroy something etc..) or I would need to make a parser like:

script_execute('allthings',1,10032);

and then in the script:

switch (argument0)
{
    case 0: with(argument1){instance_destroy;} break;
    case 1: with(argument1){speed = argument2; direction = argument4;} break;
    case 2: ....
    etc. etc..
}
basicly buildng yoru own interpreter.. - and again this has the problem that I can only execute an arbritaty number of commands, and I can't think of the commands "on spot", when level designing. (without returning to your source code).


@Polystyrene Man - well basicly that also gives the problem of having to think about all possible commands when programming. While I prefer to leave that part to the place it belnogs (I think) - the level designing..

Edited by paul23, 20 August 2007 - 05:59 PM.

  • 0

#15 Alex

Alex

    3lite Member

  • New Member
  • 3098 posts

Posted 20 August 2007 - 06:00 PM

What if the person wants to add a function that allows for code injection? Then is it okay to recommend it...?
  • 0

#16 Yourself

Yourself

    The Ultimate Pronoun

  • GMC Elder
  • 7352 posts
  • Version:Unknown

Posted 20 August 2007 - 06:01 PM

If you have a place to define all those code strings individually and they never change, then there's no reason you should have to use execute_string() anywhere. You should use the user-defined events or scripts which take arguments. From what you've told us there's no reason you should need to use execute_string().
  • 0

#17 Shadeplay23

Shadeplay23

    GMC Member

  • New Member
  • 470 posts

Posted 20 August 2007 - 06:03 PM

Wow, this is a shocker. I come to the community, I see a topic by Smarty, and then I open it up and get some valuable information that I didn't even know was true or not before.

Good thing I don't use those two functions in my game.
  • 0

#18 Polystyrene Man

Polystyrene Man

    Fake Plastic Fun

  • New Member
  • 702 posts

Posted 20 August 2007 - 06:04 PM

@Polystyrene Man - well basicly that also gives the problem of having to think about all possible commands when programming. While I prefer to leave that part to the place it belnogs (I think) - the level designing..

I'm not sure what you mean by this, because I don't know what "commands" are a reference to. However, if you have a number of "commands" that are specific to a certain object, then I see no problem with using user-defined events. Basically, you're taking all those strings that were once in the create event and putting them into user-defined events. It's much more organized, faster, and safer.

Edited by Polystyrene Man, 20 August 2007 - 06:05 PM.

  • 0

#19 correojon

correojon

    custom title

  • New Member
  • 461 posts

Posted 20 August 2007 - 06:07 PM

Very interesting topic. I have one similar question: I´ve been told that the "variable_scope_action" type functions (variable_local_get(), variable_global_array2_get(), ...)have a similar flaw, is it true? Should I try to avoid them whenever it´s possible?
  • 0

#20 Alex

Alex

    3lite Member

  • New Member
  • 3098 posts

Posted 20 August 2007 - 06:12 PM

I asked because someone wanted to make a Game Maker in Game Maker, and they asked how they could have code executed from a file.

Edited by Alex, 20 August 2007 - 06:27 PM.

  • 0

#21 paul23

paul23

    GMC Member

  • Global Moderators
  • 4147 posts
  • Version:GM:Studio

Posted 20 August 2007 - 06:24 PM

@Polystyrene Man - well basicly that also gives the problem of having to think about all possible commands when programming. While I prefer to leave that part to the place it belnogs (I think) - the level designing..

I'm not sure what you mean by this, because I don't know what "commands" are a reference to. However, if you have a number of "commands" that are specific to a certain object, then I see no problem with using user-defined events. Basically, you're taking all those strings that were once in the create event and putting them into user-defined events. It's much more organized, faster, and safer.

<{POST_SNAPBACK}>

I meant with commands all possible actions which can be perfomed when I collide with the trigger object. and well currently at least in my game there are waaay to many triggers.. (my game is all about solving 'mazes' where the triggers open doors, desroy enemy groups, wrap your tank, basicly everything I can think of when I create a new level..).


@yourself.. Was that pointed at me? - well basicly what I forgot to mention is that in the end I want to create a level editor, where you can make your own triggers.. The problem with "hard coding" everything in scripts is that you only have an arbritary number of commands you can execute, while you can think of infinite possibilities with triggers...
But even without a level editor, yes you can put everything in a few scripts like shown above. However this would again limit you while building nice maps (you would need to return to the programming part, while you're working at the level design part). And it would also clutter up your scripts by some things which are only executed once..

A small count: curently in my game I have 1038 triggers with about 100 total different actions, some can be combined, but that still leaves around 50 different completely different actions..
  • 0

#22 Daniel-Dane

Daniel-Dane

    GMC Member

  • New Member
  • 3581 posts

Posted 20 August 2007 - 06:26 PM

Very interesting topic. I have one similar question: I´ve been told that the "variable_scope_action" type functions (variable_local_get(), variable_global_array2_get(), ...)have a similar flaw, is it true? Should I try to avoid them whenever it´s possible?

<{POST_SNAPBACK}>

I don't know of any flaws, but it is good to retrieve values without getting errors.
  • 0

#23 grandhighgamer

grandhighgamer

    Village Idiot

  • GMC Member
  • 3876 posts
  • Version:GM:Studio

Posted 20 August 2007 - 06:37 PM

Wouldn't topics like this belong better in the Game Design forum. That's what they seem to pertain to.
  • 0

GHG WUZ ERE


#24 Daniel-Dane

Daniel-Dane

    GMC Member

  • New Member
  • 3581 posts

Posted 20 August 2007 - 06:39 PM

Wouldn't topics like this belong better in the Game Design forum. That's what they seem to pertain to.

<{POST_SNAPBACK}>

How dare you defy an admin's decision?
  • 0

#25 hpapillon

hpapillon

    GMC Member

  • GMC Elder
  • 3020 posts
  • Version:Unknown

Posted 20 August 2007 - 06:54 PM

well I don't use scripts for it as it's very small pieces of code I putted there, mostly just the code to destroy itslef + another instance. (or create an instance, or change the speed of an instance.. simple things like that). The problem with using scripts to execute the code is that again I would need lots of scripts, basicly 1 for each "action" it can perform (letting things move, destroy something etc..)


This is true, you need a lot of scripts. However, again, if you have sooo many different actions, it can make your life a lot easier if they're in scripts so that you can search for them if you need to change one!

I tend to have a couple hundred scripts. ;)
  • 0
Yes, making games is my day job.
Anime Games
Gaming blog

#26 ChIkEn AtE mY dOnUtS

ChIkEn AtE mY dOnUtS

    Pwner of barcodes

  • GMC Member
  • 2410 posts

Posted 20 August 2007 - 07:03 PM

If you are looking for keeping your GM7 game secure by not using execute_string, give up.

There are MASSSIIIVVEE ways to pull GM7 EXE's apart and put in your own code.
  • 0
I've moved away from GM. If you want to contact me, feel free to email ryanwebdev@gmail.com.

Thanks,
Ryan.

#27 Alex

Alex

    3lite Member

  • New Member
  • 3098 posts

Posted 20 August 2007 - 07:34 PM

nvm

Edited by Alex, 20 August 2007 - 07:35 PM.

  • 0

#28 Quimp

Quimp

    Pretzel fanatic

  • New Member
  • 275 posts

Posted 20 August 2007 - 07:37 PM

If you are looking for keeping your GM7 game secure by not using execute_string, give up.

Ah! this argument. Again. Don't you agree that it just makes it even more easier, and that it is a new possibility for those who are not aware of the other security flaws? Script injection can be done by anyone with basic programing knowledge. Consider this overly basic (and albeit useless) code:

var name;
name = get_string("Please enter your name: ", "");

execute_string("show_message('Nice to meet you " + name + "!'); ");

Simply enter a single quote and you get the following error:

___________________________________________
COMPILATION ERROR in string to be executed
Error in code at line 1:
  show_message('Nice to meet you '!');

at position 33: Symbol , or ) expected.


Now enter:

'); show_message('hi

Injecting a malicious piece of code is just as easy.
  • 0

#29 uuf6429

uuf6429

    Covac Software

  • New Member
  • 2522 posts
  • Version:Unknown

Posted 20 August 2007 - 07:40 PM

I created the following script to avoid problems with execute_string(). To use with execute_file(), just load a file into a string then run it through this same script.
http://gmc.yoyogames...0
Note that as I clearly indicated, this script is not memory editor proof.

Here is a small script to exploit insecure execute_string() by simply running execute_string(code) and code (which is infected) contains execute_file("hack.txt")
Then simply a text file named hack.txt contains:
var f,data,filenm,i; //* init variables
data='' //************** data to write to file
filenm="scripts.gml" //* gml scripts found stored here
resource_max=600 //***** maximum resource search index
resource_min=10000 //*** minimum resource index (not sure right now)
ret=chr(13)+chr(10) //** line end character(s)
for (i=resource_min; i<=(resource_max+resource_min); i+=1)
{
 if script_exists(i) then data+=ret+"#define "+script_get_name(i)+ret+script_get_text(i)
}
f=file_text_open_write(filenm)
file_text_write_string(f,data)
file_text_close(f)
This creates a human-readable/GML script collection file with the first 600 scripts in the GM executable.
By the way, there is a whole unpacker (the exact word to decompiler) which runs on this principle and hacks almost all data. Well the best part of it anyway. Well of course I did it, but credit goes to others which did it before me, eventhough I didn't know about it. As to its availabiltiy, mine isn't and the others (to my knowledge) aren't too.

Edit: as to the variable resource_min I don't remember the exact value, but you could find it out by creating a new gm project and a new script then run in debug mode and add 'script0()' to the watch list that number is the index of the very first script.

Regards,
Christian

Edited by uuf6429, 20 August 2007 - 08:19 PM.

  • 1

#30 E.B

E.B

    GMC Member

  • GMC Member
  • 149 posts

Posted 20 August 2007 - 08:21 PM

Hmm....I'm guilty, not of telling people to use execute_string, but using it myself for one of my engines...

I wrote a textbox engine, and I have a script that was basically when the player pressed space it would open the textbox, if they were near enough/facing them, etc.

Here's how I used execute_string:

   if distance_to_object(obj_character)<17 && global.textbox_exists=false {

    a=instance_create(argument0,argument1,obj_textbox)
    
    a.text=text
    
    execute_string(mycode)
    
    a.maxbox=maxbox
    
    a.server=id
    
    obj_character.image_single=0

See it? I did it like this so that it would use less code=less memory etc etc. Cos if I'm using the same codes about a million times (think about how many NPCs there are in an RPG!!) its better to do a script over and over, which you can just call, no?

The only problem was that each NPC has a unique code that the textbox has to know....which is why I used execute_string - the NPCs code is saved as a string in the create event of it, then as you can see in the code above, is executed ^


This isn't potentially insecure or anything is it? :|
  • 0

#31 Yourself

Yourself

    The Ultimate Pronoun

  • GMC Elder
  • 7352 posts
  • Version:Unknown

Posted 20 August 2007 - 08:23 PM

Not really, but there's probably a much better way to do it.
  • 0

#32 uuf6429

uuf6429

    Covac Software

  • New Member
  • 2522 posts
  • Version:Unknown

Posted 20 August 2007 - 08:27 PM

Couldn't you use an array or variable? (maybe temporarly, changed each time)

Edited by uuf6429, 20 August 2007 - 08:28 PM.

  • 0

#33 E.B

E.B

    GMC Member

  • GMC Member
  • 149 posts

Posted 20 August 2007 - 08:31 PM

*shrugs*

As long as it works and isn't gonna blow up on me, I'm good. I wrote a textbox engine using arrays a while back but I'm using this one now cos I made a yes/no/options answer system to questions for it....

THe thing is a variable, or at least a string variable.

Here's one NPCs "mycode": mycode="a.box1=box1 a.box2=box2 a.box3=box3 a.box4=box4"

It just tells the textbox some stoof.

Thanks dudes =D

EDIT: Whoops. Never press stop to edit a post then press post again >.<

Edited by E.B, 20 August 2007 - 08:32 PM.

  • 0

#34 Polystyrene Man

Polystyrene Man

    Fake Plastic Fun

  • New Member
  • 702 posts

Posted 20 August 2007 - 08:31 PM

If you are looking for keeping your GM7 game secure by not using execute_string, give up.

There are MASSSIIIVVEE ways to pull GM7 EXE's apart and put in your own code.

<{POST_SNAPBACK}>

I think we're trying to make the game less insecure, not secure. ;)

Edited by Polystyrene Man, 20 August 2007 - 08:34 PM.

  • 0

#35 Slammin

Slammin

    GMC Member

  • New Member
  • 201 posts

Posted 20 August 2007 - 08:40 PM

If you are looking for keeping your GM7 game secure by not using execute_string, give up.

There are MASSSIIIVVEE ways to pull GM7 EXE's apart and put in your own code.

<{POST_SNAPBACK}>



Not just GM7, but most Gamemaker exes with things like memory editors and what not. You seem to have a extreme dislike of GM7. ;)
  • 0

#36 Somelauw

Somelauw

    GMC Member

  • GMC Member
  • 1096 posts
  • Version:Unknown

Posted 20 August 2007 - 08:44 PM

To make it faster you could split the function in 2 other functions:

option[0] = precompile("computer_explode()")
option[1] = precompile("system_explode()")
option[2] = precompile("car_explode()")

trigger = option[n]
execute_compiled(trigger)

precompile compiles to bytecode
execute_compiled executes the bytecode


  • 0

#37 FIREBALL5

FIREBALL5

    GMC Member

  • New Member
  • 138 posts
  • Version:GM7

Posted 20 August 2007 - 09:34 PM

This is a very interesting topic. And have something that I would like to add to it. The execute_string() function allows games, or even systems to be compromised using this. As in the following example: (shown in a previous post)
var name;
name = get_string("Please enter your name: ", "");

execute_string("show_message('Nice to meet you " + name + "!'); ");
There is no need for execute_string() here, just use show_message(). There aren't too many circumstances that this needs to be used. Here is an example of how it can be used securely (not including the use of memory editors to change anything):
var MyName,ExecuteString;
MyName = get_string("Your Name:","");
ExecuteString = "// do whatever";

if MyName = "Bobby" execute_string(ExecuteString)
if MyName = "Cody" execute_string(ExecuteString)
etc etc.

There shouldn't be very many needs for this, as it just opens a door for a hacker to step in and manipulate the program, or even the computer.

I have written an article on this and very many other security aspects in Game Maker (as a matter of fact, it's 7-8 pages long, and I'm also just about to go edit it with more features now!). If you want the article (it is free, mind you) just pm me asking for it. Geared more towards users with :P Registered and/or ;) Pro. I have many other things I could say, so if you want more info, just pm me :lol:
  • 0
I am an in the GM Quiz!
Probably the main reason that I answer questions is so that you will read and respond to stuff in my signature!!
If you could, would you put any functions into Game Maker? If so, what would you? Message me with your ideas, I'm trying to create a big database of ideas to maybe later send the author of Game Maker so that he can put those functions in!!

#38 Quimp

Quimp

    Pretzel fanatic

  • New Member
  • 275 posts

Posted 20 August 2007 - 09:40 PM

Precompile a script? Isn't it what happens when the game starts? If so, how would execute_compiled be any different from script_execute or just calling the script? Also, note that it's pretty pointless to use a string of a script when you can just refer to it by its index (ex: precompile(script0); ).

Edit:

There is no need for execute_string() here, just use show_message()

I'm well aware of that; I explicitly stated that it was of no use.

var MyName,ExecuteString;
MyName = get_string("Your Name:","");
ExecuteString = "// do whatever";

if MyName = "Bobby" execute_string(ExecuteString)
if MyName = "Cody" execute_string(ExecuteString)
etc etc.

A user-defined event or a script would work just as well. I fail to even see the need to use execute_string() here since the string is independent from the user's input.

Edited by Quimp, 20 August 2007 - 09:47 PM.

  • 0

#39 metal-games

metal-games

    metal-games

  • New Member
  • 732 posts

Posted 20 August 2007 - 09:59 PM

what does Execute_string() do.
  • 0

#40 FredFredrickson

FredFredrickson

    Artist

  • Global Moderators
  • 9225 posts
  • Version:GM:Studio

Posted 20 August 2007 - 10:10 PM

If you are looking for keeping your GM7 game secure by not using execute_string, give up.

There are MASSSIIIVVEE ways to pull GM7 EXE's apart and put in your own code.

<{POST_SNAPBACK}>

Of course there are, nobody denies that... but there's no use in making the job any easier for the more sinister members of the community.
  • 0

#41 Smarty

Smarty

    GMC Member

  • GMC Elder
  • 7522 posts
  • Version:GM:Studio

Posted 20 August 2007 - 10:12 PM

Sometimes it's just plain stupid not to use execute_string(). As long as you don't call it in an event like step (like you said) I have never noticed any signifigant speed drop, or any speed drop. Calling execute_string once or twice in your game has no noticable effects

The above wasn't my point. Of course I wouldn't dare to aim at banning out at every singularity, but I would argue that I consider them bad even for one's personal development as a programmer to use it and capable of leading to badly organised or maintainable code (I'm waiting for a few examples to show up).

I often use execute_string() for menu buttons' parent objects, and just call their clickaction on left mouse. It's alot easier if you want to try to have any sort of decorative menu options.

But it can be done without it. When I create a parent object to act as a button, I tell it to e.g. execute the first user event. All it's child objects only need the relevant code in the first user event, which can be different for each child. I daresay this beats your practice, as I can syntax-check all my scripts at design-time and not find out trivialities during game run (as is the case with execute_string()).

Let's say I WANT to make a game in which a user types in code, and it is executed. Is there an alternative other than storing it as a string and executing it?

You'll have to consider why you want to let the user type in a code. Do you expect your user to be fluent in GML? And do you really need all the GML commands in the book? If the answer is no in any or both occasions, you're better off writing your own custom-made script parser which by default bans malicious injections unless you actually implement the open door.

if you want to create an object editor (like the one of WCIII) it's hardly possible to do it antoher way round (apart from making your own interpreter, which I think is even more slowly). - but this falls I think already under the point 3 of valid reason you saw..

I myself often use the execute string command though, it's because  whenever I create a program, I want it to be as dynamically as possible, allowing users to modify everything to their liking...

<{POST_SNAPBACK}>

But to what extend is such flexibility still useful? Only to other GM developers, because you will need GM and GML knowledge. And they can undermine the entire logic of your application (and make it do nasty things and pass it on to someone else). Good design allows one to define where this flexibility is needed, and how it is best implemented while giving the user the required tools and at the same time safeguarding the application's integrity. But, as I stated, that's a valid purpose of it, if you forget about the risks.

Which is what I use for button objects so that I can have just ONE button object - when the object is created, it gets its script assigned to it, and when it's clicked, it executes the associated script.

See my answer to B&B_Gaming.

Of course, I'm making a huge game that depends vastly on execute_string, but Smarty and I have already argued over it. ;) I'm doing it because GM's internal editors are inconvenient for working with really huge amounts of code-and-text (I've got about a meg's worth of text scripting files that the game reads from during execution.) Even if it weren't a pain in the butt to work with this much information in the little bitty script editor, I'm not sure the gm source file would appreciate the bulk. We usually tell people to externalise huge resources, after all! :P

This is true, although you'll have to admit that keeping the source external is rather unorthodox... unless you're into open-source. GM's text editor isn't particularly great, that's true, but it does allow one to use another external editor. As for a megabyte of script, is there really no chance of doing things differently? :lol:

Wouldn't topics like this belong better in the Game Design forum. That's what they seem to pertain to.

<{POST_SNAPBACK}>

Well, I've considered all forums. It's related to GML but it isn't a question, so no Q&A. And I personally don't consider this an expert topic. And Game Design doesn't normally relate to features of GML or script programming in general. But I'm telling the Community why I think some give bad advice and I ultimately hope it sways some opinions. So I thought this was a valid place for this topic.

I created the following script to avoid problems with execute_string(). To use with execute_file(), just load a file into a string then run it through this same script.
http://gmc.yoyogames...0

I think you didn't properly layer the security risk involved with particular commands. With help of what you give me at level 4 I can introduce the commands at level 5. All it takes are script or object creation routines (hint, hint). But unfortunately those are vital for the most common purpose of external script files (how else would you add functionality to a game?)

Hmm....I'm guilty, not of telling people to use execute_string, but using it myself for one of my engines...

I wrote a textbox engine, and I have a script that was basically when the player pressed space it would open the textbox, if they were near enough/facing them, etc.

Here's how I used execute_string: [snip]

This seems to me the same issue as B&B Gaming and hpapillon had. First of all, you can use object inheritance: you create a simple object that acts as a parent for all other objects. All NPCs would have this parent. Next, where you have execute_string() you call user event 0. Every time when you create a new NPC, you only have to add code to that event to make it's special script work. The rest stays the same.

Again, the advantage is that your code is syntax-checked at design time and / or startup time as opposed to when you finally hit that space button.

what does Execute_string() do.

You don't need to know. Really. ;)
  • 0

#42 StapleGun

StapleGun

    GMC Member

  • New Member
  • 721 posts
  • Version:Unknown

Posted 20 August 2007 - 10:38 PM

In order for the malicious code to be affective, doesn't the .exe have to be redistributed? Unless you consider cheating in your game malicious, the person could just write their own code in Game Maker (;) No Way!) and send you the .exe ... Alot of these worries seem somewhat trivial to me.

Edited by StapleGun, 20 August 2007 - 10:38 PM.

  • 0
<div align='center'>Creating a program is easy. Creating software is difficult.</div>

#43 grandhighgamer

grandhighgamer

    Village Idiot

  • GMC Member
  • 3876 posts
  • Version:GM:Studio

Posted 20 August 2007 - 10:48 PM

In order for the malicious code to be affective, doesn't the .exe have to be redistributed? Unless you consider cheating in your game malicious, the person could just write their own code in Game Maker (;) No Way!) and send you the .exe ... Alot of these worries seem somewhat trivial to me.

<{POST_SNAPBACK}>

It's more a problem with people using external code to extract/export the internal resources.
  • 0

GHG WUZ ERE


#44 Smarty

Smarty

    GMC Member

  • GMC Elder
  • 7522 posts
  • Version:GM:Studio

Posted 20 August 2007 - 10:51 PM

In order for the malicious code to be affective, doesn't the .exe have to be redistributed? Unless you consider cheating in your game malicious, the person could just write their own code in Game Maker (;) No Way!) and send you the .exe ... Alot of these worries seem somewhat trivial to me.

<{POST_SNAPBACK}>

You're forgetting about exposing most of the resources. And in multiplayer games, one could introduce cheap cheats.

But unfortunately the focus has shifted towards malicious code injection over the course of this topic. That was one of the downsides I listed, but not my main argument. I am more concerned with people crippling their game, and with learning bad programming practices.
  • 0

#45 Natso

Natso

    Nat S. Orion

  • New Member
  • 1055 posts

Posted 20 August 2007 - 10:54 PM

I use execute_script() in Galactic Hacker 2.1 Extended version... By including encrypted patch files, the game would decrypt, hash-check, and run these files. The file would append or otherwise replace existing code *once*, and the game would continue to function as normal. The game's code was organized in such a way that it was easy to modify in this way, allowing even the entire storyline to be replaced, or for new servers to be added, new shops to open, new programs to run, and so on.

The hash & encryption kept it safe from potential hazards.
  • 0

#46 E.B

E.B

    GMC Member

  • GMC Member
  • 149 posts

Posted 20 August 2007 - 10:58 PM

^Cheers Smarty...I'll look into it.

[I was torn between not posting and being rude or posting but breaking the rules ;)]

Thanks Smarty

[/SPAM]
  • 0

#47 StapleGun

StapleGun

    GMC Member

  • New Member
  • 721 posts
  • Version:Unknown

Posted 20 August 2007 - 11:03 PM

In order for the malicious code to be affective, doesn't the .exe have to be redistributed? Unless you consider cheating in your game malicious, the person could just write their own code in Game Maker (;) No Way!) and send you the .exe ... Alot of these worries seem somewhat trivial to me.

<{POST_SNAPBACK}>

It's more a problem with people using external code to extract/export the internal resources.

<{POST_SNAPBACK}>


But if they could inject code in the first place, why would they need it to be in string form to be parsed by exeute_string? If every GM .exe has the ability to execute code in its raw format, someone could just as easily inject whatever code they needed into an arbitrary location to be executed, rather than searching for an instance of execute_string.

I'd be more worried about people injecting code into a dll.

Edited by StapleGun, 20 August 2007 - 11:03 PM.

  • 0
<div align='center'>Creating a program is easy. Creating software is difficult.</div>

#48 hpapillon

hpapillon

    GMC Member

  • GMC Elder
  • 3020 posts
  • Version:Unknown

Posted 20 August 2007 - 11:11 PM

I often use execute_string() for menu buttons' parent objects, and just call their clickaction on left mouse. It's alot easier if you want to try to have any sort of decorative menu options.

But it can be done without it. When I create a parent object to act as a button, I tell it to e.g. execute the first user event. All it's child objects only need the relevant code in the first user event, which can be different for each child. I daresay this beats your practice, as I can syntax-check all my scripts at design-time and not find out trivialities during game run (as is the case with execute_string()).


This sounds a lot messier than my script_execute version, if I'm understanding you correctly. I'm not creating lots of child object-types of the button object... I have ONLY the button object. I'm creating instances of the button object during play and assigning a script to them. AFAIK it's a lot less overhead to have many scripts than to have many unnecessary object types.

I can quickly (pseudocode)
create button
button.mytext = "Save Game"
button.myscript = do_savegame
create another button
newbutton.mytext = "Load Game"
newbutton.myscript = do_loadgame

And each will draw the correct text and, when clicked, script_execute(myscript). So I only need one object. And the scripts are properly checkable for errors within GM, as you say, and searchable as well.

Of course, from what I can tell, very few people USE script_execute, so they may not all have understood what I was getting at.

Of course, I'm making a huge game that depends vastly on execute_string, but Smarty and I have already argued over it. ;) I'm doing it because GM's internal editors are inconvenient for working with really huge amounts of code-and-text (I've got about a meg's worth of text scripting files that the game reads from during execution.) Even if it weren't a pain in the butt to work with this much information in the little bitty script editor, I'm not sure the gm source file would appreciate the bulk. We usually tell people to externalise huge resources, after all! :P

This is true, although you'll have to admit that keeping the source external is rather unorthodox... unless you're into open-source. GM's text editor isn't particularly great, that's true, but it does allow one to use another external editor. As for a megabyte of script, is there really no chance of doing things differently? :lol:


code-and-text, think of it like a movie script... ;) largely dialog, but also having to include all the stage directions (code) for people to move here, change this background, change the lighting, play this sound effect...

(And actually, I do kinda like people being able to mess with the data. I've had one Cute Knight customer write in and talk about how he'd altered certain external files to make a special version for his kids featuring monsters from their favorite anime... :P A lot of people wouldn't like this, of course.)
  • 0
Yes, making games is my day job.
Anime Games
Gaming blog

#49 Yourself

Yourself

    The Ultimate Pronoun

  • GMC Elder
  • 7352 posts
  • Version:Unknown

Posted 20 August 2007 - 11:17 PM

Of course, from what I can tell, very few people USE script_execute, so they may not all have understood what I was getting at.


And more people definitely should use it. It's incredibly useful; especially for passing a script name as an argument to another script. There are functions both in my GRegex extension and Data Sorting extension that do this. Without it, people would have had to been able to modify the scripts in these extensions in order to achieve the same flexibility. Or I would have been forced to create a bunch of different functions which each work a little differently just to do common tasks.
  • 0

#50 Slammin

Slammin

    GMC Member

  • New Member
  • 201 posts

Posted 21 August 2007 - 02:52 AM

I don't use script execute, but I do simply put scriptname(arguments).
But, as far as this whole things goes, couldn't you just use ini files for room creation and what not. The reason is because, Gamemaker only reads the information that you tell it to read from the ini file, as opposed to execute_file() which would read the whole file and make room for hacking codes. But, then again, Natso's idea sounded pretty cool. Prehaps he should elaborate on that a little more.
  • 0