·首 页 ·精选文章 ·无忧学院 ·两性教育 ·商业站点 ·无忧传奇 ·私服宣传 ·无忧音乐 ·骗子举报 ·软件发布 ·无忧论坛
您现在的位置: 无忧网络网游技术网 >> 技术文章 >> 黑客教程 >> 安全漏洞 >> Windows台漏洞 >> 正文

  没有公告

| 技术文章 | 传奇技术 | 传世技术 | 魔兽技术 | 奇迹技术 | 千年技术 | 仙境技术 | 其他技术 | 传奇菜鸟 | 传世菜鸟 | 奇迹菜鸟 |
| 网游下载 | 网游版本 | 私服工具 | 游戏下载 | SF客户端 | 网站原码 | 经典工具 | 破解工具 | 绿色软件 | 教程下载 | 动画专区 |
| 操作系统 | 故障维修 | 主机架设 | 腾讯QQ区 | 流量排名 | 黑客教程 | 主机评测 | WAP 专区 | 网络游戏 | 游戏攻略 | 网吧黄页 |
| 私服必备 | 常用工具 | 网吧联盟 | 传奇站点 | 网页加密 | 网页转换 | 颜色采集 | 网页源码 | MD 5破解 | 站长工具 | 在线算命 |
| 实用查询 | I P 查询 | 邮编查询 | 区号查询 | 周公解梦 | 成语大全 | 手机查询 | 号码凶吉 | 星座查询 |身份证查询| 5UQQ查询 |
专 题 栏 目
最 新 热 门
最 新 推 荐
相 关 文 章
没有相关文章
系统安全之脱壳高级篇Import表的重建         ★★★
系统安全之脱壳高级篇Import表的重建
系统安全之脱壳高级篇Import表的重建
作者:黑虎  文章来源:本站原创  点击数:  更新时间:2007-3-27 16:11:32
    

1. 前言

大家好,我之所以写这篇短文,是由于我在 Dump 时发现,很多加压、加密软件都使得输入表(Import Table)不可用,所以 Dump 出的可执行文件必须要重建输入表。而在普通的讲授 Win32 汇编的站点上我没有找到这样的介绍,所以如果你对此感兴趣,那么这篇短文对你会有些帮助。

例如,为了让从内存中 Dump 出的经 PETite v2.1 压缩过的可执行文件正常运行,必须重建输入表。(对于 ASPack、PEPack、PESentry……也同样)这就是所有 Dump 软件都具备重建输入表功能的原因(例如 G-RoM/UCF 制作的 Phoenix Engine(ProcDump 内含),或者由 Virogen/PC 和我制作的 PE Rebuilder)。

鉴于这个问题十分特殊,而且比较复杂,所以我假定你已经了解了 PE 文件结构。

2. 预备知识

首先是一些关于输入表和 RVA/VA 的简介。

输入表的相对虚拟地址(RVA)储存在 PE 文件头部的相应目录入口(它的偏移量为[ PE 文件头偏移量+80h ])。由于是虚拟偏移量,所以它和文件输入表中的偏移量(VA)是不匹配的(除非文件纯粹是刚刚从内存中 Dump 出来的)。于是我们首先要做的事情是,找到 PE 文件的输入表,将 RVA 转换为相应的 VA。为此,我们可以采用不同的办法:你可以自行编制软件来分析块(Sections)目录并计算 VA,但最简单的办法是使用专门为此设计的应用程序接口(API)。这个 API 包括在 IMAGEHLP.DLL(Win9X 和 NT 系统都使用的一个库)中,名为 ImageRvaToVa。下面是对它的描述(完整的内容详见 MSDN 库):

# LPVOID ImageRvaToVa(# IN PIMAGE_NT_HEADERS NtHeaders,# IN LPVOID Base,# IN DWORD Rva,# IN OUT PIMAGE_SECTION_HEADER *LastRvaSection#);## 参数:## NtHeaders ## 指示一个 IMAGE_NT_HEADERS 结构。通过调用 ImageNtHeader 函数可以获得这个结构。## Base## 指定通过调用 MapViewOfFile 函数映射入内存的一个映象的基址(Base Address)。## Rva ## 指定相对虚拟地址的位置。## LastRvaSection ## 指向一个指定的最终 RVA 块的 IMAGE_SECTION_HEADER 结构。这是一个可选参数。当被#指定时,它指向一个变量,该变量包含指定映象的最后块值,以便将 RVA 转换为 VA。
 

就这么简单。你只需要将 PE 文件映射入内存,然后调用这个函数就能够得到输入表的正确 VA。

