流沙团
GetFunctionAddrByName与GetFunctionAddrByOrdinals的实现
2017-11-13 流沙团


两个函数的具体实现







直接上代码了, 懒得讲了










// PEOperate.cpp: implementation of the PEOperate class.
//
//////////////////////////////////////////////////////////////////////

#include "PEOperate.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#include "windows.h"
#include "stdio.h"
#include "string.h"

#define MESSAGEBOXADDR 0x77D507EA
#define SHELLCODELENGTH 0x12

BYTE shellCode[]={
0x6A,00,0x6A,00,0x6A,00,0x6A,00,
0xE8,00,00,00,00,
0xE9,00,00,00,00
};

//加载PE文件到内存中
LPVOID ReadPEFile(LPSTR lpszFile)
{
FILE *pFile = NULL;
DWORD fileSize = 0;
LPVOID pFileBuffer = NULL;

//打开文件
pFile = fopen(lpszFile,"rb");

if(!pFile)
{
printf("无法打开文件EXE文件");
return NULL;
}

fseek(pFile,0,SEEK_END);
fileSize = ftell(pFile);
fseek(pFile,0,SEEK_SET);

//分配缓冲区
pFileBuffer = malloc(fileSize);
if(!pFileBuffer)
{
printf("分配空间失败!\n");
fclose(pFile);
return NULL;
}

//文件读取

size_t n = fread(pFileBuffer,fileSize,1,pFile);

if(!n)
{
printf("读取数据失败\n");
free(pFileBuffer);
fclose(pFile);
return NULL;
}

//关闭文件
fclose(pFile);
return pFileBuffer;

}

//内存直接写入到文件
void WirteToFile(LPVOID pFileBuffer,size_t fileSize,LPSTR lpszFile)
{
FILE *pFile = NULL;
//打开文件
pFile = fopen(lpszFile,"wb");

if(!pFile)
{
printf("无法打开文件EXE文件");
return;
}

size_t writeSize = fwrite(pFileBuffer,fileSize,1,pFile);
printf("WirteSize:%d\n",writeSize);

//关闭文件
fclose(pFile);
return;

}


//打印所有的PE头信息
VOID PrintNTHeaders(LPSTR lpszFile)
{
LPVOID pFileBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;

pFileBuffer= ReadPEFile(lpszFile);
if(!pFileBuffer)
{
printf("文件读取失败\n");
return;
}

//MZ标志
if(*((PWORD)pFileBuffer)!=IMAGE_DOS_SIGNATURE)
{
printf("不是有效的MZ标志\n");
free(pFileBuffer);
return;
}

pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;

//打印DOS头
printf("------------DOS头------------\n");
printf("MZ标志: %x\n",pDosHeader->e_magic);
printf("PE偏移: %x\n",pDosHeader->e_lfanew);

//判断是否是有效的PE
if(*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew))!=IMAGE_NT_SIGNATURE)
{
printf("不是有效的PE标志\n");
free(pFileBuffer);
return;
}

pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);

//打印NT头
printf("------------NT头------------\n");
printf("Signature: %x\n",pNTHeader->Signature);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
printf("------------标准PE头--------\n");
printf("Machine: %x\n",pPEHeader->Machine);
printf("节的数量: %x\n",pPEHeader->NumberOfSections);
printf("SizeOfOptionHeaders: %x\n",pPEHeader->SizeOfOptionalHeader);

//可选择PE头
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
printf("------------OPTION_PE头--------\n");
printf("Machine: %x \n",pOptionHeader->Magic);
printf("OEP: %x \n",pOptionHeader->AddressOfEntryPoint);
printf("ImageBase: %x \n",pOptionHeader->ImageBase);
printf("SectionAlignment: %x \n",pOptionHeader->SectionAlignment);
printf("FileAlignment: %x \n",pOptionHeader->FileAlignment);
printf("SizeOfImage: %x \n",pOptionHeader->SizeOfImage);
printf("SizeOfHeaders: %x \n",pOptionHeader->SizeOfHeaders);


//节表的信息(分别打印)
//确定节表的个数:
int Section_Number = pPEHeader->NumberOfSections;
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

