I need to write a sort of key-logger function that can be called from C code.
what it means is a c program would call an assembly function called startlog that would indicate to start logging the keys pressed until a function called endlog is called. the logging should work like this: write the ascii value of any key pressed without disturbing the C code between startlog and endlog, meaning that if the C code also needs to read the input (let’s say by scanf, it would work ok).
I managed to write the logger by changing the interrupt vector 9th entry (interrupt for keyboard press) to a function I wrote that writes the values to a file, and it works fine. however the C code does not get the input.
Basically what i did is read the key pressed using int 21h, however after reading the ascii value it is “consumed” so I need a way to either simulate the key press again or read the value without “consuming” it so next time a key is read it reads the same key.
(I described the code in english because it is long and clumsy assembly code)
Here’s how you can do it:
Output (run on Windows XP):
KEYLOG.TXT:
There’re a few problems here. You can’t use some DOS functions when it’s busy. This is why I’m checking the
InDosflag. At the same time InDos can indicate that DOS is busy even when it’s waiting for such simple things as keyboard input (e.g. ingets()).This is why there’s a circular buffer for the scan codes that accumulates them while the program can’t safely call DOS file I/O routines.
EndLog()waits until the buffer is drained. You may need to force draining earlier as well.I’ve also tried hooking int 28h as an alternative to int 1Ch, but my ISR for int 28h got never invoked, not sure why.
I’m avoiding the use of C’s
fopen()andfwrite()/fprintf()for the log file so as not to interfere with the main program that’s unaware of the things happening in the background. Only the most trivial standard C functions are used in the ISRs for the same reason.