Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6802057
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T19:10:35+00:00 2026-05-26T19:10:35+00:00

I need to write a sort of key-logger function that can be called from

  • 0

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)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T19:10:36+00:00Added an answer on May 26, 2026 at 7:10 pm

    Here’s how you can do it:

    // Compile with Borland's Turbo C++ 1.01
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <dos.h>
    
    const char ScanToChar[] =
      "??1234567890-=??"
      "QWERTYUIOP[]??AS"
      "DFGHJKL;\"`?\\ZXCV"
      "BNM,./??? ";
    
    void interrupt (*pOldInt9)(void);
    void interrupt (*pOldInt1C)(void);
    char far* pInDosFlag;
    
    #define SCAN_BUF_SIZE 1024
    volatile unsigned char ScanBuf[SCAN_BUF_SIZE];
    volatile unsigned ScanReadIdx = 0;
    volatile unsigned ScanWriteIdx = 0;
    
    volatile unsigned LogFileHandle;
    void DosWriteFile(unsigned handle, void* data, size_t size);
    
    volatile unsigned InDos0cnt = 0;
    
    void TryToSaveLog(void)
    {
      unsigned cnt;
    
      if (*pInDosFlag)
        return;
    
      cnt = (ScanWriteIdx - ScanReadIdx) & (SCAN_BUF_SIZE - 1);
    
      InDos0cnt++;
    
      while (cnt--)
      {
        static const char hex[] = "0123456789ABCDEF";
        char s[80] = "0xXX \"?\"\r\n";
        unsigned char scanCode = ScanBuf[ScanReadIdx];
    
        s[2] = hex[scanCode >> 4];
        s[3] = hex[scanCode & 0xF];
    
        if ((scanCode & 0x7F) < strlen(ScanToChar))
        {
          s[6] = ScanToChar[scanCode & 0x7F];
        }
    
        DosWriteFile(LogFileHandle, s, strlen(s));
    
        ScanReadIdx++;
        ScanReadIdx &= SCAN_BUF_SIZE - 1;
      }
    }
    
    void interrupt NewInt9(void)
    {
      unsigned char scanCode = inp(0x60);
    
      ScanBuf[ScanWriteIdx++] = scanCode;
      ScanWriteIdx &= SCAN_BUF_SIZE - 1;
    
      pOldInt9();
    }
    
    volatile unsigned int1Ccnt = 0;
    
    void interrupt NewInt1C(void)
    {
      int1Ccnt++;
      pOldInt1C();
      TryToSaveLog();
    }
    
    unsigned DosCreateFile(const char* name)
    {
      union REGS regs;
      struct SREGS sregs;
    
      regs.h.ah = 0x3C;
      regs.x.cx = 0;
    
      sregs.ds = FP_SEG(name);
      regs.x.dx = FP_OFF(name);
    
      intdosx(&regs, &regs, &sregs);
    
      return regs.x.cflag ? 0 : regs.x.ax;
    }
    
    void DosWriteFile(unsigned handle, void* data, size_t size)
    {
      union REGS regs;
      struct SREGS sregs;
    
      if (!size) return;
    
      regs.h.ah = 0x40;
      regs.x.bx = handle;
      regs.x.cx = size;
    
      sregs.ds = FP_SEG(data);
      regs.x.dx = FP_OFF(data);
    
      intdosx(&regs, &regs, &sregs);
    }
    
    void DosCloseFile(unsigned handle)
    {
      union REGS regs;
      struct SREGS sregs;
    
      regs.h.ah = 0x3E;
      regs.x.bx = handle;
    
      intdosx(&regs, &regs, &sregs);
    }
    
    void StartLog(const char* FileName)
    {
      union REGS regs;
      struct SREGS sregs;
    
      LogFileHandle = DosCreateFile(FileName);
    
      regs.h.ah = 0x34; // get InDos flag address
      intdosx(&regs, &regs, &sregs);
      pInDosFlag = MK_FP(sregs.es, regs.x.bx);
    
      pOldInt1C = getvect(0x1C);
      setvect(0x1C, &NewInt1C);
    
      pOldInt9 = getvect(9);
      setvect(9, &NewInt9);
    }
    
    void EndLog(void)
    {
      setvect(9, pOldInt9);
    
      while (ScanWriteIdx != ScanReadIdx);
    
      setvect(0x1C, pOldInt1C);
    
      DosCloseFile(LogFileHandle);
      LogFileHandle = 0;
    }
    
    int main(void)
    {
      char str[256];
    
      StartLog("keylog.txt");
    
      printf("please enter some text:\n");
      gets(str);
      printf("you have entered \"%s\"\n", str);
    
      EndLog();
    
      printf("int 1Ch count: %u\n", int1Ccnt);
      printf("InDos=0 count: %u\n", InDos0cnt);
    
      return 0;
    }
    

    Output (run on Windows XP):

    please enter some text:
    qweasdzxc123
    you have entered "qweasdzxc123"
    int 1Ch count: 175
    InDos=0 count: 1
    

    KEYLOG.TXT:

    0x10 "Q"
    0x90 "Q"
    0x11 "W"
    0x91 "W"
    0x12 "E"
    0x92 "E"
    0x1E "A"
    0x9E "A"
    0x1F "S"
    0x9F "S"
    0x20 "D"
    0xA0 "D"
    0x2C "Z"
    0xAC "Z"
    0x2D "X"
    0xAD "X"
    0x2E "C"
    0xAE "C"
    0x02 "1"
    0x82 "1"
    0x03 "2"
    0x83 "2"
    0x04 "3"
    0x84 "3"
    0x1C "?"
    

    There’re a few problems here. You can’t use some DOS functions when it’s busy. This is why I’m checking the InDos flag. 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. in gets()).

    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() and fwrite()/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.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I need to write code that picks up PGP-encrypted files from an FTP location
Like the title says I need to write a function that will sort a
I need to write a Delphi application that pulls entries up from various tables
I need to write a query that will generate a sort of sequenced ID
I'm looking to write a function that mimics the ajax calls from the jQuery
I need to write a sorting program in C and it would be nice
I need to write a simple parser to a sort of Domain Specific Language.
I need write an update statement that used multiple tables to determine which rows
I need to write a program used internally where different users will have different
I need to write a Java Comparator class that compares Strings, however with one

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.