How can I keep my application from a keyboard logger?

Unanswered How can I keep my application from a keyboard logger?

  • Tuesday, September 18, 2012 5:51 AM
     
     

    My program needs some high security measures to keep it from any would-be attackers. So I got an idea:

    when password textbox is focused, I used a background worker to send a lot of virtual keypress by either keybd_event or Sendkeys.Send. But soon I find out, though my application can tell actual keypress from the virtual one, the user input might be interrupted or lost. For example, user often use SHIFT key to type a single capital "A", but because of the virtual keypress, all of them appears as lower-case "a". (CapsLock doesn't seem to be affected)

    Then I made some improvement: save the keyboard state by GetKeyboardState() and then restore it once codes are executed using SetKeyboardState(). It got better, but it's still fifty-fifty chance the SHIFT will be lost.

    So here I wonder why? And is there any other solutions? I searched the Internet and found a lot of anti-keylogger software, but no articles about these.

    I would really appreciate if you can help.


    Does this unit have a soul?

All Replies

  • Tuesday, September 18, 2012 6:37 AM
     
     

    When the password textbox has focus it loses the shift function from the keyboard? Do you capture the incoming keyboard keystroke and then pass it to the password textbox? And if so what code do you use to do that?


    You've taught me everything I know but not everything you know.

  • Tuesday, September 18, 2012 7:47 AM
     
      Has Code

    In this code I set the TextBox2 (password TextBox) property Read Only to true. And the GetAsyncKeyState will detect Caps Lock, Shift, Num Lock and Normal Keyboard operations. However I don't know how to make it backspace or delete in the TextBox so Button1 is used to clear the TextBox if the user entering the password needs to start over due to typing error or I suppose password mismatch unless password mismatch clears the password TextBox automatically.

    Don't know if this is what you are looking for though. Also TextBox2.Backcolor is set to white.

    Imports System.Runtime.InteropServices
    
    Public Class Form1
    
        <DllImport("user32.dll")>
        Public Shared Function GetAsyncKeyState(ByVal vKey As Int32) As UShort
        End Function
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            TextBox2.ReadOnly = True
            KeyPreview = True
        End Sub
    
        Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
            If (GetAsyncKeyState(&H6E) And My.Computer.Keyboard.NumLock) Then
                TextBox2.AppendText(".")
            ElseIf (GetAsyncKeyState(&H67) And My.Computer.Keyboard.NumLock) Then
                TextBox2.AppendText("7")
            ElseIf (GetAsyncKeyState(&H68) And My.Computer.Keyboard.NumLock) Then
                TextBox2.AppendText("8")
            ElseIf (GetAsyncKeyState(&H69) And My.Computer.Keyboard.NumLock) Then
                TextBox2.AppendText("9")
            ElseIf (GetAsyncKeyState(&H64) And My.Computer.Keyboard.NumLock) Then
                TextBox2.AppendText("4")
            ElseIf (GetAsyncKeyState(&H66) And My.Computer.Keyboard.NumLock) Then
                TextBox2.AppendText("6")
            ElseIf (GetAsyncKeyState(&H61) And My.Computer.Keyboard.NumLock) Then
                TextBox2.AppendText("1")
            ElseIf (GetAsyncKeyState(&H62) And My.Computer.Keyboard.NumLock) Then
                TextBox2.AppendText("2")
            ElseIf (GetAsyncKeyState(&H63) And My.Computer.Keyboard.NumLock) Then
                TextBox2.AppendText("3")
            ElseIf (GetAsyncKeyState(&H60) And My.Computer.Keyboard.NumLock) Then
                TextBox2.AppendText("0")
            ElseIf (GetAsyncKeyState(&H51) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("Q")
            ElseIf (GetAsyncKeyState(&H57) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("W")
            ElseIf (GetAsyncKeyState(&H45) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("E")
            ElseIf (GetAsyncKeyState(&H52) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("R")
            ElseIf (GetAsyncKeyState(&H54) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("T")
            ElseIf (GetAsyncKeyState(&H59) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("Y")
            ElseIf (GetAsyncKeyState(&H55) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("U")
            ElseIf (GetAsyncKeyState(&H49) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("I")
            ElseIf (GetAsyncKeyState(&H4F) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("O")
            ElseIf (GetAsyncKeyState(&H50) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("P")
            ElseIf (GetAsyncKeyState(&H41) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("A")
            ElseIf (GetAsyncKeyState(&H53) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("S")
            ElseIf (GetAsyncKeyState(&H44) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("D")
            ElseIf (GetAsyncKeyState(&H46) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("F")
            ElseIf (GetAsyncKeyState(&H47) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("G")
            ElseIf (GetAsyncKeyState(&H48) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("H")
            ElseIf (GetAsyncKeyState(&H4A) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("J")
            ElseIf (GetAsyncKeyState(&H4B) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("K")
            ElseIf (GetAsyncKeyState(&H4C) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("L")
            ElseIf (GetAsyncKeyState(&H5A) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("Z")
            ElseIf (GetAsyncKeyState(&H58) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("X")
            ElseIf (GetAsyncKeyState(&H43) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("C")
            ElseIf (GetAsyncKeyState(&H56) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("V")
            ElseIf (GetAsyncKeyState(&H42) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("B")
            ElseIf (GetAsyncKeyState(&H4E) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("N")
            ElseIf (GetAsyncKeyState(&H4D) And My.Computer.Keyboard.CapsLock) Then
                TextBox2.AppendText("M")
            ElseIf (GetAsyncKeyState(&HC0) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("`")
            ElseIf (GetAsyncKeyState(&H31) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("!")
            ElseIf (GetAsyncKeyState(&H32) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("@")
            ElseIf (GetAsyncKeyState(&H33) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("#")
            ElseIf (GetAsyncKeyState(&H34) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("$")
            ElseIf (GetAsyncKeyState(&H35) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("%")
            ElseIf (GetAsyncKeyState(&H36) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("^")
            ElseIf (GetAsyncKeyState(&H37) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("&")
            ElseIf (GetAsyncKeyState(&H38) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("*")
            ElseIf (GetAsyncKeyState(&H39) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("(")
            ElseIf (GetAsyncKeyState(&H30) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText(")")
            ElseIf (GetAsyncKeyState(&HBD) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("_")
            ElseIf (GetAsyncKeyState(&HBB) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("+")
            ElseIf (GetAsyncKeyState(&H51) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("Q")
            ElseIf (GetAsyncKeyState(&H57) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("W")
            ElseIf (GetAsyncKeyState(&H45) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("E")
            ElseIf (GetAsyncKeyState(&H52) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("R")
            ElseIf (GetAsyncKeyState(&H54) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("T")
            ElseIf (GetAsyncKeyState(&H59) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("Y")
            ElseIf (GetAsyncKeyState(&H55) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("U")
            ElseIf (GetAsyncKeyState(&H49) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("I")
            ElseIf (GetAsyncKeyState(&H4F) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("O")
            ElseIf (GetAsyncKeyState(&H50) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("P")
            ElseIf (GetAsyncKeyState(&HDB) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("{")
            ElseIf (GetAsyncKeyState(&HDD) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("}")
            ElseIf (GetAsyncKeyState(&HDC) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("|")
            ElseIf (GetAsyncKeyState(&H41) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("A")
            ElseIf (GetAsyncKeyState(&H53) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("S")
            ElseIf (GetAsyncKeyState(&H44) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("D")
            ElseIf (GetAsyncKeyState(&H46) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("F")
            ElseIf (GetAsyncKeyState(&H47) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("G")
            ElseIf (GetAsyncKeyState(&H48) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("H")
            ElseIf (GetAsyncKeyState(&H4A) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("J")
            ElseIf (GetAsyncKeyState(&H4B) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("K")
            ElseIf (GetAsyncKeyState(&H4C) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("L")
            ElseIf (GetAsyncKeyState(&HBA) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText(":")
            ElseIf (GetAsyncKeyState(&HDE) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("""")
            ElseIf (GetAsyncKeyState(&H5A) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("Z")
            ElseIf (GetAsyncKeyState(&H58) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("X")
            ElseIf (GetAsyncKeyState(&H43) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("C")
            ElseIf (GetAsyncKeyState(&H56) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("V")
            ElseIf (GetAsyncKeyState(&H42) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("B")
            ElseIf (GetAsyncKeyState(&H4E) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("N")
            ElseIf (GetAsyncKeyState(&H4D) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("M")
            ElseIf (GetAsyncKeyState(&HBC) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("<")
            ElseIf (GetAsyncKeyState(&HBE) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText(">")
            ElseIf (GetAsyncKeyState(&HBF) And My.Computer.Keyboard.ShiftKeyDown) Then
                TextBox2.AppendText("?")
            ElseIf GetAsyncKeyState(&HC0) Then
                TextBox2.AppendText("`")
            ElseIf GetAsyncKeyState(&H31) Then
                TextBox2.AppendText("1")
            ElseIf GetAsyncKeyState(&H32) Then
                TextBox2.AppendText("2")
            ElseIf GetAsyncKeyState(&H33) Then
                TextBox2.AppendText("3")
            ElseIf GetAsyncKeyState(&H34) Then
                TextBox2.AppendText("4")
            ElseIf GetAsyncKeyState(&H35) Then
                TextBox2.AppendText("5")
            ElseIf GetAsyncKeyState(&H36) Then
                TextBox2.AppendText("6")
            ElseIf GetAsyncKeyState(&H37) Then
                TextBox2.AppendText("7")
            ElseIf GetAsyncKeyState(&H38) Then
                TextBox2.AppendText("8")
            ElseIf GetAsyncKeyState(&H39) Then
                TextBox2.AppendText("9")
            ElseIf GetAsyncKeyState(&H30) Then
                TextBox2.AppendText("0")
            ElseIf GetAsyncKeyState(&HBD) Then
                TextBox2.AppendText("-")
            ElseIf GetAsyncKeyState(&HBB) Then
                TextBox2.AppendText("=")
            ElseIf GetAsyncKeyState(&H51) Then
                TextBox2.AppendText("q")
            ElseIf GetAsyncKeyState(&H57) Then
                TextBox2.AppendText("w")
            ElseIf GetAsyncKeyState(&H45) Then
                TextBox2.AppendText("e")
            ElseIf GetAsyncKeyState(&H52) Then
                TextBox2.AppendText("r")
            ElseIf GetAsyncKeyState(&H54) Then
                TextBox2.AppendText("t")
            ElseIf GetAsyncKeyState(&H59) Then
                TextBox2.AppendText("y")
            ElseIf GetAsyncKeyState(&H55) Then
                TextBox2.AppendText("u")
            ElseIf GetAsyncKeyState(&H49) Then
                TextBox2.AppendText("i")
            ElseIf GetAsyncKeyState(&H4F) Then
                TextBox2.AppendText("o")
            ElseIf GetAsyncKeyState(&H50) Then
                TextBox2.AppendText("p")
            ElseIf GetAsyncKeyState(&HDB) Then
                TextBox2.AppendText("[")
            ElseIf GetAsyncKeyState(&HDD) Then
                TextBox2.AppendText("]")
            ElseIf GetAsyncKeyState(&HDC) Then
                TextBox2.AppendText("\")
            ElseIf GetAsyncKeyState(&H41) Then
                TextBox2.AppendText("a")
            ElseIf GetAsyncKeyState(&H53) Then
                TextBox2.AppendText("s")
            ElseIf GetAsyncKeyState(&H44) Then
                TextBox2.AppendText("d")
            ElseIf GetAsyncKeyState(&H46) Then
                TextBox2.AppendText("f")
            ElseIf GetAsyncKeyState(&H47) Then
                TextBox2.AppendText("g")
            ElseIf GetAsyncKeyState(&H48) Then
                TextBox2.AppendText("h")
            ElseIf GetAsyncKeyState(&H4A) Then
                TextBox2.AppendText("j")
            ElseIf GetAsyncKeyState(&H4B) Then
                TextBox2.AppendText("k")
            ElseIf GetAsyncKeyState(&H4C) Then
                TextBox2.AppendText("l")
            ElseIf GetAsyncKeyState(&HBA) Then
                TextBox2.AppendText(";")
            ElseIf GetAsyncKeyState(&HDE) Then
                TextBox2.AppendText("'")
            ElseIf GetAsyncKeyState(&H5A) Then
                TextBox2.AppendText("z")
            ElseIf GetAsyncKeyState(&H58) Then
                TextBox2.AppendText("x")
            ElseIf GetAsyncKeyState(&H43) Then
                TextBox2.AppendText("c")
            ElseIf GetAsyncKeyState(&H56) Then
                TextBox2.AppendText("v")
            ElseIf GetAsyncKeyState(&H42) Then
                TextBox2.AppendText("b")
            ElseIf GetAsyncKeyState(&H4E) Then
                TextBox2.AppendText("n")
            ElseIf GetAsyncKeyState(&H4D) Then
                TextBox2.AppendText("m")
            ElseIf GetAsyncKeyState(&HBC) Then
                TextBox2.AppendText(",")
            ElseIf GetAsyncKeyState(&HBE) Then
                TextBox2.AppendText(".")
            ElseIf GetAsyncKeyState(&HBF) Then
                TextBox2.AppendText("/")
            ElseIf GetAsyncKeyState(&HA2) Then
                TextBox2.AppendText("^")
            ElseIf GetAsyncKeyState(&H12) Then
                TextBox2.AppendText("%")
            ElseIf GetAsyncKeyState(&HA3) Then
                TextBox2.AppendText("^")
            ElseIf GetAsyncKeyState(&H65) Then
                TextBox2.AppendText("5")
            End If
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            TextBox2.Text = ""
        End Sub
    End Class


    You've taught me everything I know but not everything you know.


  • Wednesday, September 19, 2012 3:36 AM
    Moderator
     
     

    Hi legion,

    Thanks for you post.

    I’d like to suggest you to use virtual keyboard instead.

    You can add a button on the right of the password textbox, and let or force the users to using mouse click on the virtual keyboard to pass the data into the textbox. In this way, you can get rid of the keylogger software.

    Here is a keyboard sample: Create a soft keyboard (VBSoftKeyboard): http://code.msdn.microsoft.com/windowsdesktop/VBSoftKeyboard-161d92d7

    Hope this helps.


    Mark Liu-lxf [MSFT]
    MSDN Community Support | Feedback to us

  • Wednesday, September 19, 2012 5:34 AM
     
      Has Code

    Dim PasswordText As New Security.SecurePassword() Friend WithEvents Disruptor As New System.ComponentModel.BackgroundWorker() Private Sub PasswordTextbox_GotFocus(sender As Object, e As EventArgs) Handles PasswordTextbox.GotFocus Disruptor.RunWorkerAsync() End Sub Private Sub PasswordTextbox_LostFocus(sender As Object, e As EventArgs) Handles PasswordTextbox.LostFocus Disruptor.CancelAsync() End Sub Private Sub PasswordTextbox_Keydown(sender As Object, e As KeyDownEventArgs) Handles PasswordTextbox.KeyDown If Not (AllowedInput.Contains(e.KeyCode)) Then e.SuppressKeyPress = True 'AllowedInput is an array of all valid key codes. 'Following lines of codes can suppress keypress send by my application. End Sub Private Sub PasswordTextbox_KeyPress(sender As Object, e As KeyPressEventArgs) Handles PasswordTextbox.KeyPress PasswordText.Append(e.KeyChar) PasswordTextbox.Text = Space(PasswordText.Length) End Sub Private Sub OK_Click(sender As Object, e As EventArgs) Handles OK.Click PasswordText.MakeReadOnly() 'Other login procedures End Sub Private Sub Disruptor_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles Disruptor.DoWork Do Dim a(255) As Byte GetKeyboardState(a) Dim b As New Random() For i = 0 to 3 Sendkeys.SendWait(Chr(a.Next(32,128))) Next SetKeyboardState(a) Threading.Thread.Sleep(10) Loop Until Disruptor.CancellationPending End Sub Private Sub Form_Load(sender As Object, e As EventArgs) Handles Me.Load Disruptor.WorkerSupportsCancellation = True End Sub

    This is my codes.
    • Edited by Legion the Geth Wednesday, September 19, 2012 5:50 AM Add some comments in code
    •  
  • Wednesday, September 19, 2012 5:36 AM
     
     

    Hello Legion the Gerth,

    You simply cannot use VB to prevent key loggers are active. 

    They work on a machine to low level to be reachable for VB. Your have to use a program language like C++, C or Intel Assembler.

    Or you should disconnect your keyboard completely like I assume the others suggest and use a keyboard on the screen done by the mouse.


    Success
    Cor

  • Wednesday, September 19, 2012 5:39 AM
     
     

    I know that, but then how can I get rid of screen capture spyware?

    And also, it causes great inconvenience.


    Does this unit have a soul?

  • Wednesday, September 19, 2012 5:46 AM
     
     
    See my codes up there, I believe it can disrupt the keylogger(I've tested it). But the problem is, it also makes SHIFT key dysfunctional.

    Does this unit have a soul?

  • Wednesday, September 19, 2012 6:00 AM
    Moderator
     
     

    I know that, but then how can I get rid of screen capture spyware?

    And also, it causes great inconvenience.


    Does this unit have a soul?

    Hi Legion,

    Personally, I think screen capture doesn't make sense. A mouse location will not be showed into the screenshot. You also can random the location of buttons in the Virtual keyboard (in every time click a letter into password) to rid of the screen capture spyware. 

    Hope this helps.


    Mark Liu-lxf [MSFT]
    MSDN Community Support | Feedback to us

  • Thursday, September 20, 2012 5:36 AM
     
     
    A mouse location will not be showed into the screenshot. You also can random the location of buttons in the Virtual keyboard (in every time click a letter into password) to rid of the screen capture spyware

    1.Random the location of buttons, that's a lovely idea. Inconvenient for user, but more secure.

    2.But I still believe that a screen-capture software can capture mouse location simultaneously. For example, if I hook the mouse click function, then get a screenshot while recording a mouse location with GetCursorPos() when mouse clicked, then I should be able to recover every letters ever typed.


    Does this unit have a soul?

  • Thursday, September 20, 2012 12:37 PM
    Moderator
     
     

    Hi Legion,

    Could you please send a simple example that can reproduce the issue(SHIFT missing)? If it is OK, please send it to alanyao@microsoft.com

    However, I do agree vitrual keyboard with random buttons is a good idea if the security is the top concern for you.

    Regards,


    Alan Yao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.



  • Friday, September 21, 2012 5:47 AM
     
     

    Thanks for your attention. I should be able to send it to you next Sunday. I'm at school right now while my source codes are at home.

    I'm still not convinced with your opinions quite though. As I said above, if I use api to add some hooks in the system, I can intercept the mouse click events and then record the mouse coordinates. So with the snapshot, it will be rather easy to recover the password. So I don't think it's safe enough.

    Please tell me if there is any mistake.


    Does this unit have a soul?

  • Friday, September 21, 2012 9:09 AM
     
      Has Code

    There's a function to stop screen capture I think. It is called SetWindowDisplayAffinity "This function and GetWindowDisplayAffinity are designed to support the window content protection feature that is new to Windows 7. This feature enables applications to protect their own onscreen window content from being captured or copied through a specific set of public operating system features and APIs. However, it works only when the Desktop Window Manager(DWM) is composing the desktop."

    http://msdn.microsoft.com/en-us/library/windows/desktop/dd375340(v=vs.85).aspx

    I have code to check if DWM is enabled prior to using SetWindowDisplayAffinity but I have no idea how to do the DLLImport or the Public Shared Function for SetWindowDisplayAffinity or use SetWindowDisplayAffinity even if I knew how to do the DllImport or Public Shared Function for it.

    DWM is at this link http://msdn.microsoft.com/en-us/library/windows/desktop/aa969518(v=vs.85).aspx

    The code for checking if DWM is enabled follows;

    Imports System.Runtime.InteropServices
    
    Public Class Form1
    
        'SetWindowDisplayAffinity - Don't know how to do that.
    
        <DllImport("dwmapi.dll", PreserveSig:=False)> _
        Public Shared Function DwmIsCompositionEnabled() As Boolean
        End Function
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            If DwmIsCompositionEnabled() Then
                MessageBox.Show(DwmIsCompositionEnabled())
            Else
                MessageBox.Show("False")
            End If
    
        End Sub
    
    
    End Class


    You've taught me everything I know but not everything you know.

  • Friday, September 21, 2012 5:24 PM
     
      Has Code

    Fernando Soto gave me the information for using SetWindowsDisplayAffinity. When it is turned on in conjunction with DWMIsCompositionEnabled (true) then your applications form window is black when someone uses print screen on it.

    Below is the code I used to check if DWMIsCompositionEnabled and to turn SetWindowsDisplayAffinity on and off. The buttons on the form are Button1 to Button3 left to right.

    On another note SetWindowsDisplayAffinity is only supported on Windows 7 Clients minimum and Windows Server 2008 R2 minimum.

    Below the code are two images of my application, the first image is with SetWindowsDisplayAffinity on and the second image is with it off.

    Imports System.Runtime.InteropServices
    
    Public Class Form1
    
        <DllImport("dwmapi.dll", PreserveSig:=False)> _
        Public Shared Function DwmIsCompositionEnabled() As Boolean
        End Function
    
        Declare Auto Function SetWindowDisplayAffinity Lib "User32.dll" Alias "SetWindowDisplayAffinity" (ByVal hWnd As Integer, ByVal dwAffinity As Integer) As Boolean
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            MessageBox.Show(DwmIsCompositionEnabled())
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            ' Get the window handle 
            Dim hWnd As Integer = Me.Handle
            ' Then call the function as follows
            SetWindowDisplayAffinity(hWnd, 1)
        End Sub
    
        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            ' Get the window handle 
            Dim hWnd As Integer = Me.Handle
            ' Then call the function as follows
            SetWindowDisplayAffinity(hWnd, 0)
        End Sub
    
    End Class


    You've taught me everything I know but not everything you know.


  • Friday, September 21, 2012 5:53 PM
     
     
    Also you could run a timer to test for DwmIsCompositionEnabled enabled and if not re-enable it and reset SetWindowsDisplayAffinity to on. I don't know if Windows 8 or later supports this feature though. And there is some discernment as to whether this function is very security worthy. But I'd say it's better than nothing on a Win 7 or later (if supported) environment.

    You've taught me everything I know but not everything you know.

  • Saturday, September 22, 2012 1:08 PM
     
      Has Code

    Here's an update to the code that allows you to turn on and off Dwm. You could run a timer to test if someone disabled Dwm and then turn Dwm and SetWindowDisplayAffinity on again before they could do a screen capture.

    Imports System.Runtime.InteropServices
    
    Public Class Form1
    
        <DllImport("dwmapi.dll", PreserveSig:=False)> _
        Public Shared Function DwmIsCompositionEnabled() As Boolean
        End Function
    
        <DllImport("dwmapi.dll", PreserveSig:=False)> _
        Public Shared Sub DwmEnableComposition(bEnable As Boolean)
        End Sub
    
    
        Declare Auto Function SetWindowDisplayAffinity Lib "User32.dll" Alias "SetWindowDisplayAffinity" (ByVal hWnd As Integer, ByVal dwAffinity As Integer) As Boolean
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            MessageBox.Show(DwmIsCompositionEnabled())
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            ' Get the window handle 
            Dim hWnd As Integer = Me.Handle
            ' Then call the function as follows to turn SetWindowDisplayAffinity on.
            SetWindowDisplayAffinity(hWnd, 1)
        End Sub
    
        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            ' Get the window handle 
            Dim hWnd As Integer = Me.Handle
            ' Then call the function as follows to turn SetWindowDisplayAffinity off.
            SetWindowDisplayAffinity(hWnd, 0)
        End Sub
    
        Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
            DwmEnableComposition(False)
        End Sub
    
        Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
            DwmEnableComposition(True)
        End Sub
    End Class
    


    You've taught me everything I know but not everything you know.

  • Monday, September 24, 2012 5:32 AM
     
      Has Code

    Thanks for your solution, though I'm still hoping to find a way to type with keyboard.

    So your solution solve half of the problem, I'm still hoping someone can solve the rest.

    I've got my source code all here, so if you find the solution, please tell me.

    <frmLogin.Designer.vb>

    <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
    <Global.System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726")> _
    Partial Class frmLogin
        Inherits System.Windows.Forms.Form
        'Form overrides dispose to clean up the component list.
        <System.Diagnostics.DebuggerNonUserCode()> _
        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            Try
                If disposing AndAlso components IsNot Nothing Then
                    components.Dispose()
                End If
            Finally
                MyBase.Dispose(disposing)
            End Try
        End Sub
        Friend WithEvents LogoPictureBox As System.Windows.Forms.PictureBox
        Friend WithEvents UsernameLabel As System.Windows.Forms.Label
        Friend WithEvents PasswordLabel As System.Windows.Forms.Label
        Friend WithEvents UsernameTextBox As System.Windows.Forms.TextBox
        Friend WithEvents PasswordTextBox As System.Windows.Forms.TextBox
        Friend WithEvents OK As System.Windows.Forms.Button
        Friend WithEvents Register As System.Windows.Forms.Button
        'Required by the Windows Form Designer
        Private components As System.ComponentModel.IContainer
        'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.
        <System.Diagnostics.DebuggerStepThrough()> _
        Private Sub InitializeComponent()
            Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(frmLogin))
            Me.LogoPictureBox = New System.Windows.Forms.PictureBox()
            Me.UsernameLabel = New System.Windows.Forms.Label()
            Me.PasswordLabel = New System.Windows.Forms.Label()
            Me.UsernameTextBox = New System.Windows.Forms.TextBox()
            Me.PasswordTextBox = New System.Windows.Forms.TextBox()
            Me.OK = New System.Windows.Forms.Button()
            Me.Register = New System.Windows.Forms.Button()
            Me.CheckPasswordChar = New System.Windows.Forms.CheckBox()
            CType(Me.LogoPictureBox, System.ComponentModel.ISupportInitialize).BeginInit()
            Me.SuspendLayout()
            '
            'LogoPictureBox
            '
            Me.LogoPictureBox.Image = CType(resources.GetObject("LogoPictureBox.Image"), System.Drawing.Image)
            Me.LogoPictureBox.Location = New System.Drawing.Point(0, 0)
            Me.LogoPictureBox.Name = "LogoPictureBox"
            Me.LogoPictureBox.Size = New System.Drawing.Size(165, 193)
            Me.LogoPictureBox.TabIndex = 0
            Me.LogoPictureBox.TabStop = False
            '
            'UsernameLabel
            '
            Me.UsernameLabel.Location = New System.Drawing.Point(172, 24)
            Me.UsernameLabel.Name = "UsernameLabel"
            Me.UsernameLabel.Size = New System.Drawing.Size(220, 23)
            Me.UsernameLabel.TabIndex = 0
            Me.UsernameLabel.Text = "&User name"
            Me.UsernameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
            '
            'PasswordLabel
            '
            Me.PasswordLabel.Location = New System.Drawing.Point(172, 81)
            Me.PasswordLabel.Name = "PasswordLabel"
            Me.PasswordLabel.Size = New System.Drawing.Size(220, 23)
            Me.PasswordLabel.TabIndex = 2
            Me.PasswordLabel.Text = "&Password"
            Me.PasswordLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
            '
            'UsernameTextBox
            '
            Me.UsernameTextBox.Location = New System.Drawing.Point(174, 44)
            Me.UsernameTextBox.Name = "UsernameTextBox"
            Me.UsernameTextBox.Size = New System.Drawing.Size(220, 20)
            Me.UsernameTextBox.TabIndex = 1
            '
            'PasswordTextBox
            '
            Me.PasswordTextBox.ContextMenuStrip = New ContextMenuStrip()
            Me.PasswordTextBox.ImeMode = System.Windows.Forms.ImeMode.Disable
            Me.PasswordTextBox.Location = New System.Drawing.Point(174, 101)
            Me.PasswordTextBox.Name = "PasswordTextBox"
            Me.PasswordTextBox.Size = New System.Drawing.Size(220, 20)
            Me.PasswordTextBox.TabIndex = 3
            Me.PasswordTextBox.UseSystemPasswordChar = True
            '
            'OK
            '
            Me.OK.Location = New System.Drawing.Point(183, 158)
            Me.OK.Name = "OK"
            Me.OK.Size = New System.Drawing.Size(100, 23)
            Me.OK.TabIndex = 4
            Me.OK.Text = "&OK"
            '
            'Register
            '
            Me.Register.DialogResult = System.Windows.Forms.DialogResult.Cancel
            Me.Register.Location = New System.Drawing.Point(289, 158)
            Me.Register.Name = "Register"
            Me.Register.Size = New System.Drawing.Size(100, 23)
            Me.Register.TabIndex = 5
            Me.Register.Text = "&Register"
            '
            'CheckPasswordChar
            '
            Me.CheckPasswordChar.Appearance = System.Windows.Forms.Appearance.Button
            Me.CheckPasswordChar.AutoCheck = False
            Me.CheckPasswordChar.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
            Me.CheckPasswordChar.Location = New System.Drawing.Point(289, 127)
            Me.CheckPasswordChar.Name = "CheckPasswordChar"
            Me.CheckPasswordChar.Size = New System.Drawing.Size(100, 25)
            Me.CheckPasswordChar.TabIndex = 7
            Me.CheckPasswordChar.Text = "&Show Password"
            Me.CheckPasswordChar.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
            Me.CheckPasswordChar.UseVisualStyleBackColor = True
            '
            'frmLogin
            '
            Me.AcceptButton = Me.OK
            Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
            Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
            Me.ClientSize = New System.Drawing.Size(401, 193)
            Me.Controls.Add(Me.CheckPasswordChar)
            Me.Controls.Add(Me.Register)
            Me.Controls.Add(Me.OK)
            Me.Controls.Add(Me.PasswordTextBox)
            Me.Controls.Add(Me.UsernameTextBox)
            Me.Controls.Add(Me.PasswordLabel)
            Me.Controls.Add(Me.UsernameLabel)
            Me.Controls.Add(Me.LogoPictureBox)
            Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
            Me.MaximizeBox = False
            Me.MinimizeBox = False
            Me.Name = "frmLogin"
            Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
            Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent
            Me.Text = "Login"
            CType(Me.LogoPictureBox, System.ComponentModel.ISupportInitialize).EndInit()
            Me.ResumeLayout(False)
            Me.PerformLayout()
        End Sub
        Friend WithEvents CheckPasswordChar As System.Windows.Forms.CheckBox
    End Class

    <frmLogin.vb>

    Public Class frmLogin
        ' TODO: Insert code to perform custom authentication using the provided username and password 
        ' (See http://go.microsoft.com/fwlink/?LinkId=35339).  
        ' The custom principal can then be attached to the current thread's principal as follows: 
        '     My.User.CurrentPrincipal = CustomPrincipal
        ' where CustomPrincipal is the IPrincipal implementation used to perform authentication. 
        ' Subsequently, My.User will return identity information encapsulated in the CustomPrincipal object
        ' such as the username, display name, etc.
        Private PasswordText As New Security.SecureString
        Private SuppressedKeys As Keys() = {Keys.Add, Keys.Alt, Keys.Apps, Keys.Attn, Keys.BrowserBack,
            Keys.BrowserFavorites, Keys.BrowserForward, Keys.BrowserHome, Keys.BrowserRefresh,
            Keys.BrowserSearch, Keys.BrowserStop, Keys.Cancel, Keys.Capital, Keys.Clear, Keys.Control,
            Keys.ControlKey, Keys.Crsel, Keys.Down, Keys.End, Keys.Enter, Keys.EraseEof, Keys.Escape,
            Keys.Execute, Keys.Exsel, Keys.F1, Keys.F2, Keys.F3, Keys.F4, Keys.F5, Keys.F6, Keys.F7,
            Keys.F8, Keys.F9, Keys.F10, Keys.F11, Keys.F12, Keys.F13, Keys.F14, Keys.F15, Keys.F16,
            Keys.F17, Keys.F18, Keys.F19, Keys.F20, Keys.F21, Keys.F22, Keys.F23, Keys.F24, Keys.FinalMode,
            Keys.HangulMode, Keys.HanjaMode, Keys.Help, Keys.Home, Keys.IMEAccept, Keys.IMEConvert,
            Keys.IMEModeChange, Keys.IMENonconvert, Keys.Insert, Keys.JunjaMode, Keys.KanaMode,
            Keys.KanjiMode, Keys.LaunchApplication1, Keys.LaunchApplication2, Keys.LaunchMail,
            Keys.LControlKey, Keys.Left, Keys.LineFeed, Keys.LMenu, Keys.LWin, Keys.MediaNextTrack,
            Keys.MediaPlayPause, Keys.MediaPreviousTrack, Keys.MediaStop, Keys.Menu, Keys.Next,
            Keys.NumLock, Keys.Oem102, Keys.Pa1, Keys.Packet, Keys.PageDown, Keys.PageUp, Keys.Pause,
            Keys.Play, Keys.Print, Keys.PrintScreen, Keys.Prior, Keys.ProcessKey, Keys.RControlKey,
            Keys.Return, Keys.Right, Keys.RMenu, Keys.RWin, Keys.Scroll, Keys.Select, Keys.SelectMedia,
            Keys.Sleep, Keys.Snapshot, Keys.Tab, Keys.Up, Keys.VolumeDown, Keys.VolumeMute, Keys.VolumeUp,
            Keys.Zoom}
        Public WithEvents Disruptor As New System.ComponentModel.BackgroundWorker
        Public Disrupting As Char
        Private Sub DisruptorDoWork(sender As Object, e As System.EventArgs) Handles PasswordTextBox.GotFocus
            Disruptor.RunWorkerAsync()
        End Sub
        Private Sub DisruptorCancel(sender As Object, e As System.EventArgs) Handles PasswordTextBox.LostFocus, Me.Deactivate
            Disruptor.CancelAsync()
        End Sub
        Private Sub PasswordTextBox_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles PasswordTextBox.KeyDown
            If SuppressedKeys.Contains(e.KeyCode) OrElse e.Control OrElse e.Alt Then
                e.Handled = True
                e.SuppressKeyPress = True
            ElseIf e.KeyCode = Keys.Back Then
                If (PasswordText.Length > 0) AndAlso (PasswordTextBox.SelectionStart > 0) Then
                    PasswordText.RemoveAt(PasswordTextBox.SelectionStart - 1)
                    Dim a As Integer = PasswordTextBox.SelectionStart
                    PasswordTextBox.Text = Space(PasswordText.Length)
                    PasswordTextBox.Select(a - 1, 0)
                End If
                e.Handled = True
                e.SuppressKeyPress = True
            ElseIf e.KeyCode = Keys.Delete Then
                If (PasswordText.Length > 0) AndAlso (PasswordTextBox.SelectionStart < PasswordText.Length) Then
                    PasswordText.RemoveAt(PasswordTextBox.SelectionStart)
                    Dim a As Integer = PasswordTextBox.SelectionStart
                    PasswordTextBox.Text = Space(PasswordText.Length)
                    PasswordTextBox.Select(a, 0)
                End If
                e.Handled = True
                e.SuppressKeyPress = True
            End If
        End Sub
        Private Sub PasswordTextBox_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles PasswordTextBox.KeyPress
            If (Asc(e.KeyChar) > 127) OrElse (Asc(e.KeyChar) < 0) Then
                e.Handled = True
                Exit Sub
            ElseIf e.KeyChar = Disrupting Then
                e.Handled = True
                Disrupting = Chr(255)
                Exit Sub
            End If
            If PasswordTextBox.SelectionStart = PasswordText.Length Then
                PasswordText.AppendChar(e.KeyChar)
            Else
                PasswordText.InsertAt(PasswordTextBox.SelectionStart, e.KeyChar)
            End If
            Dim a As Integer = PasswordTextBox.SelectionStart
            PasswordTextBox.Text = Space(PasswordText.Length)
            PasswordTextBox.Select(a + 1, 0)
            e.Handled = True
        End Sub
        Private Sub PasswordTextBox_Deselect(sender As Object, e As System.EventArgs) Handles PasswordTextBox.MouseDown,
        PasswordTextBox.MouseMove, PasswordTextBox.MouseUp, PasswordTextBox.TextChanged
            PasswordTextBox.DeselectAll()
        End Sub
        Private Sub CheckPasswordChar_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles CheckPasswordChar.MouseDown
            If e.Button = Windows.Forms.MouseButtons.Left Then
                Dim Cur As Integer = PasswordTextBox.SelectionStart
                PasswordTextBox.UseSystemPasswordChar = False
                Dim a As IntPtr = Runtime.InteropServices.Marshal.SecureStringToBSTR(PasswordText)
                PasswordTextBox.Text = Runtime.InteropServices.Marshal.PtrToStringBSTR(a)
                Runtime.InteropServices.Marshal.ZeroFreeBSTR(a)
                PasswordTextBox.SelectionStart = Cur
                PasswordTextBox.SelectionLength = 0
            End If
        End Sub
        Private Sub CheckPasswordChar_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles CheckPasswordChar.MouseUp
            If e.Button = Windows.Forms.MouseButtons.Left Then
                Dim Cur As Integer = PasswordTextBox.SelectionStart
                PasswordTextBox.UseSystemPasswordChar = True
                Do
                Loop Until DisposeString(PasswordTextBox.Text)
                PasswordTextBox.Text = Space(PasswordText.Length)
                PasswordTextBox.SelectionStart = Cur
                PasswordTextBox.SelectionLength = 0
            End If
        End Sub
        Private Sub TextBox_MouseEnter(sender As Object, e As System.EventArgs) Handles UsernameTextBox.MouseEnter, PasswordTextBox.MouseEnter
            CType(sender, TextBox).Focus()
        End Sub
        Public Function DisposeString(ByRef S As String) As Boolean
            If IsNothing(S) OrElse (S = "") Then Return True
            Try
                Dim OriginalByteCount As Integer = S.Length * 2
                Dim c As IntPtr = Runtime.InteropServices.GCHandle.Alloc(S, Runtime.InteropServices.GCHandleType.Pinned).AddrOfPinnedObject
                Dim Counter As Integer = -1
                For i = 0 To OriginalByteCount
                    Counter = Counter + 1
                    Runtime.InteropServices.Marshal.WriteByte(c + Counter, 0)
                Next
            Catch ex As Exception
                Return False
            End Try
            Return True
        End Function
        Private Sub Disruptor_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles Disruptor.DoWork
            Disruptor.WorkerSupportsCancellation = True
            Do Until Disruptor.CancellationPending
                Dim a As New Random
                Disrupting = Chr(a.Next(128, 256))
                Dim b(255) As Byte
                NativeUnsafeMethods.GetKeyState(Keys.None) 'Solve GetKeyboardState bug
                NativeUnsafeMethods.GetKeyboardState(b)
                SendKeys.SendWait("{" & Disrupting & "}")
                NativeUnsafeMethods.SetKeyboardState(b)
                Disrupting = Chr(255)
                Threading.Thread.Sleep(100)
            Loop
            Disrupting = Chr(255)
        End Sub
    End Class
    Public Class NativeUnsafeMethods
        Public Declare Function GetKeyState Lib "user32.dll" (nVirtKey As Integer) As Short
        Public Declare Function GetKeyboardState Lib "user32.dll" (lpKeyState As Byte()) As Boolean
        Public Declare Function SetKeyboardState Lib "user32.dll" (ByRef lpKeyState As Byte()) As Boolean
    End Class

    Does this unit have a soul?

  • Monday, September 24, 2012 5:35 AM
     
     

    I've send you the code. And it is also posted on this thread. If you find a way to solve this problem apart from using screen keyboard, please let me know it.


    Does this unit have a soul?

  • Monday, September 24, 2012 5:48 AM
     
     
    If you are having difficulty finding a solution to your problem, you may wish to consider that the information you need to help defend against a keylogger is the same informtion that a keylogger would use to improve their chances of success.  People might be concerned about discussing their solutions in public.
  • Thursday, September 27, 2012 5:37 AM
     
     

    Thanks. I've already considered this when I post this thread.

    But you know, I don't want a completely new solution. I just want to find out what is wrong with my solution, and to look for a way to solve it.

    So please read my description about this question up there and my code.

    A short version of my solution:

    If a keylogger wants to log the password, it must hook the keyboard input. So I send virtual keypress generated randomly which can only be distinguished by my application. So the keylogger will log a lot of keypress but cannot find out which is the password.


    Does this unit have a soul?

  • Wednesday, October 17, 2012 10:20 AM
     
     

    There is little point trying to stop key loggers from capturing the keyboard. By the time they have the ability to capture key presses they are normally able to do anything an administrator would be able to do, including installing themselves as mouse, keyboard and video drivers. They can even install a root kit to make it hard for virus checkers to spot them. If they are really targeting you specifically they can change your application at a binary level to remove any security code you have put in. As a general rule of thumb you should always assume that anything on a client computer has been compromised.

    A better way to prevent this kind of attack is to make your identity check depend on a token that changes over time or can only be used once. This is why banks all seem to be issuing hardware devices for either generating time dependant codes or using a chip and pin card to encrypt some kind of challenge response code. This way any login captured by a key logger will only be useable once and the criminal getting the information will not find it very useful as it will already have been used.


    a