20楼#
发布于:2003-12-24 09:46
下面是HOOK中断的代码:
/* Interrupt to be hooked */ #define HOOKINT 0x09 头文件中的定义 *************************************** /* sidt instruction stores the base and limit of IDTR in this format */ typedef struct idtr { short Limit; unsigned int Base; } Idtr_t, *PIdtr_t; /* Decriptor Entry corresponding to interrupt gate */ typedef struct idtentry { unsigned short OffsetLow; unsigned short Selector; unsigned char Reserved; unsigned char Type:1; unsigned char Always0:1; unsigned char Dpl:3; unsigned char Present:1; unsigned short OffsetHigh; } IdtEntry_t, *PIdtEntry_t; ************************************ /* Get the Base and Limit of IDTR Register */ _asm sidt buffer IdtEntry=(PIdtEntry_t)Idtr->Base; /* Index the interrupt number to be hooked in appropriate IDT entry and save away the Old handler\'s address */ OldHandler=((unsigned int)IdtEntry[HOOKINT].OffsetHigh<<16U)| (IdtEntry[HOOKINT].OffsetLow); /* Plug into the interrupt by changing the offset field to point to NewHandler function */ _asm cli IdtEntry[HOOKINT].OffsetLow=(unsigned short)NewHandler; IdtEntry[HOOKINT].OffsetHigh=(unsigned short)((unsigned int)NewHandler>>16); // IdtEntry[HOOKINT].Dpl=6; // IdtEntry[HOOKINT].Present=0; _asm sti 新的服务程序 ―――――――――――――――――――――――― void NewHandlerCFunc(int ServiceId) { if (ServiceId>NumberOfServices) return; ServiceCounterTable[ServiceId+1]++; return; } ――――――――――――――――――――――――― 另外的文件 ################################### _NewHandler proc near //NewHandler EIP 为FO9E2280 Ring0Prolog STI push eax call _NewHandlerCFunc@4 CLI Ring0Epilog jmp dword ptr cs:[_OldHandler] _NewHandler endp END ################################### SOFTICE中IDT命令: 运行前 0009 INTG32 0008:80466A6C DPL=0 P NTOSKRNL!KEI386EOIHELPORT+16B6 运行后 0009 INTG32 0008:FO9E2280 DPL=0 P HOOKINT!TEXT 但没有进入中断? |
|
21楼#
发布于:2003-12-24 09:53
*********************** 改就改完,把中断服务所在段的权限全部弄成3,先看看能工作不,虽然这样做有点儿不安全。 *********************** 我改了段的权限,但运行SOFTICE提示 Break due unhandledexception NTSTATAUS=STATUS_ACCESS_VIOLATION 只有重起。 |
|
22楼#
发布于:2003-12-24 11:32
一点儿一点来,首先,INTG定义有问题,应该为:
/* Decriptor Entry corresponding to interrupt gate */ typedef struct idtentry { unsigned short OffsetLow; unsigned short Selector; //unsigned char Reserved; unsigned char ParamCount:5; <<<-----INTG里没用,但定义一下比较正规(符合CALL GATE) unsigned char Reserved:3; //unsigned char Type:1; <<<------错 unsigned char Type:4; unsigned char Always0:1; //unsigned char Dpl:3; <<<-----错 unsigned char Dpl:2; unsigned char Present:1; unsigned short OffsetHigh; } IdtEntry_t, *PIdtEntry_t; 如果按以前你的定义,你设置DPL实际上把Type给改了,那哪能不出错? 而且DPL不用改,因为按照Intel的定义,硬件中断忽略INTG的DPL检查. [编辑 - 12/24/03 by cool-net] [编辑 - 12/24/03 by cool-net] [编辑 - 12/24/03 by cool-net] |
|
|
23楼#
发布于:2003-12-24 14:59
太感谢啦!! 天那!可以进入中断啦!! :D :) :D :) 但是,我不知到IRQ0在2000的IDT中对应的是多少??? (我一直以为是0008,但是中断服务程序不执行,我用SOFTICE的BPINT 8,没进入SOFTICE(如果是时钟中断每秒产生18.2次中断,那该进入SOFTICE)。但我用GENINT 8产生一个中断,可以进入我的中断程序(上面的程序HOOKINT改为0X08))。 2000下的INT=IRQ+30,那是不是0038??? 我用SOFTICE的BPINT 38,但没有进入SOFTICE,我用SOFTICE的BPINT 39,进入了SOFTICE,但39是时钟中断还是键盘中断??? 软盘的IRQ=6,我用BPINT 36,点软驱可以响应中断,那???? |
|
24楼#
发布于:2003-12-24 15:47
************************** 2000下的INT=IRQ+30,那是不是0038??? 我用SOFTICE的BPINT 38,但没有进入SOFTICE,我用SOFTICE的BPINT 39,进入了SOFTICE,但39是时钟中断还是键盘中断??? ************************** 不好意思!!又写错啦! 2000下的INT=IRQ+30,那是不是0030??? 我用SOFTICE的BPINT 30,进入了SOFTICE,30是时钟中断??? 我用SOFTICE的BPINT 31,进入了SOFTICE,31是键盘中断??? 我把HOOKINT设为30,在中断中设置断点,可以进入中断,单步但在 void NewHandlerCFunc(int ServiceId) { if (ServiceId>NumberOfServices) return; ServiceCounterTable[ServiceId+1]++; return; ――――――//****此处重起*** } 为什么??? 如果不设置断点,驱动程序一运行就跳到SOFTICE,显示 Break due to page fault(0Eh)fault=0002 又是为何??? |
|
25楼#
发布于:2003-12-24 16:41
首先,我已经说过,由于外部中断在IDT中的位置是可以软件设置的,所以象时钟或键盘之类的可能已经被移到别的地方了(初始化时是8和9没错,但由于8和9同被CPU当成别的trap用,所以我想OS一定把时钟和键盘给移到别的地方了),具体在什么地方我也不是很清楚(你可以先按照自己的想法试试).
至于出错,我还没有肯定,只是猜测: 你得看看NewHandlerCFunc生成的汇编码,注意最后的ret,是不是以__stdcall的方式返回的(反汇编之后应该是 retn 4),如果不是,你需要把NewHandlerCFunc显式声明成__stdcall(按理说DDK默认调用方式是__sdtcall,但我还是想确认一下)或者加一句: _NewHandler proc near //NewHandler EIP 为FO9E2280 Ring0Prolog STI push eax call _NewHandlerCFunc@4 pop eax <<<---------这句 CLI Ring0Epilog jmp dword ptr cs:[_OldHandler] _NewHandler endp END 如果我的猜测正确,那问题就算解决了,否则就再找找看. |
|
|
26楼#
发布于:2003-12-25 11:44
出错是因为中断服务程序,我把它删了,可能是内存泄露。 我发现时钟中断是30,键盘31。 INT=IRQ+30:2000下 INT=IRQ+50:98下 我发现在中断服务程序中用OUT操作0X378不行,数据口电平没变。 用WRITE_PORT_UCHAR宏可以,但是一条指令用了800NS,我用示波器测。 可不可以,直接在驱动程序中用OUT/IN汇编访问并口? 我想把8253的中断频率提高到100K,每次中断进入我的处理程序,55MS后调用系统老的时钟中断程序,可不可行? :D :D |
|
27楼#
发布于:2003-12-25 12:14
>> 我发现在中断服务程序中用OUT操作0X378不行
>> 用WRITE_PORT_UCHAR宏可以 检查一下你的代码,WRITE_PORT_UCHAR没什么特别的: mov EDX, 0378h mov AL, value out DX, AL >> 我想把8253的中断频率提高到100K,每次中断进入我的处理程 >> 序,55MS后调用系统老的时钟中断程序,可不可行? 最好不要这样干,会影响系统的运行. 我到现在还没搞明白你为什么要截时钟中断,用Kernel定时器不行吗? |
|
|
论坛版主
![]() |
28楼#
发布于:2003-12-25 16:35
没问题啊,我觉得只要保持系统原来的计数器不混乱就可以了,你的中断服务可以保证这点的。
对了,兄弟,我想说一句,我突然想到你们说的中断服务号被WIN重新分配,这个确定不?因为我觉得软中断和硬中断可以共享一个中断号的,做法和硬件共享中断号一样,只要这个中断服务里面可以判断得出来这是什么就可以了,比如硬件来的中断可以通过检查状态寄存器判断出来,如果状态寄存器显示无中断打过来,那么再通过AX等的值当成软中断(自陷)处理,这样也是可以的嘛。你们怎么认为 |
|
29楼#
发布于:2003-12-25 16:44
>> 没问题啊,我觉得只要保持系统原来的计数器不混乱就可以了,
>> 你的中断服务可以保证这点的。 关键是时间,你要是在里面不及时STI,操作系统所使用的那个高精度时钟可就废了(那个可不象每秒18.2次这么慢). >> 我突然想到你们说的中断服务号被WIN重新分配,这个确定不 确定. >> 我觉得软中断和硬中断可以共享一个中断号 没有总是,就象你可以在程序里直接 INT 08h 一样的道理. |
|
|
论坛版主
![]() |
30楼#
发布于:2003-12-25 17:09
高精度时钟恐怕不是用中断计数的吧,奔腾以后的内部TIMER有几个?谁有资料
COOL_NET兄弟,你说的用INT 8什么的啥子意思?:)没懂 |
|
31楼#
发布于:2003-12-25 18:56
>> 高精度时钟恐怕不是用中断计数的吧
肯定是中断 >> 奔腾以后的内部TIMER有几个 我记得386里就已经有至少两个不同的时钟了吧?一个18次的和一个um级的。 >> 谁有资料 手边没有,网上肯定有 >> COOL_NET兄弟,你说的用INT 8什么的啥子意思?:)没懂 就是可以在代码里直接触硬中断(在ASM里写一行 int 08h或写机器码 CD 08):):):) |
|
|
32楼#
发布于:2003-12-25 19:07
好好。。。做好了之后那为老兄能否贴一下源码?
|
|
论坛版主
![]() |
33楼#
发布于:2003-12-25 19:40
>> 高精度时钟恐怕不是用中断计数的吧 兄弟,那么肯定啊,片子里面的时钟自己计数的很多啊,这种高精度时钟用中断让CPU计数想想不太可能吧,0.1US一个时钟中断?不太好吧,当然,这个东西和OS于HARDWARE PALTFORM的整合有关 |
|
34楼#
发布于:2003-12-25 22:35
呵呵,这得看操作系统如果处理了。
0.1us一个中断也没什么不可以的,也许系统仅仅给某个ULONGLONG加个1而已,加到一定的时候(比如计数器%10000000==0)再执行别的操作(比如派个APC之类的),同数计数器还往上加... ...:):):) |
|
|
35楼#
发布于:2003-12-26 10:55
************************ 我到现在还没搞明白你为什么要截时钟中断,用Kernel定时器不行吗? *********************** 我要在中断服务程序里,把端口置高后又置底,输出脉冲,脉冲频率要均匀,平稳,可调。Kernel定时器能达到10US,或者更高,而且不受干扰?如果行的话,可以试试!! 我真是太笨啦,把汇编写错啦,还以为不能用OUT,不好意思。只怪当初学习不用功。 |
|
36楼#
发布于:2003-12-26 11:03
我把8253定时初值改到20(原来1700),大概是40K左右。输出脉冲也有40K,但是有杂波,为什么? 我把W2K自带并口驱动程序卸载了,就输不出波形。难道OUT还要用并口驱动程序才能工作? |
|
37楼#
发布于:2003-12-26 11:13
*************************** 0.1us一个中断也没什么不可以的,也许系统仅仅给某个ULONGLONG加个1而已,加到一定的时候(比如计数器%10000000==0)再执行别的操作(比如派个APC之类的),同数计数器还往上加... ... *************************** 如何设置一个计数器,不受8253干扰,能保证55MS调到老的中断程序? 8253的中断好象只处理系统时种和一些简单的定时吧?? |
|
38楼#
发布于:2003-12-26 11:20
哥们儿,你的这些问题对我而言太难了,在硬件控制方面我肯定没你在行.:):):):)
你先试试把,我得先研究研究资料才能知道怎么回事.:(:(:( |
|
|
39楼#
发布于:2003-12-26 11:24
杂波问题应该是有别的什么干扰源存在(也许就是并口驱动,PnP可能要时不时检查一下并口上有没有连上什么新打印机之类的). 如果你卸掉并口驱动,那么你得自己得并口控制器的初始化工作(具体要做哪些我也不太清楚),否则并口能不能用就很难说. |
|
|