for(int i=0;i<Section_Number;i++)
{
printf("------------节表信息:%d--------\n",i+1);
printf("Name: %s \n",pSectionHeader->Name);
printf("VirualSize : %x\n",pSectionHeader->Misc);
printf("VirualAddress: %x\n",pSectionHeader->VirtualAddress);
printf("SizeOfRawData: %x \n",pSectionHeader->SizeOfRawData);
printf("PointerToRowData: %x \n",pSectionHeader->PointerToRawData);

//下一个节表
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40);

}
//释放内存
free(pFileBuffer);
}


//将PE的FileBuffer拷贝到ImageBuffer
LPVOID CopyFileBufferToImageBuffer(LPVOID pFileBuffer)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;

if(!pFileBuffer)
{
printf("文件读取失败\n");
return NULL;
}

//Header信息
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

DWORD ImageSize = pOptionHeader->SizeOfImage;

//LPVOID pImageBuffer=NULL;
//分配缓冲区
LPVOID pImageBuffer=NULL;
pImageBuffer = malloc(ImageSize);

if(!pImageBuffer)
{
printf("pImageBuffer分配空间失败!\n");
return NULL;
}
//printf("%x \n",ImageSize);

memset(pImageBuffer,0,ImageSize);

//分段拷贝数据到ImageBuffer中
//1 拷贝头
DWORD HeaderSize = pOptionHeader->SizeOfHeaders;
//DWORD Head_i = 0;
//copy header
memcpy(pImageBuffer,pFileBuffer,HeaderSize);

//2 拷贝节 pSectionHeader
//数量,位置
int Section_Number = pPEHeader->NumberOfSections;
//分节进行写入

LPVOID pFileBuffer_sec = pFileBuffer;
LPVOID pImageBuffer_sec = pImageBuffer;

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

for(int i=0;i<Section_Number;i++)
{
DWORD FileSizeOfRawData = pSectionHeader->SizeOfRawData;
DWORD FilePointerToRawData = pSectionHeader->PointerToRawData;
DWORD MemVirtualAddress = pSectionHeader->VirtualAddress;
pFileBuffer_sec=(LPVOID)((DWORD)pFileBuffer+FilePointerToRawData);
pImageBuffer_sec=(LPVOID)((DWORD)pImageBuffer+MemVirtualAddress);

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

memcpy(pImageBuffer_sec,pFileBuffer_sec,FileSizeOfRawData);
//下一个节表
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40);
}

//写出
//WirteToFile(pImageBuffer,ImageSize,"c://image.exe");

return pImageBuffer;
}

LPVOID CopyImageBuffertoNewBuffer(LPVOID pImageBuffer)
{


return NULL;
}

BOOL MemeryTOFile(LPVOID pMemBuffer,LPSTR lpszFile)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;

//Header信息
pDosHeader = (PIMAGE_DOS_HEADER)pMemBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pMemBuffer+pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);


//将内存中的文件转入到File中
FILE *pFile = NULL;
//打开文件
pFile = fopen(lpszFile,"a+b");

if(!pFile)
{
printf("无法打开文件EXE文件");
return FALSE;
}

//写header
DWORD SIZE_HEADER = pOptionHeader->SizeOfHeaders;
fwrite(pMemBuffer,SIZE_HEADER,1,pFile);

//写节表
int Section_Number = pPEHeader->NumberOfSections;

LPVOID pImageBuffer_sec = pMemBuffer;

printf("pImageBuffer_SEC : %x \n",pImageBuffer_sec);
for(int i=0;i<Section_Number;i++)
{
DWORD FileSizeOfRawData = pSectionHeader->SizeOfRawData;
DWORD FilePointerToRawData = pSectionHeader->PointerToRawData;
DWORD MemVirtualAddress = pSectionHeader->VirtualAddress;

pImageBuffer_sec=(LPVOID)((DWORD)pMemBuffer+MemVirtualAddress);
printf("pImageBuffer_SEC : %x \n",pImageBuffer_sec);

fwrite(pImageBuffer_sec,FileSizeOfRawData,1,pFile);

pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40);
}



//关闭文件
fclose(pFile);

return TRUE;
}

DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;

if(!pFileBuffer)
{
printf("文件读取失败\n");
return NULL;
}

