PE文件之PE映像尺寸详解

 

pe映像就是pe文件加载到内存中的总尺寸,大部分情况下(也可以认为始终就是这样,因为没有资料说必须是这样,但经过试验发现总是为一固定值。为了此文的严谨性,此处用了“大部分情况下”)这个尺寸是以4096字节对其的,这取决于windows的内存机制,内存页的大小总是4096字节。这种情况在磁盘文件中也有所表现,我们可以在磁盘中新建一个txt文件,在里面写入一个字符“a” 并保存。这时我们查看一下此文件的大小,    这个为1字节,占用空间4096字节。即使增加此文件的大小,会发现文件所占空间始终以4096字节对齐。由此我们可以想象pe文件在内存中的情况。好了,以下转入正题。

要求,在任意一个能正确执行的pe文件中的最后一个节区添加任意大小任意形式的数据。添加完后pe文件能够正确执行。(注意这里所说的最后一个节区指的是SizeOfRawData不为0的最后一个街区,因为最后一节区可能包含未初始化数据,但它在文件中的大小为0)

添加过程就不说了,网上有很多例子。重点说一下添加完后pe中的一些属性需要修改一下

IMAGE_SECTION_HEADER .Misc.VirtualSize //节区真实大小

 IMAGE_SECTION_HEADER .SizeOfRawData //节区按文件对齐粒度对齐后的大小
 nt_head01->OptionalHeader.SizeOfImage  //整个pe文件在内存中的尺寸

假如节区的对齐粒度为4096字节,IMAGE_SECTION_HEADER .VirtualAddress + IMAGE_SECTION_HEADER .Misc.VirtualSize 为23234

则按节的对齐粒度对齐后为24576。所以nt_head01->OptionalHeader.SizeOfImage的取值范围为从24576-4096+1=20481到24576。比较简便的方法是nt_head01->OptionalHeader.SizeOfImage=IMAGE_SECTION_HEADER .VirtualAddress+IMAGE_SECTION_HEADER .Misc.VirtualSize

下面给出一个函数,功能在最后一个节区添加数据,输入参数文件名,写入数据指针,写入数据大小

