51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1031|回复: 8
打印 上一主题 下一主题

纯DOS下如何截获中断

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2008-2-1 22:44:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在纯DOS下,地址0~3FFh的内存区域存放这一张中断向量表,在这张表里每四个字节存放着一个中断过程的段地址和偏移地址,其中段地址存放在四个字节的高字上,偏移地址存放在四个字节的低字上。
那如何根据中断号找到自己在中断向量表里的位置呢?我们只要把中断号乘上4(字节数)后,得到的结果就是该中断在表中的位置。
比如INT 1CH中断是DOS系统每1/18.2秒执行一次的中断过程,它在中断向量表中的位置就是70H,用段+偏移地址的方式写就是0000:0070H,
那这个中断过程的段地址保存在0000:0072H和0000:0073H两个字节中
这个中断过程的偏移地址保存在0000:0070H和0000:0071H两个字节中
我们用DEBUG命令可以看到ICH中断过程在内存中的位置
输入DEBUG后,再输入D 0000:0070 L4
我们可以看到:0000:0070        53 FF 00 F0                                        S...
(在不同的机器上看到的值可能不同)
这是我们就能知道INT 1CH中断过程的地址是F000:FF53
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

  • TA的每日心情
    慵懒
    2020-8-11 08:18
  • 签到天数: 114 天

    连续签到: 1 天

    [LV.6]测试旅长

    2#
    发表于 2008-2-1 23:25:41 | 只看该作者
    额。。。各个版本dos都一样的?还是ms dos都一样的?
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    3#
     楼主| 发表于 2008-2-3 17:28:33 | 只看该作者

    很对不起大家,前两天比较忙,没空写,今天继续

    各种版本的DOS,以及现在的WINDOWS在内存中,从(物理)地址0~3FFh都是存放中断向量表的
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    4#
     楼主| 发表于 2008-2-3 17:41:01 | 只看该作者

    那我们知道INT 1CH中断过程的段地址和偏移地址与我们截获这个中断有什么关系呢?

    在很久之前我以为在DOS下截获一个中断应该运行一个程序,然后靠这个程序去自动截获各种中断发出的中断请求。可是DOS是个单用户单任务的操作系统,又怎么可以在运行一个程序的时候再运行第二个程序?
    后来才知道,其实答案并非我想的那样,是去运行一个程序来截获中断请求,而是把自己写的过程的地址(包括段地址和偏移地址)〖替换〗掉中断向量表中原来中断过程的地址。这样在发出中断请求的时候,DOS操作系统就会在中断向量表中找到你自己写的过程在内存中的地址,从而运行你自己的中断过程。
    当我们希望执行完自己的中断过程后继续执行操作系统原来的中断的时候,这时我们就要知道原来INT 1CH中断过程在内存中的地址了。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    5#
     楼主| 发表于 2008-2-3 17:53:17 | 只看该作者

    为什么要截获中断呢?

    目的很简单,就是为了执行自己写的中断过程。
    可是有些心理阴暗的人拿着自己掌握的专业知识不去做些有意义的事,技术这把双刃剑在他们手上变成了破坏的工具。
    由于DOS对中断向量表没有保护,所以任何一个程序都可以随意地更改这张表,所以病毒就利用了这点(当然光靠截获中断还是不够的,还需要另一项重要的技术——内存驻留)。

    以后大家都可能成为测试的精英和骨干,希望大家要有自己的职业准则和道德标准,不要滥用自己掌握的专业知识。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    6#
     楼主| 发表于 2008-2-3 18:04:45 | 只看该作者

    什么是内存驻留?

    记得以前在玩DOS游戏的时候可能会用到鼠标,所以在运行游戏之前总会运行以下MOUSE这个程序,这样在玩游戏的时候就可以使用鼠标了。
    可是大家都知道DOS是个单任务的操作系统,它又是怎么同时运行两个程序的呢?
    这是因为在DOS中,鼠标的中断号是33H,当我们运行MOUSE程序的时候,我们截获这个中断,使其执行我们自己写的中断过程,然后我们把自己的中断过程驻留在内存中,最后我们的MOUSE程序就能结束运行了。这样,在内存中就有了我们的中断过程,而且可以继续运行我们的游戏了。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    7#
     楼主| 发表于 2008-2-3 18:21:32 | 只看该作者

    为了更直观地让大家对内存驻留和截获中断,编译连接下面的代码就能明白了

    这段代码的作用是在当前光标位置上循环显示ASCII码从0~127的单个字符,频率为1秒中
    为了实现每秒显示一个ASCII字符,所以就要截取1CH中断,1CH中断是每秒产生18.2次中断请求,这个中断发生的频率为18.2HZ,中断的周期约为55ms。

    保存下面的代码,文件的扩展名必须为asm,文件主名为mytsr
    然后使用MASM5.0来汇编和连接这个程序,使用的命令如下
    masm mytsr.asm
    回车后它会提示输入文件名,不用管它,连续3个回车就可以了
    link mytsr.obj
    再两个回车就可以了
    连接完成后会有mytsr.exe文件,运行这个文件就可以了

    运行完后,用mem /c/p可以看见我们驻留在内存里的中断过程,名字就叫mytsr
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    8#
     楼主| 发表于 2008-2-3 18:49:45 | 只看该作者

    代码

    .model        tiny,stdcall
    .stack

    .code
            assume        ds:_text
    ;在标号myint与main之间的就是中断过程
    myint:
            push        ax
            push        bx
            push        cx
            push        dx
            inc        cs:cycle
            cmp        cs:cycle,18        ;18.2cycle=1s
            jb        label_callsysint
            mov        cs:cycle,0
            mov        bh,0h
            mov        al,cs:ascii
            mov        cx,1
            mov        ah,0ah
            int        10h
            inc        cs:ascii
            cmp        cs:ascii,127
            jbe        label_callsysint
            mov        cs:ascii,0

    label_callsysint:
            pop        dx
            pop        cx
            pop        bx
            pop        ax
            jmp        cs:[oldintaddr]
            oldintaddr        dd        ?
            cycle                dw        0
            ascii                db        0
    main:
            ;获取INT 1CH中断过程的地址,bx中存放偏移地址,es中存放段地址
            push        cs
            pop        ds
            mov        ax,351ch
            int        21h
            mov        word ptr oldintaddr,bx
            mov        word ptr oldintaddr+2,es

            ;将自己的中断过程的地址写入中断向量表
            mov        ax,251ch
            mov        dx,offset myint
            int        21h

            ;退出程序,并把中断过程驻留在内存中
            mov        ax,3100h
            mov        dx,offset main
            mov        cl,4
            shr        dx,cl
            inc        dx
            add        dx,10h
            int        21h

    end        main
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    9#
     楼主| 发表于 2008-2-3 18:55:34 | 只看该作者
    原本以为这个程序只能运行在纯DOS下,没想到在XP里也能运行。
    回复 支持 反对

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-24 12:49 , Processed in 0.074300 second(s), 23 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表