Windows系统的可执行PE文件的壳的设计过程
- 格式:docx
- 大小:402.45 KB
- 文档页数:10
PE,Windows PE = Windows PreInstallation Environment,Windows预安装环境,微软在2002年7月22日发布,带有限服务的最小Win32子系统,基于以保护模式运行的Windows XP Professional内核。
简单来说,PE就是一个小型的系统,它所占的空间很小,不到400KB,开机后一直保存在内存中,只要不断电就可以一直运行着。
但功能较少,因此一般是作为安装其他操作系统的环境使用。
比如说在PE系统上安装windows XP的GOST文件,那样一个操作系统就可以在几分钟之内安装好了。
有一次帮朋友装了win7之后,在激活时不小心中毒了,结果系统一直进不去,没办法了,就想拿安装盘先装个Vista的系统先进去,再重装win7(因为我没有win7的安装盘,有的只是win7的解压文件)。
后来发现他的光驱竟然坏了,安装盘读不出来,当然没办法装Vista了。
在这时候PE就派上大用场了。
先把PE做进U盘里,那么就可以用U盘来启动电脑,进入之后就可以安装win7了。
PE的制作很简单,但是在制作过程中会把U盘格式化,所以事前得做好备份。
给大家介绍一个工具——通用PE工具箱(支持sata 硬盘的WinPE-支持U盘版) V1.9.6 简体中文版-XP内核。
这个工具简单快捷,容易上手,只需几步就可以完成PE的制作了。
可以通过以下网址下载/soft/down/soft_13467.html。
这可不是做广告哦,只是希望能帮到大家,有好东西当然要share 了。
制作好PE之后,插上U盘,开机,一直不停摁Esc键,然后选择USB 2.0就进入PE系统了。
Windows PE的全称为Windows Preinstallation Environment(Windows预安装环境),它基于Windows XP内核,能引导系统、读写FAT32/NTFS格式的分区、访问网络,具有图形界面的特点很适合做系统崩溃后的救急平台,用来维护系统。
遗憾的是,普通用户没有得到微软的授权,无法使用Windows PE。
现在好了,我们可以利用Bart’s PE Builder打造一个可引导系统的CD或DVD光盘。
它的功能类似于Windows PE,引导系统后可以创建32位的图形界面操作环境,支持网络和远程管理功能,支持FAT32、NTFS、CDFS等各种分区格式,采用800×600的分辨率,可用于诊断或修复系统。
目前最新版本支持Windows XP、Windows Server 2003。
步骤1:准备工作首先在硬盘上腾出一个剩余空间较大的分区(至少有300MB剩余空间),预备存放ISO 镜像文件或刻录临时文件,将下载回来的pebuilder3015.zip文件解压缩,然后双击运行pebuilder.exe文件,在弹出的窗口中点击“Next”按钮进入下一步。
步骤2:设置文件源进入图1窗口,这里需要设置文件源,各个选项的含义如下:(1)Path to Windows installation files:Windows安装文件路径可以选择安装光盘,也可以选择本机硬盘或网络(这需要事先将安装光盘中的文件复制到硬盘中),Bart’s PE Builder支持Windows XP Home/Professional、Windows Server 2003 Web Edition/Standard Edition/Enterprise Edition等版本,可惜的是不支持Windows 2000。
(2)Path to your already installed Windows:本机或网络中已存在的Windows系统这里显示了从本机所侦测到的Windows系统,例如“C:\WINDOWS”,一般不用更改,当然你也可以选择网络中的其他Windows系统,但需要说明的是必须与“Path to Windows installation files”中的系统版本一致,主要是“\i386\ntdll.dll”文件的版本必须一致。
微软原版win10pe制作流程微软原版Win10PE制作流程Win10PE是基于Windows 10操作系统开发的一款紧凑、强大的预安装环境工具。
通过制作Win10PE,用户可以在没有安装操作系统的情况下,使用一些基本的功能和工具,进行系统修复、数据恢复、病毒清除等操作。
下面将详细介绍微软原版Win10PE的制作流程。
1. 准备工作我们需要准备一台装有Windows 10操作系统的电脑,确保系统是最新版本。
同时,我们还需要准备一个U盘或者光盘作为介质,容量至少为8GB。
另外,需要下载Win10PE的制作工具——“Win10PESE”,该工具可以从官方网站或者其他可靠的下载渠道获取。
2. 安装Win10PESE将下载好的Win10PESE安装文件解压缩到指定的目录下,然后运行“Win10PESE.exe”文件。
在弹出的窗口中,选择合适的语言和目标文件夹,点击“确定”按钮开始安装。
3. 创建Win10PE安装完成后,打开Win10PESE工具。
在左侧的菜单栏中,选择“WinBuilder”选项。
在主界面上方的工具栏中,点击“Play”按钮,开始创建Win10PE。
4. 添加源文件在弹出的窗口中,选择“Create a new project”选项,并为项目命名。
然后,点击“Next”按钮。
接下来,点击“Add”按钮,选择需要添加的源文件,包括Windows 10安装盘的ISO镜像或者操作系统文件夹。
点击“Next”按钮确认选择。
5. 配置设置在配置设置界面中,可以根据需要进行个性化设置。
可以选择是否添加驱动程序、添加网络支持、设置显示语言等。
点击“Next”按钮确认配置。
6. 构建Win10PE在构建界面中,点击“Play”按钮开始构建Win10PE。
该过程可能需要一定的时间,请耐心等待。
构建完成后,会在目标文件夹中生成Win10PE的ISO镜像文件。
7. 制作启动介质将准备好的U盘或者光盘插入电脑,打开制作启动介质的工具,选择ISO镜像文件和目标设备(U盘或光盘),点击“开始制作”按钮开始制作启动介质。
pe文件框架结构PE文件是指Windows操作系统平台下的可执行文件,它是一种二进制程序文件,在Windows操作系统中扮演着非常重要的角色。
因此,了解PE文件的框架结构对于了解Windows操作系统的关键机制和安全性方面有很大的帮助。
本文将分步骤阐述PE文件框架结构。
一、DOS头DOS头是PE文件结构的开始部分,用于在早期版本的Windows操作系统上运行应用程序。
DOS头包含了一些用于MS-DOS的信息和可执行程序的信息,比如可执行程序的起始地址和执行入口点。
二、PE文件头PE文件头是指非常关键的PE文件头部区域,包含了PE文件的组织结构信息和代码在内存中的布局信息。
PE文件头由四部分组成,分别是文件标识头(Signature),文件头部(File Header),可选头部(Optional Header),数据目录(Data Directory)。
三、节表在PE文件头部区域中,还有一块重要的信息是节表。
节表用于存储PE 文件中的区段信息,包括代码段、数据段、资源段和导出等信息。
在代码段、数据段和资源段中,存储着PE文件的程序和数据,节表为了对各个节进行可控制的访问,便于程序的控制和调试。
四、数据目录PE文件头部区域中还包含了一个数据目录,在32位PE中,数据目录通常有16个数据目录,用于存储PE文件中的各种信息,如导入表、导出表、资源表、重定位表等等。
五、代码段代码段是PE文件的主要部分,它包含了PE文件的执行代码和程序逻辑,是PE文件的核心内容。
代码段的格式主要是二进制代码,对程序的执行有很大的影响。
六、数据段数据段主要用来存放程序中要用到的各种数据,包括全局变量、局部变量和常量等。
数据段会经常开辟空间以存储函数中的局部变量和运行时生成的各种实例对象。
综上,PE文件是Windows操作系统平台下的可执行文件,其框架结构主要由DOS头、PE文件头、节表、数据目录、代码段和数据段组成。
了解PE文件的结构以及各个部分之间的关联是非常重要的,既有助于我们更好的理解操作系统机制,又有助于我们在软件开发和安全领域中进行有效的分析和优化。
如何打造⾃⼰的pe呢?微软官⽅WinPE的制作流程临近年关,⼯作压⼒辣么⼤,⼤家是不是应该⼿下留情点啊,让⼩编也轻松两天能在上班的时候耍耍《守望先锋》什么的(不是,总编您听我说,我的意思是想咱们的公众号来点新鲜的内容,不要整天系统系统啥的,太技术流),唉,还是太年轻,太天真了!你们这些懒惰的家伙,真是够了啊,明天是不是想让⼩编把做好的爱好者版WinPE盘快递给你们啊?算了,既然总编碰巧看到,⼜有好多⼩伙伴想要学习微软官⽅PE的制作流程,⼩编只能继续码字了!⼯具下载软件并不⼤,仅1.4MB左右,运⾏后会提⽰是直接安装在电脑中还是单独下载。
如果是在正在使⽤的电脑上制作PE 维护盘,就选上⾯的安装,需要分享或在其他电脑上安装的话,就选下⾯的。
随后的选项“Windows预安装环境(Windows PE)”是⼀定要勾选的,⾄于其他的⼯具看个⼈喜好了。
之后就进⼊漫长的安全下载安装时间,2.9GB左右的⽂件对⽹速是个不⼩的考验,建议晚上睡觉前准备好下载⼯作,明天再进⼊制作维护的盘的环节。
现在点击开始菜单,在“Windows Kits”程序组下,找到“部署和映像⼯具环境”,以管理员⾝份运⾏,随后出现命名提⽰符界⾯,开始制作流程吧!因为涉及较多命令操作,建议⼤家在利⽤电脑微信端,⽤浏览器打开页⾯将命令完全复制下来,避免代码执⾏出错。
⾸先输⼊以下命令开始提取WinPE镜像,此时会刷屏,等出现结果显⽰后再进⾏操作。
copype amd64 C:\WinPE_amd64接下来使⽤命令加载WinPE镜像Dism /Mount-Image /ImageFile:”C:\WinPE_amd64\media\sources\boot.wim” /index:1 /MountDir:”C:\WinPE_amd64\mount”就会在C盘下⽣成WinPE的⽂件夹,如果你想将它存放在其他磁盘位置,将上两段命令中的“C:”更改其其他位置即可,建议直接在各盘符下直接⽣成WinPE⽂件夹,不要存放在有中⽂路径或⼦⽂件夹中,容易时命令变得复杂出错。
PE文件结构详解(二)可执行文件头在PE文件结构详解(一)基本概念里,解释了一些PE文件的一些基本概念,从这篇开始,将详细讲解PE文件中的重要结构。
了解一个文件的格式,最应该首先了解的就是这个文件的文件头的含义,因为几乎所有的文件格式,重要的信息都包含在头部,顺着头部的信息,可以引导系统解析整个文件。
所以,我们先来认识一下PE文件的头部格式。
还记得上篇里的那个图吗?DOS头和NT头就是PE文件中两个重要的文件头。
一、DOS头DOS头的作用是兼容MS-DOS操作系统中的可执行文件,对于32位PE文件来说,DOS所起的作用就是显示一行文字,提示用户:我需要在32位windows上才可以运行。
我认为这是个善意的玩笑,因为他并不像显示的那样不能运行,其实已经运行了,只是在DOS上没有干用户希望看到的工作而已,好吧,我承认这不是重点。
但是,至少我们看一下这个头是如何定义的:我们只需要关注两个域:e_magic:一个WORD类型,值是一个常数0x4D5A,用文本编辑器查看该值位‘MZ’,可执行文件必须都是'MZ'开头。
e_lfanew:为32位可执行文件扩展的域,用来表示DOS头之后的NT头相对文件起始地址的偏移。
二、NT头顺着DOS头中的e_lfanew,我们很容易可以找到NT头,这个才是32位PE文件中最有用的头,定义如下:下图是一张真实的PE文件头结构以及其各个域的取值:Signature:类似于DOS头中的e_magic,其高16位是0,低16是0x4550,用字符表示是 ‘ PE’。
IMAGE_FILE_HEADER是PE文件头,C语言的定义是这样的:每个域的具体含义如下:Machine:该文件的运行平台,是x86、x64还是I64等等,可以是下面值里的某一个。
umberOfSections:该PE文件中有多少个节,也就是节表中的项数。
TimeDateStamp:PE文件的创建时间,一般有连接器填写。
PE文件结构详解1 摘要Windows NT 3.1引入了一种名为PE文件格式的新可执行文件格式。
PE文件格式的规范包含在了MSDN的CD中(Specs and Strategy, Specifications, Windows NT File Format Specifications),但是它非常之晦涩。
然而这一的文档并未提供足够的信息,所以开发者们无法很好地弄懂PE格式。
本文旨在解决这一问题,它会对整个的PE文件格式作一个十分彻底的解释,另外,本文中还带有对所有必需结构的描述以及示范如何使用这些信息的源码示例。
为了获得PE文件中所包含的重要信息,我编写了一个名为PEFILE.DLL的动态链接库,本文中所有出现的源码示例亦均摘自于此。
这个DLL和它的源代码都作为PEFile示例程序的一部分包含在了CD中(译注:示例程序请在MSDN中寻找,本站恕不提供),你可以在你自己的应用程序中使用这个DLL;同样,你亦可以依你所愿地使用并构建它的源码。
在本文末尾,你会找到PEFILE.DLL的函数导出列表和一个如何使用它们的说明。
我觉得你会发现这些函数会让你从容应付PE文件格式的。
2 介绍Windows操作系统家族最近增加的Windows NT为开发环境和应用程序本身带来了很大的改变,这之中一个最为重大的当属PE文件格式了。
新的PE文件格式主要来自于UNIX操作系统所通用的COFF规范,同时为了保证与旧版本MS-DOS及Windows操作系统的兼容,PE文件格式也保留了MS-DOS中那熟悉的MZ头部。
在本文之中,PE文件格式是以自顶而下的顺序解释的。
在你从头开始研究文件内容的过程之中,本文会详细讨论PE文件的每一个组成部分。
很多解决PE文件格式的工作和直接观看数据有关。
例如,要弄懂导入地址名称表是如何构成的,我就得同时查看.idata段头部、导入映像数据目录、可选头部以及当前的.idata段实体,而EXEVIEW.EXE就是查看这些信息的最佳示例。
PE文件壳的设计过程标题:pe文件壳的设计过程作者:baccon(PEDIY论坛),或 chenxiang(软件发布者)时间:2013年10月26日星期六今天来讨论一下PE文件的壳,壳主要用于PE文件的商业保护,以此达到软件不被暴掉的可能性,随着破解知识的普及,软件的壳也愈加复杂才可勉强不被暴。
壳的一个加载过程在许多书上都将过,这里就以图来复习一次:这张图其实是一种情形,原程序被压缩引擎压过,还可以是在EXE文件上直接加壳不压缩,这样到省了壳的大小,但原EXE代码没有压缩,反而变大了一点,还有一种是在EXE文件的节区的空隙中添加,这样压缩过的文件和原文件一样大,但是对节区的大小有要求。
这是三种常规的加壳思路。
如果单单是加一个简单的壳,象罗云彬的《windows32位环境下的汇编语言程序设计》中的那个AddCode就是一个典型代表。
主要步骤如下:首先在节区表上添加一个节区表信息,把代码写到文件的最后面(已经与新的节区表信息对应),主要注意一下,节区的SectionAlignment和FileAlignment,按照这两个参数写节区信息表,跳到节区表中对应文件偏移位置处,写入代码,代码在节区写不满,要填充0,保持文件对齐的值,通常200,最后是收尾工作,PE文件的NumberOfSections加1,SizeOfImage要加上新节区按照SectionAlignment的值对齐后的大小的值,SizeOfHeaders要按照FileAlignment对齐的,如果加上一个IMAGE_SECTION_HEADER,大小不过FileAlignment,就可能不用修改其值的,还有个SizeOfCode是添加代码的大小,就是将含有代码的节区的大小值相加(这个值已经按FileAlignment对齐,载节区表中)。
刚才讲的是上面说的第二个思路,还有两个思路,在下面的附件中有个与此类似的思路的一个,还有个是第三个思路的方法。
上面的这个方法实现是比较简单的,但是这种方法没有什么程序保护功能,下面讲一下又保护功能的方法。
要实现保护功能,可以保护的内容常见的有,导入函数,导出函数,代码段,数据段等。
1.如何实现导入函数的保护。
在PE文件的头中的DataDirectory有个导入函数的列表,指定RVA和大小,许多PE文件分析,如PEID,LoadPE,还有我的PE Scanner,都是根据这里找到函数的信息的。
这个RVA,在PE文件加载后,会指定到一个IMAGE_IMPORT_DESCRIPTOR,这个结构如下:typedefstruct_IMAGE_IMPORT_DESCRIPTOR {union {DWORD Characteristics; // 0 for terminatingnull import descriptorDWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)} DUMMYUNIONNAME;DWORD TimeDateStamp; // 0 if not bound,// -1 if bound, and real date\time stamp// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)// O.W. date/time stamp of DLL bound to (Old BIND)DWORD ForwarderChain; // -1 if no forwardersDWORD Name;DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)} IMAGE_IMPORT_DESCRIPTOR;typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;在这个结构体中OriginalFirstThunk和FirstThunk虽然不指同一位置,但是它们指向的ThunkData所知的位置是相同的,等于一个是另一个的备份,在Windows的装载器加载时,会将FirstThunk指向的所有的ThunkData替换成ThunkData指向的函数的真正的地址,如下图:在程序未加载时,可以看到磁盘文件如下:402014的位置是000020F4,这个是RVA,在看这个ThunkData指向哪里,如下:可以看出再过去两个字节就是ExitProcess的函数名,这是个IMAGE_IMPORT_BY_NAME的结构,前两个字节是HINT,是个无关紧要的WORD字段,大致熟悉了一下PE的加载原理,如果自己写保护导入表的保护的话,这些过程需要自己代码“手动”完成。
再来看一下PE文件加载后的情形,用windbg打开文件。
这些402014的位置已经被填充数据,而不再是原来的RVA,000020F4,JMP DWORD DS:[402014]也就成了:JMP 754879f8再看看754879f8处的数据:可以看到这里到了Kernel32中的ExitProcessStub,整个加载过程也就明了了。
2.如何加载“藏”的导入表因此如果要保护输入表里的函数,就必须把原来的导入表的那些信息(包括IMAGE_IMPORT_DESCRIPTOR和一系列的ThunkData)“藏”起来,自己定义一个IMAGE_IMPORT_DESCRIPTOR和ThunkData,用于定义自己必须的API函数,这样自己就不用再堆中找Kernel32的基址,查导出函数等一系列的复杂工作,比如自己定义两个位于Kernel32.dll中的函数,LoadLibraryA和GetProcAddressA,自己把原来的导入函数信息表“藏”了起来,自己在程序加载时要把找出来,并且在FirstThunk中找函数,因为导入表被“藏”,PE的装载器没有为程序将ThunkData 的值换成居如754879f8等这样的真正的函数地址,所以自己要找函数(有按序号导入的和按名称导入的两种),需要注意的是若找到的函数是序号导入的话,需去掉高位用于检测的1(即与80000000H检测),然后直接将其作为函数的名称,用GetProcAddressA来获取地址,DLL的名称获取更加简单,直接,用Name的RVA加基址,即可,获取DLL名称的字符串,可用LoadLibraryA,来加载。
通过上面这些步骤,使比如先前的 402014的这些位置,自己用LoadLibrary加载Kernel32.dll,获取ExitProcess的地址,并且把得到的地址填到402014的位置处,这样ExitProcess函数才得以顺利执行,其他的函数其次类推,要把所有的IMAGE_IMPORT_DESCRIPTOR找遍,保证所有的函数地址都被填到恰当的位置。
2.关于加密数据和代码上面的这些方法,其实只保护了导入表,但只要有点反汇编的人都能知道前面的代码,因为程序的入口虽改变,但是代码任在那里,可以改变偏移即可看到,如下两个对比图:没有加密代码段的情况(start处是我的代码):加密代码段的情况(start是我的代码):加密代码段的情况下,需要在自己的代码里有揭秘代码的内容,以便代码得以执行,我的这个例子只是简单的转位,rol,ror,所以揭秘相当简单,如果要复杂的话,可以用压缩引擎压缩代码,这样还能更多节省空间,还可以用其他的密码学原理来加密等,具体细节,自由发挥。
但是这种加密还是不太十分靠得住的,ASPack,UPX,Pecompact等,还有附件中我自己编写的这个,用的都是这种方法。
这种类型壳非常好脱,下面举个例子:这是个ASPack的壳,刚开始的时候,断点处push后面的还是0,到此处已经变为004013da,这个正是原来程序的ep,其实ASPack前面的工作跟我的那个壳差不多,无非就是填充ThunkData和揭秘数据。
到此处,可见,ASPack吧所有的ThunkData都填充了,用OllyDump顺便dump下,在看一下,导入表信息,借助LoadPE将其中的NtDllDefWindowProc_A改成DefWindowProcA,程序脱壳完成。
这种壳之所以好脱,是因为,外壳代码,在程序揭秘后又将代码写到原来的位置,如果设计一种机制,这个机制是每次需要执行代码时,先读取加密的数据,揭秘一条指令长的数据,然后再执行,然后再取,再揭秘,在执行,这个循环的过程一直执行下去,直到最后,而且用的空间只是一个指令长的地址空间,后面执行的代码覆盖前面的代码,短的指令,填充90H(nop),这样揭秘的数据不会记录,提高了安全性,但这个方法,需要面临下个数据的指令的长度,就需要个小型反汇编引擎嵌在壳上,还有eip改动到的位置等的问题,所以就复杂点了。
3.虚拟机的构想上面的问题引起这个问题的产生,虚拟机就是模仿CPU指令执行,I/O环境等的一种机制,这种机制在虚拟机软件较常见,如:vmware,vbox等,壳也可以用虚拟机这种机制,只不过他主要模仿CPU的指令,也可模仿I/O环境等,将上面的机制设置的复杂一点,如:pop eax,转到虚拟机执行,变成,deceax,inceax转到虚拟机变成push eax,还可以更复杂,自己模拟一个I/O环境,每次IN 45H,表示eax加1,每次IN 46H表示eax减去1,IN 50H表示ebx加1等等。
虚拟机还可以参入密码学加密机制,等。
总的来说,内容较多,涉及范围较广,而且若要设计起来,将是一个大的工程,估计壳的添加代码也较多。
4.最后一点补充如果加壳的程序是个随机加载基址的程序,可能会影响到自己的揭秘后的代码正常执行,这时需要修正PE,去掉.reloc的节,主要是要将DataDirectory的随机加载的数据项清零,NumberOfSections减掉1,修正SizeOfHeaders,也有可能不需要修正,但是最重要的是要把OptionalHeader中的DllCharacteristics的值清零。
附件中有两个是向程序的空余间隙添加代码,因此程序的空余间隙必须大一点,否则会失败。
完。