Solved

PC key fake

Posted on 1997-09-16
8
811 Views
Last Modified: 2008-02-26
How can I fake keystrokes in PC under MSDOS using interrupt 9 ?

Background:
I had to write a TSR to fake the keyboard.
I did it by stuffing data into the Bios Keyboard Buffer, which works fine.
However, this approach is not good enough for programs that handle interrupt 9 themselves. So, the next thing I tried was using OUTP to port 0x60 with the appropriate data, then use INT 9. However, the data that is read from that port (with INP) by program reacting to interrupt 9 is always 0xFE, regardsless of the data which was written with OUTP.

Regards,
Yadin

0
Comment
Question by:yadinf
8 Comments
 

Expert Comment

by:joesurf
ID: 1015373
Yadin, here's what you need to do:

Write another interrupt handler that can remap INT 9 to your INT9 handler *AFTER*, the INT9 has been remapped by any other software.

You can do this by saving the status/location of the INT9 handler before it gets modified, then monitor it either via Int21 or Int8(I think Int8 is the timer interrupt, it's been a while..).. I'd recommend monitoring it with Int21 function 2509.. (set int handler for int9)... so when the handle change is detected, you set a flag in your program that says "int9 has been changed", thats when YOU map INT9 to your program...

Note: you cannot use Int21 within a TSR, but you can use a call to it.. I'm not sure whether you're aware of this, but it is crucial when dealing with changing interrupts etc within a TSR.

Another alternative is to find a product that already exists that does what you want.

What is the exact purpose of the program (if its not confidential!) ?
0
 

Author Comment

by:yadinf
ID: 1015374
Either I didn't understand the answer, or, more likely, it's not quite a reply to the question asked. May be the reply meant to expalin how to INTERCEPT keystrokes, using INT 9 handler, which is not what I need. By the way, I wrote such a handler..

I need a way to write a TSR to FAKE KEYSTOROKES, using INT 9.

The purpose: To enable a checks reader to be integrated with any Dos application, that nomally expects the check's details typed from the keyboard

Some clarifications I need:
The interrupts mentioned, are they in Hex or in Decimal ?

Also, what is "Int21 function 2509" ?

0
 
LVL 9

Expert Comment

by:cymbolic
ID: 1015375
yadinf:  Heres a muchly annotated example of a keyboard stuffer written in basic.  Maybe it will help you.
'********* PDQKEY.BAS - keyboard macro substitution program

'Copyright (c) 1990 Crescent Software
'Written by Ethan Winer and Nash Bly


'WARNING: This program does NOT work in the QuickBASIC editing environment,
'and it should be uninstalled before entering QB.  Please understand that few
'TSR programs cooperate fully with QB, and this is not a failing of P.D.Q.
'
'PDQKEY is a TSR program that lets you define keyboard macros that are typed
'automatically when you press a single "hot-key".  It also expands the PC's
'15-character keyboard buffer to nearly any size.  PDQKEY examines each key
'stroke that is entered, and if it is one of those that have been defined,
'substitutes a replacement character or string of characters.  Any number of
'macros may be defined, and each may be as long as BASIC's string memory can
'accommodate.  As each recognized hot-key is detected, a "master" macro is
'concatenated with the new contents.  This allows multiple macros to be typed
'in succession, even if earlier ones have not yet been processed by the
'underlying application.  Both the macros you define and non-macro keys are
'stuffed into the keyboard buffer by PDQKEY.
'
'The macros defined below are simple examples which you can replace with your
'own.  This version of PDQKEY uses about 6.5K of memory, compared to 59K
'taken by Borland's SuperKey.  PDQKEY is of course much less capable than
'SuperKey, but it performs all that is usually needed.
'
'It is important to point out that the method used here may not cooperate
'with other TSR keyboard handlers.  For example, PDQKEY does not work with
'the QuickBASIC editor, because it installs its own replacement keyboard
'handler.  However, I have not encountered any problems using PDQKEY with any
'other programs.
'
'Also see the MACRO.BAS program which is newer, and is more direct if you
'only need to handle keyboard macros.
'
'To take as little memory from DOS as possible, compile and link as follows:
'
'   BC PDQKEY /o;
'   LINK /NOD /NOE PDQKEY STR02048 _NOVAL _NOREAD , , NUL, PDQ



'***************************************************************************
'*******************  PDQKEY.BAS - Keyboard Macro TSR  *********************
'***************************************************************************


'-- Recommended statements for any P.D.Q. program.

DEFINT A-Z                              'declare integer variables

'$INCLUDE: 'PDQDECL.BAS'                'declarations and type definitions

'-- Define variables and constants

DEF SEG = 0                             'for peeking keyboard info
CONST NumMacros = 10                    'the number of macros we're handling
DIM Registers9 AS RegType               'RegType for interrupt 9 processing
DIM Registers8 AS RegType               'RegType for interrupt 8 prcessing
DIM Macro$(0 TO NumMacros)              'dimension array of macro strings
Zero$ = CHR$(0)                         'this saves a few bytes later by
                                        '  avoiding calls to CHR$ repeatedly
                                        '  (CHR$ is a called routine)
'-- Start Execution

    Id$ = "PDQKEY 1.00 Copyright (c) 1990 Crescent Software"
    PRINT Id$

'-- Install, UnInstall, and Help

    Segment = TSRInstalled(Id$)

    Switch$ = UCASE$(COMMAND$)
    IF Switch$ = "" THEN
        IF Segment <> 0 THEN
            PRINT "PDQKEY is Already Installed"
            PRINT "Use PDQKEY /U to Uninstall"
            END
        END IF
    ELSEIF Switch$ = "/U" THEN
        IF Segment = 0 THEN
            PRINT "PDQKEY Is Not Resident and Cannot be Uninstalled"
            END
        ELSE
            Success = UnHookInt(Registers9, Segment)
            GOSUB Check
            Success = UnHookInt(Registers8, Segment)
            GOSUB Check
            Success = DeInstallTSR(Segment, Id$)
            GOSUB Check
            PRINT "PDQKEY is Removed from Memory"
            END
        END IF
    ELSE
        PRINT "PDQKEY Usage:   Install   - PDQKEY"
        PRINT "                UnInstall - PDQKEY /U"
        END
    END IF

    PRINT "PDQKey is Resident in Memory"

'-- Define Macros.  The CHR$(13) below shows how to also type an Enter.  To
'   define an extended key, use a CHR$(0) plus the extended key's code.  For
'   example, to stuff the F1 key use CHR$(0) + CHR$(59).  The second example
'   below enters an up arrow after the string.

    Macro$(1) = "REM  -  F1 Key Hit  -  F1 Key Hit" + CHR$(13)
    Macro$(2) = "REM  -  F2 Key Hit  -  F2 Key Hit" + CHR$(0) + CHR$(72)
    Macro$(3) = "REM  -  F3 Key Hit  -  F3 Key Hit  -  F3 Key Hit"
    Macro$(4) = "REM  -  F4 Key Hit  -  F4 Key Hit  -  F4 Key Hit"
    Macro$(5) = "REM  -  F5 Key Hit  -  F5 Key Hit  -  F5 Key Hit"
    Macro$(6) = "REM  -  F6 Key Hit  -  F6 Key Hit  -  F6 Key Hit"
    Macro$(7) = "REM  -  F7 Key Hit  -  F7 Key Hit  -  F7 Key Hit"
    Macro$(8) = "REM  -  F8 Key Hit  -  F8 Key Hit  -  F8 Key Hit"
    Macro$(9) = "REM  -  F9 Key Hit  -  F9 Key Hit  -  F9 Key Hit"
    Macro$(10) = "REM  - F10 Key Hit  -  F10 Key Hit  -  F10 Key Hit"


'-- Set up keyboard Interrupt 9, jump to set up Int 8.

    Registers9.IntNum = 9                   'specify keyboard interrupt 9
    PointIntHere Registers9                 'setup interrupt entry point
    GOTO Install8                           'skip to interrupt 8 setup
10                                     'this line number is needed for VB/DOS


'-- This block of code receives control each time a key is pressed.

    IntEntry1                               'mandatory first two steps for
    IntEntry2 Registers9, Zero              '  any P.D.Q. interrupt routine

    ScanCode = INP(&H60)                    'first get the key press manually
    ShiftMask = PEEK(&H417) AND &HF         'then get the shift status

    SELECT CASE ScanCode + 256 * ShiftMask  'this is the key that was pressed
    'see the P.D.Q. manual "hot key" section for an explanation of hot keys

    CASE &H3B
        ThisKey = 1                         'F1
    CASE &H3C
        ThisKey = 2                         'F2 Key
    CASE &H3D
        ThisKey = 3                         'F3 Key
    CASE &H3E
        ThisKey = 4                         'F4 Key
    CASE &H3F
        ThisKey = 5                         'F5 Key
    CASE &H40
        ThisKey = 6                         'F6 Key
    CASE &H41
        ThisKey = 7                         'F7 Key
    CASE &H42
        ThisKey = 8                         'F8 Key
    CASE &H43
        ThisKey = 9                         'F9 Key
    CASE &H44
        ThisKey = 10                        'F10 Key

    CASE ELSE

'-- The key pressed was not one we are recognizing, so call the original
'   interrupt handler to translate the scan code to an ASCII or extended
'   value.  This would place characters into the keyboard buffer and disturb
'   characters which may already be there.  For this reason, we reserve
'   keyboard buffer addresses &H3A - &H3D for interpreting key presses.
'   The buffer head and tail are saved, moved and restored for this purpose.

        ThisKey = 0
        OldHead = PDQPeek2%(&H41A)          'save keyboard buffer head
        OldTail = PDQPeek2%(&H41C)          'save keyboard buffer tail
        PDQPoke2 &H41A, &H3A                'move head to reserved area
        PDQPoke2 &H41C, &H3A                'move tail also
        CallOldInt Registers9               'call the BIOS to interpret press
                                            'if no characters end up in the
                                            'buffer (Shift, Alt, etc.) then
                                            'simply ignore
       
        IF PDQPeek2%(&H41A) = PDQPeek2%(&H41C) THEN GOTO Ignore

'-- Get ASCII code from the buffer and convert to a string.
       
        ThisChar = PDQPeek2%(&H400 + PDQPeek2%(&H41A))

        SELECT CASE ThisChar AND 255        'check the low byte
           CASE 0, 224, 240                 'treat these as extended
                Macro$(0) = Zero$ + CHR$(ThisChar \ 256)    'alt. cursor keys
           CASE ELSE                        'it's a normal key
                Macro$(0) = CHR$(ThisChar)
        END SELECT

    END SELECT

'-- This code adds the macro or other key to the master keypress queue.

    Queue$ = Queue$ + Macro$(ThisKey)       'add the macro to master queue
    QueueEmpty = 0                          'set macro pending flag

Ignore:

    IF ThisKey = 0 THEN                     'if not a macro key then
        PDQPoke2 &H41A, OldHead             'reset keyboard buffer head
        PDQPoke2 &H41C, OldTail             'reset keyboard buffer tail
    ELSE
        ResetKeyboard                       'we're handling this ourselves
    END IF
    ReturnFromInt Registers9                'return to the underlying program


'-- Set up the intercept for timer Interrupt 8.

Install8:

    Registers8.IntNum = 8                   'specify Interrupt 8
    PointIntHere Registers8                 'setup interrupt entry point
    GOTO EndIt                              'jump to finish installation
20                                     'this line number is needed for VB/DOS


'-- This block of code receives control each time a timer tick occurs.
   
    IntEntry1                               'required first two steps for any
    IntEntry2 Registers8, Zero              'P.D.Q. interrupt service routine

'-- See if we need to do anything, get out as quickly as possible if not.
'   We'll stuff the keystrokes one by one, but only when the keyboard buffer
'   is empty.

    IF QueueEmpty GOTO Done8                'no macro is pending, bye bye

    IF PDQPeek2%(&H41A) = PDQPeek2%(&H41C) THEN 'if the keyboard buffer empty
        PDQPoke2 &H41A, &H1E                'set buffer head to start address
        PDQPoke2 &H41C, &H1E                'set the buffer tail there too
        IF LEN(Queue$) < 14 THEN            'if 13 or less keys in queue then
            stuff$ = Queue$                 'stuff entire queue
            Queue$ = ""                     'clear the queue
            QueueEmpty = -1                 'set queue empty flag
        ELSE                                'if more than 13 chars in queue
            IF MID$(Queue$, 13, 1) <> Zero$ THEN 'if last char isn't CHR$(0)
                stuff$ = LEFT$(Queue$, 13)       'stuff only 12 characters
                Queue$ = MID$(Queue$, 14)        'and update the queue
            ELSE
                stuff$ = LEFT$(stuff$, 12)       'stuff 13 characters
                Queue$ = MID$(Queue$, 13)        'update the queue
            END IF
        END IF
        StuffBuf stuff$                     'stuff the keyboard buffer
    END IF

Done8:

    GotoOldInt Registers8                   'return to underlying program

EndIt:

    EndTSR Id$                              'exit while staying resident



'****************************  Subroutine  ******************************

Check:
                                            'check the uninstall success
    IF NOT Success THEN
        PRINT "Error Uninstalling - Please Reboot"
        END
    END IF

    RETURN


0
 

Author Comment

by:yadinf
ID: 1015376
Cymbolic,

thanks a lot for your program. it seems like a good one.
However, it I might have a few problems using it:

1) May be be I am wrong, but it seems that the key fake data is stuffed to the bios keyboard buffer and it doesn't generate INT 9 for each byte. I need to to use interrupt 9,
to fake a real key stroke.

