Solved

Problem with capturing int 21h

Posted on 1999-01-04
4
195 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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

In this article, you will read about the trends across the human resources departments for the upcoming year. Some of them include improving employee experience, adopting new technologies, using HR software to its full extent, and integrating artifi…
A procedure for exporting installed hotfix details of remote computers using powershell
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

708 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

20 Experts available now in Live!

Get 1:1 Help Now