热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PE文件加区块

作者:神杀中龙microsoftxiao163.com说明:根据PE文件格式原理书写1.在PE信息浏览器基础上改为增加区段工具2007-5-12#include

//
//作者: 神杀中龙 microsoftxiao@163.com
//说明: 根据PE文件格式原理书写
//1. 在PE信息浏览器基础上改为增加区段工具 2007-5-12

#include
#include
#include
#include
using namespace std;

#define SAFE_DELETE(p) { if((p)!=NULL) { delete (p); (p) = NULL; }}

bool InsertSection(BYTE *decBuf, struct _stat& st, char** argv);   // 插入区块
bool FillZeroArea(FILE* decFile, ULONG VirtualSize, ULONG VirtualAddress);                       // 填充全0区域
bool HelpInfo(char** argv);

struct _stat ST;
FILE* viewDecFile = NULL;
bool  g_bHaveSetVSizeaAddress = false;          // 是否设置插入段大小和地址

// Entry
int main(int argc, char** argv)
{
 HelpInfo(argv);
 srand(time(NULL));
 if(argc <2) {
  printf("Welcome to use  欢迎使用 ^_^ 神杀中龙 microsoftxiao&#64;163.com\n");
  
 } else {
  if(argv[2])
  {
   printf("Have VSize and VAddress\n");
   g_bHaveSetVSizeaAddress &#61; true;
  } else {
   printf("Not set VSize and VAddress(VSize默认大小4KB(0x1000)\n");
   g_bHaveSetVSizeaAddress &#61; false;
  }
  viewDecFile &#61; fopen(argv[1], "rb");
  BYTE *buf &#61; NULL;
  
        ::_stat(argv[1], &ST);
  buf &#61; new BYTE[ST.st_size];
        fread(buf, 1, ST.st_size, viewDecFile);
  fclose(viewDecFile);
  InsertSection(buf,  ST, argv);
       
  SAFE_DELETE(buf);
 }
 return 0;
}