注意,下面我会忽略所有的 RVA/VA 注释,但是,当你对重建的 PE 文件进行读出或写入RVAs 操作时,不要忘记它们之间的转换。

3. 完整说明

这里是一个完整改变输入表的例子(这个 PE 文件的输入表已经被 PETite v2.1 压缩过,并且是直接从内存中 Dump 出来的):

我们用“`”表示 00,用“-”表示非字符串

 

0000C1E8h : 00 00 00 00 00 00 00 00 00 00 00 00 BA C2 00 00 ````````````----0000C1F8h : 38 C2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ----````````````0000C208h : C5 C2 00 00 44 C2 00 00 00 00 00 00 00 00 00 00 --------````````0000C218h : 00 00 00 00 D2 C2 00 00 54 C2 00 00 00 00 00 00 ````--------````0000C228h : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ````````````````0000C238h : 7F 89 E7 77 4C BC E8 77 00 00 00 00 E6 9F F1 77 --------````----0000C248h : 1A 38 F1 77 10 40 F1 77 00 00 00 00 4F 1E D8 77 --------````----0000C258h : 00 00 00 00 00 00 4D 65 73 73 61 67 65 42 6F 78 ``````MessageBox0000C268h : 41 00 00 00 77 73 70 72 69 6E 74 66 41 00 00 00 A```wsprintfA```0000C278h : 45 78 69 74 50 72 6F 63 65 73 73 00 00 00 4C 6F ExitProcess```Lo0000C288h : 61 64 4C 69 62 72 61 72 79 41 00 00 00 00 47 65 adLibraryA````Ge0000C298h : 74 50 72 6F 63 41 64 64 72 65 73 73 00 00 00 00 tProcAddress````0000C2A8h : 47 65 74 4F 70 65 6E 46 69 6C 65 4E 61 6D 65 41 GetOpenFileNameA0000C2B8h : 00 00 55 53 45 52 33 32 2E 64 6C 6C 00 4B 45 52 ``USER32.dll`KER0000C2C8h : 4E 45 4C 33 32 2E 64 6C 6C 00 63 6F 6D 64 6C 67 NEL32.dll`comdlg0000C2D8h : 33 32 2E 64 6C 6C 00 00 00 00 00 00 00 00 00 00 32.dll``````````
 

正如你看到的,这个输入表被分成三个主要部分:

- C1E8h - C237h:IMAGE_IMPORT_DESCRIPTOR 结构部分,对应着每一个需要输入的动态链接库(DLL)。这部分以关键字 00 结束。

 

IMAGE_IMPORT_DESCRIPTOR structOriginalFirstThunk dd 0 ;原拆分 IAT 的 RVATimeDateStamp dd 0 ;没有使用ForwarderChain dd 0 ;没有使用Name dd 0 ;DLL 名字符串的 RVAFirstThunk dd 0 ;IAT 部分的 RVAIMAGE_IMPORT_DESCRIPTOR ends
 

- C238h - C25Bh:这部分双字(DWord) 称作“IAT”,由 IMAGE_IMPORT_DESCRIPTOR结构中的 FirstThunk 部分指明。这部分每一个 DWord 对应一个输入函数。

- C25Ch - C2DDh : 这里是输入函数和 DLL 文件的名称。问题是,这些是没有规定顺序的:有时候 DLL 文件在函数前面,有时候正好相反,另外一些时候它们混在一起。

输入表的简介

OriginalFirstThunk 是 IAT 的一部分,它是 PE 文件引导时首先要搜索的。如果存在,PE文件的引导部分将使用它来纠正在 FirstThunk IAT 部分的问题。当调入内存后,FirstThunk的每一个 Dword (包含有函数名字符串的 RVA),将被 RVA 替换为函数的真实地址(当调用这些函数时,它们调入内存的位置将被执行)。所以,只要 OriginalFirstThunk 没有被改变,基本上这里不存在输入表的问题。

下面来看我们的问题

好了,经过简单描述后,下面来看我们的问题。如果你试图运行包含上面显示的输入表的可执行文件,它不会被调入,Windows 会显示一个错误信息。为什么?很简单,因为OriginalFirstThunk 被删除了。事实上,你应该注意到,在这个输入表的每一个IMAGE_IMPORT_DESCRIPTOR 结构,OriginalFirstThunk 的内容都是 00000000h。嗯,所以我们可以推测出,当我们运行这个可执行程序时,PE 文件的引导部分试图从FirstThunk 部分获得输入函数的名字。但是,正象你注意到的,这部分根本没有包含函数名字符串的 RVA,但是函数地址的 RVA 在内存中。

我们需要怎么做

