How would you check for this? Exploiters can modify all code. They can delete only sections of scripts or modify those scripts such that it looks like it’s doing its job to the rest of your scripts but it’s actually making no checks and just reporting “all good” constantly.
Exploiters can stick their UI in existing CoreGui objects anyways, so you can’t just check for new ScreenGuis in CoreGui, you’d have to check to make sure it’s not added as a descendant to CoreGui. The exploiter’s GUI could start using randomized names or existing CoreGui names to make it hard to detect or differentiate from real GUI, too. GUIs can also be put in BillboardGuis, SurfaceGuis, or in the PlayerGui. It would take a ton of checks to find all of these, and all of those checks can be disabled individually no matter where you put them.
Checks like that can be good for slowing exploiters down, anyways, but it won’t be 100% prevention. Exploiters will work around it. To prevent exploits, you need to run exploit detection code on a computer that they don’t control i.e. the server.
game.DescendantAdded will fire when any object is added to the game, even for locked objects.
You can’t access any properties, events, or methods of locked objects. You can use
tostring on them though to get their name. You can use this to detect when objects with certain names are added to the game at a performance cost. Running code any time an object is added to the game is bad for performance.
You can also use the
game.ItemChanged event with the tostring technique to detect object and property changes. This would be really bad for performance, though.
If developers start using this, exploiters will just start using names of existing CoreGuis for their exploitation GUIs. I might have just spoiled this technique a bit early as I’m sure some exploit developer will read this.