//Header信息
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

DWORD ImageSize = pOptionHeader->SizeOfImage;
int Section_Number = pPEHeader->NumberOfSections;
int i=0;
for(i=0;i<Section_Number;i++)
{
//printf("VirualSize : %x\n",pSectionHeader->Misc);
//printf("VirualAddress: %x\n",pSectionHeader->VirtualAddress);

DWORD dumpVirualSize = pSectionHeader->Misc.VirtualSize;
DWORD dumpVirualAddress = pSectionHeader->VirtualAddress;

if(dwRva>=dumpVirualAddress && dwRva <=dumpVirualAddress+dumpVirualSize)
{
//printf("地址在第:%d 节 %s \n",i+1,pSectionHeader->Name);
break;
}
//下一个节表
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40);
}

//确定是第i+1节
//确定偏移距离
DWORD fileOff = pSectionHeader->PointerToRawData + (dwRva-pSectionHeader->VirtualAddress);

return fileOff;
}


void TestAddCodeInCodeSec(LPSTR lpszFile)
{
LPVOID pFileBuffer = NULL;
pFileBuffer= ReadPEFile(lpszFile);
if(!pFileBuffer)
{
printf("文件读取失败\n");
return;
}

PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;

LPVOID pImageBuffer = CopyFileBufferToImageBuffer(pFileBuffer);

//Header信息
pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer+pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);


//确定添加代码的位置
//1判断能否添加
if((pSectionHeader->SizeOfRawData-pSectionHeader->Misc.VirtualSize)<=SHELLCODELENGTH){
printf("空余字节大小不够添加shellCode\n");
free(pFileBuffer);
return;
}

//size_t file_size = pSectionHeader->SizeOfRawData-pSectionHeader->Misc.VirtualSize;
//printf("%x \n",file_size);

//2代码加的位置
printf("pImageBuffer: %x\n",pImageBuffer);
DWORD shellLocation = pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize;
//确定位置
LPVOID pShellLoc = (LPVOID)((DWORD)pImageBuffer + shellLocation);
printf("pShellLoc: %x\n",pShellLoc);

//拷贝初始化代码到内存
memcpy(pShellLoc,shellCode,SHELLCODELENGTH);

//修改E8地址
DWORD pE8Content = MESSAGEBOXADDR - (((DWORD)pShellLoc+13 )- ((DWORD)pImageBuffer)+ pOptionHeader->ImageBase);
*(PDWORD)((DWORD)pShellLoc+9)=pE8Content;

//修改E9地址
DWORD pE9Content = (pOptionHeader->AddressOfEntryPoint+pOptionHeader->ImageBase) - (((DWORD)pShellLoc+0x12 )- ((DWORD)pImageBuffer)+ pOptionHeader->ImageBase);
*(PDWORD)((DWORD)pShellLoc+14)=pE9Content;

//修改OEP
pOptionHeader->AddressOfEntryPoint = (DWORD)pShellLoc-(DWORD)pImageBuffer;

//更改完的ImageBuffer,写出到File中
MemeryTOFile(pImageBuffer,"C://testShell.exe");

//释放
free(pFileBuffer);
free(pImageBuffer);
return;
}

void TestAddSecToFile(LPSTR lpszFile)
{
LPVOID pFileBuffer = NULL;
pFileBuffer= ReadPEFile(lpszFile);
if(!pFileBuffer)
{
printf("文件读取失败\n");
return;
}

PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL;

//Header信息
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
pSectionHeader_ADD = pSectionHeader;


//1 判断能否添加节
DWORD Header_size = pDosHeader->e_lfanew + 4 + 20 + pPEHeader->SizeOfOptionalHeader + pPEHeader->NumberOfSections*40;
if(pOptionHeader->SizeOfHeaders-Header_size<80)
{
printf("没有可用空间填充节表\n");
free(pFileBuffer);
return;
}

printf("空间:%d\n",pOptionHeader->SizeOfHeaders-Header_size);



//添加一个节
//确定参数
PIMAGE_SECTION_HEADER pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40);
pSectionHeader_ADD=(PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader_ADD+(pPEHeader->NumberOfSections)*40);
//="NewSec";
strcpy((char*)pSectionHeader_ADD->Name,"NewSec");
pSectionHeader_ADD->Misc.VirtualSize = 0x1000;
pSectionHeader_ADD->VirtualAddress = pOptionHeader->SizeOfImage;
pSectionHeader_ADD->SizeOfRawData = 0x1000;
pSectionHeader_ADD->PointerToRawData = pSectionHeader_LAST->PointerToRawData+pSectionHeader_LAST->SizeOfRawData;
pSectionHeader_ADD->Characteristics = pSectionHeader->Characteristics;

