flat assembler
Message board for the users of flat assembler.

Index > Windows > switch keyboard keys around?

Author
Thread Post new topic Reply to topic
windwakr



Joined: 30 Jun 2004
Posts: 827
Location: Michigan, USA
windwakr
I saw a program today that could switch keys around. The readme said it was done with global hooks. How would I hook the keyboard, intercept the keys, dont send them, but simulate a keypress(I know how to simulate keypresses).

_________________
----> * <---- My star, won HERE
Post 30 Jul 2004, 17:42
View user's profile Send private message Reply with quote
coconut



Joined: 02 Apr 2004
Posts: 326
Location: usa
coconut
what windows version are you using
Post 30 Jul 2004, 18:09
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7721
Location: Kraków, Poland
Tomasz Grysztar
Here is a small sample from how I was doing it. First, compile this into CONVERT.DLL file:
Code:
format PE GUI 4.0 DLL at 10000000h
entry DllEntryPoint

include '%fasminc%\win32a.inc'

section '.text' code readable executable shareable

proc DllEntryPoint, hinstDLL,fdwReason,lpvReserved
        push    [hinstDLL]
        pop     [hinstance]
        mov     eax,TRUE
        return
endp

proc SetHook
        invoke  SetWindowsHookEx,WH_KEYBOARD,KeyboardProc,[hinstance],0
        mov     [hhook],eax
        return
endp

proc UnhookHook
        invoke  UnhookWindowsHookEx,[hhook]
        return
endp

proc KeyboardProc, ncode,wparam,lparam
        cmp     [ncode],HC_NOREMOVE
        je      no_conversion
        cmp     [wparam],VK_INSERT
        jne     no_conversion
        push    ebx
        mov     ebx,'A'
        invoke  MapVirtualKey,ebx,0
        bt      [lparam],31
        jc      key_up
        invoke  keybd_event,ebx,eax,0,0
        pop     ebx
        mov     eax,TRUE
        return
    key_up:
        invoke  keybd_event,ebx,eax,KEYEVENTF_KEYUP,0
        pop     ebx
        mov     eax,TRUE
        return
    no_conversion:
        invoke  CallNextHookEx,[hhook],[ncode],[wparam],[lparam]
        mov     eax,FALSE
        return
endp

section '.bss' readable writeable shareable

hinstance dd ?
hhook dd ?

section '.idata' import data readable writeable shareable

  library user,'USER32.DLL'

  import user,\
         SetWindowsHookEx,'SetWindowsHookExA',\
         CallNextHookEx,'CallNextHookEx',\
         UnhookWindowsHookEx,'UnhookWindowsHookEx',\
         MapVirtualKey,'MapVirtualKeyA',\
         keybd_event,'keybd_event'

section '.edata' export data readable shareable

  export 'CONVERT.DLL',\
         SetHook,'SetHook',\
         UnhookHook,'UnhookHook'

section '.reloc' fixups data readable shareable discardable    


And now is the code of program that uses this DLL. The code from DLL makes the Insert key act as an A key (only as an example):
Code:
format PE GUI 4.0
entry start

include '%fasminc%\win32a.inc'

section '.text' code readable executable

  start:

        invoke  GetModuleHandle,0
        invoke  DialogBoxParam,eax,IDR_DIALOG,HWND_DESKTOP,DialogProc,0
        invoke  ExitProcess,0

proc DialogProc,hwnddlg,msg,wparam,lparam
        push    ebx esi edi
        cmp     [msg],WM_INITDIALOG
        je      wminitdialog
        cmp     [msg],WM_COMMAND
        je      wmcommand
        cmp     [msg],WM_CLOSE
        je      wmclose
        xor     eax,eax
        jmp     finish
  wminitdialog:
        invoke  SetHook
        jmp     processed
  wmcommand:
        cmp     [wparam],IDCANCEL
        jne     processed
  wmclose:
        invoke  UnhookHook
        invoke  EndDialog,[hwnddlg],0
  processed:
        mov     eax,1
  finish:
        pop     edi esi ebx
        return
endp

section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',\
          user,'USER32.DLL',\
          convert,'CONVERT.DLL'

  import kernel,\
         GetModuleHandle,'GetModuleHandleA',\
         ExitProcess,'ExitProcess'

  import user,\
         DialogBoxParam,'DialogBoxParamA',\
         EndDialog,'EndDialog'

  import convert,\
         SetHook,'SetHook',\
         UnhookHook,'UnhookHook'