// 插入区块
bool InsertSection(BYTE *decBuf, struct _stat& st, char** argv)
{
 cout<<"计算区块各参数:";
 // 插入区块&#xff0c; 先获取OEP
 const int offDOSStub &#61; 0x3C;
 long      off_elfanew &#61; 0;   // 根据类型直接读出即可。
    char  szPEHead[5];           // PE00
 WORD  Machine &#61; 0;           // CPU类型   
 DWORD AddressOfEntryPoint &#61; 0; // 程序执行入口RVA
 DWORD ImageBase &#61; 0;         // 程序默认装入基址
    WORD  SubSystem &#61; 0;         // 子系统&#xff0c; 控制台或其他
    DWORD SizeOfImage &#61; 0;       // 内存中整个PE映像大小
    WORD  SizeOfOptionalHeader &#61; 0; // 可选映像头大小
    DWORD SectionTableHeaderValue &#61; 0;  // 块表首值  PE(Base) &#43; 0x12 &#43; SizeOfOptionalHeader
    WORD NumberOfSections        &#61; 0;  // 块(Section)个数
 DWORD SectionsLength          &#61; 0;  // 块长度

 
   
 memcpy(&off_elfanew, &decBuf[offDOSStub], sizeof(long));
 //fwrite(&off_elfanew, 1, sizeof(off_elfanew), test);
 memcpy(szPEHead, &decBuf[off_elfanew], sizeof(szPEHead));
 //fwrite(szPEHead, 1, sizeof(szPEHead)-1, test);
 memcpy(&Machine, &decBuf[off_elfanew &#43; 0x4], sizeof(WORD));
 if(Machine &#61;&#61; 0x14C)
   printf("CPU Intel i386或以上系列: %X\n", Machine);
    memcpy(&AddressOfEntryPoint, &decBuf[off_elfanew &#43; 0x28], sizeof(DWORD));
 printf("程序入口点: 0x0%X\n", AddressOfEntryPoint);
    memcpy(&ImageBase, &decBuf[off_elfanew &#43; 0x34], sizeof(DWORD));
 printf("镜像基址: 0x0%X\n", ImageBase);
    memcpy(&SubSystem, &decBuf[off_elfanew &#43; 0x5C], sizeof(WORD));
 switch(SubSystem)
 {
 case 0:
  printf("未知子系统\n");
  break;
 case 1:
        printf("不需要子系统: 0x0%X\n", SubSystem);
  break;
 case 2:
  printf("图形接口子系统(GUI): 0x0%X\n", SubSystem);
  break;
 case 3:
  printf("控制台子系统(Console or DOS or CUI): 0x0%X\n", SubSystem);
  break;
 case 5:
  printf("OS/2字符子系统: 0x0%X\n", SubSystem);
  break;
 case 7:
  printf("POSIX字符子系统: 0x0%X\n", SubSystem);
  break;
 
 default:
  printf("未知子系统\n");
  break;
 }
 memcpy(&SizeOfImage, &decBuf[off_elfanew &#43; 0x50], sizeof(DWORD));
 printf("内存镜像大小: 0x%X\n", SizeOfImage);
    memcpy(&SizeOfOptionalHeader, &decBuf[off_elfanew &#43; 0x14], sizeof(WORD));
 printf("可选映像头大小: %d字节(%X)\n", SizeOfOptionalHeader,SizeOfOptionalHeader);
    memcpy(&SectionTableHeaderValue, &decBuf[off_elfanew &#43; 0x18 &#43; SizeOfOptionalHeader], sizeof(DWORD));
 printf("块表首值: %X\n", SectionTableHeaderValue);
    memcpy(&NumberOfSections, &decBuf[off_elfanew &#43; 0x06], sizeof(WORD));
 printf("块(Sections)个数: %X\n", NumberOfSections);
   
 IMAGE_SECTION_HEADER  tISH;   // 块表结构实例
 ZeroMemory(&tISH, sizeof(tISH));
 printf("块表项结构大小: %d字节\n", sizeof(tISH));
 int t_totalSectionLength &#61; sizeof(tISH) * NumberOfSections;
    printf("总块表长度: %d字节(%X)\n", t_totalSectionLength, t_totalSectionLength);
    int t_InsertPosition &#61; 0x18 &#43; SizeOfOptionalHeader &#43; t_totalSectionLength;
 printf("插块表项偏移位置: 0x0%X\n", t_InsertPosition);
   

 char szNewFileName[260];
 sprintf(szNewFileName, "__666%d_.exe",rand()%10000);
 FILE* test &#61; fopen(szNewFileName, "wb");
 fwrite(decBuf, 1, ST.st_size, test);
 
 // 加区块
 if(test) {
   strncpy((char*)tISH.Name, ".pediy", sizeof(tISH.Name));
   tISH.Misc.VirtualSize &#61; 0x3E000;          // 4KB
   tISH.SizeOfRawData &#61; 0x3E000;
   tISH.VirtualAddress &#61; st.st_size;          // 改地址应该为增加的一个空闲区  应该是先加区段&#xff0c;然后再改入口点 此地址作为最后的偏移量
   tISH.PointerToRawData &#61; st.st_size;             // 行号表中行号的数目
   if(g_bHaveSetVSizeaAddress)
   {
   tISH.Misc.VirtualSize &#61; atoi(argv[2]);          // 4KB
   tISH.SizeOfRawData &#61; atoi(argv[2]);
   }
   tISH.PointerToRelocations &#61; 0;         // 在OBJ文件中使用&#xff0c; 重定位的偏移
   tISH.PointerToLinenumbers &#61; 0;         // 行号表的偏移(供调试用)
   tISH.NumberOfRelocations &#61; 0;          // 在OBJ文件中使用&#xff0c;重定位项目数
   tISH.NumberOfLinenumbers &#61; 0;
   tISH.Characteristics &#61; 0xE0000020;     // 块属性&#xff0c; 表示包含执行代码、可读写并可执行。

   fseek(test, 0, SEEK_SET);
  
      fseek(test, off_elfanew &#43; t_InsertPosition, SEEK_SET);
  
   fwrite(&tISH, 1, sizeof(tISH), test);   // 写入块结构
   fseek(test, off_elfanew &#43; 0x06, SEEK_SET);
   NumberOfSections&#43;&#43;;
   fwrite(&NumberOfSections, 1, sizeof(NumberOfSections), test);   // 修改块数目

   SizeOfImage &#43;&#61; tISH.SizeOfRawData;     // 对齐后的大小?
   fseek(test, off_elfanew &#43; 0x50, SEEK_SET);  // 定位
   fwrite(&SizeOfImage, 1, sizeof(SizeOfImage), test);

   FillZeroArea(test, tISH.Misc.VirtualSize, tISH.VirtualAddress);          //在指定地址后写零
 }
 
 
 fclose(test);
 
 remove(argv[1]);
 rename(szNewFileName, argv[1]);
 return 0;
}

// 填充全零区
bool FillZeroArea(FILE* decFile, ULONG VirtualSize, ULONG VirtualAddress)
{
    fseek(decFile, VirtualAddress, SEEK_SET);
 BYTE *szBuf &#61; NULL;
 szBuf &#61; new BYTE[VirtualSize];
 strncpy((char*)szBuf, "Z", VirtualSize);
 fwrite(szBuf, 1, VirtualSize, decFile);
 BYTE tmp &#61; 0;
 fseek(decFile, VirtualAddress, SEEK_SET);
 fwrite(&tmp, 1, sizeof(tmp), decFile);
 SAFE_DELETE(szBuf);

 return 0;
}

bool HelpInfo(char** argv)
{
 printf("帮助\n");
 printf("%s 目标PE文件(destination) 新加块大小(VirtualSize) 新加块偏移地址(VirtualAddress)\n", argv[0]);
 return 0;
}


这里破东西还不让发代码&#xff0c; 总之PE加区段编要注意 内存映像的增加&#xff0c; 区块数的增加。

还有偏移地址等。

strncpy((char*)tISH.Name, ".pediy", sizeof(tISH.Name));
    tISH.Misc.VirtualSize &#61; 0x1000;           // 4KB
    tISH.SizeOfRawData &#61; 0x1000;
    tISH.VirtualAddress &#61; SizeOfImage;           // 改地址应该为增加的一个空闲区   应该是先加区段&#xff0c;然后再改入口点 此地址作为最后的偏移量
    tISH.PointerToRawData &#61; st.st_size;              // 行号表中行号的数目
    if(g_bHaveSetVSizeaAddress)
    {
    tISH.Misc.VirtualSize &#61; atoi(argv[2]);           // 4KB
    tISH.SizeOfRawData &#61; atoi(argv[2]);
    }
    tISH.PointerToRelocations &#61; 0;          // 在OBJ文件中使用&#xff0c; 重定位的偏移
    tISH.PointerToLinenumbers &#61; 0;          // 行号表的偏移(供调试用)
    tISH.NumberOfRelocations &#61; 0;           // 在OBJ文件中使用&#xff0c;重定位项目数
    tISH.NumberOfLinenumbers &#61; 0;
    tISH.Characteristics &#61; 0xE0000020;      // 块属性&#xff0c; 表示包含执行代码、可读写并可

加区段工具&#xff0c; 在设置    VirtualAddress 实际上是该区段在内存中的偏移量&#xff0c; 所以&#xff0c; 这个地址只要是内存映像大小即可。

而文件偏移地址 PointerToRawData 则为文件的大小。

这也是为什么有的时候这两个值不一样的原因&#xff0c; 尽管内存映像的各区块大概 和磁盘文件是一一对应的。但是 实际上映射的地址 还是有偏移的。所以 有时当VirtualAddress 和 PointerToRawData相同时则可以执行&#xff0c; 有的时候相同时反而出错&#xff0c; 就是由于 装载地址不一致导致的&#xff0c; 也就是一致的地址&#xff0c;

那个地址值原来可能有数据了&#xff0c; 若再装载就等于要覆盖那个地址的数据。 既然在磁盘上区块是添加在文件尾&#xff0c; 那在内存中当然也就是内存映像尾恩。


转载于:https://www.cnblogs.com/microsoftxiao/archive/2007/05/12/744086.html


推荐阅读
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 服务器上的操作系统有哪些,如何选择适合的操作系统?
    本文介绍了服务器上常见的操作系统,包括系统盘镜像、数据盘镜像和整机镜像的数量。同时,还介绍了共享镜像的限制和使用方法。此外,还提供了关于华为云服务的帮助中心,其中包括产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题和视频帮助等技术文档。对于裸金属服务器的远程登录,本文介绍了使用密钥对登录的方法,并提供了部分操作系统配置示例。最后,还提到了SUSE云耀云服务器的特点和快速搭建方法。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 本文讨论了如何在dotnet桌面(Windows)应用程序中添加图标。作者提到可以使用dotnet命令行工具与resource.rc文件一起使用来为标准.NET核心应用程序添加图标。作者还介绍了在创建控制台应用程序时如何编辑projeto1.csproj文件来添加图标。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 解决.net项目中未注册“microsoft.ACE.oledb.12.0”提供程序的方法
    在开发.net项目中,通过microsoft.ACE.oledb读取excel文件信息时,报错“未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序”。本文提供了解决这个问题的方法,包括错误描述和代码示例。通过注册提供程序和修改连接字符串,可以成功读取excel文件信息。 ... [详细]
author-avatar
梦晗明镜百_576
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有