//填充0
LPVOID pSectionEND = (LPVOID)((DWORD)pSectionHeader_ADD+40);
memset(pSectionEND,0,IMAGE_SIZEOF_SECTION_HEADER);


printf("pFileBuffer: %x\n",pFileBuffer);
printf("pSectionHeader: %x\n",pSectionHeader);
printf("pSectionHeader_LAST: %x\n",pSectionHeader_LAST);
printf("pSectionHeader_ADD: %x\n",pSectionHeader_ADD);
printf("pSectionEND: %x\n",pSectionEND);

//修改PE头信息
pPEHeader->NumberOfSections = pPEHeader->NumberOfSections +1;
pOptionHeader->SizeOfImage = pOptionHeader->SizeOfImage+0x1000;

//写入到文件
FILE *pOutFile = NULL;
//打开文件
pOutFile = fopen("C://addSec.exe","a+b");

if(!pOutFile)
{
printf("无法打开文件EXE文件");
return;
}
//写出第一部分
printf("length: %x \n ",pSectionHeader_ADD->PointerToRawData+pSectionHeader_ADD->SizeOfRawData);

size_t writeSize = fwrite(pFileBuffer,pSectionHeader_ADD->PointerToRawData,1,pOutFile);
printf("WirteSize:%d\n",writeSize);
//写出第二部分
LPVOID pNewBuffer=(LPVOID)malloc(0x1000);
if(pNewBuffer==NULL)
{
printf("pNewBuffer分配空间失败\n");
return;
}
memset(pNewBuffer,0,0x1000);
writeSize = fwrite(pNewBuffer,0x1000,1,pOutFile);

//关闭文件
fclose(pOutFile);



free(pFileBuffer);
free(pNewBuffer);

}

void TestAddLastSectionToFile(LPSTR lpszFile)
{
LPVOID pFileBuffer = NULL;
pFileBuffer= ReadPEFile(lpszFile);
if(!pFileBuffer)
{
printf("文件读取失败\n");
return;
}

PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader_LAST = NULL;

//Header信息
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40);
int fileLength = pSectionHeader_LAST->PointerToRawData+pSectionHeader_LAST->SizeOfRawData;

//更改ImageSize
pOptionHeader->SizeOfImage = pOptionHeader->SizeOfImage+0x1000;

//更改最后一个节的SizeOfRawData 以及 VirtualSize
pSectionHeader_LAST->SizeOfRawData = pSectionHeader_LAST->SizeOfRawData+0x1000;
pSectionHeader_LAST->Misc.VirtualSize = pSectionHeader_LAST->Misc.VirtualSize+0x1000;

//写出文件

//写入到文件
FILE *pOutFile = NULL;
//打开文件
pOutFile = fopen("C://addSecLength.exe","a+b");

if(!pOutFile)
{
printf("无法打开文件EXE文件");
return;
}
//写出第一部分
printf("length: %x \n ",fileLength);

size_t writeSize = fwrite(pFileBuffer,fileLength,1,pOutFile);
printf("WirteSize:%d\n",writeSize);
//写出第二部分
LPVOID pNewBuffer=(LPVOID)malloc(0x1000);
if(pNewBuffer==NULL)
{
printf("pNewBuffer分配空间失败\n");
return;
}
memset(pNewBuffer,0,0x1000);
writeSize = fwrite(pNewBuffer,0x1000,1,pOutFile);

//关闭文件
fclose(pOutFile);
free(pFileBuffer);
free(pNewBuffer);

}