section '.rsrc' resource data readable

  IDR_DIALOG = 37

  directory RT_DIALOG,dialogs

  resource dialogs,\
           IDR_DIALOG,LANG_ENGLISH+SUBLANG_DEFAULT,main

  dialog main,'Key converter',70,70,72,32,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME
    dialogitem 'BUTTON','Exit',IDCANCEL,16,8,40,14,WS_VISIBLE+BS_PUSHBUTTON+WS_TABSTOP
  enddialog    

Note that global hook code must reside in a DLL.


Last edited by Tomasz Grysztar on 30 Jul 2004, 18:36; edited 1 time in total
Post 30 Jul 2004, 18:19
View user's profile Send private message Visit poster's website Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
Location: Michigan, USA
windwakr
when I run it then press insert it has an illeagal opperation...hmmm

btw: I have win98 SE
Post 30 Jul 2004, 18:29
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7721
Location: Kraków, Poland
Tomasz Grysztar
Forgot to preserve EBX, sorry...
Now it should work.
Post 30 Jul 2004, 18:36
View user's profile Send private message Visit poster's website Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
Location: Michigan, USA
windwakr
Thanks! It works! Does this work for all windows versions?
Post 30 Jul 2004, 19:14
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7721
Location: Kraków, Poland
Tomasz Grysztar
Yes.
Post 30 Jul 2004, 19:23
View user's profile Send private message Visit poster's website Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
Location: Michigan, USA
windwakr
Thanks again!
Post 30 Jul 2004, 20:56
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4237
Location: 2018
edfed
thanks again and again.
but i'm a little surprised on the way to proceed.
i was wondering if it was a simple way, i see it's not the case.

is there any way to just change the code page or some pointers of this code page like this:

Code:
pagecode:
.a db 'z'
.b db 'y'
.c db 'x'
.etc etc
.x db 'c'
.y db 'b'
.z db 'a'

    

for example.
Post 25 Oct 2008, 09:50
View user's profile Send private message Visit poster's website Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
Location: Michigan, USA
windwakr
wouldn't it have been better to post in your thread and not bring back this 4 year old one?

But while we're here, why doesn't this code to reverse the keys work? It goes where the insert check in the original code was.

Code:
mov eax,[wparam]
cmp eax,'A'
jb no_conversion
cmp eax,'Z'
ja no_conversion
push ebx
sub eax,64
mov ebx,90
sub ebx,eax
    


In theory that should reverse the keys like edfed wanted in his above post....but it doesn't work. If it makes it past the compares then after the sub it should be between 1 and 26. the sub from ebx would then do the reversal.

EDIT: my reversal code is right, but for some reason it's not sending the keypresses or calling the next hook.


heres the complete modified code that doesn't work:
Code:
proc KeyboardProc, ncode,wparam,lparam
        cmp     [ncode],HC_NOREMOVE
        je      no_conversion 


        mov eax,[wparam]
        cmp eax,'A'
        jb no_conversion
        cmp eax,'Z'
        ja no_conversion
        push ebx
        sub eax,65
        mov ebx,90
        sub ebx,eax

        invoke  MapVirtualKey,ebx,0
        bt      [lparam],31 
        jc      key_up 
        invoke  keybd_event,ebx,eax,0,0 
        pop     ebx
        mov     eax,TRUE 
        ret
    key_up: 
        invoke  keybd_event,ebx,eax,KEYEVENTF_KEYUP,0 
        pop     ebx
        mov     eax,TRUE 
        ret
    no_conversion:
        invoke  CallNextHookEx,[hhook],[ncode],[wparam],[lparam] 
        mov     eax,FALSE
        ret
endp            
    


EDIT 2: It works to M if I change 'cmp eax,'Z' to cmp eax,'M'.....WTF?

EDIT 3: This is really starting to frustrate me...anyone got any ideas?

_________________
----> * <---- My star, won HERE
Post 25 Oct 2008, 12:13
View user's profile Send private message Reply with quote
Hrstka



Joined: 05 May 2008
Posts: 18
Location: Czech republic
Hrstka
AFAIK, you can also remap keys by setting a key in the registry, see http://www.microsoft.com/whdc/archive/w2kscan-map.mspx. But it's for Windows 2000 and up only, in Win 95/98/ME will not work.
Post 29 Oct 2008, 19:52
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar.

Powered by rwasa.