现在,为了让这个可执行文件运行,我们需要重建 FirstThunk 部分的内容,让它们指向我们在输入表第三部分看到的函数名字符串。这不是一项很困难的任务,但是,我们需要知道哪个IAT 对应哪个函数,而函数字符串和 FirstThunk 内容并不采用同样的存储方法。所以,对于每一个 IAT,我们需要验证它对应的是哪个函数名(事实上,根据 IMAGE_IMPORT_DESCRIPTOR.Name DWord 我们已经有了 DLL 名称,这些并没有被改变)。

如何验证每一个函数

正向我们上面所见到的,在内存中,每一个被破坏的 IAT 都有一个函数地址的 RVA。这些地址并没有被破坏,所以,我们只要重新找回指向错误 IAT 的函数地址,把它们指向函数名字符串。

为此,在 Kernel32.dll 中有一个非常有用的 API:GetProcAddress。它允许你得到给定函数的地址。这里是它的描述:

 

GetProcAddress(HMODULE hModule, // DLL 模块的句柄LPCSTR lpProcName // 函数名);
 

所以,对于每一个被破坏的 IAT,在 GetProcAddress 返回我们寻找的函数地址之前,只需要分析包含在输入表第三部分的所有函数名。

- hModule 参数是 DLL 模块的句柄(也就是说,模块映象在内存中的基址),我们可以通过 GetModuleHandleA API 得到:

 

HMODULE GetModuleHandle(LPCTSTR lpModuleName // 返回模块名地址句柄);
 

(lpModuleName 只需要指向我们从 IMAGE_IMPORT_DESCRIPTOR.Name 部分得到的 DLL 文件名字符串)

- lpProcName 仅指向函数名字符串。

注意,有时候函数是按序号输入的。这些序号是在每个 [ 函数名偏移量-2 ] 处的单字(WORDS)。所以,你在分析程序时需要检查函数是按名称还是按序号输入的。

使用上面输入表的实例

针对上面输入表的例子,我将说明如何修复第一个输入 DLL 的第一个输入函数。

1. 我们来看第一个 IMAGE_IMPORT_DESCRIPTOR 结构部分(C1E8h),.Name 部分(C1E4h,指向C1BAh)指出了 DLL 名。我们看到,那是 USER32.dll。

2. 我们来看 .FirstThunk 部分,它们指向 IAT 部分;每个对应一个这个 DLL(user32.dll)的输入函数。在这里是 C1F8h,指向 C238h。所以,在 C238h,我们可以修复被破坏的 IATs。(你会注意到,这个 IAT 部分包含二个 DWords,所以,这个 DLL 有二个函数输入)

3. 我们得到了第一个被破坏的 IAT。它的值是 77E7897Fh。这是函数在内存中的地址。

4. 对每一个输入表第三部分中的函数,我们调用 GetProcAddress API。当该 API 返回 7E7897Fh时就意味着,我们到达了正确的函数。所以我们让被破坏的 IAT 指向正确函数名。(在本例中为 'wsprintfA')。

5. 现在我们只需要将 IAT 指向:偏移量(函数名字符串)-2。为什么是 -2 ?因为有时候使用了函数序列。

所以在本例中,我们改变地址 C238h,让它指向 C26Ah(以代替 77E7897Fh)。

6. 就这样,这个函数被修复了,下面你只需要对所有的 IATs 重复这个过程就可以了。

后记

我描述的是一般的操作过程。当然只有在 DLLs 被正常调入内存后才能够这样做。对于其他情况,你需要将它们调入,或者你需要仔细研究它们的输出表才能找到正确的函数地址。

本站声明:本站文章资源均来自网上转载或机器人自动搜索采集,如果本站文章资源有版权问题请联系管理员,我们尽快予以更正。所有文章只限用于个人测试学习使用,不得用于非法商业用途,请勿非法复制传播。特此声明!--[5uwl.net]

五年游戏制作经验; 金牌服务品质保障 游戏开区一条龙 第一品牌无忧网络[5uwl.net]

文章录入:黑虎    责任编辑:ceo 
  • 上一篇文章:

  • 下一篇文章:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 站点地图 | 管理登录 | 
    版权所有:Copyright © 2002-2008 中国·无忧网络 Www.5uwl.NET All Rights Reserved.
    网络支持:本站部份带宽由群英网络唯一数据赞助 (排名不分次序本站征赞助商)
    建议使用:1024*768 分辨率 Windows2000 Internet Explorer v5.0 or Higher
    广告投放:[5uwl.net] QQ 267320050 TEL [移]013689532036
    IP备案号:粤ICP备05092442号