代码节添加代码,新增节,再把新增节扩大

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include "string.h"

#include <malloc.h>

#include <windows.h>

//函数声明

LPVOID ReadPEFile(LPSTR FilePath);

void PrintNTHeaders(LPVOID pfilebuf);

void ImageBufferToFileBuffer(LPVOID ImageBuffer);

int getFileSize(FILE* fileAdress);

FILE* openFile(char* filePath, char* type);

int ReadFileSize(char* FilePath);

LPVOID Code_To_Code(LPVOID imageBuffer);

//DWORD NewSeciton(LPVOID pimageBuffer);

//读取文件大小

int ReadFileSize(char* FilePath)

{

FILE* Pfile;//一般使用FILE*类型变量表示文件句柄,通过它来访问FILE结构体,对文件进行操作。

DWORD len;//定义文件长度;

Pfile = fopen(FilePath, "rb+");//pfile可以拿到文件句柄(指针),那样就可以操作了。fopen函数是打开一个文件,其调用的一般形式为:文件指针名=fopen(文件名,使用文件方式);

if (!Pfile)

{

printf("打开文件错误,错误码01");

return NULL;

}

fseek(Pfile, 0, SEEK_END);//把文件指针位置移动到最后面,用来读取大小。函数原形:int fseek(FILE *stream, long offset, int fromwhere);函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere(偏移起始位置:文件头0(SEEK_SET),当前位置1(SEEK_CUR),文件尾2(SEEK_END))为基准,偏移offset(指针偏移量)个字节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。

len = ftell(Pfile); //用ftell函数拿到大小,ftell原型:long ftell(FILE *stream);函数 ftell 用于得到文件位置指针当前位置相对于文件首的偏移字节数。在随机方式存取文件时,由于文件位置频繁的前后移动,程序不容易确定文件的当前位置。

//printf("这个程序的大小为:%d个字节\n", len);//打印文件大小,单位字节。,读取成功66560个字节

return len;

}

//打开文件,并返回指针,LPVOID是暂时没有类型的指针

LPVOID ReadPEFile(char* FilePath)//LPSTR是一种字符串数据类型。LPSTR被定义成是一个指向以NULL(‘\0’)结尾的32位ANSI字符数组指针

{

FILE* Pfile;//一般使用FILE*类型变量表示文件句柄,通过它来访问FILE结构体,对文件进行操作。

LPVOID pfilebuffer; //定义文件缓冲区指针

DWORD len;//定义文件长度;

Pfile = fopen(FilePath, "rb+");//pfile可以拿到文件句柄(指针),那样就可以操作了。fopen函数是打开一个文件,其调用的一般形式为:文件指针名=fopen(文件名,使用文件方式);

if (!Pfile)

{

printf("打开文件错误,错误码01");

return NULL;

}

fseek(Pfile, 0, SEEK_END);//把文件指针位置移动到最后面,用来读取大小。函数原形:int fseek(FILE *stream, long offset, int fromwhere);函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere(偏移起始位置:文件头0(SEEK_SET),当前位置1(SEEK_CUR),文件尾2(SEEK_END))为基准,偏移offset(指针偏移量)个字节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。

len = ftell(Pfile); //用ftell函数拿到大小,ftell原型:long ftell(FILE *stream);函数 ftell 用于得到文件位置指针当前位置相对于文件首的偏移字节数。在随机方式存取文件时,由于文件位置频繁的前后移动,程序不容易确定文件的当前位置。

//printf("这个程序的大小为:%d个字节\n", len);//打印文件大小,单位字节。,读取成功66560个字节

pfilebuffer = malloc(len);//知道大小了后,我们就把pfilebuffer文件缓冲区指针确定大小,用malloc动态分配

fseek(Pfile, 0, SEEK_SET);//然后把文件游标指针拿到最前面来。

if (!pfilebuffer) //判断pfilebuffer获取成功没

{

printf("分配文件缓冲区空间上失败,错误码02");

pfilebuffer = 0;

fclose(Pfile);

return NULL;

}

size_t filebuffer_count = fread(pfilebuffer, 1, len, Pfile); //把len个字节全部读取到pfilebuffer缓冲区中,这里返回的是一个文件字节大小,用于判断是否读取成功函数原型size_t fread(void *buffer, size_t size, size_t count, FILE *stream);//C99前,从给定输入流stream读取最多count个对象到数组buffer中(相当于以对每个对象调用size次fgetc),把buffer当作unsigned char数组并顺序保存结果。流的文件位置指示器前进读取的字节数。

if (!filebuffer_count)

{

printf("读取文件到缓冲区失败,错误码03");

pfilebuffer = 0;

fclose(Pfile);

return 0;

}

//走到这里就读取成功了,返回一个长度为len个字节(含文件数据流)的pfilebuffer缓冲区指针

fclose(Pfile);

return  pfilebuffer;

}

