⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 786.html

📁 里面收集的是发表在www.xfocus.org上的文章
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>The NT Insider:Stop Interrupting Me -- Of PICs and APICs </title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="Keywords" content="安全焦点, xfocus, 陷阱网络, honeynet, honeypot, 调查取证, forensic, 入侵检测, intrusion detection, 无线安全, wireless security, 安全论坛, security forums, 安全工具, security tools, 攻击程序, exploits, 安全公告, security advisories, 安全漏洞, security vulnerabilities, 安全教程, security tutorials, 安全培训, security training, 安全帮助, security help, 安全标准, security standards, 安全代码, security code, 安全资源, security resources, 安全编程, security programming, 加密, cryptography," />
<link rel="stylesheet" href="../../css/plone.css" type="text/css">
</head>

<body bgcolor="#FFFFFF" text="#000000">
<div class="top">
  <div class="searchBox">
    <form name="searchform" action="http://www.google.com/search" method="get">
      <input type="hidden" name="domains" value="www.xfocus.net">
      <input type="hidden" name="sitesearch" value="www.xfocus.net">
      <input type="text" name="q" size="20">
      <input type="submit" name="btnG" value="Google Search">
    </form>
  </div>
  <img src="../../images/logo.gif" border="0" width="180" height="80" alt="xfocus logo">
  <img src="../../images/title.gif" border="0" width="230" height="20" alt="xfocus title">
</div>
<div class="tabs">
  <a href="../../index.html" class="plain">首页</a>
  <a href="../../releases/index.html" class="plain">焦点原创</a>
  <a href="../../articles/index.html" class="selected">安全文摘</a>
  <a href="../../tools/index.html" class="plain">安全工具</a>
  <a href="../../vuls/index.html" class="plain">安全漏洞</a>
  <a href="../../projects/index.html" class="plain">焦点项目</a>
  <a href="https://www.xfocus.net/bbs/index.php?lang=cn" class="plain">焦点论坛</a>
  <a href="../../about/index.html" class="plain">关于我们</a>
</div>
<div class="personalBar">
  <a href='https://www.xfocus.net/php/add_article.php'>添加文章</a> <a href='http://www.xfocus.org/'>English Version</a>
</div>
<table class="columns">
  <tr>
    <td class="left">
<div class="box">
  <h5>&nbsp;文章分类&nbsp;</h5>
  <div class="body">
    <div class="content odd">
       <div style="white-space: nowrap;">
	    <img src='../../images/folder_icon.gif' border='0'> <a href='../../articles/4.html'>专题文章</a><br><img src='../../images/folder_icon.gif' border='0'> <a href='../../articles/2.html'>漏洞分析</a><br><img src='../../images/folder_icon.gif' border='0'> <a href='../../articles/3.html'>安全配置</a><br><img src='../../images/folder_icon.gif' border='0'> <a href='../../articles/1.html'>黑客教学</a><br><img src='../../images/folder_icon.gif' border='0'> <a href='../../articles/5.html'><b>编程技术 <<</b></a><br><img src='../../images/folder_icon.gif' border='0'> <a href='../../articles/7.html'>工具介绍</a><br><img src='../../images/folder_icon.gif' border='0'> <a href='../../articles/6.html'>火墙技术</a><br><img src='../../images/folder_icon.gif' border='0'> <a href='../../articles/8.html'>入侵检测</a><br><img src='../../images/folder_icon.gif' border='0'> <a href='../../articles/9.html'>破解专题</a><br><img src='../../images/folder_icon.gif' border='0'> <a href='../../articles/11.html'>焦点公告</a><br><img src='../../images/folder_icon.gif' border='0'> <a href='../../articles/12.html'>焦点峰会</a><br>
       </div>
	    
    </div>
  </div>
</div>

<div class="box">
  <h5>&nbsp;文章推荐&nbsp;</h5>
  <div class="body">
    <div class="content odd">
	    <img src='../../images/document_icon.gif' border='0'> <a href='../../articles/200408/733.html'>补丁管理最佳安全实践之资产评估</a><br><img src='../../images/document_icon.gif' border='0'> <a href='../../articles/200404/689.html'>国内网络安全风险评估市场与技术操作</a><br><img src='../../images/document_icon.gif' border='0'> <a href='../../articles/200410/743.html'>协作的信息系统风险评估</a><br>
    </div>
  </div>