DWORD Align(int size,int filesize)
{
if(size<=filesize)
{
return filesize;
}else
{
int n=0;
if(size%filesize == 0)
{
n = size/filesize;
}else{
n = size/filesize;
n=n+1;
}

return filesize*n;

}
}


void TestChangeOneSec(LPSTR lpszFile)
{
LPVOID pFileBuffer = NULL;
pFileBuffer= ReadPEFile(lpszFile);
if(!pFileBuffer)
{
printf("文件读取失败\n");
return;
}

LPVOID pImageBuffer =NULL;
pImageBuffer = CopyFileBufferToImageBuffer(pFileBuffer);


PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader_LAST = NULL;

//Header信息
pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer+pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40);

//合并节的操作
DWORD LastSize = (pSectionHeader_LAST->SizeOfRawData > pSectionHeader_LAST->Misc.VirtualSize)?pSectionHeader_LAST->SizeOfRawData:pSectionHeader_LAST->Misc.VirtualSize;

pSectionHeader->Misc.VirtualSize = pSectionHeader_LAST->VirtualAddress + LastSize - pSectionHeader->VirtualAddress;
pSectionHeader->SizeOfRawData = pSectionHeader_LAST->VirtualAddress + LastSize - pSectionHeader->VirtualAddress;
pSectionHeader->PointerToRawData = pSectionHeader->VirtualAddress;

//设置属性值
//pSectionHeader->Characteristics
DWORD MyCharacteristics = pSectionHeader->Characteristics;
for(int k=0;k<pPEHeader->NumberOfSections;k++)
{
PIMAGE_SECTION_HEADER pSectionHeader_NEXT;
pSectionHeader_NEXT= (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+k*40);
MyCharacteristics = MyCharacteristics |(pSectionHeader_NEXT->Characteristics);
}

printf("MyCharacteristics: %x \n",MyCharacteristics);
pSectionHeader->Characteristics = MyCharacteristics;

pPEHeader->NumberOfSections = 0x1;

DWORD ImageSize = pOptionHeader->SizeOfImage;

//直接写出到文件
WirteToFile(pImageBuffer,ImageSize,"C://hebing.exe");

}

//IMAGE_DATA_DIRECTORY
void printDirectoryData(LPSTR lpszFile)
{
LPVOID pFileBuffer = NULL;
pFileBuffer= ReadPEFile(lpszFile);
if(!pFileBuffer)
{
printf("文件读取失败\n");
return;
}

PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_DATA_DIRECTORY DataDirectory=NULL;

//Header信息
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

//定位Directory_Data;
DataDirectory = pOptionHeader->DataDirectory;

//IMAGE_DIRECTORY_ENTRY_EXPORT
printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);