//定义一个打印整个PE头+节表目录信息的函数 ,//

void PrintNTHeaders(LPVOID pfilebuf)

{

LPVOID pfilebuffer;//用来接收 ReadPEFile()函数返回得pfilebuffer缓冲区指针;

PIMAGE_DOS_HEADER pDosHeader = NULL; //DOS头指针

PIMAGE_NT_HEADERS32 pNTHeader = NULL;//NT头指针

PIMAGE_FILE_HEADER pFileHeader = NULL;//标准头指针

PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;//可选头指针

pfilebuffer = pfilebuf;  //传入pfilebuffer缓冲区指针;

if (!pfilebuffer)

{

printf("传入pfilebuffer缓冲区指针失败,错误代码04");

free(pfilebuffer);

return;

}

//PWORD在DOS下(实模式)地址是分段的,每一段的长度为64K字节,刚好是16位(二进制的十六位)DOS头刚好64个字节。

if (*((PWORD)pfilebuffer) != IMAGE_DOS_SIGNATURE)

{

printf("EXE不是有效的程序,错误代码05");

free(pfilebuffer);

return;

}

printf("PIGAMGE_DOS_HEADER-DOS头指针大小:%d个字节\n", sizeof(PIMAGE_DOS_HEADER));

pDosHeader = (PIMAGE_DOS_HEADER)pfilebuffer;

printf("DOS头pDosHeader指针大小:%d个字节\n", sizeof(pDosHeader));

//开始打印DOS头

printf("\n=======即将打印DOS头=======\n");

printf("MZ标志:%x\n", pDosHeader->e_magic);

printf("PE头偏移:%x\n", pDosHeader->e_lfanew);//定位PE文件,PE头相对于文件的偏移量

   //开始判断PE标志

   //printf("IMAGE_NT_SIGNATURE值为:%x", *PWORD((DWORD)pfilebuffer + pDosHeader->e_lfanew));  其实这里就可以验证了

if ((*PWORD((DWORD)pfilebuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)//说明:pDosHeader->e_lfanew存的是DOS头开始到PE的偏移量,用(DWORD)pfilebuffer指针加上这个偏移量,那么就可以得到PE头的指针偏移量,就得到IMAGE_NT_SIGNATURE值

{

printf("没有找到PE头标志,错误代码06\n");

free(pfilebuffer);

return;

}

pNTHeader = (PIMAGE_NT_HEADERS32)((DWORD)pfilebuffer + pDosHeader->e_lfanew);

//测试打印下NT头

printf("NT头:%x\n", pNTHeader->Signature);

//拿到标准PE头指针

pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);

//打印PE标准头结构

printf("===============PE标准头结构===============\n\n\n");

printf("PE-Machine:%x\n", pFileHeader->Machine);

printf("PE结构中节的数量:%x\n", pFileHeader->NumberOfSections);

printf("PE可选PE结构体大小:%d字节\n\n", pFileHeader->SizeOfOptionalHeader);

//拿到可选PE头

pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader + 20);

printf("===============PE可选头结构===============\n\n\n");

printf("PE可选头指针:%x\n", pOptionalHeader);

printf("PE-Magic:%x\n", pOptionalHeader->Magic);

printf("程序入口OEP地址:%x\n", pOptionalHeader->AddressOfEntryPoint);

printf("PE可选头-SizeOfHeader值:%xH\n那么节表里面的首节地址也应该是:%xH\n", pOptionalHeader->SizeOfHeaders, pOptionalHeader->SizeOfHeaders);

//拿到节表地址:

PIMAGE_SECTION_HEADER pSection = NULL;

pSection = PIMAGE_SECTION_HEADER((DWORD)pOptionalHeader + 224);

printf("pSection地址:%x\n", pSection);

printf("PE节表-第一个节PointerToRawData地址:%x\n", pSection->PointerToRawData);

printf("PE节区地址:%x\n", pSection->VirtualAddress);

printf("pe节区name:%s\n", pSection->Name);

//pSection = PIMAGE_SECTION_HEADER((DWORD)pSection + 40);

//printf("第二个pe节区name:%s\n", pSection->Name);

//======================================//

DWORD dwSection = pFileHeader->NumberOfSections;//定义节区描述文件个数这里有3个

for (DWORD i = 0; i < dwSection; i++, pSection++)

{

printf("\n================第%d个节区描述============\nName:", i + 1);

for (DWORD j = 0; j < IMAGE_SIZEOF_SHORT_NAME; j++)

{

printf("%c", pSection->Name[j]);

}

printf("\nMISC:%d个字节\n",pSection->Misc);//文件中节区实际含有数据的大小

printf("VirtualAddress:%x\n", pSection->VirtualAddress);//在内存中的地址,需要加上ImageBase;

printf("SizeOfRawData:%d个字节\n", pSection->SizeOfRawData);//文件中的节区大小

printf("PointToRawData:%d偏移字节\n", pSection->PointerToRawData);//文件中节区首地址的偏移

printf("Characteristics:%08x\n",pSection->Characteristics);//节属性

printf("\n================第%d个节区描述结束============\n", i + 1);

}

}

