Solved

Problem with capturing int 21h

Posted on 1999-01-04
4
205 Views
Last Modified: 2010-04-16
I'd like to change a function of int 21h to my own. So I made up something like:

PROGRAM Foo

VAR
{$F+}
  OldInt21 : Procedure;
{$F-}
  InDOS : ^Byte;
  Regs  : Registers;
  {some more variables}

{$F+}
PROCEDURE NewInt21 (Flags, CS, IP, ... : Word); INTERRUPT;
BEGIN
  Inc (InDOS^);
  {some more code}
  OldInt21;
  {code}
  Dec (InDOS^};
END;
{$F-}

BEGIN
  Regs.AH = $34; {the function to get the InDOS address}
  Intr ($21, Regs);
  InDOS := Ptr (Regs.ES, Regs.BX);
  GetIntVec ($21, @OldInt21);
  SetIntVec ($21, @NewInt21};
  {code}
  Keep (0);
END.

On one PC this results in an endless loop (calling OldInt21
results in calling NewInt21 for some reason), another PC
just hangs. Can someone please tell me what I am doing wrong?

Thanks,
  Jaap.
0
Comment
Question by:jpboender
  • 2
4 Comments
 
LVL 3

Expert Comment

by:vikiing
ID: 1216812
Int 21 is DOS master interrupt, this is, there are TONS of things (by DOS itself and by your application) that are done thru it.

The point here is when you receive an Int 21 call that must be handled by the original code, you must branch execution to original code in order the true DOS-Int 21 works.

Failing to do that may hang the machine, or give you any other bizarre behavior.
0
 

Author Comment

by:jpboender
ID: 1216813
Okay, but isn't that what I'm doing? I mean, I do call the
old interrupt function.
0
 
LVL 3

Expert Comment

by:vikiing
ID: 1216814
Sorry, I didn't see that.

One main problem is that OldInt21 returns with IRET, not with RET

As you're calling OldInt21 as a simple procedure, it's suposed it will come back with a RET instruction, not an IRET.

Thus, when OldInt21 reaches end and does an IRET, control will NOT return to the point where you called from, but it'll make a whole mess.
0
 
LVL 10

Accepted Solution

by:
rbr earned 100 total points
ID: 1216815
The problem is that oldInt21 is defined as a procedure, so the register and the return adress will be stored at the stack. But as vikiing mentioned an interrupt uses IRET which need some different stack info than a normal procedure. In C it's no problem to call a
JMP FAR oldInt21 which will not alter the stack and the old Interrupt will end correctly. You have to to the same maybe with an inline assembler code. But you can't use code after the OldInt21 becuase an Interrupt will not jump back. You have to use a branch for your new function and make a jump far to your old interrupt for your old functions.
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Enabling the Skype for Business Meeting Scheduler in Hybrid OWA
Direct mail marketing is the act of mailing materials straight to prospective customers. This wide form of marketing is one of the oldest methods of communicating with a geographic based demographic. So is it useful in 2017 and beyond?
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

685 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