Delphi Anti Cheat (enable any disabled button)
Asked Answered
W

3

6

In my application there are some buttons that I've disabled for a reason. But these buttons are easily enabled by TNTEnforcer.

Is there any easy way to prevent this?

Tried to pack with some packer / obfuscator, but still can be enabled.

What is TNTEnforcer

Wurster answered 11/6, 2014 at 7:12 Comment(9)
Just check the condition you use for disabling those buttons in the button click handlers, and don't execute your code if those conditions are not met. That way it won't matter that buttons can be enabled.Clunk
If the user can run code at the same privilege level as your program, and we have to assume the user can, then you cannot defend against such attacks. User will always be able to enable the buttons. Even if you disable the code behind the button, the hacker can bypass that.Inverter
A link to an undocumented download is not very helpful. It even raises my 'warning, possible malware' red flag. I suggest you edit your question and explain what TNTEnforcer is/does.Dough
@Clunk Yes, i aware about that. But it will need much more code instead 'just disable'.Wurster
@DavidHeffernan So, there is no such easy way? I have no idea how that enforcer work very smooth.Wurster
You could use a ToolbarButton it states it cannot handle these!! But really my suggestion would be to use a protector such as The Enigma Protector look it up - it can easily protect against modifying your program and would take a great deal of effort and time to unpack and reverse if used in the right way.Australoid
@Australoid Please test that enforcer against enigma 4.20 and you'll be shocked. How come a very OLD program doing "nasty" thing very smooth.Wurster
8 of 12 delphi users now have that "enforcer" silently running on their systems :)Workhouse
You can use actions to avoid this sort of hack.Cheetah
I
8

VCL controls are backed by Win32 controls and these are inherently insecure. You cannot restrict access to their properties and state. External programs can readily modify state, press buttons etc.

You might be tempted to run a timer that resets the UI state at a high frequency. This might make it a little harder for a cracker. But still not particularly hard, and at what cost to your program and code?

So, in my view, you should not attempt to stop external programs interfering with the UI state. Instead you can add checks and defences to the OnClick handlers and other code behind the UI. This is perfectly crackable too, but it does at least require a little more effect from the cracker.

You might write:

button.Enabled := False;
button.OnClick := nil;

when you disable the button. When you re-enable it you could write:

button.Enabled := True;
button.OnClick := MyOnClickHandler;

That's a rather crude way to do it. It might be preferable to push the checking down the call chain, into the OnClick handler itself, or even better, further down into your business logic. That way, no matter how the code reaches the business logic, if it needs to be blocked it will be.

Inverter answered 11/6, 2014 at 7:40 Comment(5)
So the only way is just like 'if FoundExe('enforcer.exe') then Application.Terminate' ? Or should i use another approach ? Any example on how to programatically to prevent this enforcer stuff would be nice.Wurster
That's not what I am saying at all. It doesn't matter whether the button is enabled or not if your OnClick handler does nothing. Are you trying to stop the user clicking a button, or stop the program from doing the action that lies behind the button? I cannot believe that you care deeply about button pressing. Surely you only really care about what happens when the button is pressed.Inverter
You should also adjust your mindset a little. Blocking one executable by name can never be useful. The user can rename the executable. I think you have an unrealistic belief in what you might expect to achieve in defending against crackers. Your mindset should be that you program will be cracked.Inverter
@Wurster kill other process is never a good idea, because attacker can use random process names. If you want enhance the security, you might try with Firemonkey component library (no guarantee), which is relative new to the market. Or as David suggested, remove OnClick handler temporarily when you disable a button.Ander
@Bianca: What David says is that if the button does nothing, it doesn't matter if the button can be clicked or not. The user who uses the cracker wants to get at the functionality the button provides. If it doesn't do anything, it doesn't matter. So only make the button do something (by setting an OnClick handler) if the user is allowed to do that and remove the OnClick handler if he is not.Archduke
A
4

Unless the attacker has intimate knowledge of the inner workings of the particular version of the VCL that your app is using so that it can directly manipulate the VCL's internal memory, the best it can do is use standard Win32 APIs to manipulate the publicly accessible HWNDs of your app, such as by using EnableWindow() followed by BM_CLICK.

So one simple defense would be to remove the attack vector that you want to protect - in this case, by replacing TButton with TSpeedButton. TButton is a TWinControl descendant, so it has an HWND. TSpeedButton is a TGraphicControl descendant, so it does not have an HWND, and thus is not accessible to external processes because it is a custom drawn control managed exclusively by the VCL, not the OS.

Analyzer answered 11/6, 2014 at 9:27 Comment(3)
TSpeedButton is a control that cannot be automated, a control that cannot be a default or cancel button. These could be considered disadvantages.Inverter
"cannot be automated" is the whole point of this exercise. If it is accessible to automation then it is accessible to outside parties who can do whatever they want with it.Analyzer
That's a bizarre statement. Automation just allows you to do programmatically what can be done interactively. I don't accept that this question is about suppressing all automation. Do that and you render your program inaccessible. You've thrown the baby out along with the bath water.Inverter
A
1

If your application uses the traditional component TButton (from StdCtrls.pas), the button is a Windows standard control. Anyone, who knows the control handle, can access it. The attacker TNTEnforcer can iterate windows and find the button handle. After that, the malware can enable your button and simulate mouse clicks.

Solution 1: As disabled buttons are not clickable, my first idea is to intercept CM_ENABLECHANGED (David mentioned WS_DISABLE) messages, so that the malware is not able to change the button enable-state. The solution is similar to David's but over complicated. As David mentioned, we can remove the OnClick handler temporarily, when we intend to disable a button.

Solution 2: Another idea is to protect button handle from being searched. You might convert your traditional Vcl-based application to a cross-platform FireMonkey based application. Because the FMX draws components itself, the TNTEnforcer cannot attack in the old way at all. I have never done that before. The convert effort can be high.

Ander answered 11/6, 2014 at 7:47 Comment(7)
What is the purpose of the lock?Inverter
@DavidHeffernan You're right. Locking is not necessary. I've removed it. Thanks.Ander
The code doesn't compile. When I try to fix it, it has no discernible effect. It does not stop an external entity removing the WS_DISABLED window style.Inverter
@DavidHeffernan Thanks for the info about WS_DISABLED. I was inspired by TButtonStyleHook, which intercepts CM_ENABLEDCHANGED only. And code updated.Ander
It also offers no defence against EnableWindow. That's going to be tricky to block. No doubt possible with sufficient hacking. But it's the wrong way to solve this. Just bail out in the OnClick handler and the job is done. What you are attempting to do is complex and needless. It is bad advice for the asker.Inverter
@DavidHeffernan Yes, I agree that protect OnClick is the right way. But how to identify a friendly click and a malicious click? Can you share more details?Ander
You don't need or want to do that. The program decides to disable the action so it disables the button, and puts a block in OnClick. The cracker then enables the button but it doesn't matter because the OnClick handler ignores the click.Inverter

© 2022 - 2025 — McMap. All rights reserved.