实模式下的中断处理程序链接

问题描述

我试图钩住BIOS Int 13h,以向其中添加我的自定义功能,并劫持一些现有功能。 旧的Int 13h向量存储在全局变量中。 调用中断处理程序时,DS设置为某个值,该值与调用方的原始数据段不匹配。因此,访问调用者的全局变量变得很头疼。

链接中断处理程序的最佳实践是什么?

挂钩的安装方式如下:

#ifdef __cplusplus
#  define INTARGS ...
#else
#  define INTARGS unsigned bp,unsigned di,unsigned si,\
                  unsigned ds,unsigned es,unsigned dx,\
                  unsigned cx,unsigned bx,unsigned ax
#endif

void interrupt (far *hackInt13h)(INTARGS) = NULL;
void interrupt (far *biosInt13h)(INTARGS) = (void interrupt (far *)(INTARGS))0xDEADBEEF;

void main(void)
{
  struct REGPACK reg;

  biosInt13h = getvect(0x13);
  hackInt13h = int13h;

  setvect(0x13,hackInt13h);

  // Calling CAFE
  reg.r_ax = 0xCAFE;
  intr(0x13,&reg);
  printf("Cafe returned: 0x%04x\n",reg.r_ax);

  // Resetting FDD just to check interrupt handler chaining
  reg.r_ax = 0;
  reg.r_dx = 0;
  intr(0x13,&reg);
  printf("CF=%i\n",reg.r_flags & 0x01);

  setvect(0x13,biosInt13h);
}

Int 13h挂钩代码

    P286
    .MODEL TINY

_Data   SEGMENT PUBLIC 'DATA'
    EXTRN _biosInt13h:FAR
_Data   ENDS


_Text   SEGMENT PUBLIC 'CODE'
    PUBLIC _int13h
_int13h PROC FAR
    pusha
    cmp AX,0CAFEh
    jnz chain
    popa
    mov AX,0BEEFh
    iret
chain:
    popa
    call    far ptr [_biosInt13h]   ; <-- at this moment DS points to outer space
                                    ;     and _biosInt13h is not valid
_int13h ENDP
_Text   ENDS
    END

如果需要的话,我正在使用Borland C ++

解决方法

谢谢大家,我找到了解决方法!

我错过的第一件事是将变量移动到代码段并明确指定它。

第二种方法是使用被黑的(压入堆栈)返回地址,而使用retf而不是call在堆栈上添加真实的返回地址。

无需显式pushf,因为int之后的标记已经在堆栈中。无论在我的处理程序中还是在链接的处理程序中,标志都会在iret上弹出。

    P286
    .MODEL TINY

_Text   SEGMENT PUBLIC 'CODE'
    EXTRN _biosInt13h:FAR ; This should be in CODE 'cause CS is only segreg reliable
    PUBLIC _int13h
_int13h PROC FAR
    pusha
    cmp AX,0CAFEh
    jnz chain
    popa
    mov AX,0BEEFh
    iret
chain:
    popa
    push    word ptr cs:[_biosInt13h + 2]   ; Pushing chained handler SEG on stack
    push    word ptr cs:[_biosInt13h]       ; Pushing chained handler OFFSET on stack
    retf                        ; ...actually this is JMP FAR to address on stack
_int13h ENDP
_Text   ENDS
    END