//复制FileBuffer到ImageBuffer的函数

//参数1:Filebuffer指针

LPVOID CopyFileBufferToImageBuffer(LPVOID pFileBuffer)

{

LPVOID TempiamgeBuffer = NULL;

PIMAGE_DOS_HEADER pDosHeader1=NULL;

PIMAGE_NT_HEADERS32 pNTHeader1 = NULL;

PIMAGE_FILE_HEADER pFileHeader1 = NULL;

PIMAGE_OPTIONAL_HEADER32 pOptionHeader1 = NULL;

PIMAGE_SECTION_HEADER pSectionHeader1 = NULL;

if (!pFileBuffer)

{

printf("文件指针未获取到,请检查你的参数设置,错误代码07\n");

pFileBuffer = NULL;

return 0;

}

pDosHeader1 = (PIMAGE_DOS_HEADER)pFileBuffer;

if (*((PWORD)pDosHeader1) != IMAGE_DOS_SIGNATURE) //这里为什么要用(PWORD)呢,第一,pDosHeader1指针是4字节,IMAGE_DOS_SIGNATURE的值是两个字节。第二*的操作数必须是一个指针,所以用指向WORD的指针PWORD

{

printf("没有找到MZ标志,错误代码07\n");

pDosHeader1 = NULL;

pFileBuffer = NULL;

return 0 ;

}

//找到所有头

pNTHeader1 = PIMAGE_NT_HEADERS32((DWORD)pDosHeader1 + pDosHeader1->e_lfanew);

if (*(PDWORD)pNTHeader1 != IMAGE_NT_SIGNATURE)

{

printf("没有找到PE标志,错误代码08\n");

pNTHeader1 = NULL;

pFileBuffer = NULL;

return 0 ;

}

pFileHeader1 = PIMAGE_FILE_HEADER((DWORD)pNTHeader1 + 4);

pOptionHeader1 = PIMAGE_OPTIONAL_HEADER32((DWORD)pFileHeader1 + IMAGE_SIZEOF_FILE_HEADER);

pSectionHeader1 = PIMAGE_SECTION_HEADER((DWORD)pOptionHeader1 + pFileHeader1->SizeOfOptionalHeader);

printf("sizeofimage:%d\n", pOptionHeader1->SizeOfImage);

printf("sizeofHeader:%d\n", pOptionHeader1->SizeOfHeaders);

//申请一块动态内存,并用Tempimagebuffer指向他=======================

TempiamgeBuffer = malloc(pOptionHeader1->SizeOfImage + 0x1000);

printf("pOptionHeader1->ImageBase:%x\n", pOptionHeader1->ImageBase);

printf("pOptionHeader1->FileAlignment:%d\n", pOptionHeader1->FileAlignment);

printf("pOptionHeader1->SectionAlignment:%d\n", pOptionHeader1->SectionAlignment);

//判断是否申请成功

if (!TempiamgeBuffer)

{

printf("动态内存申请失败\n,错误代码09");

TempiamgeBuffer = NULL;

free(TempiamgeBuffer);

return 0;

}

//刷新清空这块内存里面的数据memset(TempiamgeBuffer, 0, pOptionHeader1->SizeOfImage+0x1000);//函数原型:void *memset(void *s, int ch, size_t n);将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。

//然后就可以复制了

//函数原型void *memcpy(void *destin, void *source, unsigned n);destin-- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。从源source所指的内存地址的起始位置开始拷贝n个字节到目标destin所指的内存地址的起始位置中。

//destin-- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。

//source-- 指向要复制的数据源,类型强制转换为 void* 指针。

//n-- 要被复制的字节数。

//复制整个PE头

memcpy(TempiamgeBuffer, pDosHeader1, pOptionHeader1->SizeOfHeaders); //函数原型void *memcpy(void *destin, void *source, unsigned n);destin-- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。

//

DWORD dwSection = pFileHeader1->NumberOfSections;//节的个数

PIMAGE_SECTION_HEADER pTempSectionHeader = pSectionHeader1;

for (DWORD i = 0; i < dwSection; i++)

{

memcpy((void*)((DWORD)TempiamgeBuffer + (pTempSectionHeader->VirtualAddress)),((void*)((DWORD)pFileBuffer + pTempSectionHeader->PointerToRawData)), pTempSectionHeader->SizeOfRawData);

//pSectionHeader1 = (PIMAGE_SECTION_HEADER)(pSectionHeader1+sizeof(_IMAGE_SECTION_HEADER));

//PIMAGE_SECTION_HEADER pTempSectionHeader = pSectionHeader1;

pTempSectionHeader++;

}

printf("复制数据到ImageBuffer成功\n");

//memset(TempiamgeBuffer, 0, pOptionHeader1->SizeOfImage); //清空

//free(TempiamgeBuffer);//释放内存

//TempiamgeBuffer = NULL;

   // TempiamgeBuffer =  Code_To_Code(TempiamgeBuffer);

//printf("TempiamgeBuffer:%x\n", TempiamgeBuffer);

//=========================新增节=====================

PIMAGE_SECTION_HEADER NewSection;

//pSection--;

NewSection = pTempSectionHeader;

pTempSectionHeader--;

NewSection->Name[0] = 'a'; NewSection->Name[1] = 'b'; NewSection->Name[2] = 'c'; NewSection->Name[3] = 'd';

NewSection->Misc.VirtualSize = 0x1000;

NewSection->VirtualAddress = pTempSectionHeader->VirtualAddress + pTempSectionHeader->SizeOfRawData;

NewSection->PointerToRawData = pTempSectionHeader->PointerToRawData + pTempSectionHeader->SizeOfRawData;

NewSection->SizeOfRawData = 0x1000;

int n = (pTempSectionHeader - (pFileHeader1->NumberOfSections - 1))->Characteristics; //这里是取到第一个节表的属性

pFileHeader1->NumberOfSections += 1;

NewSection->Characteristics = n;

pOptionHeader1->SizeOfImage += 0x1000;

memcpy(TempiamgeBuffer, pDosHeader1, pOptionHeader1->SizeOfHeaders);

//在代码节添加代码

TempiamgeBuffer = Code_To_Code(TempiamgeBuffer);

return TempiamgeBuffer;

}