DWORD zjSJ(char * wenJM,char * shuJi,DWORD size) //在可执行文件最后一个节区添加数据 文件名,写入数据指针,写入数据大小
{  //返回新增加内容在文件中的偏移量
 HANDLE h_file,h_map;
 LPVOID h_Memory=0;
 DWORD diZhi;
 DWORD fanHui; //返回偏移
 DWORD ySZ,xSZ,zjDX; //原节区大小,新节区大小,需增加大小
 IMAGE_DOS_HEADER * dos_head01;
 IMAGE_NT_HEADERS * nt_head01;
 IMAGE_SECTION_HEADER * section01;
 if(FALSE==ysWJ(wenJM,h_file,h_map,h_Memory)) //文件映射,映射后只用到h_Memory
  printCW("映射文件失败 zjSJ(char * wenJM\x0d\x0a");
 diZhi=(DWORD)h_Memory;
 dos_head01=(IMAGE_DOS_HEADER *)h_Memory;
 nt_head01=(IMAGE_NT_HEADERS *)(diZhi+(dos_head01->e_lfanew));
 section01=(IMAGE_SECTION_HEADER *)(nt_head01+1);
 section01+=nt_head01->FileHeader.NumberOfSections-1;  //指向最后一个节区
 if(section01->SizeOfRawData==0)
  printCW("最后一个节区大小为0,错误\x0d\x0a");
 ySZ=section01->SizeOfRawData;
 xSZ=align(section01->Misc.VirtualSize+size,nt_head01->OptionalHeader.FileAlignment);  //对齐函数
 zjDX=xSZ-ySZ;
 UnmapViewOfFile(h_Memory);  //增加大小前需关闭映射
 CloseHandle(h_map);
 SetFilePointer(h_file,0,0,FILE_END);
 SetFilePointer(h_file,zjDX,0,FILE_CURRENT);
 SetEndOfFile(h_file);         //增加文件大小
 h_map=CreateFileMapping(h_file,0,PAGE_READWRITE,0,0,0);

 if(h_map!=NULL)
 {
  h_Memory=MapViewOfFile(h_map,FILE_MAP_ALL_ACCESS,0,0,0);
  if(h_Memory==NULL)
   printCW("重新映射失败MapViewOfFile\x0d\x0a");
 }
 else
  printCW("重新映射失败CreateFileMapping\x0d\x0a");

 diZhi=(DWORD)h_Memory;
 dos_head01=(IMAGE_DOS_HEADER *)h_Memory;
 nt_head01=(IMAGE_NT_HEADERS *)(diZhi+(dos_head01->e_lfanew));
 section01=(IMAGE_SECTION_HEADER *)(nt_head01+1);
 section01+=nt_head01->FileHeader.NumberOfSections-1;
 fanHui=section01->PointerToRawData+section01->Misc.VirtualSize;
 RtlMoveMemory((void *)(diZhi+fanHui),shuJi,size); //写入文件

 section01->Misc.VirtualSize+=size;
 section01->SizeOfRawData=xSZ;
 nt_head01->OptionalHeader.SizeOfImage=section01->VirtualAddress+section01->Misc.VirtualSize;
 FlushViewOfFile(h_Memory,0);
 sfWJ(h_file,h_map,h_Memory); //释放映射文件
 return fanHui;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
软件加密技术内幕 要花时间看 第1章 PE文件格式深入研究 1.1 PE文件格式格式纵览 1.1.1 区块(Section) 1.1.2 相对虚拟地址(Relative Virtual Addresses) 1.1.3 数据目录 1.1.4 输入函数(Importing Functions) 1.2 PE文件结构 1.2.1 The MS-DOS头部 1.2.2 IMAGE_NT_HEADERS头部 1.2.3 区块表(The Section Table) 1.2.4 各种块(Sections)的描述 1.2.5 输出表 1.2.6 输出转向(Export Forwarding) 1.2.7 输入表 1.2.8 绑定输入(Bound import) 1.2.9 延迟装入数据(Delayload Data) 1.2.10 资源 1.2.11 基址重定位(Base Relocations) 1.2.12 调试目录(DebugDirectory) 1.2.13 NET头部 1.2.14 TLS初始化 1.2.15 程序异常数据 第2章 PE分析工具编写 2.1 文件格式检查 2.2 FileHeader和OptionalHeader内容的读取 2.3 得到数据目录(Data Dircetory)信息 2.4 得到块表(SectionTable)信息 2.5 得到输出表(ExportTable)信息 2.6 得到输入表(ImportTable)信息 第3章 Win32 调试API 3.1 Win32调试API原理 3.1.1 调试相关函数简要说明 3.1.2 调试事件 3.1.3 如何在调试时创建并跟踪一个进程 3.1.4 最主要的循环体 3.1.5 如何处理调试事件 3.1.6 线程环境详解 3.1.7 如何在另一个进程中注入代码 3.2 利用调试API编写脱壳机 3.2.1 tElock 0.98脱壳简介 3.2.2 脱壳机的编写 3.3 利用调试API制作内存补丁 3.3.1 跨进程内存存取机制 3.3.2 Debug API机制 第4章 Windows下的异常处理 4.1 基本概念 4.1.1 Windows下的软件异常 4.1.2 未公开的可靠吗 4.2 结构化异常处理(SEH) 4.2.1 异常处理的基本过程 4.2.2 SEH的分类 4.2.3 相关API 4.2.4 SEH相关数据结构 4.3 异常处理程序设计 4.3.1 顶层(top-level)异常处理 4.3.2 线程异常处理 4.3.3 异常处理的堆栈展开(Stack unwind) 4.3.4 异常处理程序设计中的几个注意事项: 4.4 SEH的简单应用 4.4.1 Win9x下利用SEH进ring0 4.4.2 利用SEH实现对自身的单步自跟踪 4.4.3 其它应用 4.5 系统背后的秘密 4.6 VC是如何封装系统提供的SEH机制的 4.6.1 扩展的EXCEPTION_REGISTRATION级相关结构 4.6.2 数据结构组织 4.7 Windows XP下的向量化异常处理(VEH) 第5章 软件加密技术 5.1 反调试技术(Anti-Debug) 5.1.1 句柄检测 5.1.2 SoftICE后门指令 5.1.3 int68子类型 5.1.4 ICECream子类型 5.1.5 判断NTICE服务是否运行 5.1.6 INT 1 检测 5.1.7 利用UnhandledExceptionFilter检测 5.1.8 INT 41子类型 5.2 反跟踪技术(Anti-Trace) 5.2.1 断点检测 5.2.2 利用SEH反跟踪 5.2.3 SMC技术实现 5.3 反加载技术(Anti-Loader) 5.3.1 利用TEB检测 5.3.2 利用IsDebuggerPresent函数检测 5.3.3 检查父进程 5.4 反DUMP技术(Anti
chm格式,目录如下。 第1章 PE文件格式深入研究 1.1 PE文件格式格式纵览 1.1.1 区块(Section) 1.1.2 相对虚拟地址(Relative Virtual Addresses) 1.1.3 数据目录 1.1.4 输入函数(Importing Functions) 1.2 PE文件结构 1.2.1 The MS-DOS头部 1.2.2 IMAGE_NT_HEADERS头部 1.2.3 区块表(The Section Table) 1.2.4 各种块(Sections)的描述 1.2.5 输出表 1.2.6 输出转向(Export Forwarding) 1.2.7 输入表 1.2.8 绑定输入(Bound import) 1.2.9 延迟装入数据(Delayload Data) 1.2.10 资源 1.2.11 基址重定位(Base Relocations) 1.2.12 调试目录(DebugDirectory) 1.2.13 NET头部 1.2.14 TLS初始化 1.2.15 程序异常数据 第2章 PE分析工具编写 2.1 文件格式检查 2.2 FileHeader和OptionalHeader内容的读取 2.3 得到数据目录(Data Dircetory)信息 2.4 得到块表(SectionTable)信息 2.5 得到输出表(ExportTable)信息 2.6 得到输入表(ImportTable)信息 第3章 Win32 调试API 3.1 Win32调试API原理 3.1.1 调试相关函数简要说明 3.1.2 调试事件 3.1.3 如何在调试时创建并跟踪一个进程 3.1.4 最主要的循环体 3.1.5 如何处理调试事件 3.1.6 线程环境详解 3.1.7 如何在另一个进程中注入代码 3.2 利用调试API编写脱壳机 3.2.1 tElock 0.98脱壳简介 3.2.2 脱壳机的编写 3.3 利用调试API制作内存补丁 3.3.1 跨进程内存存取机制 3.3.2 Debug API机制 第4章 Windows下的异常处理 4.1 基本概念 4.1.1 Windows下的软件异常 4.1.2 未公开的可靠吗 4.2 结构化异常处理(SEH) 4.2.1 异常处理的基本过程 4.2.2 SEH的分类 4.2.3 相关API 4.2.4 SEH相关数据结构 4.3 异常处理程序设计 4.3.1 顶层(top-level)异常处理 4.3.2 线程异常处理 4.3.3 异常处理的堆栈展开(Stack unwind) 4.3.4 异常处理程序设计中的几个注意事项: 4.4 SEH的简单应用 4.4.1 Win9x下利用SEH进ring0 4.4.2 利用SEH实现对自身的单步自跟踪 4.4.3 其它应用 4.5 系统背后的秘密 4.6 VC是如何封装系统提供的SEH机制的 4.6.1 扩展的EXCEPTION_REGISTRATION级相关结构 4.6.2 数据结构组织 4.7 Windows XP下的向量化异常处理(VEH) 第5章 软件加密技术 5.1 反调试技术(Anti-Debug) 5.1.1 句柄检测 5.1.2 SoftICE后门指令 5.1.3 int68子类型 5.1.4 ICECream子类型 5.1.5 判断NTICE服务是否运行 5.1.6 INT 1 检测 5.1.7 利用UnhandledExceptionFilter检测 5.1.8 INT 41子类型 5.2 反跟踪技术(Anti-Trace) 5.2.1 断点检测 5.2.2 利用SEH反跟踪 5.2.3 SMC技术实现 5.3 反加载技术(Anti-Loader) 5.3.1 利用TEB检测 5.3.2 利用IsDebuggerPresent函数检测 5.3.3 检查父进程 5.4 反DUMP技术(Anti-Dump) 5.5 文件完整性检验 5.5.1 CRC校验实现 5.5.2 校验和(Checksum) 5.5.3 内存映像校验 5.6 反监视技术(Anti-Monitor) 5.6.1 窗口方法检测 5.6.2 句柄检测 5.7 反静态分析技术 5.7.1 扰乱汇编代码 5.7.2 花指令 5.7.3 信息隐藏 5.8 代码与数据结合技术 5.9 软件保护的若干忠告 第6章 加壳软件编写 6.1 外壳编写基础 6.1.1 判断文件是否是PE格式的EXE文件 6.1.2 文件基本数据的读入 6.1.3 额外数据保留 6.1.4 重定位数据的去除 6.1.5 文件的压缩 6.1.6 资源区块的处理 6.1.7 区块的融合 6.1.8 输入表的处理 6.1.9 外壳部分的编写 6.1.10 将外壳部分添加至原程序 6.1.10 小结 6.2 加壳程序综合运用的实例 6.2.1 程序简介 6.2.2 加壳子程序(WJQ_ShellBegin()) 6.2.3 PE外壳程序 6.2.4 加进Anti技术 6.2.5 通过外壳修改被加壳PE 6.2.6 VC++调用汇编子程序 第7章 如何让壳与程序融为一体 7.1 序 7.1.1 为何需要壳和程序一体化 7.1.2 为阅读此章节需要的知识 7.1.3 基于此章节用的的例子程序说明 7.2 欺骗检查壳的工具 7.2.1 fi是如何检查壳的 7.2.2 欺骗fi 7.3 判断自己是否给脱壳了 7.3.1 判断文件尺寸 7.3.2 检查标记 7.3.3 外部检测(使用dll) 7.3.4 hook 相关的api(防止loader和调试api) 7.4 使用sdk把程序和壳溶为一体 7.4.1 sdk的意义 7.4.2 一个带sdk的壳 7.5 后记:关于壳和程序的思考 第8章 Visual Basic 6 逆向工程 8.1 简介 8.2 P-code传奇 8.3 VB编译奥秘 8.4 VB与COM 8.5 VB可执行程序结构研究 8.6 VB程序事件解读 8.7 VB程序图形界面(GUI)解读 8.8 VB程序执行代码研究 8.9 我们的工具 8.10 VB程序保护篇 附录A 在Visual C++中使用内联汇编 附录B 在Visual Basic中使用汇编
U盘启动PE可以用来启动计算机,以便进行系统维护和恢复操作。TIB映像文件是由Acronis True Image创建的系统备份文件,它包含了整个系统的完整镜像。下面是使用U盘启动PE还原TIB映像文件的步骤: 1.准备一个空的U盘,确保其容量足够存储TIB映像文件PE工具。 2.下载一个适合的PE启动工具,例如EasyUEFI或Rufus等,将其安装在本地计算机上。 3.用选定的PE启动工具创建一个可启动的U盘。这个步骤可能会涉及选择一个PE映像文件(ISO文件)和指定U盘的分区格式。 4.将TIB映像文件复制到U盘的根目录下。确保复制过程顺利完成。 5.将U盘插入需要还原的计算机的USB接口中。 6.将需要还原的计算机重启,并进入BIOS设置界面。 7.在BIOS设置界面中,将U盘设置为首选启动设备。保存设置并退出。 8.计算机重新启动后,系统将从U盘中的PE工具启动。 9.在PE环境中,找到并打开Acronis True Image软件。 10.在Acronis True Image界面中,选择“还原”功能,并浏览到U盘的根目录找到需要还原的TIB映像文件。 11.选择恢复选项,如目标磁盘、目标分区等。 12.点击“开始”按钮开始还原操作。请谨慎选择还原目标,以免损坏数据。 13.等待还原过程完成,这可能需要一段时间,取决于TIB映像文件的大小和计算机性能。 14.还原完成后,从U盘中拔出U盘,并重启计算机。 15.计算机重新启动后,将进入恢复后的系统。 这是使用U盘启动PE还原TIB映像文件的步骤。请注意,操作系统PE工具和Acronis True Image软件的版本可能会有所不同,具体步骤可能会略有差异。在操作过程中,请确保备份重要数据,并小心操作,以免造成数据丢失或系统损坏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值