已阅读5页,还剩62页未读, 继续免费阅读
(计算机软件与理论专业论文)二进制翻译中自修改代码的缓存策略研究.pdf.pdf 免费下载
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
华 中 科 技 大 学 硕 士 学 位 论 文 i 摘 要 自修改代码是二进制翻译研究中的难点和影响翻译效率的重要因素。众多文献 介绍了自修改代码对二进制翻译效率的影响,但均缺乏量化分析;自修改代码具有 在程序执行过程中动态地改变程序自身执行指令的特点,在计算机安全领域有广泛 的应用。在自修改代码频繁出现时,二进制翻译器中如何设计和实现高效的代码缓 存策略是加速二进制翻译效率值得研究的问题。 针对上述问题,利用 qemu 作为实验平台,对自修改代码和非自修改代码进行 了大量的测试,量化地分析了自修改代码对翻译器的翻译效率和翻译块数量的影响。 在量化分析了自修改代码对翻译效率影响的基础上,结合翻译器以基本块和 trace 翻译的优点,精确的自修改代码缓存策略 pscm(precise self- modifying code cache management policy)在以 trace 为翻译机制的前提下,通过基本块的精确替换方式, 替换由于自修改造成的代码缓存中不一致的翻译块。pscm 通过页块映射把发生自 修代码的物理页映射到具体的基本翻译块, 通过 trace 的定位确定基本翻译块对应的 trace,通过代码缓存管理维护代码缓存中的基本翻译块和 trace 链,通过精确的块 替换方法替换由于自修改代码造成的代码缓存中失效的基本翻译块。 研究结果表明,在 qemu 翻译器上,自修改代码随着自修改同比次数增长,其 执行时间的增加速度平均是非自修改程序的 5.81 倍。平均每增加 1 次自修改,对应 在 qemu 上的翻译块数量增加 10.51。 翻译器以 trace 为翻译机制的效率较基本块有 明显优势。对于 pscm 的测试表明,在代码缓存(code cache)中的翻译块的数量 (flush blocks counts,fb)为 11 时,pscm 策略加速因子为 3.95;pscm 策略加速 因子随着 fb 的增加而增加,数据说明利用 pscm 策略能够改进翻译器在自修改代 码翻译的效率。 关键词:二进制翻译,自修改代码,代码缓存,自修改翻译策略,自修改缓存策略 华 中 科 技 大 学 硕 士 学 位 论 文 ii abstract in binary translation, self- modifying code is a difficult issue and factor that influences the translation efficiency. many papers introduce the influence of self- modifying code on binary translator, but there are no quantitative research discovered. self- modifying code has the characteristics that it can dynamically modify and yield the code of the program during running time. and self- modifying code has abroad application in the field of computer secutity. there is a great valueable issue to accelerate the translation efficiency through design and relize great efficiency policy of code cache in binary translator, when self- modifying code occurs frequently. to address the issues above, using qemu as the experimentation platform, this thesis carries on massive tests about the self- modifying and non- self- modifying code, thoroughly analyses translation time efficiency and the translation block number which is influenced by the self- modifying code. bases on quantitative research of self- modifying code s influence on the translation efficiency, and combines the advantages of basic block and trace translation mechanism, to accelerate self- modifying code translation, the thesis provides a code cache policy named pscm, and realizes fundamental pscm prototype system. pscm uses trace as the translation mechanism. through precise- block replace, replaces the disaccorded block in code cache. through mapping, relates the modified page and basic translation block. through locating, finds the trace that a block belongs to. through code cache management maintains the trace information and translation block in code cache. from the research, the speed about procedure execution time increasing with numbers of self- modifying when self- modifying code is executed on qemu is 5.81 times of the speed when non- self- modifying code is executed on qemu; each time there is one more time of self- modifying, the translation block averagely increases 10.51 blocks; trace mechanism has more distinct advantage than basic block in translator. the test result of pscm prototype indicates, when the fb (numbers of translated blocks in code cache) is 11, the tactics acceleration ratio of pscm is 3.95; pscm tactics acceleration ratio increases with the increasement of fb, which means the advantage of pscm appears more obvious when fb is big. pscm can be used to improve translation efficiency for self- modifying code. key words: binary translation,self- modifying code, code cache management, self- modifying code translation policy,self- modifying code cache policy 独创性声明 本人声明所呈交的学位论文是我个人在导师指导下进行的研究工作及取得的研 究成果。尽我所知,除文中已经标明引用的内容外,本论文不包含任何其他个人或 集体已经发表或撰写过的研究成果。对本文的研究做出贡献的个人和集体,均已在 文中以明确方式标明。本人完全意识到,本声明的法律结果由本人承担。 学位论文作者签名: 日期: 年 月 日 学位论文版权使用授权书 本学位论文作者完全了解学校有关保留、使用学位论文的规定,即:学校有权 保留并向国家有关部门或机构送交论文的复印件和电子版,允许论文被查阅和借阅。 本人授权华中科技大学可以将本学位论文的全部或部分内容编入有关数据库进行检 索,可以采用影印、缩印或扫描等复制手段保存和汇编本学位论文。 保密 ,在_年解密后适用本授权书。 不保密。 (请在以上方框内打“” ) 学位论文作者签名: 指导教师签名: 日期: 年 月 日 日期: 年 月 日 本论文属于 华 中 科 技 大 学 硕 士 学 位 论 文 1 1 绪 论 本章首先介绍了课题背景,然后对二进制翻译进行了概述,包括二进制翻译的 概念、意义、分类及特点、历史上的系统,并分别对解释执行、静态翻译和动态翻 译进行了介绍,接着本章介绍了二进制翻译的研究热点,介绍了二进制翻译中的自 修改代码问题,最后是本文的研究内容和文章的组织。 1.1 课题背景 随着计算系统的资源规模不断扩展、处理能力快速增强、资源种类日益丰富、 应用需求灵活多样,新型的计算机理与模式已成为未来信息技术领域面临的重大挑 战。计算系统虚拟化作为一种新型计算模式推动科技发展和社会进步,已成为国际 竞争的焦点和制高点。因此不同平台之间的软件移植成为一个研究的热点,不仅对 软件重用有重大意义,而且对于开阔处理器研发的思路,促进新处理器创新也有现 实的意义。 为使得源指令集体系(instruction set architecture,isa)的目标代码在新的指令 集体系结构中执行,有以下三种方法选择1: 1. 在新处理器上提供一种特殊模式执行代码仿真,如 intel 的安腾处理器存在专 门执行 x86 代码的硬件2; 2. 重新编译程序,成为新处理器的二进制代码; 3. 用软件的方法解释或翻译应用程序。 其中第三种方法,称为二进制翻译技术(binary translation) 。它是一种直接翻 译可执行二进制程序的技术,能够把一种机器上的二进制程序翻译到另外一种机器 上3,有助于打破 isa和其软件基础之间形成的扼制创新的局面,打破 cpu 设计改 革的瓶颈,使开发新 isa 机器变得可行,同时也使得一种机器上的二进制程序能够 很容易地移植到另一种机器上,扩大了硬件/软件的适用范围。 本课题受国家 973 计划项目“计算系统虚拟化基础理论与方法研究 ” (no.2007cb310900)支持,属于子课题“体系结构虚拟化研究” 。本课题关于虚拟 化动态二进制翻译方法研究,包括支持跨体系结构的虚拟化计算系统的动态二进制 翻译方法和支持高效的虚拟化计算系统的动态优化方法的研究。 华 中 科 技 大 学 硕 士 学 位 论 文 2 自修改代码(self- modifying code,smc)以其具有在程序执行过程中动态地修 改和产生程序本身执行的指令的特点,在增加代码的理解难度阻止逆向工程和软件 保护方面有广泛的应用4,5, 利用自修改代码将可执行文件中的代码或数据进行加密, 可以防止使用逆向工程工具对程序进行静态分析。自修改代码的动态特性也使其成 为二进制翻译中的难点和影响翻译效率的因素。 代码缓存(code cache)是一种基于软件的代码缓存区,是动态二进制翻译器中 存储翻译好的块加速翻译效率的主要机制。然而,自修改代码在动态二进制翻译过 程中造成的 code cache 一致性的问题,大大影响了动态二进制翻译器对自修改代码 程序的翻译效率。 本研究致力于自修代码对二进制翻译影响的量化研究,并力求通过改进翻译器 中 code cache 的管理机制提高二进制翻译器对自修改代码的翻译效率。以此来推动 支持高效的虚拟化计算系统的动态翻译。 1.2 国内外研究进展与现状 1.2.1 二进制翻译的研究 1二进制翻译介绍 从本质上说二进制翻译技术也是一种编译技术,它与传统编译的差别在于其编 译处理对象不是一种高级语言,而是某种机器的二进制代码。按照传统编译程序前 端、中端和后端的划分,可以把二进制翻译器理解为拥有特殊前端的编译器。 像编译器那样,二进制翻译器在概念上可以分为三个部分3,如图 1.1 所示。 源二进制文件 解码器 目标机二进制文件 分析器 编码器 图 1.1 二进制翻译示意图 (1) 解码器根据源机器的指令结构特点,以及可执行文件的格式规定,通过指令 模式匹配对二进制码进行处理,完成类似反汇编的功能。这部分需要准确地对二进 华 中 科 技 大 学 硕 士 学 位 论 文 3 制代码进行解码,处理间接跳转/间接调用、自修改代码、数据内容的识别和分析等。 解码器的输出是某种形式的抽象中间表示。这个阶段的功能与传统编译器的前端不 同的是传统编译器的前端是将用源语言书写的程序进行分析。因此二者的一些核心 技术和关键问题也有所不同。 (2) 分析器的功能是完成两级中间表示的转换工作,逐渐去除代码中源机器特 性,实现到目标机器的转化,并且对程序进行分析和优化。分析器的首要任务是实 现两级中间表示的等价变换。为了更好地体现目标平台的特点,在编译系统中,与 机器直接对应的中间表示或多或少有着该机器的特点,在二进制翻译系统中,采用 两级中间表示可以隔离不同的机器平台的特点,从而方便系统的设计与实现。 (3) 编码器类似于一般的编译器,其功能是从一种中间语言生成目标机代码。根 据目标机器以及目标机器采用的操作系统的特点,将中间表示翻译成为目标机器上 可执行的二进制代码。编码器一般综合了常规编译系统中的后端代码优化和生成器, 以及类似链接器和装载程序的功能。 2二进制翻译的意义 (1) 体系结构的虚拟化 从体系结构虚拟化方面考虑,二进制翻译把一种指令集的二进制可执行代码翻 译成可以在另外一种指令集体系结构上可以执行二进制代码。因此,二进制翻译可 以实现跨平台的指令之间的转换,屏蔽因为指令集而造成的底层平台的异构性,实 现体系结构的虚拟化。二进制翻译方法可以从软件方面优化支持跨体系结构的计算 系统虚拟化。设计和实现上层软件无需考虑底层的体系结构,通过翻译器的翻译解 决体系结构的不一致问题。 (2) 代码遗留问题 从软件开发方面考虑。软件生命周期中,维护费用几乎占了一半。维护工作一 般发生在二进制代码及其应用客户使用软件产品的过程中,通常分为以下几类:纠 错性维护,适应性维护,完善性维护。纠错性维护是排除在用户使用过程中发现的 软件错误,大概占维护费用的四分之一;适应性维护是系统环境的变更导致系统不 得不进行的修改,如硬件平台、操作系统平台、数据库平台的改变等等,大概占维 护费用的五分之一。完善性维护包括增加新的功能或改变完善已有的功能,使其更 符合用户的需求,如:用户要增加分析统计功能等,占维护费用的一半以上;二进 制翻译技术有助于减少适应性维护,它可以使得不用花很多时间和编程工作就能把 华 中 科 技 大 学 硕 士 学 位 论 文 4 旧平台(legacy platform)上的软件容易地移植到新硬件平台上。特别是历史遗留的 已经失去源代码程序的二进制代码,通过二进制翻译可以使得遗留代码在新的体系 结构下运行,避免再次开发。 (3) 芯片的研发 商业化微处理器为了兼容,保留着上一代产品的所有指令,尽管其中有的指令 也许已经有相当长的历史,并且已经很少使用了。尽管这些 isa(instruction set architecture)的缺点很多,但是硬件开发商们仍然不愿意去开发一套全新的 isa,因 为这么做会冒很大的风险。首先,基于原 isa 的软件不能在新的 isa 上运行,造成 原来 isa 上的软件投资浪费;其次,软件开发商觉得为一个全新的体系结构写应用 软件有一定难度,不仅费时而且开销巨大。如果这种体系结构没有赢得足够的市场 份额,那么软件开发商为其开发软件是会面临很大风险的。由于这两方面的制约, 限制了芯片设计的改革,也限制了新的竞争者进入芯片设计领域。 二进制翻译有助于我国自主研发 cpu 芯片,自主研发 cpu 面临支撑软件的移 植问题, intel x86 芯片盛行多年,用户希望原本使用的运行于 x86 机器平台的各种应 用软件,能够在新的机器正确使用。这就需要在开发芯片的同时,解决遗留的应用 软件使用问题。进行二进制翻译有助于支持国产 cpu 的研制工作,如龙芯的研制。 3二进制翻译分类及特点 根据翻译时机的不同,二进制翻译分为静态二进制翻译和动态二进制翻译。进 一步可以把二进制翻译分为三类:解释执行,静态翻译,动态翻译,图 1.2 展示了这 三种方法,以及使用了该方法的翻译系统1。 aries boa jits jvm fx!32 uqbt 在ibm/360上 仿真ibm 1401、7070 和7090; 在vax上 仿真pdp- 11 解释执行静态翻译动态翻译 图 1.2 二进制翻译的分类图 (1) 解释执行 解释器的出现可以追溯到上世纪五、六十年代,许多程序设计语言都采用解释 的方式执行,如 lisp、perl、forth 等等,但本节仅关心如何采用解释技术实现二 华 中 科 技 大 学 硕 士 学 位 论 文 5 进制代码的翻译,而不考虑高级语言的解释。解释执行对源处理器代码中的每条指 令实时解释执行,系统不保存也不缓存解释过的指令,不需要用户干涉,也不进行 任何优化。解释器相对容易开发,且容易与老的体系结构高度兼容,但效率很差。 图 1.3 是解释器的基本结构,它实时解释并执行源处理器代码中的每条指令,系 统不保存也不缓存解释过的指令,整个解释过程无需用户干涉,也不进行任何代码 优化。除指令外,源处理器的代码映像还包含一定的数据,为了完整地再现源处理 器代码的执行情况,解释器还必须忠实地记录源处理器的运行状态,如程序计数器、 寄存器的值。图 1.3 中的源处理器上下文块(source context block)就是保存处理器 状态的存储区。 代码 数据 . . . 堆栈 源处理器 存储状态 解释代码 程序计数器 条件码 寄存器1 寄存器2 寄存器n - 1 源处理器 上下文块 图 1.3 解释器的逻辑结构 (2) 静态翻译 静态翻译是在源处理器代码执行之前对其进行翻译,将源机器上的二进制可执 行程序文件 a 完全翻译成目标机器上的二进制可执行程序文件 b,然后在目标机上 执行程序 b。一次翻译的结果可以多次使用。静态翻译器离线翻译程序,有足够的 时间进行更完整细致的优化,效率较高,静态翻译器还可以利用程序以往执行的记 录进行优化,即基于 profiling 的翻译,获取更好的优化结果。然而,静态翻译器可 能无法完整地翻译一个程序6,因而需要依赖解释器的支持;而且静态翻译器作为一 个独立的工具,需要终端用户的参与1,这给用户使用造成了很大不便。dec 公司 的 fx!327,8,9系统,uqbt10,11就采用了这种方法。 华 中 科 技 大 学 硕 士 学 位 论 文 6 解释执行与翻译执行在一定程度上很相似,因为它们都引入了预译码技术,但 它们仍是两种完全不同的技术,图 1.4 描述了二者的异同。尽管采用这两种方法,源 处理器代码都将被转换为另一种形式的二进制目标代码,但解释执行时目标代码还 必须依赖对应的解释程序才能间接地在目标处理器上执行,而翻译得到的目标代码 可以直接在目标处理器上执行。 中间 代码 解释 代码 源处理 器代码 预翻译 程序 目标处理 器代码 源处理 器代码 二进制 翻译程 序 图 1.4 解释方法与翻译方法的异同 (3) 动态翻译 动态翻译在程序运行时对执行到的片段进行翻译,克服了静态翻译的一些缺点, 比如说静态翻译时由于不能知道控制流中某点的寄存器或内存的值,从而不能解决 自修改代码问题。动态翻译可以解决实际情况中的自修改代码和精确中断问题,而 这对于静态翻译是不可能解决的。动态翻译可以利用执行时的动态信息来发掘静态 编译器所不能发现的优化机会。动态翻译器对用户可以做到完全透明,无需用户干 预12,。虽然动态翻译器拥有上述诸多优点,翻译过程却由于受到动态执行的限制而 不能进行更全面细致的优化,使得翻译生成的代码效率比静态翻译器差1。比较有代 表性的动态翻译系统包括 aries13,boa14等 动态翻译系统的简单结构如图 1.5 所示,它由四个部分组成:管理模块负责整个 系统的控制;code cache 缓存翻译后得到的目标代码;地址映射表记录了源机器程 序指令地址(spc)与目标机器程序指令地址(tpc)的对应关系,如果源程序中起 始地址为 spc1的代码段已经被翻译并保存在 code cache 中(假设目标代码起始地址 为 tpc1) ,映射表中将有一项;翻译模块负责完成从源指令集到目标指令 集的翻译。 华 中 科 技 大 学 硕 士 学 位 论 文 7 动态翻译的执行过程如下:首先,管理模块查找源机器程序的入口地址 spc0在 映射表中是否有对应项;如果命中则直接从 code cache 中取出相应的一个目标代码 块执行,直至该块的出口,如果出口地址为 spci,则继续查找映射表中有无 spci对应 的项;若不命中,则管理模块将启动翻译模块,从 spc0开始取源机器程序的一个基 本块进行翻译, 翻译结果将被存入code cache中, 并在地址映射表中添加相应项(设目标代码块地址为 tpc0) ;这一过程将一直重复,直到程序执行结束。 管理模块 翻译模块 c o d e c a c h e s p c 0 t p c 0 . . . . . s p c i t p c i s p ct p c 地址映射表 源代码 命中 非命中 图 1.5 动态翻译系统简单结构图 表 1.1 是上述三种方法的优缺点1,3。 表 1.1 三种二进制翻译方法的比较 优 点 缺 点 解释执行 容易开发,不需要用户干涉,高度兼容 代码执行效率很差 静态翻译 离线翻译,可以进行更好的优化,代码 执行效率较高 依赖解释器、运行环境的支持,要终端用 户的参与,给用户使用造成了不便 动态翻译 无需解释器和运行环境支持,需用户参 与,可利用动态信息进行优化 翻译的代码执行效率不如静态翻译高,对 目标机器有额外的空间开销 4二进制翻译系统 从 1987 年开始出现第一个二进制翻译系统 hp3000 emulation 15至今,二进制翻 译系统已有二十一年的研究历史。 表 1.2 中列出了一些实验性和商用的二进制翻译研 究历史中一些有代表性的系统,并按照翻译方式和它们所针对的源和目标平台进行 了归类。这些基本反映了二进制翻译的研究历史和发展过程,涵盖了各个研究阶段 的技术成果。 华 中 科 技 大 学 硕 士 学 位 论 文 8 表 1.2 二进制翻译研究历史中一些有代表性的系统 系统名称 源平台 目标平台 翻译方式 mimic16 固定 固定 解释执行 accelerator17 固定 固定 vest,mx18,19 可变 固定 静态翻译和解释 执行结合 btran20,21 固定 可变 静态翻译 walkabout22,23 可变 可变 动态翻译和解释 执行结合 daisy24 code morphing software25 digitalbridge21,26,27 ia- 32 execution layer28 hdtrans29 pin30,31 固定 固定 uqdbt32,33 bintran34,35 strata36 可变 可变 动态翻译 1.2.2 二进制翻译的研究热点 二进制翻译技术可以应用在不同领域,满足不同的需求。在设计二进制翻译系 统的时候可以从很多方面来权衡和选择。 二进制翻译可以是解释执行或者翻译/优化; 静态翻译或者动态翻译;模拟一个虚拟机器或者模拟真实机器;完整系统级或者用 户级;操作系统相关或者操作系统独立;同一指令集或者不同指令集等。以下几个 方面是二进制翻译技术目前的研究热点。 1. 代码挖掘问题:在冯诺伊曼结构机器中,代码和数据以相同形式表示,给 出一个可执行文件,常常不能容易的区分代码和数据,因此前端解码器准确地挖掘 出源机器的代码很困难。一般的方法是从代码入口点开始,沿着可到达的路径解码 37,38,但对静态翻译来说,由于间接跳转和间接调用的存在,前述方法无法解决。 文献6采用了基于分割和表达式替换方法恢复跳转表的目标地址,使得用静态分析 可以解决大部分间接跳转造成的代码挖掘困难。 自修改代码(self- modifying code,smc)问题是代码挖掘问题之一。自修改代 码程序具有在执行过程中动态地修改程序自身执行指令的特点。在动态翻译自修改 代码时,必须要及时发现并正确处理自修改指令所带来的代码缓存一致性维护问题。 与代码挖掘相关的另外一个问题是自引用代码问题 (self- referential code, src) , 即代码引用它本身,比如求检验和39。 华 中 科 技 大 学 硕 士 学 位 论 文 9 2. code cache 的管理:code cache 的大小是有限的,无论是当 code cache 满时, 还是当发生自修改代码时,都需要对 code cache 中的翻译好的代码进行管理。高效 的 code cache 管理可以提高二进制翻译的效率。 3. 异常的精确性:同步异常(如页面故障)和异步异常(如时钟中断)发生时, 翻译器的异常处理机构必须提供一个与原结构状态一致的、正确的状态。 4. 地址翻译:不同硬件结构的地址空间设计存在一定的差异,对 i/o 地址的处 理也大相径庭,全系统的二进制翻译还必须完成虚拟地址和物理地址之间的转化。 5. 实时行为:二进制翻译系统必须根据代码是否已经被翻译、被如何翻译来决 定执行速度的不同,执行时间是一个不定因素。 上述问题是目前研究二进制翻译技术的研究热点,通过对这些热点的研究,可 以全面了解在开发一个实用的二进制翻译系统时需要解决哪些问题,如何提高二进 制翻译系统的效率,如何更好地满足用户对系统通用性、透明性、实时性等各方面 的要求。值得一提的是二进制翻译是一项复杂而艰苦的工作,解决这些问题需要相 当多的科研工作者的长期努力。 1.2.3 二进制翻译中的自修改代码问题 自修改代码(self- modifying code, smc)意思是自我修改的代码,是程序在运 行时向代码段中写数据,并且写入的数据被作为指令执行,是程序运行期间修改或 产生代码的一种机制40。解决自修改代码问题,首先是要能够发现自修改代码,由 于自修改代码的动态性,这使得对一个纯静态翻译器来说是不可能的,对动态翻译 器也比较困难。如果能够提供一些手段监视被修改的代码41,42,就可以在发现源机 器代码被修改后,置其对应的目标机器代码无效,并进行重新翻译,从而解决自修 改代码问题。daisy24系统通过在页设置写保护标识,在发现自修改时, 销毁页中 的所有的翻译的信息。qemu43,44系统把所有翻译过的块的目标代码段存放在自己 开辟的内存空间 code cache 中。被翻译器翻译的程序执行就是执行 code cache 中翻 译好的代码块。 在自修改代码发生时, qemu通过系统信号判断, 然后清空code cache 中的所有翻译好的块。文献45给出关于二进制翻译中的自修代码的介绍。 在设计二进制翻译器过程中,自修改代码有时被认为是不经常事件,但是自修 改代码以其动态改变或生成运行中的指令的特点,在增加代码的理解难度阻止逆向 工程和软件保护方面有广泛应用46,47,有文献利用自修改代码技术描述基于 rsa算 法的软件加密保护方法48,把自修改的特点和经典的 rsa加密算法结合保护软件。 华 中 科 技 大 学 硕 士 学 位 论 文 10 在游戏(如 doom)中自修改代码也有应用,为了能兼容原有的程序以及对现有程序 进行完整支持,有些处理器实现了对 smc 的支持49,50。自修改在嵌入式系统中有较 为广泛的应用,在嵌入式系统中,内存空间一般都比较有限,当一些指令被执行过 后其仍可能占用内存,而实际上是没有必要继续保留这些指令的,通过自修改可以 改变这些指令为新的指令,在达到程序功能的同时,也充分利用了内存空间。 自修改代码影响翻译效率的原因是自修改代码造成的翻译器的 code cache 的一 致性维护问题。在翻译过程中,当自修改发生时,加载在翻译空间中的源二进制代 码发生了改变,致使 code cache 中对应的已经翻译好的块和源二进制代码表达的意 义不一致。如果翻译器不对被修改的块进行重新翻译,而直接去执行 code cache 中 翻译好的块,则就会造成翻译执行的错误。 1.3 本文研究的内容 自修改代码以其在程序运行过程中动态生成代码的特点,在计算机安全方面有 较为广泛的应用。与此同时,自修改代码是二进制翻译中的难点问题,特别是在自 修改代码频繁发生的情况下,对翻译器的效率的影响很大。code cache 是二进制翻 译器中加速翻译效率的主要组件。本文着重研究自修改代码 code cache 策略,以便 提高翻译器对自修改代码的翻译效率。 国家 973 计划项目“计算系统虚拟化基础理论与方法研究” (no.2007cb310900) 的子课题“体系结构虚拟化研究”的主要方向之一就是二进制翻译及其优化问题。 在项目的初期调研阶段,项目小组成员深入调研众多二进制翻译器,对 qemu 翻译 系统做了深入的分析,并特别专注于二进制翻译中的自修改代码和精确异常问题, 以及翻译器的加载器和解码器的研究。 本文在分析了 qemu 的翻译机制基础上,利用 qemu 作为实验平台,对自修 改代码和非自修改代码的进行了大量的测试,就自修改代码对翻译器的翻译时间效 率影响进行了深入的分析。采用了量化的方法分析了自修改代码对翻译器翻译效率 的影响,分析了自修改代码对翻译过程中翻译块数量的影响。通过对 nbench测试程 序的测试,对比分析了 qemu、hdtrans 和 pin 的翻译效率,证明了以 trace 为单位 的翻译机制较基本块机制有明显的优势,但是缺乏对自修改代码的支持。 在分析了自修改代码对二进制翻译影响基础上, 结合基本块和 trace 翻译机制的 优点,本文给出了精确的自修改代码缓存管理策略 (precise self- modifying code 华 中 科 技 大 学 硕 士 学 位 论 文 11 cache management policy, pscm) ,pscm 策略通过备份源二进制代码的方式为自修 改发现机制的基础,在利用 trace 机制提高翻译效率的同时,通过仅仅替换 trace 链 中的一个翻译基本块的策略,避免由于自修改带来的不必要的块的重复翻译,达到 提高翻译效率的目的,在策略分析和设计的基础上,本文实现了一个策略原型系统, 并对原型系统进行了实验测试,根据测试结果做了进一步的分析,通过分析发现, pscm 策略对于提升自修改代码的翻译效率上有明显的提高。 1.4 文章结构 下面是论文的组织结构。 第 1 章首先介绍了课题背景,二进制翻译的研究,二进制翻译的研究热点,以 及二进制翻译中的自修改代码问题。最后介绍了文章要研究的内容和文章结构。 第 2 章研究 qemu 系统翻译机制,并主要通过在 qemu 上测试自修改代码和 非自修改代码的翻译,量化地分析自修改代码对翻译效率和翻译块数量的影响,并 分析造成这种影响的原因。 第 3 章根据第 2 章的分析,结合翻译器以基本块和 trace 翻译机制的优点。给出 了一种自修改代码的代码缓存策略 pscm,对 pscm 的设计进行了详细的阐述。包 括 pscm 的系统介绍、pscm 的设计思想、pscm 的核心设计和 pscm 的自修改处 理流程。在 pscm 的核心设计中,分别对自修改的发现、自修改代码的处理和 code cache 管理进行了介绍。 第 4 章对 pscm 的 code cache 策略实现进行了详细的阐述。 包括页块映射机制、 trace 定位机制、代码缓存的管理策略和精确的块替换策略。详细介绍了策略中从页 到 code cache 中翻译块的定位过程。 第 5 章对 pscm 进行了测试和评价。首先介绍评价方法和测试环境,然后介绍 了功能测试,最后介绍了性能测试与分析。 第 6 章对全文做了进一步的总结,并对进一步的研究工作提出了展望。 最后是致谢和参考文献。 华 中 科 技 大 学 硕 士 学 位 论 文 12 2 自修改代码与二进制翻译效率 本章在介绍自修改代码、翻译器的 code cache 策略和 qemu 的翻译机制的基础 上,主要对自修改代码对翻译器的影响进行测试和分析。实验采用的操作系统是 cetos- 4.6,翻译器采用 qemu,针对的源和目标平台都是 intel x86 指令集。通过在 物理机和 qemu 平台上测试自修改和相同指令数量的非自修改程序,对比分析自修 改代码对翻译效率的影响。 2.1 自修改代码 2.1.1 自修改代码介绍 图 2.1 给出了一个简单的用汇编语言书写的自修改代码段。 start: nop mov $0 x08, %eax loop: inc %eax target: xor %eax, %eax test %eax, %eax jnz end modify: movb $0 x40, target ; 0 x40 = “ inc %eax” jmp loop end: nop 图 2.1 自修改代码实例 对图 2.1 中的这段代码,当程序运行到 modify标识时,此处对应的指令 movb $0 x40, target向地址为 target 的内存单元写数据 0 x40, 对应位置上的指令被修 改,被修改位置上原来的指令为 xor %eax, %eax 被自修改而变成了指令 inc %eax %eax, 程序继续运行至 jmp loop 指令, 跳转到 loop 位置, 当再次运行到 target 位置时,则运行修改后的指令 inc %eax %eax而非原代码段的指令 xor %eax, %eax, 这样 test %eax, %eax的结果是非零值,接着 jnz end使得程序运行结束。如果该段 程序没有 modify这一自修改代码指令,此程序段将陷入死循环中。 所谓自修改代码技术就是一种将可执行文件中的代码或数据进行加密,防止别 人使用逆向工程工具(比如一些常见的反汇编工具)对程序进行静态分析的方法, 只有程序运行时才对代码和数据进行解密,从而正常运行程序和访问数据。计算机 病毒通常也会采用自修改代码技术动态修改内存中的可执行代码来达到变形或对代 华 中 科 技 大 学 硕 士 学 位 论 文 13 码加密的目的,从而躲过杀毒软件的查杀或者迷惑反病毒工作者对代码进行分析。 现在,很多加密软件(或者称为“壳”程序)为了防止破解者(cracker)跟踪自己 的代码,也采用了动态代码修改技术对自身代码进行保护。图 2.2 为伪代码书写的一 种自修改代码技术的典型应用: proc main: . if .运行条件满足 call decryptproc (address of securityproc); 对代码段进行解密 . call securityproc ;调用这个函数 . call encryptproc (address of securityproc); 再对代码段进行加密,保护程序 . end main 图 2.2 自修改代码的典型应用伪代码 在调用一个函数(securityproc)前,首先对这个函数进行解密操作(call decryptproc) ,等调用结束后又对这个函数代码段进行加密(call encryptproc)操作。 这样该函数(securityproc)只要在非运行期间就以密文的形式存在,可以大大提高 其被反汇编的可能性。在软件中使用自修改技术可以极大地提高软件的安全性,保 护私有数据和关键功能代码段,对防止软件破解可以起到很好的作用。但是,自修 改代码技术一般需要直接读写内存中的机器码,需要对汇编语言和机器码有相当的 了解,具体的实现一般都是采用汇编语言。由于汇编语言晦涩难懂,不容易掌握, 这使得很多想在自己的程序中使用自修改技术进行软件加密的高级语言程序员望而 却步。其实,从理论上讲,只要支持指针变量和内存直接访问的高级语言,象 c/c+ 这样的高级语言都可以进行自修改代码编程。 有研究表明,自修改代码主要应用于增加代码的理解难度阻止逆向工程和软件 保护方面46,47。自修改机制基本思想是,程序中的代码 p 在软件发布前被加密,但 是在运行时通过指令 q 恢复过来,当代码 p 执行后又被指令 t 所加密46,这样, 当破解者通过反汇编工具进行分析时很难理解原先指令。 文献46中所采用的方法是 首先对原先的软件通过反汇编得到汇编代码,然后在汇编代码中选取一条要加密的 目标指令 o,并确定加密指令 e 和解密指令 d 及其位置,然后用加密后的指令 o 覆盖原先的指令 o,再将加解密指令插人到程序中,然后用汇编器生成二进制代码。 有文献利用自修改代码技术描述基于 rsa算法的软件加密保护方法48,把自修改的 华 中 科 技 大 学 硕 士 学 位 论 文 14 特点和经典的 rsa加密算法结合保护软件。自修改代码在嵌入式软件中也有应用。 自修改代码之所以在嵌入式系统中有较为广泛的应用,是因为自修改程序可以在运 行过程中产生指令。在嵌入式系统中,内存空间一般都比较有限,通过自修改指令 修改那些废弃的指令可以达到充分利用内存空间的目的。为了能兼容原有的程序以 及对现有程序进行完整支持,有的处理器实现了对自修改代码的支持49,50。kris kaspersky编写的shellcoder 编程揭秘51一书把自修改列为一种安全技术。 2.1.2 自修改代码的实例 通过一定的编程技巧用高级语言也可以编写自修改代码,图 2.3 是一个用 c 伪 代码编写的自修改代码的实例。 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 包含相关头文件 预定义变量 count 控制自修改同比次数,初始值设为 100 定义不同名,但包含同语句的函数 fun1,fun2 主函数开始 定义相关局部变量如: i 等; 定义控制自修改位置指针 * ptr,*ptr0;函数指针 fun;时间变量等。 ptr = mmap(0 x40000000,0 x1000,prot_read|prot_write|prot_exec, map_fixed | map_anon | map_private, - 1, 0); /08 行,开辟内存可写可执行空间,并使得 ptr 指向该 *ptr=0 xe8; / 0 xe8 表示 call 指令,在 ptr 指向空间写入指令 * (ptr+5)= 0 xc3; / 0 xc3 表示返回指令,在 ptr+5 指向的空间写入返回指令 /在 ptr 和 ptr+5 指向的地址之间是 call 指令的参数,参数在 15 行循环体中写入 把 fun 指向 ptr 获取当前时间 t0 循环执行 count 次以下自修改代码段,i 从 1 到 count 如果 i 为偶数 赋值*(ptr+1)为 fun1 相对于 ptr 地址 调用 fun; /此时调用的是 fun1 函数 如果 i 为奇数 赋值*(ptr+1)为 fun2 相对于 ptr 地址 调用 fun; /此时调用的是 fun2 函数 /循环结束 获取当前时间 t1, 由 t1 和 t0 计算运行自修改代码段的执行时间 /主函数结束 图 2.3 c 伪代码自修改实例 华 中 科 技 大 学 硕 士 学 位 论 文 15 图 2.3 中的伪代码利用系统调用 mmap 开辟了一个可读写且可执行的内存空间, 然后 ptr 指针指向该内存空间,通过语句*ptr=0 xe8 向给区域中写入 call 指令,然后 把 0 xc3 写入到 ptr+5 的位置,0 xc3 表示的 ret 指令,就是返回指令,以便 call指令执 行完后返回。然后通过 fun=(void*)ptr 把 fun 指向 call 指令,这样对函数指针 fun 的执行也就是执行这里的 call 指令。call 指令需要有被调用的地址参数,参数在 call 和 ret 之间,call 指令的地址参数是在 for 循环中给出的,这个地址参数是相对于 call 指令的相对地址,通过计算获得 fun1 或 fun2 相对于 call 指令的地址位置然后把计算 的结果写在 call 指令后面参数的位置作为 call 指令的参数。在 for 循环中根据变量
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 应急事件处置练习题及答案
- 煤矿注氮工考核试题及详细答案
- 2026年环境监测技术与应用试题
- 2026年四川省生态文明知识竞赛考点题库
- 2026年公务员考试行政法与行政诉讼法模拟题
- 2026年会计学原理期末考试复习题库
- 2026年心理健康知识应用测试题
- 2026年幼儿音乐节奏感与音乐理解测试
- 2026年申论模拟试卷社会现象评论专项练习
- 2026年环境监测技术标准解读知识测试卷
- 2026年数字安徽有限责任公司所属企业安徽数安系统集成有限公司第1批次社会招聘18人笔试备考试题及答案详解
- 2026书记员面试题目及答案
- 2026秋北师大版小学数学幼升小暑期30天每日练习卷
- 养鸡场成本核算与效益分析手册 (标准版)
- 2026年看护辅警人员笔试题库及答案参考
- 私募股权投资基金投资房地产企业的风险解析与防范策略
- 2026年中国铁路南宁局铁路局校园招聘真题
- 采购文件三级审核制度
- 《数据中心锂离子电池消防安全白皮书》
- T∕SMA 0078-2025 高压电缆接地回路电阻检测导则
- 工业信息安全制度
评论
0/150
提交评论