2) My program is written in C, so I wonder, how I can integrate your routines, with mine.

3) I have never used BC. How can I obtain it?

Waiting for your comments.

Reagrds,
Yadinf



0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 

Author Comment

by:yadinf
ID: 1015377
Cymbolic,
Thanks for your info, however it doesn't help me with my problem, so I have to reject it.

yadinf
0
 
LVL 1

Accepted Solution

by:
qed070297 earned 100 total points
ID: 1015378
If I understand your problem correctly, you need:

(1) Trigger int 09 by something other than a bonafide keystroke.

Easy.  (int 09h)

(2) Force port 0x60 to simulate another keystroke.

This is only possible if you write a protected mode ISR which
traps IO read/write accesses.  (Simply 'out'ing to a port
doesn't mean that 'in'ing it will return the value you put
there.)  386's and above, however, can actually trap IO
accesses, and you can simulate its response to queries.  
Clearly this will not work under Win 95, Win NT, or OS/2, which
obviously already do this to redirect keystrokes only to focus
windows.  However it should work under DOS or protected mode
DOS without a problem.

Unfortunately, I don't know the details, however if you look in
the Pentium architectural manuals available from Intel, I think
they cover what you need to know.
0
 

Author Comment

by:yadinf
ID: 1015379
Qed,

