zoukankan      html  css  js  c++  java
  • 在PE中,新增节,添加代码

    在PE中,新增节,添加代码

    一、先判断节表后是否有空闲位置,添加节表信息,必须多出两个节表位置,最后以零结尾。

    二、新增节后,需要修改以下信息

      1、添加一个新节,可以复制一份,最好是拥有可执行属性的节,如.text。

      2、在节表区,新增节的后面,填充一个节,用零填充。

      3、修改标准PE头中节的数量。

      4、修改SizeOfImage的大小。

      5、在原有数据的后面,新增一个节的数据(内存对齐的整倍数)。

      6、修正新增节表的属性。

    三、新节各个属性修改说明

      1、Name:名字随便修改,不能超过八个字节。

      2、VirtualSize:申请的新节空间大小,比如1000

      3、VirtualAddress:等于上一个节的VirtualAddress  +  SizeOfRawData

      4、SizeOfRawData:设置可以和VirtualSize一样,比如1000

      5、PointerToRawData:等于上一个节的PointerToRawData+  SizeOfRawData

      6、PointerToRelocation:设置成零

      7、PointerToLineNumbers:设置成零

      8、NumberOfLineRelocations:设置成零

      9、NumberOfLineNumbers:设置成零

      10、Characteristics:块属性0x20000060  可以取上一个节表和本节表的属性值,进行异或  如x|y

    标志(属性块) 常用特征值对照表:

    [值:00000020h] [IMAGE_SCN_CNT_CODE                // Section contains code.(包含可执行代码)]

    [值:00000040h] [IMAGE_SCN_CNT_INITIALIZED_DATA    // Section contains initialized data.(该块包含已初始化的数据)]

    [值:00000080h] [IMAGE_SCN_CNT_UNINITIALIZED_DATA  // Section contains uninitialized data.(该块包含未初始化的数据)]

    [值:00000200h] [IMAGE_SCN_LNK_INFO                // Section contains comments or some other type of information.]

    [值:00000800h] [IMAGE_SCN_LNK_REMOVE              // Section contents will not become part of image.]

    [值:00001000h] [IMAGE_SCN_LNK_COMDAT              // Section contents comdat.]

    [值:00004000h] [IMAGE_SCN_NO_DEFER_SPEC_EXC       // Reset speculative exceptions handling bits in the TLB entries for this section.]

    [值:00008000h] [IMAGE_SCN_GPREL                   // Section content can be accessed relative to GP.]

    [值:00500000h] [IMAGE_SCN_ALIGN_16BYTES           // Default alignment if no others are specified.]

    [值:01000000h] [IMAGE_SCN_LNK_NRELOC_OVFL         // Section contains extended relocations.]

    [值:02000000h] [IMAGE_SCN_MEM_DISCARDABLE         // Section can be discarded.]

    [值:04000000h] [IMAGE_SCN_MEM_NOT_CACHED          // Section is not cachable.]

    [值:08000000h] [IMAGE_SCN_MEM_NOT_PAGED           // Section is not pageable.]

    [值:10000000h] [IMAGE_SCN_MEM_SHARED              // Section is shareable(该块为共享块).]

    [值:20000000h] [IMAGE_SCN_MEM_EXECUTE             // Section is executable.(该块可执行)]

    [值:40000000h] [IMAGE_SCN_MEM_READ                // Section is readable.(该块可读)]

    [值:80000000h] [IMAGE_SCN_MEM_WRITE               // Section is writeable.(该块可写)]

    -----------------------------------------------------------------------------------------------------

    // mem.cpp : 定义控制台应用程序的入口点。
    //PE文件从文件加载到内存,再从内存读取,然后存盘到文件
    
    #include "stdafx.h"
    #include <windows.h>
    #include <winnt.h>
    
    //#define  PATH "C:\Windows\System32\notepad.exe"
    #define  PATH "C:\Users\Administrator\Desktop\ipmsg.exe"
    #define  MsgADD 0x75cffde6
    char Shellcode[] =
    {
    	0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00,
    	0xE8, 0x00, 0x00, 0x00, 0x00,
    	0xE9, 0x00, 0x00, 0x00, 0x00
    };
    
    int Filelength(FILE *fp);
    int _tmain(int argc, _TCHAR* argv[])
    {
    	FILE *Fp;
    	fopen_s(&Fp, PATH, "rb");
    	int FileSize = Filelength(Fp);//获取文件大小
    	char * FileBuffer = (char *)malloc(FileSize);//申请存放文件的内存空间
    	if (FileBuffer == NULL)
    	{
    		printf("申请iImageBuffer失败");
    	}
    	fread_s(FileBuffer, FileSize, 1, FileSize, Fp); //将文件复制到内存中
    	//定位一下内存中的数据 各个头表
    	//定位标准PE头 
    	PIMAGE_FILE_HEADER MyFileHeader;
    	MyFileHeader = (PIMAGE_FILE_HEADER)(char *)(FileBuffer + *(int *)(FileBuffer + 0x3c) + 0x4);
    	//定位可选PE头 
    	PIMAGE_OPTIONAL_HEADER  MyOptionalHeader;
    	MyOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((char *)MyFileHeader + 0x14);
    	//定位节表
    	PIMAGE_SECTION_HEADER MySectionHeader;
    	MySectionHeader = (PIMAGE_SECTION_HEADER)((char *)MyOptionalHeader + MyFileHeader->SizeOfOptionalHeader);
    
    
    	//拉伸,也就是读到内存中的状态
    	char * ImageBuffer = (char *)malloc(MyOptionalHeader->SizeOfImage+0x1000);//给拉伸申请内存空间
    	ZeroMemory(ImageBuffer, MyOptionalHeader->SizeOfImage+0x1000);
    
    	if (ImageBuffer == NULL)
    	{
    		printf("申请iImageBuffer失败");
    	}
    	memcpy(ImageBuffer, FileBuffer, MyOptionalHeader->SizeOfHeaders);
    
    
    	for (int i = 0; i < MyFileHeader->NumberOfSections; i++)
    	{
    		memcpy(ImageBuffer + MySectionHeader->VirtualAddress, FileBuffer + MySectionHeader->PointerToRawData, MySectionHeader->SizeOfRawData);//
    		MySectionHeader++;
    	}
    	//新增节开始
    	PIMAGE_SECTION_HEADER AddSectionHeader;
    	AddSectionHeader = MySectionHeader;
    	MySectionHeader--;
    	//AddSectionHeader->Name = "cyp";
    	//AddSectionHeader->Name = { 0 };
    	AddSectionHeader->Name[0] = '.'; AddSectionHeader->Name[1] = 'c'; AddSectionHeader->Name[2] = 'y'; AddSectionHeader->Name[3] = 'p';
    	AddSectionHeader->Misc.VirtualSize = 0x1000;
    	AddSectionHeader->VirtualAddress = MySectionHeader->VirtualAddress + MySectionHeader->SizeOfRawData;
    	AddSectionHeader->SizeOfRawData = 0x1000;
    	AddSectionHeader->PointerToRawData = MySectionHeader->PointerToRawData + MySectionHeader->SizeOfRawData;
    	int x = (MySectionHeader - (MyFileHeader->NumberOfSections-1))->Characteristics;
    	AddSectionHeader->Characteristics = x;
    	MyFileHeader->NumberOfSections += 1;
    	MyOptionalHeader->SizeOfImage + 0x1000;
    	//新增节结束
    
    	//添加代码到PE中 
    	MyFileHeader = (PIMAGE_FILE_HEADER)(char *)(ImageBuffer + *(int *)(ImageBuffer + 0x3c) + 0x4);
    	MyOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((char *)MyFileHeader + 0x14);
    	MySectionHeader = (PIMAGE_SECTION_HEADER)((char *)MyOptionalHeader + MyFileHeader->SizeOfOptionalHeader);//重新指一下,前面动过了
    
    	//E8后面的硬编码地址 =真正要到的地址 - E8的下一行或E8本行 +0x5
    	char *CodeAdd = ImageBuffer + MySectionHeader->VirtualAddress + MySectionHeader->Misc.VirtualSize;//为要增加的代码确定位置
    	memcpy(CodeAdd, Shellcode, sizeof(Shellcode));//把硬编码复制到指定位置
    	int CallAdd = MsgADD - (MyOptionalHeader->ImageBase + ((int)(CodeAdd + 0xd) - (int)ImageBuffer));
    	*(int *)(CodeAdd + 0x9) = CallAdd;//定位CALL函数位置
    	int JmpAdd = MyOptionalHeader->ImageBase + MyOptionalHeader->AddressOfEntryPoint - (MyOptionalHeader->ImageBase + (CodeAdd + 0xd - ImageBuffer));//前面是真正要跳的地址  后面括号是下一条指令的地址
    	*(int *)(CodeAdd + 0xe) = JmpAdd;//定位JMP 跳回位置,也就是修改程序入口
    	MyOptionalHeader->AddressOfEntryPoint = CodeAdd - ImageBuffer;//重新定位程序入口处
    
    	//添加代码到PE结束
    
    	//压缩,为存盘做准备
    	char *NewBuffer = (char *)malloc(FileSize+0x1000);//给压缩申请内存空间
    	if (NewBuffer == NULL)
    	{
    		printf("申请iImageBuffer失败");
    	}
    	memcpy(NewBuffer, ImageBuffer, MyOptionalHeader->SizeOfHeaders);
    	MySectionHeader = (PIMAGE_SECTION_HEADER)((char *)MyOptionalHeader + MyFileHeader->SizeOfOptionalHeader);//重新指一下,前面动过了
    
    	for (int i = 0; i < MyFileHeader->NumberOfSections; i++)
    	{
    		memcpy(NewBuffer + MySectionHeader->PointerToRawData, ImageBuffer + MySectionHeader->VirtualAddress, MySectionHeader->SizeOfRawData);
    		MySectionHeader++;
    	}
    	FILE *nFp;
    	fopen_s(&nFp, "C:\Users\Administrator\Desktop\CYP.exe", "wb");
    	fwrite(NewBuffer, FileSize, 1, nFp);
    
    	//getchar();
    	fclose(nFp);
    	free(FileBuffer);
    	free(ImageBuffer);
    	free(NewBuffer);
    	return 0;
    }
    
    //获取文件大小
    
    
    
    int Filelength(FILE *fp)
    {
    	int num;
    	fseek(fp, 0, SEEK_END);
    	num = ftell(fp);
    	fseek(fp, 0, SEEK_SET);
    	return num;
    }
    
  • 相关阅读:
    20172325 2017-2018-2 《Java程序设计》第八周学习总结
    20172325《结对编程——四则运算》第一周总结
    20172325 2017-2018-2 《程序设计与数据结构》实验二报告
    20172325 2017-2018-2 《Java程序设计》第七周学习总结
    20172325 2017-2018-2 《Java程序设计》第六周学习总结
    20172325 2017-2018-2 《Java程序设计》第五周学习总结
    20172325 2016-2017-2 《Java程序设计》第四周学习总结
    20172306 《程序设计与数据结构》实验四报告
    20172306《程序设计与数据结构》实验三报告
    20172306《Java程序设计与数据结构》第十周学习总结
  • 原文地址:https://www.cnblogs.com/wumac/p/5274559.html
Copyright © 2011-2022 走看看