//imagebuffer 到filebuffer

DWORD ImagebufferToFilebuffer(LPVOID imagebuffer) 

{

LPVOID TempFileBuffer = NULL;

PIMAGE_DOS_HEADER pDosHeader2 = NULL;

PIMAGE_NT_HEADERS32 pNTHeader2 = NULL;

PIMAGE_FILE_HEADER pFileHeader2 = NULL;

PIMAGE_OPTIONAL_HEADER32 pOptionHeader2 = NULL;

PIMAGE_SECTION_HEADER pSectionHeader2 = NULL;

if (!imagebuffer)

{

printf("ImagebufferToFilebuffer函数没有获取到imagebuffer指针,错误码20");

return 0;

}

if (*(PWORD)((PIMAGE_DOS_HEADER)imagebuffer) != IMAGE_DOS_SIGNATURE)

{

printf("imagebuffer不是有效的MZ");

return 0;

}

pDosHeader2=(PIMAGE_DOS_HEADER)imagebuffer;

pNTHeader2 = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader2 + pDosHeader2->e_lfanew);

pFileHeader2 = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader2 + 4);

pOptionHeader2 = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader2 + IMAGE_SIZEOF_FILE_HEADER);

pSectionHeader2 = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader2 + pFileHeader2->SizeOfOptionalHeader);

//先拿到文件buffer大小

int File_size = ReadFileSize("D:\\ipmsg.exe");

File_size += 0x1000;

pOptionHeader2->SizeOfImage += 0x1000;

//申请内存

TempFileBuffer = malloc(File_size+0x1000);

//清空内存中的数据

memset(TempFileBuffer, 0, File_size);

//复制PE头

memcpy(TempFileBuffer, imagebuffer, pOptionHeader2->SizeOfHeaders);

//获得节个数

int DwSetion = pFileHeader2->NumberOfSections;

//imageBase加1000个字节

//申请一个节变量,用于自增

PIMAGE_SECTION_HEADER pSection = pSectionHeader2;

//开始复制节到文件内存里

for (int i = 0; i < DwSetion; i++)

{

memcpy((VOID*)((DWORD)TempFileBuffer + pSection->PointerToRawData), (void*)((DWORD)imagebuffer + pSection->VirtualAddress), pSection->SizeOfRawData);

pSection++;

}

printf("sizeofimage:%d", pOptionHeader2->SizeOfImage);

printf("imagebuffer到FileBuffer成功了"); //好吧,真的成功了。接下来要存盘了。

//====================开始存盘,看看能不能用========================

char Save_exe[] = "D:\\ipmsg_NewSection.exe";

FILE* Save_file = fopen(Save_exe, "wb+");

fwrite(TempFileBuffer,File_size,1,Save_file);

if (!Save_file)

{

printf("拷贝失败了,错误代码22\n");

fclose(Save_file);

return 0;

}

fclose(Save_file);

return 0;

}

//imagebuffer直接存盘函数

DWORD ImagebufferToFilebuffer2(LPVOID imagebuffer) 

{

LPVOID TempFileBuffer = NULL;

PIMAGE_DOS_HEADER pDosHeader2 = NULL;

PIMAGE_NT_HEADERS32 pNTHeader2 = NULL;

PIMAGE_FILE_HEADER pFileHeader2 = NULL;

PIMAGE_OPTIONAL_HEADER32 pOptionHeader2 = NULL;

PIMAGE_SECTION_HEADER pSectionHeader2 = NULL;

if (!imagebuffer)

{

printf("ImagebufferToFilebuffer函数没有获取到imagebuffer指针,错误码20");

return 0;

}

if (*(PWORD)((PIMAGE_DOS_HEADER)imagebuffer) != IMAGE_DOS_SIGNATURE)

{

printf("imagebuffer不是有效的MZ");

return 0;

}

pDosHeader2 = (PIMAGE_DOS_HEADER)imagebuffer;

pNTHeader2 = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader2 + pDosHeader2->e_lfanew);

pFileHeader2 = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader2 + 4);