printf("IMAGE_DIRECTORY_ENTRY_IMPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size);

printf("IMAGE_DIRECTORY_ENTRY_RESOURCE: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);

printf("IMAGE_DIRECTORY_ENTRY_EXCEPTION: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size);

printf("IMAGE_DIRECTORY_ENTRY_SECURITY: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size);

printf("IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);

printf("IMAGE_DIRECTORY_ENTRY_DEBUG: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size);

printf("IMAGE_DIRECTORY_ENTRY_ARCHITECTURE: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].Size);

printf("IMAGE_DIRECTORY_ENTRY_GLOBALPTR: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].Size);

printf("IMAGE_DIRECTORY_ENTRY_TLS: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size);

printf("IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size);

printf("IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size);

printf("IMAGE_DIRECTORY_ENTRY_IAT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size);

printf("IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size);

printf("IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size);


}

void TestExportDirectory(LPSTR lpszFile)
{
LPVOID pFileBuffer = NULL;
pFileBuffer= ReadPEFile(lpszFile);
if(!pFileBuffer)
{
printf("文件读取失败\n");
return;
}

PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_DATA_DIRECTORY DataDirectory=NULL;

//Header信息
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

//定位Directory_Data;
DataDirectory = pOptionHeader->DataDirectory;

//导出表

printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);

//DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10);
//printf("%x \n",FoA);

DWORD Export_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
DWORD Export_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
FoA = RVAToFileOffset(pFileBuffer,Export_Directory_Address);

/*
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name; //指向该导出表文件名字符串
DWORD Base; //导出函数起始序号
DWORD NumberOfFunctions; //所有导出函数的个数
DWORD NumberOfNames; //以函数名字导出的函数个数
DWORD AddressOfFunctions; // 导出函数地址表 RVA
DWORD AddressOfNames; // 导出函数名称表 RVA
DWORD AddressOfNameOrdinals; // 导出函数序号表 RVA
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
*/

//定位导出表的位置

PIMAGE_EXPORT_DIRECTORY pExDirectory = NULL;
pExDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + FoA);

printf("Characteristics: %x\n",pExDirectory->Characteristics);
printf("TimeDateStamp: %x\n",pExDirectory->TimeDateStamp);
printf("MajorVersion: %x\n",pExDirectory->MajorVersion);
printf("MinorVersion: %x\n",pExDirectory->MinorVersion);
printf("Name: %x\n",pExDirectory->Name);
printf("Base: %x\n",pExDirectory->Base);
printf("NumberOfFunctions: %x\n",pExDirectory->NumberOfFunctions);
printf("NumberOfNames: %x\n",pExDirectory->NumberOfNames);
printf("AddressOfFunctions: %x\n",pExDirectory->AddressOfFunctions);
printf("AddressOfNames: %x\n",pExDirectory->AddressOfNames);
printf("AddressOfNameOrdinals: %x\n",pExDirectory->AddressOfNameOrdinals);

printf("------------------------\n");
//输出函数地址表信息
//AddressOfFunctions
DWORD ExAddressOfFunctions = pExDirectory->AddressOfFunctions;
DWORD ExAddressOfFunctionsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfFunctions);
DWORD ExNumberOfFunctions = pExDirectory->NumberOfFunctions;

PDWORD pExAddressOfFunctions = NULL;
pExAddressOfFunctions = (PDWORD)((DWORD)pFileBuffer + ExAddressOfFunctionsFoA);

//输出每个函数地址表信息
DWORD k =0;
for(k=0;k<ExNumberOfFunctions;k++)
{
printf("%d : %x \n",k,*pExAddressOfFunctions);
pExAddressOfFunctions++;
}
printf("------------------------\n");
//函数名称表
DWORD ExAddressOfNames = pExDirectory->AddressOfNames;
DWORD ExAddressOfNamesFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNames);
DWORD ExNumberOfNames = pExDirectory->NumberOfNames;

PDWORD pExAddressOfNames = NULL;
pExAddressOfNames = (PDWORD)((DWORD)pFileBuffer + ExAddressOfNamesFoA);

for(k=0;k<ExNumberOfNames;k++)
{
printf("%d : %x \n",k,*pExAddressOfNames);
//函数名的地址转换为FoA ,输出函数名
PDWORD NameAddress = (PDWORD)RVAToFileOffset(pFileBuffer,*pExAddressOfNames);
//输出函数名
printf("%s \n",(char*)((DWORD)pFileBuffer + (DWORD)NameAddress));
pExAddressOfNames++;
}

//函数序号表
printf("------------------------\n");
DWORD ExAddressOfNameOrdinals = pExDirectory->AddressOfNameOrdinals;
DWORD ExAddressOfNameOrdinalsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNameOrdinals);
ExNumberOfNames = pExDirectory->NumberOfNames;

PWORD pExAddressOfNameOrdinals = NULL;
pExAddressOfNameOrdinals = (PWORD)((DWORD)pFileBuffer + ExAddressOfNameOrdinalsFoA);


for(k=0;k<ExNumberOfNames;k++)
{
printf("%d : %x \n",k,*pExAddressOfNameOrdinals);
pExAddressOfNameOrdinals++;
}
}

DWORD GetFunctionAddrByName(LPVOID pFileBuffer,LPSTR FunctionName)
{
//LPVOID pFileBuffer = NULL;
//pFileBuffer= ReadPEFile(lpszFile);
if(!pFileBuffer)
{
printf("文件读取失败\n");
return 0;
}

PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_DATA_DIRECTORY DataDirectory=NULL;

//Header信息
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

//定位Directory_Data;
DataDirectory = pOptionHeader->DataDirectory;

//导出表

printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);

//DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10);
//printf("%x \n",FoA);

DWORD Export_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
DWORD Export_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
FoA = RVAToFileOffset(pFileBuffer,Export_Directory_Address);

//定位导出表的位置

PIMAGE_EXPORT_DIRECTORY pExDirectory = NULL;
pExDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + FoA);

printf("------------------------\n");


//输出每个函数地址表信息
WORD k =0;

//函数名称表
DWORD ExAddressOfNames = pExDirectory->AddressOfNames;
DWORD ExAddressOfNamesFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNames);
DWORD ExNumberOfNames = pExDirectory->NumberOfNames;

PDWORD pExAddressOfNames = NULL;
pExAddressOfNames = (PDWORD)((DWORD)pFileBuffer + ExAddressOfNamesFoA);

for(k=0;k<ExNumberOfNames;k++)
{
//printf("%d : %x \n",k,*pExAddressOfNames);
//函数名的地址转换为FoA ,输出函数名
PDWORD NameAddress = (PDWORD)RVAToFileOffset(pFileBuffer,*pExAddressOfNames);
//输出函数名
//printf("%s \n",(char*)((DWORD)pFileBuffer + (DWORD)NameAddress));
char* s_name = (char*)((DWORD)pFileBuffer + (DWORD)NameAddress);
WORD num = strcmp(FunctionName,s_name);
if(num==0)
{
break;
}
pExAddressOfNames++;
}


//函数的位置k
WORD Location_Fun = k;
printf("Function: %s\n",FunctionName);
printf("Location_Fun: %d \n",Location_Fun);

//return 0;
//函数序号表

DWORD ExAddressOfNameOrdinals = pExDirectory->AddressOfNameOrdinals;
DWORD ExAddressOfNameOrdinalsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNameOrdinals);
ExNumberOfNames = pExDirectory->NumberOfNames;
PWORD pExAddressOfNameOrdinals = NULL;
pExAddressOfNameOrdinals = (PWORD)((DWORD)pFileBuffer + ExAddressOfNameOrdinalsFoA);

//函数表的序号
WORD NUM_FUN = pExAddressOfNameOrdinals[Location_Fun];

printf("NUM_FUN: %d \n",NUM_FUN);

//return 0;

//输出函数地址表信息
//AddressOfFunctions
DWORD ExAddressOfFunctions = pExDirectory->AddressOfFunctions;
DWORD ExAddressOfFunctionsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfFunctions);
DWORD ExNumberOfFunctions = pExDirectory->NumberOfFunctions;

PDWORD pExAddressOfFunctions = NULL;
pExAddressOfFunctions = (PDWORD)((DWORD)pFileBuffer + ExAddressOfFunctionsFoA);

//确定函数的地址

DWORD Fun_Addr = pExAddressOfFunctions[NUM_FUN];
return Fun_Addr;
}

DWORD GetFunctionAddrByOrdinals(LPVOID pFileBuffer,WORD FunctionOrdinals)
{
if(!pFileBuffer)
{
printf("文件读取失败\n");
return 0;
}

PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_DATA_DIRECTORY DataDirectory=NULL;

//Header信息
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);

//定位Directory_Data;
DataDirectory = pOptionHeader->DataDirectory;

//导出表
printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);

//DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva)
DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10);
//printf("%x \n",FoA);

DWORD Export_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
DWORD Export_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
FoA = RVAToFileOffset(pFileBuffer,Export_Directory_Address);

//定位导出表的位置
PIMAGE_EXPORT_DIRECTORY pExDirectory = NULL;
pExDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + FoA);

//直接定位函数的位置
WORD Function_Index = FunctionOrdinals-pExDirectory->Base;

//输出函数地址表信息
//AddressOfFunctions
DWORD ExAddressOfFunctions = pExDirectory->AddressOfFunctions;
DWORD ExAddressOfFunctionsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfFunctions);
DWORD ExNumberOfFunctions = pExDirectory->NumberOfFunctions;

PDWORD pExAddressOfFunctions = NULL;
pExAddressOfFunctions = (PDWORD)((DWORD)pFileBuffer + ExAddressOfFunctionsFoA);

//确定函数的地址

DWORD Fun_Addr = pExAddressOfFunctions[Function_Index];
return Fun_Addr;

//return 0;
}




发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容