问题描述
我试图钩住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,®);
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,®);
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