</div>
	</td>
    <td class="main">
	  <h1>The NT Insider:Stop Interrupting Me -- Of PICs and APICs</h1><br>创建时间:2005-03-16<br>文章属性:翻译<br>文章提交:<a href='https://www.xfocus.net/bbs/index.php?lang=cn&act=Profile&do=03&MID=7499'>tombkeeper</a> (t0mbkeeper_at_hotmail.com)<br><br>The NT Insider:Stop Interrupting Me -- Of PICs and APICs <br />
<br />
董岩 译<br />
greatdong_2001@163.com <br />
<br />
尽管 Windows 的设计是使其能够运行在多种平台上,而实际上我们大多数都用的是32位的 x86 系统。正如我们在最近一期 The NT Insider (“Don&#39;t Call Us – Calling Conventions for the x86”, V10N1)所见到的,在尝试分析 crash dump 时,对 x86 构建调用帧的透彻理解所带来的益处是无与伦比的——特别是在没有符号的时候。在编写驱动程序时,程序员就成了操作系统的一部分,深刻理解操作系统所运行的平台有助于开发和调试。<br />
<br />
记住,永远要使用 HAL 来编写平台相关的代码。但这并不意味着就可以对所运行的平台体系一无所知。我们编写了一系列的文章来探索平台的一些内幕,这些内幕都是我们所感兴趣的也是我们认为每一个驱动程序开发人员都应该知道的。下面这篇文章就是这个系列文章中的第一篇。我们假设读者了解设备的基本知识,还知道一些 Windows 驱动程序的东西:中断服务程序、IRQLs 和其它相关的东西。<br />
<br />
<br />
The Interrupt<br />
<br />
要是没有输入输出,CPU 可就没什么事好做了(duh! 没有输入输出的计算机也肯定没什么意思)。当设备状态发生变化时,要么是因为它要传送数据,要么是因为一些其它的外部情况需要人注意,设备设置设备相关的寄存器的某个设备相关的位。为了检测到设备状态的变化,驱动程序要反复测试此位。但是这样效率太低了。另外一种解决办法就是当设备状态变化时它可以产生一个中断将变化异步地通知给系统。通过使用中断,在我们不使用设备时可以忽略设备的存在,因此不用浪费时钟周期进行查询并提高了系统整体的性能。<br />
<br />
因为中断是设备和设备驱动开发的不可分割的一部分,所以我们将探索中断的内部运行。同时,我们还希望解释清楚从设备产生中断到设备驱动得到通知这之间的过程。我们的解释是站在驱动开发者的角度的,这也就意味着我们不会无限度地追究硬件的细节。因此,如果读者是搞硬件的,熟悉中断控制器的连接,请不要抱怨我们没有讲到 8259 与 8259A-2 之间的区别、何时及如何对 OCW4 编程或是 CPU 第二次将 INTA 置为有效时作了哪些数据交换。可不是我们不知道哦(当然也不绝对),只是从本文的出发点来看,我们不用管这些东西。<br />
<br />
<br />
Interrupt Descriptor Table<br />
<br />
要理解中断,先理解“中断描述符表(IDT)”可是很重要的。简单讲,IDT 就是一个函数指针的数组。每个数组成员中的函数要么指向一个中断处理程序(在驱动开发里叫 Interrupt Service Routine)要么指向一个异常处理程序。这里我们只关心中断,异常就忽略了。IDT 的索引就是“中断向量”,中断向量是一个 UCHAR 值。注意中断和异常处理程序的数目限制在256个。每个 CPU 都有自己的 IDT,可以通过 WinDBG 的 kdex2x86.idt 命令察看。下面的代码节选自在我的测试系统上使用此命令所得到的输出。<br />
<br />
1: kd&gt; !kdex2x86.idt<br />
<br />
IDT for processor #0<br />
<br />
...<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;dd: 80ac2ac2 (nt!_KiUnexpectedInterrupt173)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;de: 80ac2acc (nt!_KiUnexpectedInterrupt174)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;df: 80ac2ad6 (nt!_KiUnexpectedInterrupt175)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;e0: 80ac2ae0 (nt!_KiUnexpectedInterrupt176)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;e1: 804e0084 (HAL!HalpIpiHandler)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;e2: 80ac2af4 (nt!_KiUnexpectedInterrupt178)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;e3: 804dfdd8 (HAL!HalpLocalApicErrorService)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;e4: 80ac2b08 (nt!_KiUnexpectedInterrupt180)<br />
<br />
...<br />
<br />
当设备产生中断时,中断向量又是如何成为 CPU 的 IDT 的索引,进而调用了相应的终端服务程序的呢?唔,这时就要提到硬件中断控制器了。下面就来看一下两种 Intel “可编程中断控制器”(PIC)的实现,一种是传统的 8259 PIC,另一种则是更高级的“Advanced PIC”(APIC)。我们还要挖掘一下 Windows 的中断处理机制,使得我们可以明白 PIC 和 APIC 是如何在现实世界中使用的。<br />
<br />
<br />
The 8259<br />
<br />
起初 IBM PC 使用 Intel 的 8259 PIC。8259 只支持单处理器的系统且只提供标号为 IRQ0-IRQ7 的8条“中断请求线”使设备与中断相关联,因此最多只能处理8个中断。之后,系统中加入了第二个 8259,这个 8259 通过三条级联线(CAS0-CAS2)与主 8259 级联起来。第二个 8259 的 INT 线还要连到主 8259 的 IRQ2 上,这样算上新添加的8个 IRQs 中再减去用于连接的一个 IRQ,就有了总共15个 IRQs。Figure 1 就是简化的示意图。<br />
<br />
<br />
Figure 1<br />
<br />
所有现代的主板都要么使用两个物理 8259 芯片,要么使用其它芯片来模拟这两个芯片。好了,历史课到此结束,我们再深入一点儿细节。<br />
<br />
每个需要中断的设备都需要得到一个唯一的 IRQ 然后连接到 8259 上。为了产生一个指定 IRQ 的中断,设备要使总线上相应的 IRQ 线有效。<br />
<br />
8259 为每个 IRQ 都分配了一个优先级,IRQ0 最高,号越大优先级越低。因此 IRQ0 是最高,IRQ15 最低,对吗?哦,不,也不全对。还记着第二个 8259 连到了 IRQ2 上吗?实际的 IRQ 优先级为:<br />
<br />
<br />
IRQ0, IRQ1, (now off to the second 8259) IRQ8-IRQ15, (now back to the first 8259) IRQ3-IRQ7<br />
<br />
乍一看这种安排也不是那么显然,但如果歪过脑袋来眯缝着眼看似乎还是合理的。<br />
<br />
每一个 IRQ 都是“可屏蔽的”,意思就是可以通过编程 8259 的“Interrupt Mask Register”(IMR)可以将其禁用。如果 IRQ 被屏蔽掉,则连到这个 IRQ 的设备中断请求就都被忽略了。再有,高优先级的 IRQ 比低优先级的 IRQ 先得到服务,而且高优先级的 IRQ 还可以打断低优先级的 IRQ。因此若服务 IRQ1 时 IRQ0 又来了,则 IRQ1 中断的处理停止,IRQ0 中断被送往 CPU。<br />
<br />
很重要的一点是,尽管存在着硬件优先级,但 Windows 系统并没有实际使用它。Windows 系统通过直接操纵 IMR (见本文 conclustion 处的 sidebar)为 8259 加上了自己的优先级机制。<br />
<br />
现在我们知道了设备时如何连接到 8259 以及 8259 是如何连接到一起的,那 8259 又是如何与 CPU 连接的呢?<br />
<br />
x86 体系的 CPU 有两条中断线,LINT0 和 LINT1。在 8259 的配置中,LINT1 连到了“Non-Maskable Interrupt”(NMI),当检测到严重的、潜在的、不可恢复的错误时就会产生 NMI。之所以叫做“Non-Maskable Interrupt”是因为没有办法阻断它——除了处理器,没有谁能屏蔽它。引起 NMI 的一个典型的例子就是内存校验错。<br />
<br />
LINT0 被用作“Interrupt Input Line”(INTR),它连接在主 8259 的 INT 脚上。8259 通过使 INT 有效来将中断通知给系统。当 CPU 确认后,8259 通过总线向 CPU 发送一个8位的值(之前被 O/S 编程进了 PIC)。这个8位的值就是相应 IRQ 的中断向量。这个中断向量被用作 IDT 的索引来确定中断服务程序(ISR)的地址。然后,CPU 跳转到 ISR,进行服务此中断所需的处理。<br />
<br />
唔,看起来还不算很难。但是,要是需要中断的设备多于15个该怎么办呢?那就要共享中断了,这时链接起来的 ISRs 就粉墨登场了。在这种情形下,OS 调用第一个注册到所给中断向量上的 ISR,将中断通知给它。假设此中断是一个 level-triggered 的中断(比如 PCI 总线上的 line-based 的中断),OS 会调用与所给中断向量号相关联的所有的 ISRs 直到找到返回 TRUE 的那个,返回 TRUE 就说明这个中断就是用于此设备的。共享中断存在一些问题,因为写得不好的 ISR 会使系统挂掉。实际上,甚至写得好的 ISR 都有可能挂掉系统。要得到对此问题的解释,可以参阅 <a href='http://www.microsoft.com/hwdev/platform/proc/apic.asp' target='_blank'>http://www.microsoft.com/hwdev/platform/proc/apic.asp</a> 处的文章。再有,8259 不能用在多处理器系统中,这就太过时了,因为如今我们使用的桌面计算机大多都有两颗 CPU。还是用 APIC 吧。<br />
<br />
<br />
The APIC<br />
<br />
通常所说的 APIC 实际上由两个部分:“Local APIC”(LAPIC)和“I/O APIC”(IOAPIC)。系统中每个(逻辑上的)CPU 一般都有一个片上的 LAPIC。因此,若系统有四个 CPU 则有四个 LAPICs(注意,因为是每个逻辑处理器有一个 LPIC,所以如果有两个超线程的 CPU 也会有四个 LPIC)。IOPIC 是 Intel 芯片组的一部分,Pentium IV 及以后的系统可以有任意数量的 IOAPICs。Pentium IV 之前的 CPU 则限制在8个。一个 IOPIC 可以设计为支持最多64条“中断输入线” (Interrupt Input Lines,INTINs),但是大多数标准的系统的 IOAPICs 都是24条 INTINs。INTINs 与 8259 里的 IRQs 作用相同。换句话说,每个产生中断的设备都会取得一个 INTIN。如你所见,在 APIC 的配置中可以使用足够多的 INTINs 来减少 8259 中存在的共享问题。好,为了节约时间,我们来仔细看一下 APIC 的这两部分。<br />
<br />
<br />
LAPIC<br />
<br />
如前所述,LAPIC 一般都在实际的 CPU 上,Pentium 之后的 CPU 上都有。其他厂商的处理器可能也可能不把 APICs 作为 CPU 的一部分。不管怎样,还记得 LINT0 和 LINT1 这两条线吗?在 APIC 的配置中,这些线都联结到 LAPIC,LAPIC 再连接到系统总线(Pentium IV 之前的 Intel CPU 实际有一条单独的 APIC 总线,但我们这里忽略这些硬件细节)。系统中的所有 CPU 都如法炮制,这就使得“处理器间中断”(Interprocessor Interrupts,IPIs)能够通过系统总线从一个 LAPIC 送至另一个 CPU 的 LAPIC,如 Figure 2 所示。<br />
<br />
Figure 2 – The LAPIC and IOAPIC<br />
<br />
需要注意 LAPIC 中的一个重要的寄存器,即“Task Priority Register”(TPR)。通过将 TPR 设置为一定的值,操作系统可以设置 CPU 运行的优先级。这些优先级从0至15,0 的优先级最低。中断的 INTIN 为一个范围从16至255间的一个向量,当中断从 IOAPIC 送往 LAPIC 时,中断的优先级由下式计算:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;priority = ceil(vector / 16)<br />
<br />
x86 已经预定义了范围在0至31的向量,因此 OS 从31开始定义设备中断。当请求中断时,如果得到的优先级小于或等于目标处理器 LAPIC 的当前 TPR 值,中断就不会在那个 CPU 上生效。这样 OS 就可以通过控制分配给中断处理程序在 IDT 中的中断向量并通过执行这些处理程序时向 LAPIC 的 TPR 写入相应的值就可以控制中断的优先级。OS 给中断赋的向量值越高,中断的优先级就越高。<br />
<br />

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -