#include"stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include"64.h"
//#define file_path "c:\\windows\\system32\\notepad.exe"
//open the file and get the files size
/*void Function()
{
printf("Hello\n");
}
*/
int main()
{
// LPVOID PFilebuffer = NULL;
// LPVOID* ptr = &PFilebuffer;
LPSTR PNewImagebuffer =NULL;
char filepath[] = "c:\\dynamic.dll";
char memoryfiletopath[] = "c:\\ipmsg_memory.exe";
char Imagefiletopath[] = "c:\\ipmsg_Imagebuffer.exe";
char opmode[] = "ab+";
FILE* fp = openfile(filepath,opmode);
int size = calcutesize(fp);
char* file_address = allocate_buffer(size);
char* buffer = filebuffer(file_address,size,fp);
WriteMemorytoFile(memoryfiletopath,"wb+",buffer,size);
// ReadPefileDos(buffer); //reade pe
//ilebuffertoImagebuffer(buffer,PPImagebuffer);
//magebuffertoFilebuffer(PPImagebuffer,buffer);
// ImagebuffertoNewbuffer(buffer,PNewImagebuffer);
int SizeOfFileBuffer = size;
LPSTR ImageBuffer = FileBuffertoImageBuffer(buffer);
LPSTR PNewBuffer = ImageBuffertoNewBuffer(ImageBuffer,size);
LPSTR PImageBuffer = ShellCode(SizeOfFileBuffer,ImageBuffer);
writeMemorytoFile2(Imagefiletopath,PNewBuffer,size);
// AddNewSection(buffer);
GetFuncFileAddressOfDll(ImageBuffer);
// GetFunctionAddrByName(ImageBuffer);
//ReadPefileDos(buffer);
// DWORD pRVA =NULL;
// convertRVAtoFOA(pRVA,ImageBuffer);
// Function();
// MessageBox(0,"0",0,0);
return 0;
}
//64.h
#define MESSAGEBOXADDR 0x77D507EA //这个值需要将任一exe文件拖入OD打开,搜索 MessageBoxA 记录它的地址到这里(不同机子的地址不一样)
/*unsigned char ShellCodeData[] =
{
0x6A,0x00,0x6A,0x00,0x6A,0x00,0x6A,0x00, //这行是push 四个0 作为 MessageBox 的参数
0xE8,0x00,0x00,0x00,0x00,
0xE9,0x00,0x00,0x00,0x00
};
*/
unsigned char ShellCodeData[] =
{
0x6A,0x00,0x6A,0x00,0x6A,0x00,0x6A,0x00, //这行是push 四个0 作为 MessageBox 的参数
0xE8,0x00,0x00,0x00,0x00,
0xE9,0x00,0x00,0x00,0x00
};
FILE* openfile(char* file_path,char* opmode);
int calcutesize(FILE* fp);
char* allocate_buffer(int size_t);
char* filebuffer(char* ptr,int size,FILE* fp);
int WriteMemorytoFile(char* file_path,char* opmode,char* buffer,int size);
LPSTR FileBuffertoImageBuffer(LPSTR pfilebuffer);
LPSTR ImageBuffertoNewBuffer(LPSTR pfileBuffer,int NewBufferSize);
DWORD convertRVAtoFOA(PVOID pImageBuffer,DWORD pRVA);
DWORD GetFuncFileAddressOfDll(char* dllbuffer);
FILE* openfile(char* file_path,char* opmode)
{
// char file_path[]="c:\\windows\\system32\\notepad.exe";
FILE* fp=fopen(file_path,opmode);
if(!fp)
{
printf("open file failed!\n");
exit(1);
}
else
{
printf("open file OK!,start load files to memory...\n");
}
return fp;
}
int calcutesize(FILE* fp)
{
fseek(fp,0,SEEK_END);
int size = ftell(fp);
printf("start calculate the file size is : %d\n",size);
fseek(fp,0,SEEK_SET);
return size;
}
char* allocate_buffer(int size_t)
{
//load files to memory,read memory address
char* ptr=(char*)malloc(size_t);
if(!ptr)
{
printf("malloc the memory failed!");
exit(1);
}
else
{
printf("malloc the memory ok!\n");
}
return ptr;
}
char* filebuffer(char* ptr,int size,FILE* fp)
{
if(!(fread(ptr,size,1,fp)))
{
printf("fread files to filebuffer failed!\n");
exit(1);
}
else
{
printf("fread files to filebuffer ok!\n");
}
printf("the filebuffer address is : %x\n",ptr);
return ptr;
}
int WriteMemorytoFile(char* file_path,char* opmode,char* buffer,int size)
{
FILE* fp = fopen(file_path, opmode);
if (!(fwrite(buffer, 1, size, fp))) {
printf("memory write to file failed!\n");
return 0;
}else
{
printf("write to file ok!\n");
}
return 1;
}
LPSTR FileBuffertoImageBuffer(LPSTR pfilebuffer)
{
// char* ImageBuffer = pfilebuffer;
// LPSTR imagebuffer = NULL;
PIMAGE_DOS_HEADER pdos = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER PPeHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 POptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
pdos = (PIMAGE_DOS_HEADER)pfilebuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pdos+pdos->e_lfanew);
PPeHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4);
POptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)PPeHeader+IMAGE_SIZEOF_FILE_HEADER); //nt IS 20 BYTE
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)POptionHeader+PPeHeader->SizeOfOptionalHeader);
DWORD numbofsections = PPeHeader->NumberOfSections;
DWORD headerSize = POptionHeader->SizeOfHeaders;
// memcpy(PNewImagebuffer, pfileBuffer, headerSize);
DWORD ImageSize = POptionHeader->SizeOfImage;
// DWORD headerSize = POptionHeader->SizeOfHeaders;
char* ImageBuffer = pfilebuffer;
// memcpy(ImageBuffer,pfileBuffer,ImageSize);
ImageBuffer = (char*)malloc(POptionHeader->SizeOfImage);
memset(ImageBuffer,0,POptionHeader->SizeOfImage);
memcpy(ImageBuffer,pdos,POptionHeader->SizeOfHeaders);
for(DWORD i=0;i<numbofsections;i++,pSectionHeader++)
{
memcpy(LPVOID((DWORD)ImageBuffer+pSectionHeader->VirtualAddress),LPVOID((DWORD)pdos+pSectionHeader->PointerToRawData),pSectionHeader->SizeOfRawData);
}
printf("ImageBuffer address is : %x\n",ImageBuffer);
// return (LPSTR)POptionHeader->SizeOfImage;
return ImageBuffer;
}
LPSTR ImageBuffertoNewBuffer(LPSTR pfileBuffer,int NewBufferSize)
{
LPSTR pNewBuffer = NULL;
PIMAGE_DOS_HEADER pdos = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER PPeHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 POptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
pdos = (PIMAGE_DOS_HEADER)pfileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pdos+pdos->e_lfanew);
PPeHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4);
POptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)PPeHeader+IMAGE_SIZEOF_FILE_HEADER); //nt IS 20 BYTE
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)POptionHeader+PPeHeader->SizeOfOptionalHeader);
DWORD numbofsections = PPeHeader->NumberOfSections;
// pNewBuffer = (char*)malloc(NewBufferSize);
pNewBuffer = pfileBuffer;
// DWORD headerSize = POptionHeader->SizeOfHeaders;
//**********************************************************
//void *memcpy(void *str1, const void *str2, size_t n)
//str1 -- 目标数组
//str2 -- 要复制的数据源
//n -- 要被复制的字节数
//**********************************************************
// memcpy(pNewBuffer, pdos, headerSize);
memcpy(pNewBuffer,pdos,POptionHeader->SizeOfHeaders);
for(DWORD i=0;i<numbofsections;i++,pSectionHeader++)
{
// printf(".......the %d Sections Name.........\n",i+1);
memcpy((pNewBuffer + (DWORD)(pSectionHeader->PointerToRawData)), (pNewBuffer + (DWORD)(pSectionHeader->VirtualAddress)),pSectionHeader->SizeOfRawData);
// pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader + sizeof(_IMAGE_SECTION_HEADER));
}
printf("pNewBuffer address is : %x\n",pNewBuffer);
return pNewBuffer;
}
DWORD convertRVAtoFOA(PVOID pImageBuffer,DWORD pRVA)
{
PIMAGE_DOS_HEADER pdos = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER PPeHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 POptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
pdos = (PIMAGE_DOS_HEADER)pImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pdos+pdos->e_lfanew);
PPeHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4);
POptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)PPeHeader+IMAGE_SIZEOF_FILE_HEADER); //nt IS 20 BYTE
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)POptionHeader+PPeHeader->SizeOfOptionalHeader);
DWORD numbofsections = PPeHeader->NumberOfSections;
int image_panyi = pRVA; // pRVA是在内存中的偏移偏移
// printf("VirtulAddress : %x\n",(DWORD)pSectionHeader->VirtualAddress);
// printf("image_panyi:%#x\n",image_panyi);
// 循环查找在那个imagebuffer节中
PIMAGE_SECTION_HEADER pTempSectionHeader = pSectionHeader;
for(DWORD i = 0;i<PPeHeader->NumberOfSections;i++,pTempSectionHeader++)
{ //判断 : Misc.VirtualSize+ VirtualAddress 内存偏移+节数据没对齐的大小>image_panyi>内存偏移 VirtualAddress (即是在文件的哪个节中)
if(((DWORD)image_panyi>=(DWORD)pTempSectionHeader->VirtualAddress) && ((DWORD)image_panyi<pTempSectionHeader->VirtualAddress+pTempSectionHeader->Misc.VirtualSize))
{
return image_panyi-pTempSectionHeader->VirtualAddress+pTempSectionHeader->PointerToRawData;
}
}
return 0;
}
DWORD GetFunctionAddrByName(char* dllbuffer)
{
PIMAGE_DOS_HEADER pdos = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER PPeHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 POptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
DWORD nameFOA = NULL;
DWORD AddressOfNamesFOA = NULL;
DWORD AddressOfNameOrdinalsFOA = NULL;
DWORD AddressOfFunctionsFOA = NULL;
DWORD AddressOfFunctions = NULL;
WORD Ordinal = NULL;
char* name = NULL;
pdos = (PIMAGE_DOS_HEADER)dllbuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pdos+pdos->e_lfanew);
PPeHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4);
POptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)PPeHeader+IMAGE_SIZEOF_FILE_HEADER); //nt IS 20 BYTE
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)POptionHeader+PPeHeader->SizeOfOptionalHeader);
DWORD numbofsections = PPeHeader->NumberOfSections;
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)dllbuffer + convertRVAtoFOA(dllbuffer, POptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress));
AddressOfFunctionsFOA = convertRVAtoFOA(dllbuffer, pExportDirectory->AddressOfFunctions);
AddressOfNamesFOA = convertRVAtoFOA(dllbuffer,pExportDirectory->AddressOfNames);
for(DWORD k = 0; k < (DWORD)pExportDirectory->NumberOfFunctions; k++)
{
//因Address表元素为4字节,绝对地址加上k*4直接取第k个元素
AddressOfFunctions = *(PDWORD)((DWORD)dllbuffer + AddressOfFunctionsFOA + k*4);
printf("%x\n",AddressOfFunctions);
}
for (DWORD i = 0; i < (DWORD)pExportDirectory->NumberOfNames; i++)
{
printf("*******函数名称表*******\n");
//AddressOfNamesFOA只是Names表的FOA地址,需加上pFileBuffer构成的绝对地址才能取出其中的值。
//取出的值即Names地址表第i个name的Rva地址,转成FOA得到name的FOA地址
nameFOA = convertRVAtoFOA(dllbuffer,*(PDWORD)(AddressOfNamesFOA+(DWORD)dllbuffer));
name = (char*)(nameFOA + (DWORD)dllbuffer);
printf("%s\n",name);
AddressOfNamesFOA = AddressOfNamesFOA + 4;
}
return 0;
}
DWORD GetFuncFileAddressOfDll(char* dllbuffer)
{
PIMAGE_DOS_HEADER pdos = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER PPeHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 POptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
DWORD nameFOA = NULL;
DWORD AddressOfNamesFOA = NULL;
DWORD AddressOfNameOrdinalsFOA = NULL;
DWORD AddressOfFunctionsFOA = NULL;
DWORD AddressOfFunctions = NULL;
WORD Ordinal = NULL;
char * name = NULL;
pdos = (PIMAGE_DOS_HEADER)dllbuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pdos+pdos->e_lfanew);
PPeHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4);
POptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)PPeHeader+IMAGE_SIZEOF_FILE_HEADER); //nt IS 20 BYTE
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)POptionHeader+PPeHeader->SizeOfOptionalHeader);
DWORD numbofsections = PPeHeader->NumberOfSections;
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)dllbuffer + convertRVAtoFOA(dllbuffer, POptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress));
// printf("DIRECTORY_ENTRY_EXPORT VirtualAddress:%x\n", POptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
// printf("FOA:%x\n", convertRVAtoFOA(dllbuffer, POptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress));
// printf("导出表文件名字符串Name:%x\n", pExportDirectory->Name);
// printf("导出函数起始序号Base:%d\n", pExportDirectory->Base);
// printf("导出函数的个数:%d\n", pExportDirectory->NumberOfFunctions);
// printf("以函数名字导出的函数个数NumberOfNames:%d\n", pExportDirectory->NumberOfNames);
printf("*******函数地址表*******\n");
AddressOfFunctionsFOA = convertRVAtoFOA(dllbuffer, pExportDirectory->AddressOfFunctions);
// printf("导出函数RVA:%x\n", AddressOfFunctionsFOA);
for (DWORD i = 0; i < (DWORD)pExportDirectory->NumberOfFunctions; i++)
{
AddressOfFunctions = *(PDWORD)((DWORD)dllbuffer + AddressOfFunctionsFOA + i * 4); //因Address表元素为4字节,绝对地址加上i*4直接取第i个元素
printf("下标:%d,函数地址:%x\n", i, AddressOfFunctions);
}
printf("*******函数名称表*******\n");
//导出表中的AddressOfNames为Rva,将其转换为FOA得到AddressOfNamesFOA
AddressOfNamesFOA = convertRVAtoFOA(dllbuffer, pExportDirectory->AddressOfNames);
for (DWORD k = 0; k < pExportDirectory->NumberOfNames; k++)
{ //AddressOfNamesFOA只是Names表的FOA地址,需加上pFileBuffer构成的绝对地址才能取出其中的值。
//取出的值即Names地址表第i个name的Rva地址,转成FOA得到name的FOA地址
nameFOA = convertRVAtoFOA(dllbuffer, *(PDWORD)((DWORD)dllbuffer + AddressOfNamesFOA));
name = (char *)(nameFOA + (DWORD)dllbuffer);//name的FOA加上pFileBuffer构成绝对地址,该地址才真正指向字符串
printf("下标:%d,函数名称:%s\n", k, name);
AddressOfNamesFOA = AddressOfNamesFOA + 4; //往前走4字节,指向Names地址表下一个元素,即下一个name地址
}
printf("*******函数序号表*******\n");
AddressOfNameOrdinalsFOA = convertRVAtoFOA(dllbuffer, pExportDirectory->AddressOfNameOrdinals); //同Names表找法
for (DWORD f = 0; f < pExportDirectory->NumberOfNames; f++)
{
Ordinal = *(WORD*)((DWORD)dllbuffer + AddressOfNameOrdinalsFOA + f * 2); //因为序号表元素为2字节,绝对地址加上f*2直接取第f个元素
printf("下标:%d,函数序号:%d\n", f, Ordinal);
}
// result = (DWORD)GetFunctionAddrByName(dllbuffer, "plus"); //得到的是函数Rva地址
// printf("result:%x\n", result);
// result = (DWORD)GetFunctionAddrByOrdinals(dllbuffer, 2);
// printf("result:%x\n", result);
return 0;
}
/*
DWORD AddNewSection(LPSTR PFilebuffer)
{
PIMAGE_DOS_HEADER pdos = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER PPeHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 POptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_SECTION_HEADER LastpSectionHeader = NULL;
pdos = (PIMAGE_DOS_HEADER)PFilebuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)PFilebuffer+pdos->e_lfanew);
PPeHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4);
POptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)PPeHeader+IMAGE_SIZEOF_FILE_HEADER); //nt IS 20 BYTE
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)POptionHeader+PPeHeader->SizeOfOptionalHeader);
DWORD numbofsections = PPeHeader->NumberOfSections;
//判断条件:
// if ((DWORD)pNewSectionHeader + IMAGE_SIZEOF_SECTION_HEADER * 2 <= (DWORD)pFileBuffer + pOptionalHeader->SizeOfHeaders)
for(DWORD i=0;i<numbofsections;i++,pSectionHeader++){
// printf("%d\n",i);
}
LastpSectionHeader = pSectionHeader + 1;
if ((DWORD)LastpSectionHeader + IMAGE_SIZEOF_SECTION_HEADER * 2 <= (DWORD)PFilebuffer + POptionHeader->SizeOfHeaders)
{
printf("SizeofHeaders >= 2个节表的大小,you can add new sectioncode\n");
}
else
{
printf("SizeofHeaders < 2个节表的大小");
}
printf(".........start add new sectioncode.......\n");
//开始构造新节表
strcpy((char*)LastpSectionHeader->Name,(char*)".NewSec");
LastpSectionHeader->Misc.VirtualSize = sizeof(ShellCodeData);
//节区在内存中的偏移 = 内存中整个PE文件映射的大小
LastpSectionHeader->VirtualAddress = POptionHeader->SizeOfImage;
LastpSectionHeader->SizeOfRawData = POptionHeader->SizeOfImage;
LastpSectionHeader->PointerToRawData = (unsigned)PFilebuffer;//pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData;
LastpSectionHeader->PointerToRelocations = 0;
LastpSectionHeader->PointerToLinenumbers = 0;
LastpSectionHeader->NumberOfRelocations = 0;
LastpSectionHeader->NumberOfLinenumbers = 0;
LastpSectionHeader->Characteristics = 0x60000020;
PPeHeader->NumberOfSections++;
}
*/
BOOL writeMemorytoFile2(char* filePath,LPSTR pNewBuffer,int NewBufferSize)
{
FILE* fpw = fopen(filePath, "wb+");
if (fpw == NULL)
{
printf("fpw fopen fail");
return false;
}
if (fwrite(pNewBuffer, 1, NewBufferSize, fpw) == 0)
{
printf("fpw fwrite fail");
return false;
}
fclose(fpw);
fpw = NULL;
printf("success\n");
return true;
}
LPSTR ShellCode(int SizeOfFileBuffer,LPSTR ImageBuffer)
{
PIMAGE_DOS_HEADER pdos = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER PPeHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 POptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
DWORD CallX = NULL; //即E8后跟的4字节
DWORD JmpX = NULL; //即E9后跟的4字节
if (!SizeOfFileBuffer) //SizeOfFileBuffer == size
{
printf("文件读取失败\n");
return 0;
}
if(!ImageBuffer)
{
printf("Filebuffer to Imagebuffer failed!\n");
return 0;
}
pdos = (PIMAGE_DOS_HEADER)ImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pdos+pdos->e_lfanew);
PPeHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4);
POptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)PPeHeader+IMAGE_SIZEOF_FILE_HEADER); //nt IS 20 BYTE
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)POptionHeader+PPeHeader->SizeOfOptionalHeader);
if ( pSectionHeader->Misc.VirtualSize + sizeof(ShellCodeData) > pSectionHeader->SizeOfRawData)
{
printf("空间不足");
free(ImageBuffer);
return 0;
}else
{
printf("Congratulations,this space can write!\n");
}
//那么要跳转的地址即messageboxA地址。E8所在地址即 ImageBase内存运行基址 + VirtualAddress节所在偏移 + VirtualSize 节真正长度即节结束的偏移 再加上8才到E8
CallX = MESSAGEBOXADDR - ( POptionHeader->ImageBase + pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize + 8 +5);
//jump 要跳转的地址即OEP程序入口点, X = 程序入口点 - (E9所在地址 + 5)
//这里程序入口点即ImageBase基址 + AddressOfEntryPoint E9所在地址计算同上
JmpX = POptionHeader->ImageBase + POptionHeader->AddressOfEntryPoint - (POptionHeader->ImageBase + pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize + 13 + 5);
*(PDWORD)(ShellCodeData + 9) = CallX;
*(PDWORD)(ShellCodeData + 14) = JmpX;
for(int i = 0;i<sizeof(ShellCodeData);i++)
{
printf("%x ", ShellCodeData[i]);
}
printf("\n");
memcpy((void*)((DWORD)ImageBuffer + pSectionHeader->PointerToRawData + pSectionHeader->Misc.VirtualSize), ShellCodeData,sizeof(ShellCodeData));
//修改OEP的值
POptionHeader->AddressOfEntryPoint = pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize;
return ImageBuffer;
}
void ReadPefileDos(char* buffer)
{
PIMAGE_DOS_HEADER pdos = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER PPeHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 POptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
pdos = (PIMAGE_DOS_HEADER)buffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)buffer+pdos->e_lfanew);
PPeHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4);
POptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)PPeHeader+IMAGE_SIZEOF_FILE_HEADER); //nt IS 20 BYTE
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)POptionHeader+PPeHeader->SizeOfOptionalHeader);
DWORD numbofsections = PPeHeader->NumberOfSections;
printf("..........................................\n");
printf("e_magic\t\t\t%04x\n",pdos->e_magic);
printf("e_lfanew\t\t%08x\n",pdos->e_lfanew);
printf("..........................................\n");
printf("Signature\t\t%08x\n",pNTHeader->Signature);
printf("Machine\t\t\t%04x\n",PPeHeader->Machine);
printf("PE NUMBER Sections\t%x\n",PPeHeader->NumberOfSections);
for(DWORD i=0;i<numbofsections;i++,pSectionHeader++)
{
printf(".......the %d Sections Name.........\n",i+1);
for(DWORD j=0;j<IMAGE_SIZEOF_SHORT_NAME;j++)
{
printf("%c",pSectionHeader->Name[j]);
}
printf("\r\n");
printf("Misc:\t\t\t%08x\n",pSectionHeader->Misc);
printf("VirtualAddress:\t\t%08x\n",pSectionHeader->VirtualAddress);
printf("SizeOfRawData:\t\t%08x\n",pSectionHeader->SizeOfRawData);
printf("Characteristics:\t%08x\n",pSectionHeader->Characteristics);
}
}