Sorry for not responding, so far. I couldn't check your tip, to use protected mode .exe. I use Microsoft C 6.0 for Dos. However, I don't have the install disks (I only have QC25 disks). It seems that I need SLIBCEP.LIB file. Do you have that file ? If so could you send me ?
0
 
LVL 1

Expert Comment

by:qed070297
ID: 1015380
I don't use Microsoft C 6.0.  But since you are, you are clearly
operating in real mode or v86 mode.  As I said before, in v86
mode you are dead (Windows, OS/2) but in real mode what you need
to do is pop into protected mode yourself, and set up an IO trap
on the keyboard port (0x60) and return execution to v86 mode.
(You become the DOS extender.)  Of course you have to set up
some backdoor comunication to activate your TSR as usual.

For this to work you need your other program to be running in
v86 mode.  This can be a problem for "DOS extended appliations."
If they don't find a DPMI server they will assume none is present
and try to load their own and may simply override your IO trap.

In a sense this would probably be easiest if you were starting
from inside of another framework such as EMM386 or a DPMI server.
I don't know all the details, but in theory, if the DPMI server
will let you, the easiest way is to simply run a DPMI server,
then patch your TSR on top of it.

As I tried to indicate, this is not easy.  What you are trying
to do is quite complicated.  You have to basically control the
keyboard at a level equivalent to what protected mode OS's like
Windows and OS/2 do.  For me this would be at the level of
"research project".  I don't know all the details, but I know
roughly where to look.
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

We recently endured a series of broadcast storms that caused our ISP to shut us down for brief periods of time. After going through a multitude of tests, we determined that the issue was related to Intel NIC drivers on some new HP desktop computers …
This paper addresses the security of Sennheiser DECT Contact Center and Office (CC&O) headsets. It describes the DECT security chain comprised of “Pairing”, “Per Call Authentication” and “Encryption”, which are all part of the standard DECT protocol.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now