#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#pragma warning(disable:4996)
#define FILEPATH_IN "D:\IPMSG2007.exe"
#define FILEPATH_OUT "D:\Dll2.dll"
#define FILEPATH "D:\Dll3.dll"
#define SHELLCODELENGTH 12
#define MESSAGEBOXADDR 0x76A885D0
#define INFILEPATH "D:\IPMSG2007.exe"
BYTE shellCode[] = {
0x6A, 00, 0x6A, 00, 0x6A, 00, 0x6A, 00,
0xE8, 00, 00, 00, 00,
0xE9, 00, 00, 00, 00
};
//函数声明
//**************************************************************************
//ReadPEFile:将文件读取到缓冲区
//参数说明:
//lpszFile 文件路径
//pFileBuffer 缓冲区指针
//返回值说明:
//读取失败返回0 否则返回实际读取的大小
//**************************************************************************
DWORD ReadPEFile(IN LPSTR lpszFile, OUT LPVOID* pFileBuffer);
//**************************************************************************
//CopyFileBufferToImageBuffer:将文件从FileBuffer复制到ImageBuffer
//参数说明:
//pFileBuffer FileBuffer指针
//pImageBuffer ImageBuffer指针
//返回值说明:
//读取失败返回0 否则返回复制的大小
//**************************************************************************
DWORD CopyFileBufferToImageBuffer(IN LPVOID pFileBuffer, OUT LPVOID* pImageBuffer);
//**************************************************************************
//CopyImageBufferToNewBuffer:将ImageBuffer中的数据复制到新的缓冲区
//参数说明:
//pImageBuffer ImageBuffer指针
//pNewBuffer NewBuffer指针
//返回值说明:
//读取失败返回0 否则返回复制的大小
//**************************************************************************
DWORD CopyImageBufferToNewBuffer(IN LPVOID pImageBuffer,OUT LPVOID* pNewBuffer);
//**************************************************************************
//MemeryTOFile:将内存中的数据复制到文件
//参数说明:
//pMemBuffer 内存中数据的指针
//size 要复制的大小
//lpszFile 要存储的文件路径
//返回值说明:
//读取失败返回0 否则返回复制的大小
//**************************************************************************
BOOL MemeryTOFile(IN LPVOID pMemBuffer, IN size_t size, OUT LPSTR lpszFile);
//**************************************************************************
//RvaToFileOffset:将内存偏移转换为文件偏移
//参数说明:
//pFileBuffer FileBuffer指针
//dwRva RVA的值
//返回值说明:
//返回转换后的FOA的值 如果失败返回0
//**************************************************************************
DWORD RvaToFileOffset(IN LPVOID pFileBuffer, IN DWORD dwRva);
DWORD ReadPEFile(IN LPSTR lpszFile, OUT LPVOID* pFileBuffer)
{
FILE* fp = fopen(lpszFile, "rb");
DWORD fileSize = 0;
if (!fp)
{
printf("无法打开exe文件!");
return 0;
}
fseek(fp, 0, SEEK_END);
fileSize = ftell(fp);
fseek(fp, 0, SEEK_SET);
*pFileBuffer = malloc(fileSize);
if (!(*pFileBuffer))
{
printf("分配空间失败!");
fclose(fp);
return 0;
}
size_t n = fread(*pFileBuffer, fileSize, 1, fp);
if (!n)
{
printf("读取数据失败!");
free(*pFileBuffer);
fclose(fp);
return 0;
}
fclose(fp);
return n;
}
DWORD CopyFileBufferToImageBuffer(IN LPVOID pFileBuffer, OUT LPVOID* pImageBuffer)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
if ((*(PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("不是有效的MZ标志!");
free(pFileBuffer);
return 0;
}
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
if (*((PDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("不是有效的PE标志!");
free(pFileBuffer);
return 0;
}
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
*pImageBuffer = malloc(pOptionalHeader->SizeOfImage);
if (!(*pImageBuffer))
{
printf("分配内存失败!");
return 0;
}
memset(*pImageBuffer, 0, pOptionalHeader->SizeOfImage);
memcpy(*pImageBuffer, pFileBuffer, pOptionalHeader->SizeOfHeaders);
//printf("%c%c", *((char *)*pImageBuffer), *((char*)*pImageBuffer + 1));
for (int i = 0; i < pFileHeader->NumberOfSections;i++)
{
memcpy((char *) *pImageBuffer + pSectionHeader->VirtualAddress,(char *) pFileBuffer + pSectionHeader->PointerToRawData,
pSectionHeader->SizeOfRawData);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader + IMAGE_SIZEOF_SECTION_HEADER);
}
return pOptionalHeader->SizeOfImage;
}
DWORD CopyImageBufferToNewBuffer(IN LPVOID pImageBuffer, OUT LPVOID* pNewBuffer)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL, flag = NULL;
if ((*(PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("不是有效的MZ标志!");
free(pImageBuffer);
return 0;
}
pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
if (*((PDWORD)((DWORD)pImageBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("不是有效的PE标志!");
free(pImageBuffer);
return 0;
}
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = flag = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
int num = 0;
for (int i = 0; i < pFileHeader->NumberOfSections; i++)
{
num += pSectionHeader->SizeOfRawData;
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader + IMAGE_SIZEOF_SECTION_HEADER);
}
pSectionHeader = flag;
num += pOptionalHeader->SizeOfHeaders;
*pNewBuffer = malloc(num);
memset(*pNewBuffer, 0, num);
memcpy(*pNewBuffer, pImageBuffer, pOptionalHeader->SizeOfHeaders);
for (int j = 0; j < pFileHeader->NumberOfSections; j++)
{
memcpy((char*)*pNewBuffer + pSectionHeader->PointerToRawData, (char*)pImageBuffer + pSectionHeader->VirtualAddress,
pSectionHeader->SizeOfRawData);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader + IMAGE_SIZEOF_SECTION_HEADER);
}
//printf("%c %c %d
", *((char*)*pNewBuffer), *((char*)*pNewBuffer + 1), __LINE__);
return num;
}
BOOL MemeryTOFile(IN LPVOID pMemBuffer, IN size_t size, OUT LPSTR lpszFile)
{
FILE* fp;
fp = fopen(lpszFile, "wb");
if (!fp)
{
printf("打开文件失败!");
return FALSE;
}
fwrite(pMemBuffer, size, 1, fp);
fclose(fp);
return TRUE;
}
VOID TestAddCodeInCodeSec()
{
LPVOID pFileBuffer = NULL;
LPVOID pImageBuffer = NULL;
LPVOID pNewBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PBYTE codeBegin = NULL;
BOOL isOk = FALSE;
DWORD size = 0;
ReadPEFile(FILEPATH_IN, &pFileBuffer);
if (!pFileBuffer)
{
printf("文件-->缓冲区失败!");
return;
}
CopyFileBufferToImageBuffer(pFileBuffer, &pImageBuffer);
if (!pImageBuffer)
{
printf("FileBuffer-->ImageBuffer失败!");
free(pFileBuffer);
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(((DWORD)pDosHeader + pDosHeader->e_lfanew) + 4 + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + 0XE0);
if (pSectionHeader->SizeOfRawData - pSectionHeader->Misc.VirtualSize < SHELLCODELENGTH)
{
printf("代码空闲区不够!");
free(pFileBuffer);
free(pImageBuffer);
}
codeBegin = (PBYTE)((DWORD)pImageBuffer + pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize);
memcpy(codeBegin, shellCode, SHELLCODELENGTH);
//修改E8 X
DWORD callAddr = MESSAGEBOXADDR - (pOptionalHeader->ImageBase + (((DWORD)codeBegin + 0xD) - (DWORD)pImageBuffer));
*(PDWORD)(codeBegin + 9) = callAddr;
//修改E9 X
DWORD jmpAddr = (pOptionalHeader->ImageBase + pOptionalHeader->AddressOfEntryPoint)
- (pOptionalHeader->ImageBase + ((DWORD)codeBegin + SHELLCODELENGTH - (DWORD)pImageBuffer));
*(PWORD)(codeBegin + 0xE) = jmpAddr;
pOptionalHeader->AddressOfEntryPoint = (DWORD)codeBegin - (DWORD)pImageBuffer;
size = CopyImageBufferToNewBuffer(pImageBuffer, &pNewBuffer);
if (size == 0 || !pNewBuffer)
{
printf("ImageBuffer-->NewBuffer失败!");
free(pFileBuffer);
free(pImageBuffer);
return;
}
isOk = MemeryTOFile(pNewBuffer, size, FILEPATH_OUT);
if (isOk)
{
printf("存盘成功!");
}
}
//添加节和节表
DWORD AddSectionToFileBuffer()
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
LPVOID pFileBuffer = NULL;
DWORD addr = 0;
ReadPEFile(FILEPATH_IN, &pFileBuffer);
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
pSectionHeader = (PIMAGE_SECTION_HEADER)(pOptionalHeader + 1);
if (pOptionalHeader->SizeOfHeaders - (pDosHeader->e_lfanew + 4 + 20 + pFileHeader->SizeOfOptionalHeader
+ pFileHeader->NumberOfSections * 0x28) < 80)
{
printf("节表后空间不足!");
free(pFileBuffer);
return;
}
PIMAGE_SECTION_HEADER pNewSectionHeader = pSectionHeader + (pFileHeader->NumberOfSections - 1);
int sum = pNewSectionHeader->PointerToRawData + pNewSectionHeader->SizeOfRawData + 0x1000;
addr = pNewSectionHeader->PointerToRawData + pNewSectionHeader->SizeOfRawData;
LPVOID pNewBuffer = malloc(sum);
memset((char *)pNewBuffer + pNewSectionHeader->PointerToRawData + pNewSectionHeader->SizeOfRawData, 0x20, 0x1000);
pFileHeader->NumberOfSections += 1;
pOptionalHeader->SizeOfImage += 0x1000;
PIMAGE_SECTION_HEADER pLastSectionHeader = pSectionHeader + 4;
memcpy(pLastSectionHeader, pSectionHeader, 0x28);
strcpy(pLastSectionHeader->Name, ".tttt");
pLastSectionHeader->Misc.VirtualSize = 0x1000;
int size = (pNewSectionHeader->Misc.VirtualSize > pNewSectionHeader->SizeOfRawData) ? pNewSectionHeader->Misc.VirtualSize : pNewSectionHeader->SizeOfRawData;
pLastSectionHeader->VirtualAddress = pNewSectionHeader->VirtualAddress + size;
pLastSectionHeader->SizeOfRawData = 0x1000;
pLastSectionHeader->PointerToRawData = pNewSectionHeader->PointerToRawData + pNewSectionHeader->SizeOfRawData;
//printf("%x
", pLastSectionHeader->PointerToRawData);
memcpy(pNewBuffer, pFileBuffer, sum);
free(pFileBuffer);
if (MemeryTOFile(pNewBuffer, sum, FILEPATH_OUT))
{
printf("存盘成功!");
}
free(pNewBuffer);
return addr;
}
//扩大最后一个节
VOID ExpandLastSection()
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
LPVOID pFileBuffer = NULL;
LPVOID pNewBuffer = NULL;
ReadPEFile(FILEPATH_IN, &pFileBuffer);
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
pSectionHeader = (PIMAGE_SECTION_HEADER)(pOptionalHeader + 1);
PIMAGE_SECTION_HEADER pLastSectionHeader = pSectionHeader + pFileHeader->NumberOfSections - 1;
pNewBuffer = malloc(pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData + 0x1000);
memset((char*)pNewBuffer + pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData, 0x20, 0x1000);
pOptionalHeader->SizeOfImage += 0x1000;
pLastSectionHeader->Misc.VirtualSize = pLastSectionHeader->SizeOfRawData = pLastSectionHeader->SizeOfRawData + 0x1000;
memcpy(pNewBuffer, pFileBuffer, pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData);
if (MemeryTOFile(pNewBuffer, pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData + 0x1000
, FILEPATH_OUT))
{
printf("存盘成功!");
}
free(pFileBuffer);
free(pNewBuffer);
}
//合并所有节
VOID MergeAllSection()
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL, pNextSectionHeader = NULL;
LPVOID pFileBuffer = NULL, pImageBuffer = NULL, pNewBuffer = NULL;
ReadPEFile(FILEPATH_IN, &pFileBuffer);
CopyFileBufferToImageBuffer(pFileBuffer, &pImageBuffer);
free(pFileBuffer);
pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
pNextSectionHeader = pSectionHeader = (PIMAGE_SECTION_HEADER)(pOptionalHeader + 1);
pSectionHeader->Misc.VirtualSize = pSectionHeader->SizeOfRawData = pOptionalHeader->SizeOfImage -
pSectionHeader->VirtualAddress;
for (int i = 0; i < pFileHeader->NumberOfSections; i++)
{
pSectionHeader->Characteristics = pSectionHeader->Characteristics | pNextSectionHeader->Characteristics;
pNextSectionHeader += 1;
}
pFileHeader->NumberOfSections = 1;
CopyImageBufferToNewBuffer(pImageBuffer, &pNewBuffer);
if (MemeryTOFile(pNewBuffer, pOptionalHeader->SizeOfImage, FILEPATH_OUT))
{
printf("存盘成功!");
}
free(pImageBuffer);
free(pNewBuffer);
}
DWORD RvaToFileOffset(IN LPVOID FileBuffer, IN DWORD Rva)
{
PIMAGE_DOS_HEADER pDOS = (PIMAGE_DOS_HEADER)FileBuffer;
PIMAGE_NT_HEADERS pNT = (PIMAGE_NT_HEADERS)((DWORD)FileBuffer + pDOS->e_lfanew);
PIMAGE_SECTION_HEADER pSECTION = (PIMAGE_SECTION_HEADER)(pNT + 1);
int i;
for (i = 0; i < pNT->FileHeader.NumberOfSections; i++, pSECTION++) {
if (Rva >= pSECTION->VirtualAddress && Rva < pSECTION->VirtualAddress + pSECTION->SizeOfRawData) {
return (Rva - pSECTION->VirtualAddress + pSECTION->PointerToRawData);
break;
}
}
return 0;
}
VOID PrintfExportImform()
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_EXPORT_DIRECTORY pExport = NULL;
LPVOID pFileBuffer = NULL;
DWORD pExportFileOffset = NULL;
ReadPEFile(FILEPATH_IN, &pFileBuffer);
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
pExportFileOffset = pOptionalHeader->DataDirectory[0].VirtualAddress;
pExportFileOffset = RvaToFileOffset(pFileBuffer, pExportFileOffset);
pExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + pExportFileOffset);
//printf("%d", pExport->NumberOfFunctions);
//函数地址
DWORD FileOffOfFunctions = RvaToFileOffset(pFileBuffer, pExport->AddressOfFunctions);
LPVOID pFunctionInFile = (LPVOID)((DWORD)pFileBuffer + FileOffOfFunctions);
for (int i = 0; i < pExport->NumberOfFunctions; i++)
{
printf("%x
", *((PDWORD)pFunctionInFile));
pFunctionInFile = (LPVOID)((DWORD)pFunctionInFile + 4);
}
//函数名称
//AddressOfNames在文件中的偏移
DWORD FileOffOfNames = RvaToFileOffset(pFileBuffer, pExport->AddressOfNames);
//printf("%x", FileOffOfNames);
//AddressOfNames在文件中的地址
LPVOID pNamesInFile = (LPVOID)((DWORD)pFileBuffer + FileOffOfNames);
//printf("%x", pNamesInFile);
//AddressOfNames数组项在文件中的偏移
DWORD OffsetOfNames;
LPVOID pNameInFile = NULL;
//OffsetOfNames = RvaToFileOffset(pFileBuffer, (DWORD)(*((PDWORD)pNamesInFile)));
for (int j = 0; j < pExport->NumberOfNames; j++)
{
OffsetOfNames = RvaToFileOffset(pFileBuffer, (DWORD)(*((PDWORD)pNamesInFile)));
pNameInFile = (LPVOID)((DWORD)pFileBuffer + OffsetOfNames);
printf("%s
", pNameInFile);
pNamesInFile = (LPVOID)((DWORD)pNamesInFile + 4);
}
//函数序号
DWORD OrdOffsetInFile = RvaToFileOffset(pFileBuffer, pExport->AddressOfNameOrdinals);
LPVOID pOrdinalsInFile = (LPVOID)((DWORD)pFileBuffer + OrdOffsetInFile);
for (int k = 0; k < pExport->NumberOfNames; k++)
{
printf("%d
", *((PWORD)pOrdinalsInFile));
pOrdinalsInFile = (LPVOID)((DWORD)pOrdinalsInFile + 2);
}
}
VOID GetFunctionAddrByName(LPVOID pFileBuffer, char* funcName)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_EXPORT_DIRECTORY pExport = NULL;
DWORD pExportFileOffset = NULL;
//ReadPEFile(FILEPATH_IN, &pFileBuffer);
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
pExportFileOffset = pOptionalHeader->DataDirectory[0].VirtualAddress;
pExportFileOffset = RvaToFileOffset(pFileBuffer, pExportFileOffset);
pExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + pExportFileOffset);
//printf("%d", pExport->NumberOfFunctions);
//函数名称
//AddressOfNames在文件中的偏移
DWORD FileOffOfNames = RvaToFileOffset(pFileBuffer, pExport->AddressOfNames);
//printf("%x", FileOffOfNames);
//AddressOfNames在文件中的地址
LPVOID pNamesInFile = (LPVOID)((DWORD)pFileBuffer + FileOffOfNames);
//printf("%x", pNamesInFile);
//AddressOfNames数组项在文件中的偏移
DWORD OffsetOfNames;
LPVOID pNameInFile = NULL;
//OffsetOfNames = RvaToFileOffset(pFileBuffer, (DWORD)(*((PDWORD)pNamesInFile)));
int j;
for (j = 0; j < pExport->NumberOfNames; j++)
{
OffsetOfNames = RvaToFileOffset(pFileBuffer, (DWORD)(*((PDWORD)pNamesInFile)));
pNameInFile = (LPVOID)((DWORD)pFileBuffer + OffsetOfNames);
if( !strcmp(funcName, (char *)pNameInFile))
break;
pNamesInFile = (LPVOID)((DWORD)pNamesInFile + 4);
}
//函数序号
DWORD OrdOffsetInFile = RvaToFileOffset(pFileBuffer, pExport->AddressOfNameOrdinals);
LPVOID pOrdinalsInFile = (LPVOID)((DWORD)pFileBuffer + OrdOffsetInFile);
pOrdinalsInFile = (LPVOID)((DWORD)pOrdinalsInFile + 2 * j);
int flag = *((PWORD)pOrdinalsInFile);
//函数地址
DWORD FileOffOfFunctions = RvaToFileOffset(pFileBuffer, pExport->AddressOfFunctions);
LPVOID pFunctionInFile = (LPVOID)((DWORD)pFileBuffer + FileOffOfFunctions);
pFunctionInFile = (LPVOID)((DWORD)pFunctionInFile + 4 * flag);
printf("%x
", *((PDWORD)pFunctionInFile));
}
VOID GetFunctionAddrByOrdinals(LPVOID pFileBuffer, int num)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_EXPORT_DIRECTORY pExport = NULL;
DWORD pExportFileOffset = NULL;
//ReadPEFile(FILEPATH_IN, &pFileBuffer);
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
pExportFileOffset = pOptionalHeader->DataDirectory[0].VirtualAddress;
pExportFileOffset = RvaToFileOffset(pFileBuffer, pExportFileOffset);
pExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + pExportFileOffset);
//printf("%d", pExport->NumberOfFunctions);
DWORD FileOffOfFunctions = RvaToFileOffset(pFileBuffer, pExport->AddressOfFunctions);
LPVOID pFunctionInFile = (LPVOID)((DWORD)pFileBuffer + FileOffOfFunctions);
pFunctionInFile = (LPVOID)((DWORD)pFunctionInFile + 4 * (num - pExport->Base));
printf("%x
", *((PDWORD)pFunctionInFile));
}
//打印重定位表
VOID PrintRelocation()
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
LPVOID pFileBuffer = NULL;
PIMAGE_BASE_RELOCATION pRelocation = NULL;
DWORD offset = 0;
ReadPEFile(FILEPATH_IN, &pFileBuffer);
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
offset = RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[5].VirtualAddress);
pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + offset);
int num = 0;
int i = 0;
LPVOID pDetails = NULL;
while (1)
{
if (pRelocation->VirtualAddress == 0 && pRelocation->SizeOfBlock == 0)
break;
num = (pRelocation->SizeOfBlock - 8) / 2;
printf("VirtualAddress:%x
", pRelocation->VirtualAddress);
printf("SizeOfBlock:%d
", pRelocation->SizeOfBlock);
printf("修改项:
");
pDetails = (LPVOID)((DWORD)pRelocation + 8);
for (i = 0; i < num; i++)
{
printf("%x
", *((PWORD)pDetails));
pDetails = (LPVOID)((DWORD)pDetails + 2);
}
pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocation + pRelocation->SizeOfBlock);
}
}
DWORD FileFoaToRva(LPVOID pFileBuffer, DWORD foa)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)(pNTHeader + 1);
for (int i = 0; i < pNTHeader->FileHeader.NumberOfSections; i++, pSectionHeader++)
{
if (foa > pSectionHeader->PointerToRawData && foa <= pSectionHeader->PointerToRawData + pSectionHeader->SizeOfRawData)
return (foa - pSectionHeader->PointerToRawData + pSectionHeader->VirtualAddress);
}
return 0;
}
VOID MoveExport()
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
PIMAGE_EXPORT_DIRECTORY pExport = NULL;
LPVOID pFileBuffer = NULL;
LPVOID pAddrOfFunc = NULL;
LPVOID pAddrOfNames = NULL;
LPVOID pAddrOfOri = NULL;
LPVOID pCurrent = NULL;
LPVOID pFunc = NULL;
LPVOID pNames = NULL;
LPVOID pOrdinals = NULL;
LPVOID pNamesInFile = NULL;
LPVOID pAddrName = NULL;
int sum = 0;
DWORD addr = AddSectionToFileBuffer();
sum = addr + 0x1000;
ReadPEFile(FILEPATH_OUT, &pFileBuffer);
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
DWORD Foa = RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[0].VirtualAddress);
pExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + Foa);
pAddrOfFunc = (LPVOID)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pExport->AddressOfFunctions));
pAddrOfNames = (LPVOID)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pExport->AddressOfNames));
pAddrOfOri = (LPVOID)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pExport->AddressOfNameOrdinals));
pFunc = pCurrent = (LPVOID)((DWORD)pFileBuffer + addr);
memcpy(pCurrent, pAddrOfFunc, 4 * pExport->NumberOfFunctions);
pOrdinals = pCurrent = (LPVOID)((DWORD)pCurrent + 4 * pExport->NumberOfFunctions);
memcpy(pCurrent, pAddrOfOri, 2 * pExport->NumberOfNames);
pNames = pAddrName = pCurrent = (LPVOID)((DWORD)pCurrent + 2 * pExport->NumberOfNames);
memcpy(pCurrent, pAddrOfNames, 4 * pExport->NumberOfNames);
pCurrent = (LPVOID)((DWORD)pCurrent + 4 * pExport->NumberOfNames);
for (int i = 0; i < pExport->NumberOfNames; i++)
{
Foa = RvaToFileOffset(pFileBuffer,(DWORD) (*((PDWORD)pAddrOfNames)));
pNamesInFile = (LPVOID)((DWORD)pFileBuffer + Foa);
strcpy((char*)pCurrent, (char*)pNamesInFile);
*((PDWORD)pAddrName) = FileFoaToRva(pFileBuffer,(DWORD)pCurrent - (DWORD)pFileBuffer);
pCurrent = (LPVOID)((DWORD)pCurrent + strlen((char*)pNamesInFile) + 1);
pAddrName = (LPVOID)((DWORD)pAddrName + 4);
pAddrOfNames = (LPVOID)((DWORD)pAddrOfNames + 4);
}
memcpy(pCurrent, pExport, 0x28);
pExport = (PIMAGE_EXPORT_DIRECTORY)pCurrent;
pExport->AddressOfFunctions = FileFoaToRva(pFileBuffer, (DWORD)pFunc - (DWORD)pFileBuffer);
pExport->AddressOfNames = FileFoaToRva(pFileBuffer, (DWORD)pNames - (DWORD)pFileBuffer);
pExport->AddressOfNameOrdinals = FileFoaToRva(pFileBuffer, (DWORD)pOrdinals - (DWORD)pFileBuffer);
pOptionalHeader->DataDirectory[0].VirtualAddress = FileFoaToRva(pFileBuffer,(DWORD)pCurrent - (DWORD)pFileBuffer);
MemeryTOFile(pFileBuffer, sum, FILEPATH);
}
DWORD MoveRelo()
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
PIMAGE_BASE_RELOCATION pRelocation = NULL;
LPVOID pFileBuffer = NULL;
LPVOID pNewBuffer = NULL;
LPVOID pNewRe = NULL;
int sum = 0;
DWORD addr = AddSectionToFileBuffer();
sum = addr + 0x1000;
ReadPEFile(FILEPATH_OUT, &pFileBuffer);
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[5].VirtualAddress));
pNewRe = pNewBuffer = (LPVOID)((DWORD)pFileBuffer + addr);
while (1)
{
if (pRelocation->SizeOfBlock == 0 && pRelocation->VirtualAddress == 0)
{
memcpy(pNewBuffer, pRelocation, 8);
break;
}
memcpy(pNewBuffer, pRelocation, pRelocation->SizeOfBlock);
pNewBuffer = (LPVOID)((DWORD)pNewBuffer + pRelocation->SizeOfBlock);
pRelocation = (LPVOID)((DWORD)pRelocation + pRelocation->SizeOfBlock);
}
pOptionalHeader->DataDirectory[5].VirtualAddress = FileFoaToRva(pFileBuffer, (DWORD)pNewRe - (DWORD)pFileBuffer);
MemeryTOFile(pFileBuffer, sum, FILEPATH);
return addr;
}
VOID FixRelocation()
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
PIMAGE_BASE_RELOCATION pRelocation = NULL;
LPVOID pFileBuffer = NULL;
LPVOID pr = NULL;
LPVOID offset = NULL;
int addr = MoveRelo();
int sum = 0, howMany = 0;
sum = addr + 0x1000;
//printf("%x
", addr);
ReadPEFile(FILEPATH, &pFileBuffer);
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
//printf("%x
", RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[5].VirtualAddress));
pr = pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[5].VirtualAddress));
pOptionalHeader->ImageBase += 0x1000;
int i = 0;
while (1)
{
if (pRelocation->VirtualAddress == 0 && pRelocation->SizeOfBlock == 0)
break;
howMany = (pRelocation->SizeOfBlock - 8) / 2;
for (i = 0; i < howMany; i++)
{
pr = (LPVOID)((DWORD)pRelocation + 8);
if (*((PWORD)pr) >> 12 == 3)
{
offset = (LPVOID)(RvaToFileOffset(pFileBuffer, (pRelocation->VirtualAddress +
(*((PWORD)pr) & 0xfff))) + (DWORD)pFileBuffer);
*((PDWORD)offset) += 0x1000;
}
pr = (LPVOID)((DWORD)pr + 2);
}
pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocation + pRelocation->SizeOfBlock);
}
MemeryTOFile(pFileBuffer, sum, FILEPATH);
}
VOID PrintImportTable()
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
LPVOID pFileBuffer = NULL;
PIMAGE_IMPORT_DESCRIPTOR pImport = NULL;
PIMAGE_IMPORT_BY_NAME pName = NULL;
DWORD addrOfOri = 0;
int i = 0;
ReadPEFile(FILEPATH_IN, &pFileBuffer);
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
pImport = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer +
RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[1].VirtualAddress));
addrOfOri = (DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pImport->OriginalFirstThunk);
while (1)
{
if (pImport->OriginalFirstThunk == 0)
break;
printf("****************%s****************
", (char *)((DWORD)pFileBuffer +
RvaToFileOffset(pFileBuffer, pImport->Name)));
addrOfOri = (DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pImport->OriginalFirstThunk);
while (1)
{
if ((DWORD)(*(PDWORD)addrOfOri == 0))
{
break;
}
if ((DWORD)(*(PDWORD)addrOfOri) >> 31 == 1)
printf("序号:%d
", (DWORD)(*(PDWORD)addrOfOri) & 0x7fffffff);
else
{
pName = (PIMAGE_IMPORT_BY_NAME)((DWORD)pFileBuffer +
RvaToFileOffset(pFileBuffer, (DWORD)(*(PDWORD)addrOfOri)));
i = 0;
while (pName->Name[i] != 0)
{
printf("%c", pName->Name[i]);
i++;
}
printf("
");
}
addrOfOri += 4;
}
pImport = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImport + 20);
}
free(pFileBuffer);
}
VOID printBoundImportTable()
{//RVATOFOA需要考虑rva在sizeofheaders里的情况
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
PIMAGE_BOUND_IMPORT_DESCRIPTOR pBdImport = NULL, pImport = NULL;
PIMAGE_BOUND_FORWARDER_REF pRef = NULL;
LPVOID pFileBuffer = NULL;
ReadPEFile(FILEPATH_IN, &pFileBuffer);
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
if (pOptionalHeader->DataDirectory[11].VirtualAddress == 0)
{
printf("没有绑定导入表
");
return;
}
pBdImport = pImport = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer +
RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[11].VirtualAddress));
int i = 0;
while (1)
{
if (pBdImport->OffsetModuleName == 0 && pBdImport->NumberOfModuleForwarderRefs == 0 && pBdImport->TimeDateStamp == 0)
break;
printf("***************OffsetMoudleName:%s*****************
", (char*)((DWORD)pImport + pBdImport->OffsetModuleName));
printf("TimeDateStamp:%d
", pBdImport->TimeDateStamp);
printf("NumberOfModuleForWarderRefs:%d
", pBdImport->NumberOfModuleForwarderRefs);
pRef = (PIMAGE_BOUND_FORWARDER_REF)((DWORD)pBdImport + 8);
for (i = 0; i < pBdImport->NumberOfModuleForwarderRefs; i++)
{
printf("***************OffsetMoudleName:%s*****************
", (char*)((DWORD)pImport + pRef->OffsetModuleName));
printf("TimeDateStamp:%d
", pRef->TimeDateStamp);
pRef += 1;
}
pBdImport += pBdImport->NumberOfModuleForwarderRefs + 1;
}
}
PrintResourceTable()
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
PIMAGE_RESOURCE_DIRECTORY pRes = NULL;
PIMAGE_RESOURCE_DIRECTORY_ENTRY pEntry = NULL;
PIMAGE_DATA_DIRECTORY pDataDir = NULL;
LPVOID pFileBuffer = NULL;
ReadPEFile(FILEPATH_IN, &pFileBuffer);
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1);
pRes = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer,pOptionalHeader->DataDirectory[2].VirtualAddress));
size_t num1 = pRes->NumberOfNamedEntries + pRes->NumberOfIdEntries;
pEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pRes + sizeof(IMAGE_RESOURCE_DIRECTORY));
for (size_t i = 0; i < num1; i++)
{
if (!pEntry[i].NameIsString)
{
printf("资源类型ID: %d
", pEntry[i].Id);
if (pEntry[i].Id == 3)
{
PIMAGE_RESOURCE_DIRECTORY pRes2 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pRes + pEntry[i].OffsetToDirectory);
PIMAGE_RESOURCE_DIRECTORY_ENTRY pEntry1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes2 + 1);
size_t num2 = pRes2->NumberOfIdEntries + pRes2->NumberOfNamedEntries;
for (size_t i = 0; i < num2; i++)
{
if(!pEntry1[i].NameIsString)
{
printf("资源编号ID: %d", pEntry1[1].Id);
}
else
{
PIMAGE_RESOURCE_DIR_STRING_U pStr1 = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pRes + pEntry1[i].NameOffset);
WCHAR str1[MAX_PATH] = { 0 };
memcpy_s(str1, MAX_PATH, pStr1, pStr1->Length * sizeof(WCHAR));
printf("%资源名称: %ls", str1);
}
PIMAGE_RESOURCE_DIRECTORY pRes3 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pRes + pEntry1[i].OffsetToDirectory);
PIMAGE_RESOURCE_DIRECTORY_ENTRY pEntry2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes3 + 1);
size_t num3 = pRes3->NumberOfIdEntries + pRes3->NumberOfNamedEntries;
for (size_t i = 0; i < num3; i++)
{
PIMAGE_RESOURCE_DATA_ENTRY pData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pRes + pEntry2[i].OffsetToData);
printf("rva: %x size: %x
", pData->OffsetToData, pData->Size);
}
printf("
");
}
}
}
else {
PIMAGE_RESOURCE_DIR_STRING_U pStr = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pRes + pEntry[i].NameOffset);
WCHAR str[MAX_PATH] = { 0 };
memcpy_s(str, MAX_PATH, pStr, pStr->Length * sizeof(WCHAR));
printf("%资源名称: %ls", str);
}
}
}
VOID PrintfResourceTable() {
//定义一个名称数组
static char* szResName[0x11] =
{ 0, "鼠标指针", "位图", "图标", "菜单", "对话框", "字符串列表",
"字体目录", "字体", "快捷键", "非格式化资源", "消息列表",
"鼠标指针组", "zz", "图标组", "xx", "版本信息"
};
//读取文件
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNtHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;
PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = NULL;
printf("打印的文件是:%s!
", INFILEPATH);
//定义文件缓冲区
LPVOID pFileBuffer = NULL;
ReadPEFile(INFILEPATH, &pFileBuffer);
if (pFileBuffer != 0) {
printf("文件打开成功!
");
}
else
{
printf("文件打开失败!
");
free(pFileBuffer);
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNtHeader) + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)(((DWORD)pOptionalHeader) + 96);
pDataDirectory += 2;
PIMAGE_RESOURCE_DIRECTORY pResourceDirectory = NULL;
DWORD RESRVA = pDataDirectory->VirtualAddress;
DWORD RESFOA = 0;
RESFOA = RvaToFileOffset(pFileBuffer, RESRVA);
//定位资源目录
pResourceDirectory = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pFileBuffer + RESFOA);
//printf("NumberOfNameEntries:%d,NumberOfIdEntries:%d
", pResourceDirectory->NumberOfNamedEntries, pResourceDirectory->NumberOfIdEntries);
//获取RESOURCEENTRY 的个数
size_t NumEntry = pResourceDirectory->NumberOfIdEntries + pResourceDirectory->NumberOfNamedEntries;
//资源目录表的宽度
size_t dwResourceData = sizeof(PIMAGE_RESOURCE_DIRECTORY);
//定位资源目录节点
PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResourceDirectory + 16);
//获取第一层
for (size_t i = 0; i < NumEntry; i++)
{
if (!pResEntry[i].NameIsString) {//0
if (pResEntry[i].Id < 0x11)
//如果id大于0x11就是自己写的ID资源
{
printf("资源类型ID:%p %s
", pResEntry[i].Id, szResName[pResEntry[i].Id]);
}
else {
char type[20];
sprintf_s(type, "%d", pResEntry[i].Id);
printf("资源类型ID:%p %s
", pResEntry[i].Id, type);
}
}
else {//1那么这个第一个联合体的最高位为1,也就是说NameIsString为1,如果资源是未知的,这种资源属于字符串作为资源标识, Name就不会起作用了,NameOffset会指向IMAGE_RESOUCE_DIR_STRING_U的位置
//先获取偏移
PIMAGE_RESOURCE_DIR_STRING_U pStringRes = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResourceDirectory + pResEntry[i].NameOffset);
//定义一个用来接收自定义字符串的宽数组然后直接复制
WCHAR szStr[MAX_PATH] = { 0 };
memcpy_s(szStr, MAX_PATH, pStringRes->NameString, pStringRes->Length * sizeof(WCHAR));
printf("资源名称:%ls
", szStr);
}
//第二层
if (pResEntry[i].DataIsDirectory) {
printf("第二层目录偏移是:%p
", pResEntry[i].OffsetToDirectory);
//定义二层目录的目录头 以及entry
PIMAGE_RESOURCE_DIRECTORY pResDirectory2 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResourceDirectory + pResEntry[i].OffsetToDirectory);
PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResDirectory2 + 1);
//获得ENtry个数
size_t NumEntry2 = pResDirectory2->NumberOfIdEntries + pResDirectory2->NumberOfNamedEntries;
for (DWORD i = 0; i < NumEntry2; i++)
{
if (!pResEntry2[i].NameIsString)
{
printf("->资源标识ID:%d
", pResEntry2[i].Id);
}
else
{
// 显示资源字符串
// NameOffset为相对资源的文件偏移
// 字符串偏移为 资源基地址+NameOffset
PIMAGE_RESOURCE_DIR_STRING_U pstcString = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResourceDirectory + pResEntry2[i].NameOffset);
WCHAR szStr[MAX_PATH] = { 0 };
memcpy(szStr,
pstcString->NameString,
pstcString->Length * sizeof(WCHAR)
);
printf("->资源字符串:%ls
", szStr);
}
}
//第三层
PIMAGE_RESOURCE_DIRECTORY pResourceDirectory3 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResourceDirectory + pResEntry2[i].OffsetToDirectory);
printf("第三层目录:%d
", pResourceDirectory3->NumberOfIdEntries);
PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry3 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResourceDirectory3 + 1);
if (!pResEntry3[i].DataIsDirectory)
{
// 取数据偏移,显示数据
PIMAGE_RESOURCE_DATA_ENTRY pResData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pResourceDirectory + pResEntry3->OffsetToData);
printf("->->->数据RVA:%x 数据大小:%x
", pResData->OffsetToData, pResData->Size);
//printf("->->->数据大小:%x
", pResData->Size);
//printf("->->->数据RVA:%x
", pResData->OffsetToData);
}
}
printf("
");
}
}
void main()
{
PVOID p2 = NULL; //pFileBuffer
PVOID p3 = NULL; //pImageBuffer
PVOID p4 = NULL; //pNewBuffer
FILE* fp;
int sum;
ReadPEFile(FILEPATH_IN, &p2);
//CopyFileBufferToImageBuffer(p2, &p3);
//free(p2);
/*sum = CopyImageBufferToNewBuffer(p3, &p4);
free(p3);*/
//TestAddCodeInCodeSec();
//AddSectionToFileBuffer();
//ExpandLastSection();
//MergeAllSection();
//PrintfExportImform();
//GetFunctionAddrByName(p2, "sub1");
//GetFunctionAddrByOrdinals(p2, 2);
//PrintRelocation();
//MoveExport();
//MoveRelo();
//FixRelocation();
//PrintImportTable();
//printBoundImportTable();
// LPVOID pFileBuffer = NULL;
//ReadPEFile(FILEPATH_IN, &pFileBuffer);
//PrintBoundImport(pFileBuffer);
PrintResourceTable();
}