pOptionHeader2 = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader2 + IMAGE_SIZEOF_FILE_HEADER);

pSectionHeader2 = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader2 + pFileHeader2->SizeOfOptionalHeader);

//申请内存

TempFileBuffer = malloc(pOptionHeader2->SizeOfImage);

//清空内存中的数据

memset(TempFileBuffer, 0, pOptionHeader2->SizeOfImage);

//复制PE头

memcpy(TempFileBuffer, imagebuffer, pOptionHeader2->SizeOfImage);

//获得节个数

int DwSetion = pFileHeader2->NumberOfSections;

//申请一个节变量,用于自增

PIMAGE_SECTION_HEADER pSection = pSectionHeader2;

//开始复制节到文件内存里

for (int i = 0; i < DwSetion; i++)

{

memcpy((VOID*)((DWORD)TempFileBuffer + pSection->PointerToRawData), (void*)((DWORD)imagebuffer + pSection->VirtualAddress), pSection->SizeOfRawData);

pSection++;

}

printf("sizeofimage:%d", pOptionHeader2->SizeOfImage);

printf("imagebuffer到FileBuffer成功了"); //好吧,真的成功了。接下来要存盘了。

 //====================开始存盘,看看能不能用========================

char Save_exe[] = "D:\\ipmsg_NewSection2222.exe";

FILE* Save_file = fopen(Save_exe, "wb+");

fwrite(TempFileBuffer, pOptionHeader2->SizeOfImage, 1, Save_file);

if (!Save_file)

{

printf("拷贝失败了,错误代码22\n");

fclose(Save_file);

return 0;

}

fclose(Save_file);

return 0;

}

//代码节添加代码

LPVOID Code_To_Code(LPVOID pImageBuffer)

{

char Code[] =

{

0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00,

0xE8, 0x00, 0x00, 0x00, 0x00,

0xE9, 0x00, 0x00, 0x00, 0x00

};

DWORD MessageBoxAddress = 0x762d1e80 ;

PIMAGE_DOS_HEADER pDosHeader3 = NULL;

PIMAGE_NT_HEADERS32 pNTHeader3 = NULL;

PIMAGE_FILE_HEADER pFileHeader3 = NULL;

PIMAGE_OPTIONAL_HEADER32 pOptionHeader3 = NULL;

PIMAGE_SECTION_HEADER pSectionHeader3 = NULL;

pDosHeader3 = (PIMAGE_DOS_HEADER)pImageBuffer;

pNTHeader3 = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader3 + pDosHeader3->e_lfanew);

pFileHeader3 = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader3 + 4);

pOptionHeader3 = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader3 + IMAGE_SIZEOF_FILE_HEADER);

pSectionHeader3 = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader3 + pFileHeader3->SizeOfOptionalHeader);

//添加代码,首先找到代码节的空白区,用imagebase(这里是)+VirtualAddress+SizeOfRawData拿到空白区地址,这个空白区开始的地址就是 我们保存代码的开始地址 CodeBegin

PBYTE CodeBebin = PBYTE((DWORD)pImageBuffer + pSectionHeader3->VirtualAddress + pSectionHeader3->Misc.VirtualSize);

//然后把Code代码复制进去

memcpy(CodeBebin, Code, sizeof(Code));

//计算E8后的地址,,,,((DWORD)CodeBebin + 0xD) - (DWORD)pImageBuffer)是在imagebuffer里的值(就是个偏移)(不是真正运行中)

int E8ShellCode = MessageBoxAddress - (pOptionHeader3->ImageBase + ((DWORD)CodeBebin + 0xd) - (DWORD)pImageBuffer);//得到E8 后4个字节的硬编码

//修改

*(PDWORD)(CodeBebin + 9) = E8ShellCode;

//计算E9后的地址

int E9ShellCode = (pOptionHeader3->ImageBase + pOptionHeader3->AddressOfEntryPoint) - (pOptionHeader3->ImageBase + ((DWORD)CodeBebin + 0x12)-(DWORD)pImageBuffer);

//修改

