WINDOWS+PE权威指南读书笔记(26)
目录
EXE 捆绑器
基本思路:
EXE 执行调度机制:
控制进程同步运行实例分析:
字节码转换工具 hex2db:
hex2db 源代码:
运行测试:
执行调度程序 _host.exe:
主要代码:
数据结构分析:
宿主程序 host.exe:
宿主程序的功能:
宿主程序的状态:
遍历文件:
释放文件:
宿主程序主函数:
EXE 捆绑器 bind.exe:
绑定列表定位:
捆绑步骤及主要代码:
测试运行:
小结:
EXE 捆绑器
本书 8.4 节,也就是前面的 "延迟加载导入编程" 目录中介绍了一种通过附加资源文件的方式对文件进行捆绑的例子。本章使用补丁技术编写一个小工具,该工具可以将某个目录中的所有相关文件 (含子目录中的文件) 捆绑在一起,捆绑前还可以定义要运行的 EXE 序列。
EXE 捆绑器允许用户将多个可执行文件及相关文件捆绑到一起,通过运行捆绑程序实现多个可执行文件的依次执行。
基本思路:
EXE 捆绑是指将两个或多个可执行文件和非执行文件捆绑到一起的技术。
捆绑的目的有三个:
口 减少某个待发布系统的独立文件的个数。
口 隐藏某些特殊用途的文件。
口 实现一些特殊功能,如本案例中通过捆绑实现了多个程序的顺序执行。
EXE 捆绑器结合 EXE 加锁器 (本书第 20 章讲述的内容) 可以用于加密文件夹或文件。因为在捆绑过程中,可以指定被捆绑的文件中哪些需要运行,所以,该捆绑器还可以用于运行多个 PE 文件的批处理,通过依次运行多个文件 (结合本书第 19 章讲述的软件安装自动化技术) 则可以实现多个补丁的自动安装。
捆绑的实现方法有很多种,其中最常见有两种方法:
1) 通过编写一个新的 EXE 程序,把要捆绑的所有文件以资源的方式进行,或者直接写在文件末尾来进行,运行时只需将文件提取出来依次运行即可。
2) 通过直接修改第一个 PE 程序,将其他文件作为资源或直接写在文件末尾,通过在第一个 PE 程序中设置补丁程序的方式,依次运行多个程序。
本章将讲解第一种捆绑方法:
以下是本章要用到的几个程序,以及每个程序的相关说明:
口 hex2db:将字节码转变为汇编语言数据定义语句的小工具。
口 _host.exex:调度执行程序的模板,该文件最终嵌入到宿主程序中。
口 hostexe:宿主程序。是补丁程序的目标,用于存储 _host.exe 和其他要捆绑的文件。
口 bind.exe:捆绑器。负责执行捆绑,类似于进阶部分的补丁工具。
EXE 执行调度机制:
大部分情况下,被捆绑的文件集合中只有一个 EXE 文件是主运行文件。但也有例外,比如有的用户会将多个程序捆绑起来,然后依次安装这些程序以提高计算机的安全性能,这时候就要用到 EXE 执行调度。EXE 执行调度就是在捆绑前,指定补丁程序中要安装的程序的运行顺序,当被捆绑的程序被释放出来后,还要有一个进程专门负责调度这些程序按照先后顺序依次运行。
要实现 EXE 同步执行,需要使用两个 Windows API 函数,它们分别是:
口 CreateProcess (创建进程函数)
口 WaitForSingleObject (等待指定进程结束)
控制进程同步运行实例分析:
本节根据对操作系统进程管理的理解,介绍使用 Windows API 函数实现控制进程同步运行的实例,以帮助大家更加深入地理解多个应用程序依次被执行调度的过程。
代码清单 18-1 简单地模拟了捆绑被释放以后,各个程序的同步运行效果:
主程序通过函数 CreateThread 把调度函数 _RunThread 当成一个线程来运行 (行76)。调度函数首先通过 CreateProcess 打开一个程序 (行54) ,然后,调用函数 WaitForSingleObject 等待进程结束 (行 38)。第一个程序结束后,继续使用 CreateProcess 打开第二个程序,使用 WaitForSingleObject 等待第二个程序的结束,依次类推。
执行程序后,首先打开记事本程序,无论你如何操作,均会等待记事本程序退出后 (选择菜单 “文件”|“退出” 选项或者直接选择标题栏最右端的关闭按钮退出记事本),才打开第二个程序 “helloworld.exe”。
字节码转换工具 hex2db:
执行调度的代码会以字节码定义的方式 (使用伪指令 db 语句) 嵌入到源码中。这些字节码可以通过 FlexHex 复制获得,但转换起来特别麻烦。为了方便后续的开发,本节编写一个小工具 hex2db,该工具实现了将文件中的字节码转换为汇编语言字节定义的方式。
例如,文件中的以下字节码:
00 01 02 03 04 A5
利用小工具 hex2db 最终转换为:
db 00h,01h,02h,03h,04h, 0A5h
数据定义该语句包括三部分:
口 前置空格。本例中有四个空格。
口 数据定义伪指令 db。db 和数据之间有一个空格。
口 数据。以逗号分隔,如果某个字节的高八位超过 0ah,则在该字节前添加一个 “0”。
hex2db 源代码:
hex2db 的编写思路与第 2 章的小工具 PEDump 雷同,两者都是以控制输出格式为核心。
hex2db 的源代码见代码清单 18-2:
运行测试:
编译链接执行文件,打开文件 1.txt,查看对 PE 文件 _hostexe 的执行结果(节选) 如下:
注意:
使用小工具 hex2db 生成的数据定义语句外的最后一行末尾有一个逗号,在将结果引入汇编代码时,必须将该过号去掉,否则编译源文件时会出现错误。
执行调度程序 _host.exe:
前面 "EXE 执行调度机制" 目录中通过一个程序模拟了多个应用程序的执行调度过程。接下来就要编写本章通用的执行调度程序 _hostexe。该程序可以对同步运行更多的应用程序,且定义上会更灵活。
主要代码:
主要代码见代码清单 18-3:
与 18.2.2 小节的例子不同,在线程函数 _RunThread 中,要调度的程序不再是固定的某个 PE 文件,而是通过遍历绑定列表数据结构得到的由用户定义的程序。
将 _hostasm 编译,链接以后,生成可执行文件。使用上一节开发的小工具 hex2db.exe,将可执行代码 _host.exe 转换为汇编语言里的字节码定义语句,保存放在 C:\1.txt 中,以便在后面想整体将可执行代码嵌入到汇编源代码时使用。
数据结构分析:
本章开发的 EXE 捆绑器最大能捆绑 100 个文件,由常量 TOTAL_FILE_COUNT 定义。每个捆绑文件都对应一个结构,用来说明文件的名称、所处的位置、是否加入到最终的可执行序列标志等。
该结构的详细定义如下:
函数参数的解释如下:
1) inExeSequence: 标志字节。如果是 0,则表示该捆绑文件是一般文件,不参与释放后的执行调度过程; 如果是 1,则表示该文件为 PE 文件,且参与释放后的执行调度过程。
2) dwFileOff: 该文件字节码在宿主程序中的偏移。指出了文件在宿主程序中的位置。
3) dwFileSize: 文件的大小。
4) name: 要绑定的文件的名字,含子目录。
特别提示:
BinderFileStructname 不是绝对路径,而是当前路径下的相对路径。该路径中包含子目录,可能的表达形式如 pic\background.gif,指当前目录下的 pic 子目录中的 background.gif 图片文件,子目录允许嵌套。(就是相对目录了啦)
宿主程序 host.exe:
下面将开发宿主程序,即 EXE 捆绑器最终生成的携带了捆绑文件的可执行程序。
宿主程序的功能:
宿主程序 host.exe 是 EXE 捆绑器的核心 PE 文件,它具备以下三个功能:
1) 存储所有要捆绑的文件,包括可运行的文件和不可运行的文件,这些文件将通过程序补丁的方式存储到宿主程序的最后一节。
2) 按原目录结构释放所有文件。
3) 具备调度程序执行的功能。该部分功能由释放的 _host.exe 来完成。而 _host.exe 的添加方法则是直接将指令字节码添加到宿主程序的源程序中。
和 _host.exe 程序一样,宿主程序 host.exe 中也定义了一套绑定列表的数据结构。这两个程序维护了同样的数据实例,_host.exe 的绑定列表中每个字段的值都来自于宿主程序。
举个简单例子,如果文件夹中有以下 5 个文件待绑定:
口 A1.exe
口 A2.exe
口 Config.ini
口 dat\abc.dat (注意含子目录)
口 db\abc.mdb (注意含子目录 )
其中 A1、A2 为可执行程序,要求绑定后的程序在运行时先执行 A1,然后执行 A2。
以下数字模拟了宿主程序的绑定列表可能的数据排列方式:(对应的是前面的数据结构)
宿主程序维护了这样的一套数据,用它来释放捆绑文件,嵌入到宿主程序源代码中的 _host.exe 字节码中也维护了这样的一套数据,用它来执行调度。
宿主程序的状态:
由于宿主程序完成了对捆绑文件的存储,所以,在捆绑文件前后不同时期,宿主程序存在不同的状态。
如图 18-1 所示:
如图所示,捆绑前,宿主程序是轻身的,与捆绑文件没有任何的关联; 捆绑后 (执行前),宿主程序已经包含了所有的捆绑文件数据; 执行时,宿主程序会释放捆绑的所有文件。所以,除了宿主程序不发生任何变化外,磁盘上还多出了 _host.exe 和所有绑定的文件。
_host.exe 为进程调度指挥长,释放出的可执行文件就是在它的调度指挥下实现了顺序执行的。该程序包含在捆绑前的宿主程序中。那么,对文件的捆绑工作由谁来完成呢? 答案是由捆绑器来完成。捆绑器类似于 PE 进阶部分的补丁工具。
遍历文件:
为了确认当前目录要捆绑的文件,程序需要首先遍历当前目录下的文件和文件夹,获取当前目录下所有的文件名称,以及每个文件的大小。
遍历文件的代码见代码清单 18-4:
函数 _FindFile 是个递归函数,入口参数是目录名。行6一78是一个循环,通过调用函数 FindNextFile 获得下一个文件或文件夹。行 69 ~ 73 判断 : 得到的如果是一个子文件夹,则继续调用函数 _FindFile 遍历下一个文件夹的内容,如果是文件,则调用函数 _ProcessFile 输出文件名及长度。
释放文件:
文件的释放比较容易。在宿主程序中,根据功能的不同分类,共有两种文件需要释放;
第一种:只有一个文件,它就是进程调度程序 _host.exe。该文件是事先通过将程序字节码 (前面生成的 C\1.txt 文件) 写和到数据段的方法嵌入宿主程序的。
另一种:是捆绑文件,这些文件是通过后面介绍的打补丁方法,把所有相关文件的数据附加到宿主文件的最后一个节来实现的。
1. 释放 _host.exe
由于进程调度程序所有的字节码均写入到了宿主程序的数据段中,数据定义如下:
所以,释放该文件非常容易,只需要将这些字节码原样写回文件即可,代码如下:
2. 释放捆绑文件:
补丁工具在打补丁时,将所有待捆绑的文件的相关信息记录到宿主程序的绑定列表中。这些信息包括: 每个文件在宿主中的偏移、文件大小和释放后所在目录位置及文件名。
所以,释放捆绑文件时,只需根据绑定列表的描述释放每一个文件即可,具体包括以下四步:
步骤1:确定捆绑文件在宿主中的偏移。
步骤2:确定捆绑文件的大小。
步骤3:确定该文件释放以后的绝对路径。
步骤4:执行释放操作。
释放捆绑文件的主要代码见代码清单 18-5:
行 47 一 94 根据绑定列表结构 BinderFileStruct 中定义的值,对每一个文件进行释放处理。因为文件在宿主程序中的起始地址和大小都有记录,文件内容唾手可得。
程序首先根据 BinderFileStructname 一次性完成文件所在目录的创建操作 (如果目录存在嵌套则循环创建名字中所有嵌套的子目录),然后在目录中用结构指定的名称新建文件,并调用函数 writeToFile 将宿主程序中指定位置、指定大小数据写入,从而完成对捆绑文件的释放工作。
宿主程序主函数:
宿主程序的主函数只有三个调用,这三个调用很明晰地展示出该函数的三个主要作用,它们依次是:
口 writeToFile (用以释放 _host.exe 文件)
口 releaseFiles (用以释放捆绑的文件)
口 _RunThread (用以调度执行程序的线程函数,执行的是 _host.exe 文件)
主函数代码如下所示:
EXE 捆绑器 bind.exe:
EXE 捆绑器的主要任务是,将要捆绑的文件附加到宿主程序 host.exe 文件的最后一节。这类似于 PE 进阶部分讲的补丁工具 bind.exe。除了打补丁,捆绑器还要完成对宿主程序 host.exe 中的两套绑定列表数据的修正,以便用于后期的释放捆绑文件和调度运行程序。要完成对补丁列表数据的修正,首先需要完成对绑定列表数据的定位。
绑定列表定位:
绑定列表在 host.exe 和要释放的 _host.exe 中均保留了一份,那么这个位置在宿主程序 host.exe 的哪个偏移处呢? 使用十六进制编辑器 FlexHex 打开 host.exe,查找 .data 中两个 0xFFFFFFFFFFFF 双字的位置(标志变量,仅做标志作用),其后紧跟着的就是绑定列表数据结构。
如下所示:(根目录由 c:\ql 改成 ql,所以位置与原文件不一样)
通过查找可以找到这两套绑定列表数据所在文件的偏移:
口 由 host.exe 维护的第一套绑定列表起始位置: 13a9h
口 由 _host.exe 维护的第二套绑定列表起始位置: 8be2h
最终运行时,绑定列表的数据结构排列看起来类似以下字节码所示:
加框部分是捆绑的文件个数,每个文件都由结构 BinderFileStruct 定义。结构中包含的字段在前面已经进行了介绍,如文件路径、是否可执行、文件长度、所在位置等。
捆绑步骤及主要代码:
捆绑器使用了本书第 17 章介绍的,在 PE 最后一节附加数据的方法;由于不需要调整指令指针的值,所以相对简单。
以下是对捆绑步骤的简单描述:
步骤1:打开宿主程序,将宿主程序映射到内存文件。获取要捆绑目录下所有文件的长度,并按照文件对齐粒度对齐。将现有宿主程序的大小加上对齐后的大小,重新映射宿主程序。
步骤2:将宿主程序,要捆绑的文件复制到新映射的内存文件中,记录每个文件的相对位置,同时,将这些信息写入宿主程序中的两处捆绑列表所在位置。
步骤3:修改最后一节的相关参数。
捆绑过程的主要代码见代码清单 18-6:
测试运行:
为了查看程序执行效果,请按照以下步骤进行测试:
步骤1:编译 _hostasm,生成 _host.exe 可执行代码。
步骤2:编译 hex2db.asm,运行 hex2db,生成 _host.exe 的字节码 1.txt。
步骤3:编译 host.asm,将上一步生成的 _host.exe 字节码加入到数据段中。
步骤4:通过十六进制查看器查看生成的 host.exe 字节码,查找两个捆绑表所在位置。记录这个位置并将结果写到 bind.asm 中 。
步骤5:编译 bind.asm 并运行,生成最终的 D:\桌面\host.exe 程序。
图 18-2 是对本节中部分文件进行捆绑的示意图。其中各按钮的解释如下:
开始测试:
小结:
本章通过在目标 PE 文件未尾追加补丁的方式 (参见第 17 章),演示了一种将用户指定目录下的所有文件捆绑在一起的编程方法。实例中的补丁程序完成了释放宿主程序、释放相关捆绑文件、运行调度程序、实施绑定列表中指定可运行 PE 文件的批量同步运行。
EXE 捆绑器可应用于对指定 目录或文件进行加密,也可用于对批量 EXE 文件的执行,特别是在升级多个补丁工具时比较有用。
WINDOWS+PE权威指南读书笔记(26)相关推荐
- WINDOWS+PE权威指南读书笔记(20)
目录 PE补丁技术 动态补丁: 进程间的通信机制: 读写进程内存: 目标进程枚举: 执行远程线程: 静态补丁: 整体替换 PE 文件: 整体替换 DLL 文件: 部分修改 PE 文件 嵌入补丁程序: ...
- WINDOWS+PE权威指南读书笔记(27)
目录 软件安装自动化 基本思路: 补丁程序 patch.exe: 执行线程函数: 简单测试: 消息发送器 _Message.exe: 窗口枚举回调函数: 调用窗口枚举函数: 向指定窗口发送消息: 消息 ...
- [读书][笔记]WINDOWS PE权威指南《零》PE基础
参考: https://zhuanlan.zhihu.com/p/47075612 https://docs.microsoft.com/zh-cn/windows/win32/debug/pe-fo ...
- mysql数据库权威指南_MySQL_MySQL权威指南读书笔记(三),第二章:MYSQL数据库里面的数 - phpStudy...
MySQL权威指南读书笔记(三) 第二章:MYSQL数据库里面的数据 用想用好MYSQL,就必须透彻理解MYSQL是如何看待和处理数据的.本章主要讨论了两个问题:一是SQL所能处理的数据值的类型:二是 ...
- MongoDB权威指南读书笔记——CRUD
插入并保存文档 插入是向MongoDB中添加数据的基本方法.可以使用Insert方法向目标集合插入一个文档:db.foo.insert({"bar" : "baz&quo ...
- HTTP权威指南读书笔记
<<HTTP权威指南>>读书笔记 第一部分:Web的基础 第1章:HTTP概述 主要内容 1.什么是HTTP 2.HTTP的基本组件 HTTP HTTP:HTTP(Hypert ...
- HTML5权威指南----读书笔记
<!DOCTYPE html> <html> <head><meta name = 'keywords' content="HTML5权威指南--- ...
- [读书][笔记]WINDOWS PE权威指南《一》PE的原理和基础 之 第一章 环境搭建及简单破解
文章目录 前言 前期准备 1.1 开发语言MASM32 1.1.1 设置开发环境 下载安装masm 环境变量配置 测试是否配置成功 1.1.2 开发第一个源程序HelloWorld.asm 配置 代码 ...
- 计算机网络和http权威指南 读书笔记
计算机网络笔记 网络层 网络层向上提供无连接的,尽最大努力交付的数据报服务 网络层不提供数据质量承诺 物理层使用的中间设备叫转发器repeater 数据链路层叫网桥bridge 网络层叫路由器rout ...
最新文章
- 【Java】基本二叉搜索树讲解
- php中implode()和explode()的应用
- Python FastApi:快速建立docker容器/挂载共享文件夹/导入导出
- linux中匿名用户怎么登陆_南京课工场IT培训:Linux中vsftpd服务配置(匿名,用户,虚拟用户)...
- DEVC++编译奇怪报错问题解决
- 定义字符串 && 字符串数组
- 另菜单或工具栏按钮失效的mfc处理方法
- linux下交叉编译ffmpeg,并加入H264编码支持
- 大数据时代,CRM帮助企业进行升级转型
- Google退出中国 Mark
- android切图规范,APP切图详细规范终极指南
- 好好搭搭机器人编程视频_机器人编程搭建 | 乐创世界学员作品展示第4期!
- 篇1:如何为FPGA选择合适的电源管理方案
- PLC中ST语言的几种程序流程控制语句
- 软件行业职位英文缩写介
- 计算机主机的是指什么,电脑基本操作包括哪些 电脑的基本的操作是指什么
- 做汽车工程师需要哪些计算机语言,做好汽车研发工程师,需要懂哪些?
- 国内外开源分析及实践
- vue2.x使用jodit富文本编辑器,并配置自定义字体和中文
- MICROSOFT HYPER-V SERVER 2019 许可协议
热门文章
- 超强阵容!2022亚马逊云科技 re:Invent 全球大会主题演讲嘉宾揭晓
- 1995-2022年中国经济政策不确定性指数
- 声音识别入门经典模型实践-基于大数据训练CNN14网络实现食物咀嚼声音识别
- 上海西门子培训-第四天(周三)
- Educational Codeforces Round 133 (Rated for Div. 2)
- python整理桌面,让桌面干净清爽井井有条。
- 光耦继电器工作原理与参数详解
- 制作一个简单的Android版的音乐播放器
- 安全siem_当时和现在的安全相关性是关于siem的可悲事实
- dw支持css3 html,通过DW设计网页时组织CSS的建议