I'm making user definable key macros to a program. (Those macros are limited to that program.)
I'm using TApplicationEvents to record key messages. And then use SendInput to play them back. But I need to disable mouse and keyboard so it wouldn't interrupt playback.
I can't use JournalPlaybackProc and JournalRecordProc because they are subject to UAC, UIPI in Vista and Win7.
Is there a easy way to block mouse and keyboard input while still using SendInput. (A way that doesn't need heightened privileges.)
Also I need one escape key that stops playback.
EDIT:
TControl.Perform didn't work because it ignores hotkeys.
I thought of using reserved nibble (bits 25-28) in WM_KEY messages, but in the windows documentation it says it's reserved and do not use. What could be the consequences.
If you want the 'artificial input' to be limited to your own application, I wouldn't use SendInput. If you use TApplicationEvents.OnMessage to record messages, I would add a 'if not(PlayingBack) then' check in the OnMessage when playing back a macro and use Form1.Perform
I have always used AutoIT's DLL for sending KeyStrokes as well as Blocking Keyboard and Mouse.
There is one thing and that is AutoIT can't block Ctrl+Alt+Del keys.
Do check it out.
HTH
Related
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
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.
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.
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.
I have two keyboards attached to a PC. One is used to type in TMemo1 and the other in TMemo2. Both are allowed to type at the same time. The problem is I cannot distinguish what keyboard-one has typed and what keyboard-two has typed.
Is there any way to distinguish, which device certain input came from?
#Dian, you can use the RegisterRawInputDevices function to register the keyboards and monitor the WM_INPUT message to determine the device (keyboard) where the input came from.
check theses links for more info
Using Raw Input from C# to handle multiple keyboards
WM_INPUT Message
As far as I know there is no way to distinguish keyboards unil you have hooked keyboard driver. Windows provide solid input model to application, so there is no difference for application receiving input from keyboard, second keyboard, IR remote control, or from another program that uses SendInput API function.
A colleague and myself were debating over which way was less of a burden on the system resources. (Note: this is not the question I want an answer to. Rather the title and the line below in bold is the question I seek an answer for.)
1. Using KeyPreview to get the keypresses on a form.
or
2. Using defining an OnMessage procedure and handling it there.
At first glance it seems KeyPreview would be less of a system burden since defining an OnMessage procedure results in our program checking every message that comes in. Note messages we don't care about would cause it to jump out by the first if statement. That is at worst we would have an if statement executed for every message.
But we're wondering how Delphi deals with the KeyPreview property... We wonder if Delphi internally defines its own OnMessage and looks at the messages to then trigger the events that are related to keypresses.
If this is the case then would both approaches be about the same?
As others have already said - there is probably no noticeable difference.
I just wanted to point out an exellent article by Peter Below on that topic: A Key's Odyssey archive
This article describes the key message processing as implemented in Delphi 2007 for Win32 VCL forms applications. A few things have changed in this area compared with Delphi 7, but these are mostly additions that I will highlight when we get to them. Most of this code has survived basically unchanged since the times of Delphi 1, a tribute to the robustness of the design. If you are in a hurry or not interested in all the details you can refer to the outline in the summary for a condensed overview.
The KeyPreview functioning:
The KeyPreview property of the current active form is checked for the KeyUp-, KeyDown- and KeyPress- event handlers of the current active control. I.e.: a key press in any control results in the check of the form's KeyPreview property.
If that property is True, the event handler in question invokes the event handler of the form prior to that of itself. If the form's event handler does not change the key value to 0 (or #0, depending on KeyPress or KeyDown/KeyUp), then the active control's event handler takes back over, otherwise the event is considered handled.
Compared to Application.OnMessage:
So setting the key value to 0/#0 in a form's event handler is synonymous to setting the Handled parameter of Application.OnMessage. In this, there is virtually no difference. But since OnMessage is called very early in the dispatching process, there is a theoretical gain in performance because the message is not being dispatched any further. When you leave Handled to False, there is no difference at all, because the KeyPreview property is always checked, whether it is set or not.
The main difference that is left is that you have to set the KeyPreview of áll Forms to True, ánd implement and maintain for each of all forms the appropriate event handlers. Compare this to having just one event handler for Application.OnMessage. That is: assuming you could do with just one routine for all of your forms.
The best answer would be, measure it. Most likely neither one is going to place any noticeable "burden" on the system, and if you don't notice it when you're specifically looking for it, then your users won't either. So just go with whichever one's easier to understand in case you need to come back to that code sometime in the future.
The bottom line here is that you can't generate input quick enough to make the computer even notice. The computer would not be troubled if you produced input messages at rates hundreds or even thousands greater than you typically do.
You won't be able to measure the difference between handling something in OnMessage and using KeyPreview.
So the decision as to which to use comes down to which is most convenient. If you need handling to happen at an application wide level, and you don't have a common base class for all your forms, then you use OnMessage. If you want different behaviour for different forms then you need to use KeyPreview.
Personally I strongly recommend refactoring so that all forms in your projects derive from a common base (a subclass of TForm). This allows you much more flexibility. Done this way you can, for example, use the KeyPreview mechanism to apply intervention points for all forms in your applications.
As for how KeyPreview is implemented, the input messages get redirected in KeyDown, KeyPress etc. in TControl. To learn more read the source code.
sorry for this little bit strange title, didn't found a better one..
I've got the following situation:
I have a PC with an RFID reader connected via USB.
I now need a program which pops up when ab transponder was scanned the the RFID reader and shows the scanned value. (The reader just simulates keystrokes)
Problem: the value of the transponder is something like 0001230431, and I can't change it. (To prefix a hotkey combination or so)
So I have thought about using a global keyboard hook, check if three zeros where typed in, capture rest of data and when the 10 digits are complete, call the application through an automation object and show the number.
But I'm not very exalted about using a global keyboard hook. Many AV programs don't like them very much, they are not so easy to handle with Delphi and I guess that's not very resource-friendly for such a little task...
So I'm looking for an alternative solution...maybe somebody has an idea?
Big thx!
ben, you can use the RegisterRawInputDevices and GetRawInputData functions.
first you must use the RegisterRawInputDevices function to register the input device to monitor and then you can retrieves the data from the input device using the GetRawInputData function.
Check theses functions too
GetRawInputDeviceList retrieves the list of input devices attached to the system.
GetRawInputDeviceInfo retrieves information on a device.
Why not make sure the Delphi app with a text edit control has focus before the scan is done? Then the keystrokes will go straight into your Delphi app.
I've written some BlackBerry apps, but now i'm trying to write one that must access the hardware (keyboard) in some low level way, and I can't seem to find a way to do it, nor any help to it in the 'official' boards.
The thing is, I need to know when, at any time, the '$' key is pressed in the blackberry keyboard, so my app (or resident service) can catch it, stop the '$' char from displaying, and if the user presses a vowel next, then add an accent to that vowel... and if it presses another key, just send back the '$' char + the other char.
i.e. '$' + 'a' = á
In other words, I need to create an app or service that converts the '$' key into an accent key, just like typical non-US PC keyboards works.
Now here's the problem: The whole Blackberry OS works under a Java Virtual Machine (Kind of making the JVM the actual OS). So as you can imagine, every app written for it is written in Java.
There's obviously a set of special blackberry api libraries into their Java implementation so the developer is able to access particular Blackberry functions and features... however there doesn't seem to be a thing that I can use to achieve my particular task.
But then maybe there is, and I haven't found it, since I'm still new to Blackberry Programming.
So, in that note, any help or comment will be greatly appreciated.
-Gabriel Alonso.
A screen need to have the focus to be able to get key Event.
RIM dosen't allow low level access to their hardware for security reason.
Press and hold a letter key and roll the thumb-wheel to scroll through international/accent characters, equation symbols and other marks.
Here is the source
Blackberry do not allow execute applications, if they use certain API, not to mention the low-level programming.
All that you can use in your applications for keypad handling - it is possibilities of Java. Like KeyListener interface and Keypad class.
This is a very late reply, however...
You can use keyChar (member of screen, and of KeyListenerInterface) to intercept any key - for the first letter, capture the key pressed. If it's "$" hold onto it and don't call super.keyChar. On the next keyChar (or after a delay with no input) perform your mapping if $ was previously pressed, and send your designed character code to the super.keyChar call. keyDown and keyUp can be used similarly if keyChar presents implementation issues.