*(PDWORD)(CodeBebin + 0xe) = E9ShellCode;

//修改AddressOfEntryPoint(OEP)里面存的值为 E8开始的地方

pOptionHeader3->AddressOfEntryPoint = (DWORD)CodeBebin - (DWORD)pImageBuffer;

printf("COde to code:%x\n", pImageBuffer);

return pImageBuffer;

}

//扩大节

//传入Imagebuffer(这里由于我比较懒,传入的就是一个拉伸后的imagebuffer),对其最后一个节区进行扩大1000个字节

LPVOID ExpSection(LPVOID imagebuffer)

{

PIMAGE_DOS_HEADER ExpDos = (PIMAGE_DOS_HEADER)imagebuffer;

PIMAGE_NT_HEADERS ExpNT = PIMAGE_NT_HEADERS((DWORD)imagebuffer + (DWORD)ExpDos->e_lfanew);

PIMAGE_FILE_HEADER ExpFile = PIMAGE_FILE_HEADER((DWORD)ExpNT + 4);

PIMAGE_OPTIONAL_HEADER ExpOption= PIMAGE_OPTIONAL_HEADER((DWORD)ExpFile + 20);

PIMAGE_SECTION_HEADER ExpSec = PIMAGE_SECTION_HEADER((DWORD)ExpOption + (DWORD)ExpFile->SizeOfOptionalHeader);

LPVOID ExpTempP = NULL;

if (*(PDWORD)ExpNT != IMAGE_NT_SIGNATURE)

{

printf("没有传入拉伸后的内存指针,请检查代码,060");

return 0;

}

//申请动态内存

ExpTempP = malloc(ExpOption->SizeOfImage + 0x1000);

//把imagebuffer的数据复制进去

memcpy(ExpTempP, imagebuffer, ExpOption->SizeOfImage);

PIMAGE_DOS_HEADER ExpDos2 = (PIMAGE_DOS_HEADER)ExpTempP;

PIMAGE_NT_HEADERS ExpNT2 = PIMAGE_NT_HEADERS((DWORD)ExpTempP + (DWORD)ExpDos2->e_lfanew);

PIMAGE_FILE_HEADER ExpFile2 = PIMAGE_FILE_HEADER((DWORD)ExpNT2 + 4);

PIMAGE_OPTIONAL_HEADER ExpOption2 = PIMAGE_OPTIONAL_HEADER((DWORD)ExpFile2 + 20);

PIMAGE_SECTION_HEADER ExpSec2 = PIMAGE_SECTION_HEADER((DWORD)ExpOption2 + (DWORD)ExpFile2->SizeOfOptionalHeader);

//修改节表里面最后一个节的部分属性

for (int i = 1; i < ExpFile2->NumberOfSections; i++,ExpSec2++);

ExpSec2->SizeOfRawData += 0x1000; //把节区增大1000个字节

ExpSec2->Misc.VirtualSize += 0x1000;//在内存中大小加0x1000字节

ExpOption2->SizeOfImage += 0x1000;

return ExpTempP;

}

//得到文件大小函数 返回文件大小

int getFileSize(FILE* fileAdress) 

{

int size;

//定位文件末尾

fseek(fileAdress, NULL, SEEK_END);

//得到文件流大小

size = ftell(fileAdress);

//重定位文件开头

fseek(fileAdress, NULL, SEEK_SET);

returnsize;

}

FILE* openFile(char* filePath, char* type) 

{

FILE* fileAdress;

//通过传入的文件地址以及读写类型打开文件创建文件流

if (!(fileAdress = fopen(filePath, type)))

{

printf("获取文件出错!\n");

return 0;

}

return fileAdress;

}

int main()

{

char FilePath[]  = "D:\\ipmsg.exe";

LPVOID p = CopyFileBufferToImageBuffer(ReadPEFile(FilePath));

LPVOID p2 = ExpSection(p);

//ImagebufferToFilebuffer(p);

//Code_To_Code(p);

ImagebufferToFilebuffer2(p2);

//NewSeciton(ReadPEFile(FilePath));

getchar();

return 1;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值