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

📄 782.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>浅析本机API </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,本机API" />
<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>浅析本机API</h1><br>创建时间:2005-03-09<br>文章属性:转载<br>文章提交:<a href='https://www.xfocus.net/bbs/index.php?lang=cn&act=Profile&do=03&MID=82515'>cisocker</a> (cisocker_at_163.com)<br><br>by sunwear [E.S.T]&nbsp;&nbsp;<br />
2004/10/02&nbsp;&nbsp; <br />
shellcoder@163.com<br />
<br />
此文只能说是一篇笔记,是关于本机API的.本机API是除了Win32 API,NT平台开放了另一个基本接口。本机API也被很多人所熟悉,因为内核模式模块位于更低的系统级别,在那个级别上环境子系统是不可见的。尽管如此,并不需要驱动级别去访问这个接口,普通的Win32程序可以在任何时候向下调用本机API。并没有任何技术上的限制,只不过微软不支持这种应用开发方法。&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;User32.dll,kernel32.dll,shell32.dll,gdi32.dll,rpcrt4.dll,comctl32.dll,advapi32.dll,version.dll等dll代表了Win32 API的基本提供者。Win32 API中的所有调用最终都转向了ntdll.dll,再由它转发至ntoskrnl.exe。ntdll.dll是本机 API用户模式的终端。真正的接口在ntoskrnl.exe里完成。事实上,内核模式的驱动大部分时间调用这个模块,如果它们请求系统服务。Ntdll.dll的主要作用就是让内核函数的特定子集可以被用户模式下运行的程序调用。Ntdll.dll通过软件中断int 2Eh进入ntoskrnl.exe,就是通过中断门切换CPU特权级。比如kernel32.dll导出的函数DeviceIoControl()实际上调用ntdll.dll中导出的NtDeviceIoControlFile(),反汇编一下这个函数可以看到,EAX载入magic数0x38,实际上是系统调用号,然后EDX指向堆栈。目标地址是当前堆栈指针ESP+4,所以EDX指向返回地址后面一个,也就是指向在进入NtDeviceIoControlFile()之前存入堆栈的东西。事实上就是函数的参数。下一个指令是int 2Eh,转到中断描述符表IDT位置0x2E处的中断处理程序。<br />
<br />
反编汇这个函数得到:<br />
<br />
mov eax, 38h<br />
<br />
lea edx, [esp+4]<br />
<br />
int 2Eh<br />
<br />
ret 28h<br />
<br />
当然int 2E接口不仅仅是简单的API调用调度员,他是从用户模式进入内核模式的main gate。<br />
<br />
W2k Native API由248个这么处理的函数组成,比NT 4.0多了37个。可以从ntdll.dll的导出列表中很容易认出来:前缀Nt。Ntdll.dll中导出了249个,原因在于NtCurrentTeb()为一个纯用户模式函数,所以不需要传给内核。令人惊奇的是,仅仅Native API的一个子集能够从内核模式调用。而另一方面,ntoskrnl.exe导出了两个Nt*符号,它们不存在于ntdll.dll中: NtBuildNumber, NtGlobalFlag。它们不指向函数,事实上,是指向ntoskrnl.exe的变量,可以被使用C编译器extern关键字的驱动模块导入。Ntdll.dll和ntoskrnl.exe中都有两种前缀Nt*,Zw*。事实上ntdll.dll中反汇编结果两者是一样的。而在ntoskrnl.exe中,nt前缀指向真正的代码,而zw还是一个int 2Eh的stub。也就是说zw*函数集通过用户模式到内核模式门传递的,而Nt*符号直接指向模式切换以后的代码。Ntdll.dll中的NtCurrentTeb()没有相对应的zw函数。Ntoskrnl并不导出配对的Nt/zw函数。有些函数只以一种方式出现。<br />
<br />
2Eh中断处理程序把EAX里的值作为查找表中的索引,去找到最终的目标函数。这个表就是系统服务表SST,C的结构SYSTEM_SERVICE_TABLE的定义如下:清单也包含了结构SERVICE_DESCRIPTOR_TABLE中的定义,为SST数组第四个成员,前两个有着特别的用途。<br />
<br />
typedef NTSTATUS (NTAPI *NTPROC) ( ) ;<br />
<br />
typedef NTPROC *PNTPROC;<br />
<br />
#define NTPROC_ sizeof (NTPROC)<br />
<br />
typedef struct _SYSTEM_SERVICE_TABLE<br />
<br />
{ PNTPROC ServiceTable; // 这里是入口指针数组<br />
<br />
PDWORD CounterTable; // 此处是调用次数计数数组<br />
<br />
DWORD ServiceLimit ; // 服务入口的个数<br />
<br />
PBYTE ArgumentTable; // 服务参数字节数的数组<br />
<br />
) SYSTEM_SERVICE_TABLE ,<br />
<br />
* PSYSTEM_SERVICE_TABLE ,<br />
<br />
* * PPSYSTEM_SERVICE_TABLE ;<br />
<br />
/ / _ _ _ _ _ _ _ _ _ _ _ _<br />
<br />
typedef struct _SERVICE_DESCRIPTOR_TABLE<br />
<br />
{ SYSTEM_SERVICE_TABLE ntoskrnl ; // ntoskrnl所实现的系统服务,本机的API}<br />
<br />
SYSTEM_SERVICE_TABLE win32k; // win32k所实现的系统服务<br />
<br />
SYSTEM_SERVICE_TABLE Table3; // 未使用<br />
<br />
SYSTEM_SERVICE_TABLE Table4; // 未使用<br />
<br />
} SERVICE_DESCRIPTOR_TABLE ,<br />
<br />
* PSERVICE_DESCRIPTOR_TABLE,<br />
<br />
* PPSERVICE_DESCRIPTOR_TABLE ;<br />
<br />
ntoskrnl通过KeServiceDescriptorTable符号,导出了主要SDT的一个指针。内核维护另外的一个SDT,就是KeServiceDescriptorTableShadow。但这个符号没有导出。要想在内核模式组件中存取主要SDT很简单,只需两行C语言的代码:<br />
<br />
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;<br />
<br />
PSERVICE_DESCRIPTOR_TABLE psdt= KeServiceDescriptorTable;<br />
<br />
NTPROC为本机 API的方便的占位符,他类似于Win32编程中的PROC。Native API正常的返回应该是一个NTSTATUS代码,他使用NTAPI调用约定,它和_stdcall一样。ServiceLimit成员有在ServiceTable数组里找到的入口数目。在2000下,默认值是248。ArgumentTable为BYTEs的数组,每一个对应于ServiceTable的位置并显示了在调用者堆栈里的参数比特数。这个信息与EDX结合,这是内核从调用者堆栈copy参数到自己的堆栈所需的。CounterTable成员在free buid的2000中并没有使用到,在debug build中,这个成员指向代表所有函数使用计数的DWORDS数组,这个信息能用于性能分析。<br />
&nbsp;&nbsp;&nbsp;&nbsp;可以使用这个命令来显示:dd KeServiceDescriptorTable,调试器把此符号解析为0x8046e0c0。只有前四行是最重要的,对应那四个SDT成员。<br />
&nbsp;&nbsp;&nbsp;&nbsp;运行这个命令:ln 8046e100,显示符号是KeServiceDescriptorTableShadow,说明第五个开始确实为内核维护的第二个SDT。主要的区别在于后一个包含了win32k.sys的入口,前一个却没有。在这两个表中,Table3与Table4都是空的。Ntoskrnl.exe提供了一个方便的API函数。这个函数的名字为:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;KeAddSystemServiceTable<br />
此函数去填充这些位置。<br />
<br />
2Eh的中断处理标记是KisystemService()。这也是ntoskrnl.exe没有导出的内部的符号,但包含在2k符号文件中。关于KisystemService的操作如下:<br />
<br />
1 从当前的线程控制块检索SDT指针<br />
<br />
2 决定使用SDT中4个SST的其中一个。通过测试EAX中递送ID的第12和13位来决定。ID在0x0000-0x0fff的映射至ntoskrnl表格,ID在<br />
<br />
0x1000与0x1ffff的分配给win32k表格。剩下的0x2000-0x2ffff与<br />
<br />
0x3000-0x3ffff则是Table3和Table4保留。<br />
<br />
3 通过选定SST中的ServiceLimit成员检查EAX的0-11位。如果ID超过了范围,返回错误代码为STATUS_INVALID_SYSTEM_SERVICE。<br />
<br />
4 检查EAX中的参数堆栈指针与MmUserProbeAddress。这是一个ntoskrnl导出的全局变量。通常等于0x7FFF0000,如果参数指针不在这个地址之下,返回STATUS_ACCESS_VIOLATION。<br />
<br />
5 查找ArgumentTable中的参数堆栈的字节数,从调用者的堆栈copy所有的参数至当前内核模式堆栈。<br />
<br />
6 搜索serviceTable中的服务函数指针,并调用这个函数。<br />
<br />
7 控制转到内部的函数KiserviceExit,在此次服务调用返回之后。<br />
<br />
从对SDT的讨论可以看到与本机API一起还有第二个内核模式接口。这个接口把Win32子系统的图形设备接口和窗口管理器和内核模式组件Win32k连接起来。Win32k接口一样是基于int 2eh。本机API的服务号是从0x0000到0x0fff,win32k的服务号是从0x1000到0x1fff。(ddW32pServiceTable认定win32k.sys的符号可用。)win32k总共包含639个系统服务。<br />
<br />
<br />
2Eh的处理过程没有使用全局SDT KeServiceDescriptorTable。<br />
<br />
而是一个与线程相关的指针。显然,线程可以有不同得SDT相关到自身。线程初试化的时候,KeInitializeThread()把KeServiceDescriptorTable写到线程的控制块。尽管这样,这个默认设置之后可能被改变为其它值,例如KeServiceDescriptorTableShadow。<br />
<br />
<br />
Windows 2000运行时库<br />
<br />
Ntdll.dll至少导出了不少于1179个符号。其中的249/248是属于Nt*/zw*集合。所以还有682个函数不是通过int 2eh门中转。很显然,这么多的函数不依靠2k的内核。<br />
<br />
其中一些是和c运行时库几乎一样的函数。其实ntoskrnl也实现了一些类似C运行时库的一些函数。可以通过ddk里的ntdll.lib来链接和使用这些函数。反汇编ntdll.dll与ntoskrnl.exe的C运行时函数能发现,ntdll.dll并不是依赖ntoskrnl.exe。这两个模块各自实现了这些函数。<br />
<br />

⌨️ 快捷键说明

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