1.移动要点:
2.代码实现:
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#define size_shellcode 0x12
#define size_surplus_sizeofheader 0x50
#define messagebox_add 0x76EE2030
#define test 1
DWORD ToLeaderPE(LPSTR file_path, PVOID* pFileBuffer);
VOID ReadPEFile(IN LPVOID pFileBuffer);
DWORD CopyFileBufferToImageBuffer(PVOID pFileBuffer, PVOID* pImageBuffer);
DWORD CopyImageBufferToNewBuffer(PVOID pImageBuffer, PVOID* pNewBuffer);
BOOL MemeryTOFile(IN LPVOID pMemBuffer, IN size_t size, OUT LPSTR lpszFile);
DWORD TestAddCodeInDataSec(PVOID pImageBuffer, PVOID* pNewFileBuffer, DWORD FileSize);
DWORD TestAddCodeInXXXSec(PVOID pImageBuffer, PVOID* pNewFileBuffer, DWORD SecNumb, DWORD FileSize);
DWORD RvaToFileOffset(IN LPVOID pBuffer, IN DWORD dwRva);
DWORD FoaToImageOffset(IN LPVOID pBuffer, IN DWORD dwFoa);
DWORD TestAddSection(IN LPVOID file_path, IN LPVOID* pFileBuffer, IN LPVOID* pAddSectionBuffer);
DWORD TestEnlargeSection(IN LPVOID* pFileBuffer, IN LPVOID* pEnlargerSection);
DWORD TestMergeSection(IN LPVOID* pFileBuffer, IN LPVOID* pEnlargerSection);
DWORD Alignment(DWORD alignment_value, DWORD addend, DWORD address);
VOID LogExportTable(IN LPVOID pFileBuffer);
DWORD GetFunctionAddrByName(PVOID pFileBuffer, LPSTR fun_name);
DWORD GetFunctionAddrByOrdinals(PVOID pFileBuffer, DWORD fun_order);
VOID LogBaseRelocationTable(IN LPVOID pFileBuffer);
DWORD MoveExportTable(IN LPVOID pFileBuffer,IN DWORD FileBuffer, IN LPVOID* pFileBuffer_ExportTable);
DWORD SizeOfExportTableSection(IN LPVOID* pFileBuffer);
DWORD MoveBaseRelocationTable(IN LPVOID pFileBuffer, IN DWORD FileBuffer, IN LPVOID* pFileBuffer_ExportTable);
DWORD SizeOfBaseRelocationTable(IN LPVOID* pFileBuffer);
BYTE shellcode[] = {
0x6A,00,0x6A,00,0x6A,00,0x6A,00,
0XE8,00,00,00,00,
0XE9,00,00,00,00
};
char fun_name[] = "??4CInitGdiplus@wui@@QAEAAV01@ABV01@@Z";
char file_path[] = "c:\\users\\njupt\\desktop\\dll1test.dll";
char write_file_path[] = "D:\\Lib\\cp_XX.exe";
char write_adddata_file_path[] = "D:\\Lib\\cp_adddata_XX.exe";
char write_addXXXsec_file_path[] = "D:\\Lib\\cp_addXXXsec_XX.exe";
char write_addsec_file_path[] = "D:\\Lib\\cp_addsec_XX.exe";
char write_enlargersec_file_path[] = "D:\\Lib\\cp_enlargersec_XX.exe";
char write_mergesec_file_path[] = "D:\\Lib\\cp_mergesec_XX.exe";
char write_movexportable_file_path[] = "D:\\Lib\\dll1test.dll";
char write_movreloctable_file_path[] = "D:\\Lib\\dll1test.dll";
DWORD ToLeaderPE(LPSTR file_path, PVOID* pFileBuffer)
{
FILE *pFile = NULL;
DWORD fileSize = 0;
LPVOID pFileBufferTemp = NULL;
pFile = fopen(file_path, "rb");
if (!pFile)
{
printf("can't open file1\n");
return 0;
}
fseek(pFile, 0, SEEK_END);
fileSize = ftell(pFile);
printf("FileBuffer: %#x\n", fileSize);
fseek(pFile, 0, SEEK_SET);
pFileBufferTemp = malloc(fileSize);
if (!pFileBufferTemp)
{
printf("Apply memory failed.\n");
fclose(pFile);
return 0;
}
size_t n = fread(pFileBufferTemp, fileSize, 1, pFile);
if (!n)
{
printf("Read data filed.\n");
free(pFileBufferTemp);
fclose(pFile);
return 0;
}
*pFileBuffer = pFileBufferTemp;
pFileBufferTemp = NULL;
fclose(pFile);
return fileSize;
}
VOID ReadPEFile(IN 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;
}
//判断是否是有效的MZ标志
if (*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("不是有效的MZ标志.\n");
free(pFileBuffer);
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
//打印DOC头
printf("\n********************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("NT:%#x\n", pNTHeader->Signature);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4);
//int NumberOfSections = pPEHeader->NumberOfSections;
//int SizeOfOptionalHeader = pPEHeader->SizeOfOptionalHeader;
printf("********************PE头********************\n");
printf("PE:%#x\n", pPEHeader->Machine);
printf("节的数量:%#x\n", pPEHeader->NumberOfSections);
printf("SizeOfOptionalHeader:%#x\n", pPEHeader->SizeOfOptionalHeader);
//可选PE头
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
printf("********************OPTIOIN_PE头********************\n");
printf("OPTION_PE:%#x\n", pOptionHeader->Magic);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
for (int n = 0; n < pPEHeader->NumberOfSections; n++)
{
printf("********************SECTION %d********************\n", n + 1);
char name[9] = { 0 };
memcpy(name, pSectionHeader->Name, 8);
printf("SECTION NAME: %s\n", name);
printf("VirtualAddress: %#x\n", pSectionHeader->VirtualAddress);
printf("SizeOfRawData: %#x\n", pSectionHeader->SizeOfRawData);
printf("PointerToRawData: %#x\n", pSectionHeader->PointerToRawData);
printf("Characteristics: %#x\n", pSectionHeader->Characteristics);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader + IMAGE_SIZEOF_SECTION_HEADER);
}
}
DWORD CopyFileBufferToImageBuffer(PVOID pFileBuffer, PVOID* pImageBuffer)
{
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 pImageTemp = NULL;
if (!pFileBuffer)
{
printf("(CopyFileBufferToImageBuffer)FileBuffer open failed.\n");
return 0;
}
if (*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("(CopyFileBufferToImageBuffer)不含MZ标志,不是exe文件.\n");
return 0;
}
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
if (*((PDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(CopyFileBufferToImageBuffer)不是有效的PE标志.\n");
return 0;
}
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);
pImageTemp = malloc(pOptionHeader->SizeOfImage);
if (!pImageTemp)
{
printf("(CopyFileBufferToImageBuffer)allocate dynamic memory failed.\n");
free(pImageTemp);
return 0;
}
memset(pImageTemp, 0, pOptionHeader->SizeOfImage);
memcpy(pImageTemp, pDosHeader, pOptionHeader->SizeOfHeaders);
PIMAGE_SECTION_HEADER pSectionHeaderTemp = pSectionHeader;
for (int n = 0; n < pPEHeader->NumberOfSections; n++, pSectionHeaderTemp++)
{
memcpy((PVOID)((DWORD)pImageTemp + pSectionHeaderTemp->VirtualAddress), (PVOID)((DWORD)pFileBuffer + pSectionHeaderTemp->PointerToRawData), pSectionHeaderTemp->SizeOfRawData);
printf("VirtualAddress%d: %#10x PointerToRawData%d: %#10x\n", n, (DWORD)pImageTemp + pSectionHeader->VirtualAddress, n, (DWORD)pFileBuffer + pSectionHeader->PointerToRawData);
}
*pImageBuffer = pImageTemp;
pImageTemp = NULL;
return pOptionHeader->SizeOfImage;
}
DWORD CopyImageBufferToNewBuffer(PVOID pImageBuffer, PVOID* pNewBuffer)
{
// 初始化PE头部结构体
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;
// 初始化NEW_BUFFER指针(temparay)
LPVOID pTempNewbuffer = NULL;
// 判断pImageBuffer是否有效
if (!pImageBuffer)
{
printf("(CopyImageBufferToNewBuffer)读取到内存的pimagebuffer无效.\n");
return 0;
}
//判断是不是exe文件
if (*((PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("(CopyImageBufferToNewBuffer)不含MZ标志,不是exe文件.\n");
return 0;
}
// 强制结构体类型转换
pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
if (*((PDWORD)((DWORD)pImageBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(CopyImageBufferToNewBuffer)不是有效的PE标志.\n");
return 0;
}
// 强制结构体类型转换
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);
//获取new_buffer的大小
int new_buffer_size = pOptionHeader->SizeOfHeaders;
for (DWORD i = 0; i < pPEHeader->NumberOfSections; i++)
{
new_buffer_size += pSectionHeader[i].SizeOfRawData; // pSectionHeader[i]另一种加法
}
// 分配内存(newbuffer)
pTempNewbuffer = malloc(new_buffer_size);
if (!pTempNewbuffer)
{
printf("(CopyImageBufferToNewBuffer)分配Newbuffer失败.\n");
return 0;
}
memset(pTempNewbuffer, 0, new_buffer_size);
// 拷贝头部
memcpy(pTempNewbuffer, pDosHeader, pOptionHeader->SizeOfHeaders);
// 循环拷贝节区
PIMAGE_SECTION_HEADER pTempSectionHeader = pSectionHeader;
for (DWORD j = 0; j < pPEHeader->NumberOfSections; j++, pTempSectionHeader++)
{ //PointerToRawData节区在文件中的偏移,VirtualAddress节区在内存中的偏移地址,SizeOfRawData节在文件中对齐后的尺寸
memcpy((PDWORD)((DWORD)pTempNewbuffer + pTempSectionHeader->PointerToRawData), (PDWORD)((DWORD)pImageBuffer + pTempSectionHeader->VirtualAddress), pTempSectionHeader->SizeOfRawData);
}
//返回数据
*pNewBuffer = pTempNewbuffer; //暂存的数据传给参数后释放
pTempNewbuffer = NULL;
return new_buffer_size; // 返回计算得到的分配内存的大小
}
BOOL MemeryTOFile(IN LPVOID pMemBuffer, IN size_t size, OUT LPSTR lpszFile)
{
FILE *fp;
fp = fopen(lpszFile, "wb");
if (fp != NULL)
{
fwrite(pMemBuffer, size, 1, fp);
}
fclose(fp);
return 1;
}
DWORD RvaToFileOffset(IN LPVOID pBuffer, IN DWORD dwRva)
{
// 初始化PE头部结构体
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;
// 判断pImageBuffer是否有效
if (!pBuffer)
{
printf("(RvaToFileOffset)读取到内存的ImageBuffer无效.\n");
return 0;
}
//判断是不是exe文件
if (*((PWORD)pBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("(RvaToFileOffset)不含MZ标志,不是exe文件.\n");
return 0;
}
// 强制结构体类型转换
pDosHeader = (PIMAGE_DOS_HEADER)pBuffer;
if (*((PDWORD)((DWORD)pBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(RvaToFileOffset)不是有效的PE标志.\n");
return 0;
}
//printf("ImageOffset: %#x\n", dwRva);
// 强制结构体类型转换
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pBuffer + 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);
PIMAGE_SECTION_HEADER pSectionTemp = pSectionHeader;
if (dwRva <= pOptionHeader->SizeOfHeaders)
return (DWORD)dwRva;
else
{
for (int n = 0; n < pPEHeader->NumberOfSections; n++, pSectionTemp++)
{ //判断 : 文件对齐+文件偏移>file_panyi>文件偏移 (即是在文件的哪个节中)
if ((dwRva >= pSectionTemp->VirtualAddress) && (dwRva < pSectionTemp->VirtualAddress + pSectionTemp->Misc.VirtualSize))
{
return dwRva - pSectionTemp->VirtualAddress + pSectionTemp->PointerToRawData;
}
}
}
printf("地址转换失败!\n");
return 0;
}
DWORD FoaToImageOffset(IN LPVOID pBuffer, IN DWORD dwFoa)
{
// 初始化PE头部结构体
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;
// 判断pImageBuffer是否有效
if (!pBuffer)
{
printf("(FoaToImageOffset)读取到内存的ImageBuffer无效.\n");
return 0;
}
//判断是不是exe文件
if (*((PWORD)pBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("(FoaToImageOffset)不含MZ标志,不是exe文件.\n");
return 0;
}
// 强制结构体类型转换
pDosHeader = (PIMAGE_DOS_HEADER)pBuffer;
if (*((PDWORD)((DWORD)pBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(FoaToImageOffset)不是有效的PE标志.\n");
return 0;
}
printf("FileOffset: %#x\n", dwFoa);
// 强制结构体类型转换
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pBuffer + 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);
PIMAGE_SECTION_HEADER pSectionTemp = pSectionHeader;
if (dwFoa <= pOptionHeader->SizeOfHeaders)
return (DWORD)dwFoa;
else
{
for (int n = 0; n < pPEHeader->NumberOfSections; n++, pSectionTemp++)
{ //判断 : 文件对齐+文件偏移>file_panyi>文件偏移 (即是在文件的哪个节中)
if ((dwFoa >= pSectionTemp->PointerToRawData) && (dwFoa < pSectionTemp->PointerToRawData + pSectionTemp->SizeOfRawData))
{
return dwFoa - pSectionTemp->PointerToRawData + pSectionTemp->VirtualAddress;
}
}
}
printf("地址转换失败!\n");
return 0;
}
DWORD TestAddCodeInXXXSec(PVOID pImageBuffer, PVOID* pNewFileBuffer, DWORD SecNumb, DWORD FileSize)
{
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;
// 判断pImageBuffer是否有效
if (!pImageBuffer)
{
printf("(TestAddCodeInDataSec)ImageBuffer open failed.\n");
return 0;
}
//判断是不是exe文件
if (*((PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("(TestAddCodeInDataSec)不含MZ标志,不是exe文件!\n");
return 0;
}
// 强制结构体类型转换
pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
if (*((PDWORD)((DWORD)pImageBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(TestAddCodeInDataSec)不是有效的PE标志.\n");
return 0;
}
// 强制结构体类型转换
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);
PIMAGE_SECTION_HEADER pSectionHeaderTemp = pSectionHeader;
for (int n = 1; n < SecNumb; n++, pSectionHeaderTemp++)
{
//
}
//判断XX区空间够不够放shellcode
if (size_shellcode > (pSectionHeaderTemp->SizeOfRawData - pSectionHeaderTemp->Misc.VirtualSize))
{
printf("XX section sapce not enough to store shellcode\n");
free(pImageBuffer);
return 0;
}
printf("pSectionHeader->PointerToRawData: %#x pSectionHeader->Misc.VirtualSize: %#x\n", pSectionHeaderTemp->PointerToRawData, pSectionHeaderTemp->Misc.VirtualSize);
printf("pImageBuffer: %#x\n", pImageBuffer);
//填充代码
PBYTE CodeAddLoc = (PBYTE)((DWORD)pImageBuffer + pSectionHeaderTemp->VirtualAddress + pSectionHeaderTemp->Misc.VirtualSize);
printf("pSectionHeader->VirtualAddress: %#x\n", pSectionHeaderTemp->VirtualAddress);
printf("CodeAddLoc: %#x\n", CodeAddLoc);
memcpy(CodeAddLoc, shellcode, size_shellcode);
//修改E8跳转地址
DWORD callAddr = (messagebox_add - (pOptionHeader->ImageBase + ((DWORD)(CodeAddLoc + 0xD) - (DWORD)pImageBuffer)));
*(PDWORD)(CodeAddLoc + 0x09) = callAddr;
//修改E9跳转地址
DWORD jmpAddr = (pOptionHeader->AddressOfEntryPoint - ((DWORD)(CodeAddLoc + size_shellcode) - (DWORD)pImageBuffer));
*(PDWORD)(CodeAddLoc + 0x0E) = jmpAddr;
pOptionHeader->AddressOfEntryPoint = (DWORD)CodeAddLoc - (DWORD)pImageBuffer;
size_t size = CopyImageBufferToNewBuffer(pImageBuffer, pNewFileBuffer);
if (size = 0 || !pNewFileBuffer)
{
printf("imagebuffer->newfilebuffer失败.\n");
free(pImageBuffer);
free(pNewFileBuffer);
}
// 存盘
size_t ret_loc1 = MemeryTOFile(*pNewFileBuffer, FileSize, write_addsec_file_path);
if (!ret_loc1)
{
printf("store memory failed.\n");
return 0;
}
return 1;
}
DWORD TestAddCodeInDataSec(PVOID pImageBuffer, PVOID* pNewFileBuffer, DWORD FileSize)
{
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;
// 判断pImageBuffer是否有效
if (!pImageBuffer)
{
printf("(TestAddCodeInDataSec)ImageBuffer open failed.\n");
return 0;
}
//判断是不是exe文件
if (*((PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("(TestAddCodeInDataSec)不含MZ标志,不是exe文件.\n");
return 0;
}
// 强制结构体类型转换
pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
if (*((PDWORD)((DWORD)pImageBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(TestAddCodeInDataSec)不是有效的PE标志.\n");
return 0;
}
// 强制结构体类型转换
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);
//判断代码区空间够不够放shellcode
if (size_shellcode > (pSectionHeader->SizeOfRawData - pSectionHeader->Misc.VirtualSize))
{
printf("Data section sapce not enough to store shellcode.\n");
free(pImageBuffer);
return 0;
}
printf("pSectionHeader->PointerToRawData: %#x pSectionHeader->Misc.VirtualSize: %#x\n", pSectionHeader->PointerToRawData, pSectionHeader->Misc.VirtualSize);
printf("pImageBuffer: %#x\n", pImageBuffer);
//填充代码
PBYTE CodeAddLoc = (PBYTE)((DWORD)pImageBuffer + pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize);
printf("pSectionHeader->VirtualAddress: %#x\n", pSectionHeader->VirtualAddress);
printf("CodeAddLoc: %#x\n", CodeAddLoc);
memcpy(CodeAddLoc, shellcode, size_shellcode);
//修改E8跳转地址
DWORD callAddr = (messagebox_add - (pOptionHeader->ImageBase + ((DWORD)(CodeAddLoc + 0xD) - (DWORD)pImageBuffer)));
*(PDWORD)(CodeAddLoc + 0x09) = callAddr;
//修改E9跳转地址
DWORD jmpAddr = (pOptionHeader->AddressOfEntryPoint - ((DWORD)(CodeAddLoc + size_shellcode) - (DWORD)pImageBuffer));
*(PDWORD)(CodeAddLoc + 0x0E) = jmpAddr;
pOptionHeader->AddressOfEntryPoint = (DWORD)CodeAddLoc - (DWORD)pImageBuffer;
size_t size = CopyImageBufferToNewBuffer(pImageBuffer, pNewFileBuffer);
if (size = 0 || !pNewFileBuffer)
{
printf("imagebuffer->newfilebuffer失败.\n");
free(pImageBuffer);
free(pNewFileBuffer);
}
// 存盘
size_t ret_loc1 = MemeryTOFile(*pNewFileBuffer, FileSize, write_adddata_file_path);
if (!ret_loc1)
{
printf("store memory failed.\n");
return 0;
}
return 1;
}
DWORD Alignment(DWORD alignment_value, DWORD addend, DWORD address)
{
int n = 0;
if (addend / alignment_value)
{
if (addend%alignment_value)
{
n = addend / alignment_value + 1;
}
else
{
n = addend / alignment_value;
}
}
else
{
if (addend)
n = 0;
else
n = 1;
}
address += n * alignment_value;
return address;
}
DWORD TestAddSection(IN LPVOID file_path, IN LPVOID* pFileBuffer, IN LPVOID* pAddSectionBuffer)
{
LPVOID pAddSectionTemp = NULL;
//加载.exe的PE结构
size_t ret_loc2 = ToLeaderPE(file_path, pFileBuffer);
size_t AddSecTotal = ret_loc2 + 0x1000;
pAddSectionTemp = malloc(AddSecTotal);
if (!pAddSectionTemp)
{
printf("(TestAddSection)apply memory failed.\n");
return 0;
}
memset(pAddSectionTemp, 0, AddSecTotal);
memcpy(pAddSectionTemp, *pFileBuffer, ret_loc2);
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 (!pAddSectionTemp)
{
printf("(TestAddSection)文件读取失败.\n");
return;
}
//判断是否是有效的MZ标志
if (*((PWORD)pAddSectionTemp) != IMAGE_DOS_SIGNATURE)
{
printf("(TestAddSection)不是有效的MZ标志.\n");
free(pAddSectionTemp);
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)pAddSectionTemp;
//判断是否是有效的PE标志
if (*((PDWORD)((DWORD)pAddSectionTemp + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(TestAddSection)不是有效的PE标志.\n");
free(pAddSectionTemp);
return;
}
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pAddSectionTemp + 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);
PIMAGE_SECTION_HEADER pSectionHeaderTemp = pSectionHeader;
for (DWORD i = 0; i < pPEHeader->NumberOfSections; i++, pSectionHeaderTemp++)
{
//
}
//判断SizeOFHeader能否放下多余两个节区(一个新增节区,一个全0节区代表区块结束)
//分三种情况:1.节表后直接可以放下两个节区 2.节表后放不下,但是dos头后pe前可放下 3.前两种情况都不行,需扩大最后一个节把代码填进去
//就讨论第一种情况吧...
if (size_surplus_sizeofheader <= (pOptionHeader->SizeOfHeaders - ((DWORD)(pSectionHeaderTemp - pAddSectionTemp))))
{
printf("Enough.\n");
//得到最后一个节的信息
pSectionHeaderTemp--;
//填充节
DWORD ret_loc3 = Alignment(pOptionHeader->SectionAlignment, (DWORD)pSectionHeaderTemp->Misc.VirtualSize, (DWORD)pSectionHeaderTemp->VirtualAddress);
memset(((PBYTE)(DWORD)pAddSectionTemp + ret_loc3), 0, 0x1000);
//改节数目
pPEHeader->NumberOfSections = pPEHeader->NumberOfSections + 1;
//填充节表
pSectionHeaderTemp++;
memcpy(pSectionHeaderTemp, pSectionHeader, IMAGE_SIZEOF_SECTION_HEADER);
memcpy(pSectionHeaderTemp, ".add", 8);
pSectionHeaderTemp->VirtualAddress = ret_loc3;
pSectionHeaderTemp->SizeOfRawData = 0x1000;
pSectionHeaderTemp->PointerToRawData = ret_loc3;
pSectionHeaderTemp->Misc.VirtualSize = 0x1000;
pOptionHeader->SizeOfImage = AddSecTotal;
}
else
{
free(pAddSectionTemp);
printf("Insufficient.\n");
}
size_t ret_loc4 = MemeryTOFile(pAddSectionTemp, AddSecTotal, write_addsec_file_path);
if (!ret_loc4)
{
printf("(TestAddSection)store memory failed.\n");
return 0;
}
*pAddSectionBuffer = pAddSectionTemp; //暂存的数据传给参数后释放
free(pAddSectionTemp);
pAddSectionTemp = NULL;
return AddSecTotal;
}
DWORD TestEnlargeSection(IN LPVOID* pFileBuffer, IN LPVOID* pEnlargerSection)
{
LPVOID pEnlargerSectionTemp = NULL;
//加载.exe的PE结构
size_t ret_loc2 = ToLeaderPE(file_path, pFileBuffer);
size_t EnlargerSecTotal = ret_loc2 + 0x1000;
pEnlargerSectionTemp = malloc(EnlargerSecTotal);
if (!pEnlargerSectionTemp)
{
printf("(TestEnlargeSection)apply memory failed.\n");
return 0;
}
memset(pEnlargerSectionTemp, 0, EnlargerSecTotal);
memcpy(pEnlargerSectionTemp, *pFileBuffer, ret_loc2);
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 (!pEnlargerSectionTemp)
{
printf("(TestEnlargeSection)文件读取失败.\n");
return;
}
//判断是否是有效的MZ标志
if (*((PWORD)pEnlargerSectionTemp) != IMAGE_DOS_SIGNATURE)
{
printf("(TestEnlargeSection)不是有效的MZ标志.\n");
free(pEnlargerSectionTemp);
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)pEnlargerSectionTemp;
//判断是否是有效的PE标志
if (*((PDWORD)((DWORD)pEnlargerSectionTemp + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(TestEnlargeSection)不是有效的PE标志.\n");
free(pEnlargerSectionTemp);
return;
}
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pEnlargerSectionTemp + 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);
//遍历到最后一个节表
PIMAGE_SECTION_HEADER pSectionHeaderTemp = pSectionHeader;
for (DWORD i = 0; i < pPEHeader->NumberOfSections; i++, pSectionHeaderTemp++)
{
//
}
DWORD max = (pSectionHeaderTemp->SizeOfRawData > pSectionHeaderTemp->Misc.VirtualSize ? pSectionHeaderTemp->SizeOfRawData : pSectionHeaderTemp->Misc.VirtualSize);
pSectionHeaderTemp->SizeOfRawData = max + 0x1000;
pSectionHeaderTemp->Misc.VirtualSize = max + 0x1000;
pOptionHeader->SizeOfImage = Alignment(pOptionHeader->SectionAlignment, pSectionHeaderTemp->Misc.VirtualSize, pOptionHeader->SizeOfImage);
size_t ret_loc4 = MemeryTOFile(pEnlargerSectionTemp, pOptionHeader->SizeOfImage, write_enlargersec_file_path);
if (!ret_loc4)
{
printf("(TestEnlargeSection)store memory failed.\n");
return 0;
}
*pEnlargerSection = pEnlargerSectionTemp; //暂存的数据传给参数后释放
free(pEnlargerSectionTemp);
pEnlargerSectionTemp = NULL;
return EnlargerSecTotal;
}
DWORD TestMergeSection(IN LPVOID* pFileBuffer, IN LPVOID* pEnlargerSection)
{
LPVOID pMergeSectionTemp = NULL;
//加载.exe的PE结构
size_t ret_loc2 = ToLeaderPE(file_path, pFileBuffer);
pMergeSectionTemp = malloc(ret_loc2);
if (!pMergeSectionTemp)
{
printf("(TestMergeSection)apply memory failed.\n");
return 0;
}
memset(pMergeSectionTemp, 0, ret_loc2);
memcpy(pMergeSectionTemp, *pFileBuffer, ret_loc2);
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 (!pMergeSectionTemp)
{
printf("(TestMergeSection)文件读取失败.\n");
return;
}
//判断是否是有效的MZ标志
if (*((PWORD)pMergeSectionTemp) != IMAGE_DOS_SIGNATURE)
{
printf("(TestMergeSection)不是有效的MZ标志.\n");
free(pMergeSectionTemp);
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)pMergeSectionTemp;
//判断是否是有效的PE标志
if (*((PDWORD)((DWORD)pMergeSectionTemp + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(TestMergeSection)不是有效的PE标志.\n");
free(pMergeSectionTemp);
return;
}
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pMergeSectionTemp + 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 NewSecCharacteristics = 0;
//遍历到最后一个节表
PIMAGE_SECTION_HEADER pSectionHeaderTemp = pSectionHeader;
for (DWORD i = 0; i < pPEHeader->NumberOfSections; i++, pSectionHeaderTemp++)
{
//
}
DWORD max = (pSectionHeaderTemp->SizeOfRawData > pSectionHeaderTemp->Misc.VirtualSize ? pSectionHeaderTemp->SizeOfRawData : pSectionHeaderTemp->Misc.VirtualSize);
DWORD NewSecBuffer = (pSectionHeaderTemp->VirtualAddress + max - pOptionHeader->SizeOfHeaders);
for (DWORD i = pPEHeader->NumberOfSections; i > 1; i--, pSectionHeaderTemp--)
{
NewSecCharacteristics = NewSecCharacteristics || pSectionHeaderTemp->Characteristics;
}
pSectionHeaderTemp->Characteristics = NewSecCharacteristics;
pSectionHeaderTemp->SizeOfRawData = Alignment(pOptionHeader->FileAlignment, NewSecBuffer, 0);
pSectionHeaderTemp->Misc.VirtualSize = Alignment(pOptionHeader->SectionAlignment, NewSecBuffer, 0);
pPEHeader->NumberOfSections = 0x01;
size_t ret_loc4 = MemeryTOFile(pMergeSectionTemp, pOptionHeader->SizeOfImage, write_mergesec_file_path);
if (!ret_loc4)
{
printf("(TestMergeSection)store memory failed.\n");
return 0;
}
*pEnlargerSection = pMergeSectionTemp; //暂存的数据传给参数后释放
free(pMergeSectionTemp);
pMergeSectionTemp = NULL;
return ret_loc2;
}
VOID LogExportTable(IN LPVOID pFileBuffer)
{
// 初始化PE头部结构体
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 pDataDirectory = NULL;
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
// 判断pImageBuffer是否有效
if (!pFileBuffer)
{
printf("(LogExportDirectory)读取到内存的ImageBuffer无效.\n");
return 0;
}
//判断是不是exe文件
if (*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("(LogExportDirectory)不含MZ标志,不是exe文件.\n");
return 0;
}
// 强制结构体类型转换
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
if (*((PDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(LogExportDirectory)不是有效的PE标志.\n");
return 0;
}
// 强制结构体类型转换
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);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory;
if (!pDataDirectory->VirtualAddress)
{
printf("(LogExportDirectory)This program has no export table.\n");
return 0;
}
printf("Export Table Rva: %#x\n", pDataDirectory->VirtualAddress);
DWORD Foa_ExportTable = RvaToFileOffset(pFileBuffer, pDataDirectory->VirtualAddress);
printf("Export Table Foa: %#x\n", Foa_ExportTable);
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + Foa_ExportTable);
printf("Characteristics: %#x\n", pExportDirectory->Characteristics);
printf("TimeDateStamp: %#x\n", pExportDirectory->TimeDateStamp);
printf("MajorVersion: %#x\n", pExportDirectory->MajorVersion);
printf("MinorVersion: %#x\n", pExportDirectory->MinorVersion);
printf("Name: %#x\n", pExportDirectory->Name);
printf("Base: %#x\n", pExportDirectory->Base);
printf("NumberOfFunctions: %#x\n", pExportDirectory->NumberOfFunctions);
printf("NumberOfNames: %#x\n", pExportDirectory->NumberOfNames);
printf("AddressOfFunctions: %#x\n", pExportDirectory->AddressOfFunctions);
printf("AddressOfNames: %#x\n", pExportDirectory->AddressOfNames);
printf("AddressOfNameOrdinals: %#x\n", pExportDirectory->AddressOfNameOrdinals);
}
DWORD GetFunctionAddrByOrdinals(PVOID pFileBuffer, DWORD fun_order)
{
printf("Function Order: %#x\n", fun_order);
// 初始化PE头部结构体
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 pDataDirectory = NULL;
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
// 判断pImageBuffer是否有效
if (!pFileBuffer)
{
printf("(LogExportDirectory)读取到内存的ImageBuffer无效.\n");
return 0;
}
//判断是不是exe文件
if (*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("(LogExportDirectory)不含MZ标志,不是exe文件.\n");
return 0;
}
// 强制结构体类型转换
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
if (*((PDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(LogExportDirectory)不是有效的PE标志.\n");
return 0;
}
// 强制结构体类型转换
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);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory;
if (!pDataDirectory->VirtualAddress)
{
printf("This program has no export table.\n");
return 0;
}
printf("Export Table Rva: %#x\n", pDataDirectory->VirtualAddress);
DWORD Foa_ExportTable = RvaToFileOffset(pFileBuffer, pDataDirectory->VirtualAddress);
printf("Export Table Foa: %#x\n", Foa_ExportTable);
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + Foa_ExportTable);
if (!test)
{
printf("Characteristics: %#x\n", pExportDirectory->Characteristics);
printf("TimeDateStamp:%#x\n", pExportDirectory->TimeDateStamp);
printf("MajorVersion: %#x\n", pExportDirectory->MajorVersion);
printf("MinorVersion: %#x\n", pExportDirectory->MinorVersion);
printf("Name: %#x\n", pExportDirectory->Name);
printf("Base: %#x\n", pExportDirectory->Base);
printf("NumberOfFunctions: %#x\n", pExportDirectory->NumberOfFunctions);
printf("NumberOfNames: %#x\n", pExportDirectory->NumberOfNames);
printf("AddressOfFunctions: %#x\n", pExportDirectory->AddressOfFunctions);
printf("AddressOfNames: %#x\n", pExportDirectory->AddressOfNames);
printf("AddressOfNameOrdinals: %#x\n", pExportDirectory->AddressOfNameOrdinals);
}
DWORD Sequence = fun_order - pExportDirectory->Base;
DWORD Foa_AddressOfFunctions = RvaToFileOffset(pFileBuffer, pExportDirectory->AddressOfFunctions);
if (!test)
{
DWORD test1 = Foa_AddressOfFunctions + (DWORD)pFileBuffer;
printf("AddressOfFunctions in this moment: %#x\n", test1);
printf("Foa_AddressOfFunctions: %#x\n", Foa_AddressOfFunctions);
}
PDWORD pFoa_AddressOfFunctions = (PBYTE)(Foa_AddressOfFunctions + (DWORD)pFileBuffer);
for (DWORD n = 0; n < Sequence; n++)
{
pFoa_AddressOfFunctions++;
}
DWORD Foa_AddrFun = RvaToFileOffset(pFileBuffer, *pFoa_AddressOfFunctions);
return Foa_AddrFun;
}
DWORD GetFunctionAddrByName(PVOID pFileBuffer, LPSTR fun_name)
{
printf("Function Name: %s\n", fun_name);
// 初始化PE头部结构体
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 pDataDirectory = NULL;
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
// 判断pImageBuffer是否有效
if (!pFileBuffer)
{
printf("(LogExportDirectory)读取到内存的ImageBuffer无效.\n");
return 0;
}
//判断是不是exe文件
if (*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("(LogExportDirectory)不含MZ标志,不是exe文件.\n");
return 0;
}
// 强制结构体类型转换
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
if (*((PDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(LogExportDirectory)不是有效的PE标志.\n");
return 0;
}
// 强制结构体类型转换
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);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory;
if (!pDataDirectory->VirtualAddress)
{
printf("This program has no export table.\n");
return 0;
}
printf("Export Table Rva: %#x\n", pDataDirectory->VirtualAddress);
DWORD Foa_ExportTable = RvaToFileOffset(pFileBuffer, pDataDirectory->VirtualAddress);
printf("Export Table Foa: %#x\n", Foa_ExportTable);
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + Foa_ExportTable);
if (!test)
{
printf("Characteristics: %#x\n", pExportDirectory->Characteristics);
printf("TimeDateStamp: %#x\n", pExportDirectory->TimeDateStamp);
printf("MajorVersion: %#x\n", pExportDirectory->MajorVersion);
printf("MinorVersion: %#x\n", pExportDirectory->MinorVersion);
printf("Name: %#x\n", pExportDirectory->Name);
printf("Base: %#x\n", pExportDirectory->Base);
printf("NumberOfFunctions: %#x\n", pExportDirectory->NumberOfFunctions);
printf("NumberOfNames: %#x\n", pExportDirectory->NumberOfNames);
printf("AddressOfFunctions: %#x\n", pExportDirectory->AddressOfFunctions);
printf("AddressOfNames: %#x\n", pExportDirectory->AddressOfNames);
printf("AddressOfNameOrdinals: %#x\n", pExportDirectory->AddressOfNameOrdinals);
}
DWORD Foa_AddressOfNames = RvaToFileOffset(pFileBuffer, pExportDirectory->AddressOfNames);
DWORD Foa_AddressOfNameOrdinals = RvaToFileOffset(pFileBuffer, pExportDirectory->AddressOfNameOrdinals);
DWORD Foa_AddressOfFunctions = RvaToFileOffset(pFileBuffer, pExportDirectory->AddressOfFunctions);
if (!test)
{
DWORD test1 = Foa_AddressOfNames + (DWORD)pFileBuffer;
printf("AddressOfNames in this moment: %#x\n", test1);
printf("Foa__AddressOfNames: %#x\n", Foa_AddressOfNames);
}
//1.循环从名字表中找与目标函数名相同的;如有有返回该名字在表中的索引
DWORD ordIndex = -1;
for (DWORD i = 0; i < pExportDirectory->NumberOfNames; i++)
{
DWORD nameOffset = *(PDWORD)((DWORD)pFileBuffer + (DWORD)((LPDWORD)Foa_AddressOfNames + i));
LPSTR nameAddr = (LPSTR)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, nameOffset));
if (!strcmp(nameAddr, fun_name))
{
ordIndex = i;
break;
}
}
if (ordIndex == -1)
{
printf("The export table does not have this function name.\n");
return 0;
}
//2.用获得的索引从序号表中找函数的序号
WORD ord = *(PWORD)((DWORD)pFileBuffer + (DWORD)((LPWORD)Foa_AddressOfNameOrdinals + ordIndex));
if (!test)
{
DWORD test1 = Foa_AddressOfNameOrdinals + (DWORD)pFileBuffer;
printf("AddressOfNameOrdinals in this moment: %#x\n", test1);
printf("Foa__AddressOfNameOrdinals: %#x\n", Foa_AddressOfNameOrdinals);
printf("ordInex in AddressOfNames: %#x\n", ordIndex);
printf("ordInex in AddressOfNameOrdinals: %#x\n", ord);
}
//3.以序号表中查出来的序号为索引从函数地址表中找函数地址
DWORD addr = *(PDWORD)((DWORD)pFileBuffer + (DWORD)((LPDWORD)Foa_AddressOfFunctions + ord));
DWORD Foa_AddrFun = RvaToFileOffset(pFileBuffer, addr);
return Foa_AddrFun;
}
VOID LogBaseRelocationTable(IN LPVOID pFileBuffer)
{
// 初始化PE头部结构体
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 pDataDirectory = NULL;
PIMAGE_BASE_RELOCATION pRelocationTable = NULL;
// 判断pImageBuffer是否有效
if (!pFileBuffer)
{
printf("(LogBaseRelocationTable)读取到内存的ImageBuffer无效.\n");
return 0;
}
//判断是不是exe文件
if (*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("(LogBaseRelocationTable)不含MZ标志,不是exe文件.\n");
return 0;
}
// 强制结构体类型转换
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
if (*((PDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(LogBaseRelocationTable)不是有效的PE标志.\n");
return 0;
}
// 强制结构体类型转换
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);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory;
PIMAGE_DATA_DIRECTORY pDataDirectory_RelocTable = pDataDirectory + 5;
if (!pDataDirectory_RelocTable->VirtualAddress)
{
printf("This program has no relocation table.\n");
return 0;
}
DWORD Foa_RelocationTable = RvaToFileOffset(pFileBuffer, pDataDirectory_RelocTable->VirtualAddress);
if (!test)
{
printf("Relocation Table Rva: %#x\n", pDataDirectory_RelocTable->VirtualAddress);
printf("Relocation Table Foa: %#x\n", Foa_RelocationTable);
printf("pFileBuffer: %#x\n", (DWORD)pFileBuffer);
printf("Relocation Table in this moment: %#x\n", (DWORD)pFileBuffer + Foa_RelocationTable);
}
pRelocationTable = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + Foa_RelocationTable);
printf("pRelocationTable: %#x\n", (DWORD)pRelocationTable);
for (DWORD n = 0; pRelocationTable->VirtualAddress != IMAGE_REL_BASED_ABSOLUTE; n++)
{
printf(".....................RelocationTable %#5xth.................................\n", n + 1);
DWORD arrNumber = (pRelocationTable->SizeOfBlock - 8) / 2;
printf("TypeOffset Number: %#x\n", arrNumber);
PDWORD pTypeOffsetOrg = ((PDWORD)pRelocationTable + 2);
PWORD pTypeOffset = (PWORD)pTypeOffsetOrg;
for (DWORD i = 0; i < arrNumber; i++)
{
printf("pTypeOffset: %#-10x", (WORD)pTypeOffset);
WORD TypeOffset = *pTypeOffset;
if (!test)
{
printf("TypeOffset(011) = %#x\n", TypeOffset);
}
BYTE attribute = (TypeOffset & 0b11000000000000) >> 12;
TypeOffset = (TypeOffset & 0b111111111111);
if (!test)
{
printf("TypeOffset(000) = %#x\n", TypeOffset);
}
printf("Attribute: %-5x", attribute);
DWORD Offset = pRelocationTable->VirtualAddress + (DWORD)TypeOffset;
printf("Rva_BaseRelocation: %#-10x", Offset);
printf("Foa_BaseRelocation: %#-10x\n", RvaToFileOffset(pFileBuffer, Offset));
pTypeOffset++;
}
pRelocationTable = (PDWORD)((DWORD)pRelocationTable + pRelocationTable->SizeOfBlock);
}
}
DWORD SizeOfExportTableSection(IN LPVOID* pFileBuffer)
{
// 初始化PE头部结构体
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 pDataDirectory = NULL;
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
DWORD SizeOfExportTableSectionTotal = 0;
// 判断pImageBuffer是否有效
if (!*pFileBuffer)
{
printf("(SizeOfExportTableSection)读取到内存的ImageBuffer无效.\n");
return 0;
}
//判断是不是exe文件
if (*((PWORD)(*pFileBuffer)) != IMAGE_DOS_SIGNATURE)
{
printf("(SizeOfExportTableSection)不含MZ标志,不是exe文件.\n");
return 0;
}
// 强制结构体类型转换
pDosHeader = (PIMAGE_DOS_HEADER)*pFileBuffer;
if (*((PDWORD)((DWORD)*pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(SizeOfExportTableSection)不是有效的PE标志.\n");
return 0;
}
// 强制结构体类型转换
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);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory;
if (!pDataDirectory->VirtualAddress)
{
printf("This program has no export table.\n");
return 0;
}
DWORD Foa_ExportTable = RvaToFileOffset(*pFileBuffer, pDataDirectory->VirtualAddress);
if (!test)
{
printf("Export Table Rva: %#x\n", pDataDirectory->VirtualAddress);
printf("Export Table Foa: %#x\n", Foa_ExportTable);
}
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)*pFileBuffer + Foa_ExportTable);
if (!test)
{
printf("Characteristics: %#x\n", pExportDirectory->Characteristics);
printf("TimeDateStamp: %#x\n", pExportDirectory->TimeDateStamp);
printf("MajorVersion: %#x\n", pExportDirectory->MajorVersion);
printf("MinorVersion: %#x\n", pExportDirectory->MinorVersion);
printf("Name: %#x\n", pExportDirectory->Name);
printf("Base: %#x\n", pExportDirectory->Base);
printf("NumberOfFunctions: %#x\n", pExportDirectory->NumberOfFunctions);
printf("NumberOfNames: %#x\n", pExportDirectory->NumberOfNames);
printf("AddressOfFunctions: %#x\n", pExportDirectory->AddressOfFunctions);
printf("AddressOfNames: %#x\n", pExportDirectory->AddressOfNames);
printf("AddressOfNameOrdinals: %#x\n", pExportDirectory->AddressOfNameOrdinals);
}
//size输出表
SizeOfExportTableSectionTotal += 40;
//size AddressOfFunctions
SizeOfExportTableSectionTotal += (4 * pExportDirectory->NumberOfFunctions);
//size AddressOfNames
SizeOfExportTableSectionTotal += (4 * pExportDirectory->NumberOfNames);
//size AddressOfNameOrdinals
SizeOfExportTableSectionTotal += (2 * pExportDirectory->NumberOfNames);
//size Function Name string in AddressOfNames
DWORD Foa_AddressOfNames = RvaToFileOffset(*pFileBuffer, pExportDirectory->AddressOfNames);
if (!test)
{
DWORD test1 = Foa_AddressOfNames + (DWORD)*pFileBuffer;
printf("AddressOfNames in this moment: %#x\n", test1);
printf("Foa__AddressOfNames: %#x\n", Foa_AddressOfNames);
}
DWORD namestringSizeTotal = 0;
for (DWORD i = 0; i < pExportDirectory->NumberOfNames; i++)
{
DWORD nameOffset = *(PDWORD)((DWORD)*pFileBuffer + (DWORD)((LPDWORD)Foa_AddressOfNames + i));
LPSTR nameAddr = (LPSTR)((DWORD)*pFileBuffer + RvaToFileOffset(*pFileBuffer, nameOffset));
//strlen得到每个函数名的长度,strlen不包含"\0",因此+1
DWORD namestringSize = strlen(nameAddr) + 1;
namestringSizeTotal += namestringSize;
}
SizeOfExportTableSectionTotal += namestringSizeTotal;
if (SizeOfExportTableSectionTotal % pOptionHeader->SectionAlignment)
{
SizeOfExportTableSectionTotal = (SizeOfExportTableSectionTotal / pOptionHeader->SectionAlignment) * pOptionHeader->SectionAlignment + pOptionHeader->SectionAlignment;
}
return SizeOfExportTableSectionTotal;
}
DWORD MoveExportTable(IN LPVOID pFileBuffer, IN DWORD FileBuffer, IN LPVOID* pFileBuffer_ExportTable)
{
//未加载pMoveExportTableTemp,所以用pFileBuffer得到pOptionHeaderFileBuffer->SectionAlignment
PIMAGE_DOS_HEADER pDosHeaderFileBuffer = NULL;
PIMAGE_NT_HEADERS pNTHeaderFileBuffer = NULL;
PIMAGE_FILE_HEADER pPEHeaderFileBuffer = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeaderFileBuffer = NULL;
pDosHeaderFileBuffer = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeaderFileBuffer = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeaderFileBuffer->e_lfanew);
pPEHeaderFileBuffer = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeaderFileBuffer) + 4);
pOptionHeaderFileBuffer = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeaderFileBuffer + IMAGE_SIZEOF_FILE_HEADER);
LPVOID pMoveExportTableTemp = NULL;
DWORD SizeExportTableSection = SizeOfExportTableSection(&pFileBuffer);
size_t AddSecTotal = FileBuffer + SizeExportTableSection;
if (!test)
{
printf("SizeExportTableSection: %#x\n", SizeExportTableSection);
printf("pFileBuffer: %#x\n", FileBuffer);
printf("pOptionHeaderFileBuffer->SizeOfImage: %#x\n", pOptionHeaderFileBuffer->SizeOfImage);
printf("pFileBufferAddSecTotal: %#x\n", AddSecTotal);
printf("NTHeader->OptionalHeader.SizeOfImage + SizeOfSection: %#x\n", pOptionHeaderFileBuffer->SizeOfImage+SizeExportTableSection);
}
//内存对齐
if (AddSecTotal % pOptionHeaderFileBuffer->SectionAlignment)
{
AddSecTotal = (AddSecTotal / pOptionHeaderFileBuffer->SectionAlignment) * pOptionHeaderFileBuffer->SectionAlignment + pOptionHeaderFileBuffer->SectionAlignment;
}
if (!test)
{
printf("pFileBuffer: %#x\n", FileBuffer);
printf("pFileBufferAddSecTotal: %#x\n", AddSecTotal);
}
pMoveExportTableTemp = malloc(AddSecTotal);
if (!pMoveExportTableTemp)
{
printf("(MoveExportTable)apply memory failed.\n");
return 0;
}
memset(pMoveExportTableTemp, 0, AddSecTotal);
memcpy(pMoveExportTableTemp, pFileBuffer, FileBuffer);
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 pDataDirectory = NULL;
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
if (!pMoveExportTableTemp)
{
printf("(MoveExportTable)文件读取失败.\n");
return;
}
//判断是否是有效的MZ标志
if (*((PWORD)pMoveExportTableTemp) != IMAGE_DOS_SIGNATURE)
{
printf("(MoveExportTable)不是有效的MZ标志\n");
free(pMoveExportTableTemp);
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)pMoveExportTableTemp;
//判断是否是有效的PE标志
if (*((PDWORD)((DWORD)pMoveExportTableTemp + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(MoveExportTable)不是有效的PE标志\n");
free(pMoveExportTableTemp);
return;
}
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pMoveExportTableTemp + 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);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory;
PIMAGE_SECTION_HEADER pSectionHeaderTemp = pSectionHeader;
for (DWORD i = 0; i < pPEHeader->NumberOfSections; i++, pSectionHeaderTemp++)
{
//
}
//加节
if (size_surplus_sizeofheader <= (pOptionHeader->SizeOfHeaders - ((DWORD)(pSectionHeaderTemp - pMoveExportTableTemp))))
{
//printf("Enough.\n");
//得到最后一个节的信息
pSectionHeaderTemp--;
PIMAGE_SECTION_HEADER pLastSectionHeader = pSectionHeaderTemp;
//填充节
//memset(((PBYTE)(DWORD)pMoveExportTableTemp + ret_loc3), 0, SizeOfExportTableSection(&pFileBuffer));
//改节数目
pPEHeader->NumberOfSections = pPEHeader->NumberOfSections + 1;
//填充节表
pSectionHeaderTemp++;
memcpy(pSectionHeaderTemp, pSectionHeader, IMAGE_SIZEOF_SECTION_HEADER);
memcpy(pSectionHeaderTemp, ".movExp", 8);
pSectionHeaderTemp->VirtualAddress = pLastSectionHeader->VirtualAddress + pLastSectionHeader->Misc.VirtualSize;
pSectionHeaderTemp->SizeOfRawData = SizeExportTableSection;
pSectionHeaderTemp->PointerToRawData = pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData;
pSectionHeaderTemp->Misc.VirtualSize = SizeExportTableSection;
pOptionHeader->SizeOfImage = pOptionHeaderFileBuffer->SizeOfImage + SizeExportTableSection;
if ((pSectionHeaderTemp->VirtualAddress) % pOptionHeaderFileBuffer->SectionAlignment)
{
(pSectionHeaderTemp->VirtualAddress) = ((pSectionHeaderTemp->VirtualAddress) / pOptionHeaderFileBuffer->SectionAlignment)*pOptionHeaderFileBuffer->SectionAlignment + pOptionHeaderFileBuffer->SectionAlignment;
}
if ((pSectionHeaderTemp->PointerToRawData) % pOptionHeaderFileBuffer->FileAlignment)
{
(pSectionHeaderTemp->PointerToRawData) = ((pSectionHeaderTemp->PointerToRawData) / pOptionHeaderFileBuffer->FileAlignment)*pOptionHeaderFileBuffer->FileAlignment + pOptionHeaderFileBuffer->FileAlignment;
}
/*
if ((pSectionHeaderTemp->PointerToRawData) % pOptionHeaderFileBuffer->SectionAlignment)
{
(pSectionHeaderTemp->PointerToRawData) = ((pSectionHeaderTemp->PointerToRawData) / pOptionHeaderFileBuffer->SectionAlignment)*pOptionHeaderFileBuffer->SectionAlignment + pOptionHeaderFileBuffer->SectionAlignment;
}
*/
}
else
{
free(pMoveExportTableTemp);
printf("Insufficient.\n");
}
if (!pDataDirectory->VirtualAddress)
{
printf("This program has no export table.\n");
return 0;
}
printf("Export Table Rva: %#x\n", pDataDirectory->VirtualAddress);
DWORD Foa_ExportTable = RvaToFileOffset(pMoveExportTableTemp, pDataDirectory->VirtualAddress);
printf("Export Table Foa: %#x\n", Foa_ExportTable);
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pMoveExportTableTemp + Foa_ExportTable);
PVOID pAddInsSction = (PDWORD)((DWORD)pMoveExportTableTemp + pSectionHeaderTemp->PointerToRawData);
if (!test)
{
printf("新添节区的开始地址: %#x\n", ((DWORD)pMoveExportTableTemp + pSectionHeaderTemp->PointerToRawData));
}
PDWORD pAddressOfFunctions = (PDWORD)((DWORD)pMoveExportTableTemp + RvaToFileOffset(pMoveExportTableTemp, pExportDirectory->AddressOfFunctions));
printf("AddressOfFunctions: %#x\n", pExportDirectory->AddressOfFunctions);
DWORD NewAddressOfFunctions = (DWORD)pAddInsSction;
memcpy(pAddInsSction, pAddressOfFunctions, 4 * pExportDirectory->NumberOfFunctions);
pAddInsSction = (PWORD)((DWORD)pAddInsSction + 4 * pExportDirectory->NumberOfFunctions);
PDWORD pAddressOfNameOrdinals = (PDWORD)((DWORD)pMoveExportTableTemp + RvaToFileOffset(pMoveExportTableTemp, pExportDirectory->AddressOfNameOrdinals));
DWORD NewAddressOfNameOrdinals = (DWORD)pAddInsSction;
memcpy(pAddInsSction, pAddressOfNameOrdinals, 2 * pExportDirectory->NumberOfNames);
pAddInsSction = (PDWORD)((DWORD)pAddInsSction + 2 * pExportDirectory->NumberOfNames);
PDWORD pAddressOfNames = (PDWORD)((DWORD)pMoveExportTableTemp + RvaToFileOffset(pMoveExportTableTemp, pExportDirectory->AddressOfNames));
PDWORD pAddressOfNamesOrg = pAddressOfNames;
if (!test)
{
printf("pAddressOfNamesOrg: %#x\n", *pAddressOfNamesOrg);
printf("%#x\n", *pAddressOfNamesOrg);
}
DWORD NewAddressOfNames = (DWORD)pAddInsSction;
memcpy(pAddInsSction, pAddressOfNames, 4 * pExportDirectory->NumberOfNames);
pAddInsSction = (PDWORD)((DWORD)pAddInsSction + 4 * pExportDirectory->NumberOfNames);
for (DWORD n = 0; n < pExportDirectory->NumberOfNames; n++)
{
PVOID pAddressNameString = *pAddressOfNames;
DWORD nameSize = strlen((PVOID)((DWORD)pMoveExportTableTemp+RvaToFileOffset(pMoveExportTableTemp, pAddressNameString)));
*pAddressOfNames = RvaToFileOffset(pMoveExportTableTemp, pAddressNameString);
if (!test)
{
printf("pAddressNameString: %#x\n", (DWORD)pAddressNameString);
printf("&pAddressOfNames: %#x\n", &pAddressOfNames);
printf("pAddressOfNames: %#x\n", pAddressOfNames);
printf("*pAddressOfNames: %#x\n", *pAddressOfNames);
}
memcpy(pAddInsSction, (PVOID)((DWORD)pMoveExportTableTemp + RvaToFileOffset(pMoveExportTableTemp, pAddressNameString)), nameSize);
*(PDWORD)NewAddressOfNames = FoaToImageOffset(pMoveExportTableTemp, (DWORD)pAddInsSction- (DWORD)pMoveExportTableTemp);
printf("pAddInsSction: %#x\n", (DWORD)pAddInsSction);
pAddInsSction = (PDWORD)((DWORD)pAddInsSction + nameSize);
memcpy(pAddInsSction, "\0", 1);
pAddInsSction = (PDWORD)((DWORD)pAddInsSction + 1);
pAddressOfNames++;
((PDWORD)NewAddressOfNames)++;
}
DWORD NewExportDirectory = (DWORD)pAddInsSction;
memcpy(pAddInsSction, pExportDirectory, 0x28);
PIMAGE_EXPORT_DIRECTORY pAddInsSctionTemp = (PIMAGE_EXPORT_DIRECTORY)pAddInsSction;
//修改导出表信息
if (!test)
{
printf("pMoveExportTableTemp: %#x\n", (DWORD)pMoveExportTableTemp);
printf("pSectionHeaderTemp->PointerToRawData: %#x\n", pSectionHeaderTemp->PointerToRawData);
printf("pSectionHeaderTemp->VirtualAddress: %#x\n", pSectionHeaderTemp->VirtualAddress);
}
pAddInsSctionTemp->AddressOfFunctions = FoaToImageOffset(pMoveExportTableTemp, NewAddressOfFunctions - (DWORD)pMoveExportTableTemp);
pAddInsSctionTemp->AddressOfNames = FoaToImageOffset(pMoveExportTableTemp, NewAddressOfNames - (DWORD)pMoveExportTableTemp);
pAddInsSctionTemp->AddressOfNameOrdinals = FoaToImageOffset(pMoveExportTableTemp, NewAddressOfNameOrdinals - (DWORD)pMoveExportTableTemp);
//修改数据目录表信息
pDataDirectory->VirtualAddress= FoaToImageOffset(pMoveExportTableTemp, NewExportDirectory - (DWORD)pMoveExportTableTemp);
size_t ret_loc5 = MemeryTOFile(pMoveExportTableTemp, AddSecTotal, write_movexportable_file_path);
if (!ret_loc5)
{
printf("(MoveExportTable)store memory failed.\n");
return 0;
}
*pFileBuffer_ExportTable = pMoveExportTableTemp; //暂存的数据传给参数后释放
free(pMoveExportTableTemp);
pMoveExportTableTemp = NULL;
return AddSecTotal;
}
DWORD MoveBaseRelocationTable(IN LPVOID pFileBuffer, IN DWORD FileBuffer, IN LPVOID* pFileBuffer_ExportTable)
{
//未加载pMoveExportTableTemp,所以用pFileBuffer得到pOptionHeaderFileBuffer->SectionAlignment
PIMAGE_DOS_HEADER pDosHeaderFileBuffer = NULL;
PIMAGE_NT_HEADERS pNTHeaderFileBuffer = NULL;
PIMAGE_FILE_HEADER pPEHeaderFileBuffer = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeaderFileBuffer = NULL;
pDosHeaderFileBuffer = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeaderFileBuffer = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeaderFileBuffer->e_lfanew);
pPEHeaderFileBuffer = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeaderFileBuffer) + 4);
pOptionHeaderFileBuffer = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeaderFileBuffer + IMAGE_SIZEOF_FILE_HEADER);
LPVOID pMoveBaseRelocationTableTemp = NULL;
DWORD SizeBaseRelocationTableSection = SizeOfBaseRelocationTable(&pFileBuffer);
size_t AddSecTotal = FileBuffer + SizeBaseRelocationTableSection;
if (!test)
{
printf("SizeBaseRelocationTableSection: %#x\n", SizeBaseRelocationTableSection);
printf("pFileBuffer: %#x\n", FileBuffer);
printf("pOptionHeaderFileBuffer->SizeOfImage: %#x\n", pOptionHeaderFileBuffer->SizeOfImage);
printf("AddSecTotal: %#x\n", AddSecTotal);
printf("NTHeader->OptionalHeader.SizeOfImage + SizeOfSection: %#x\n", pOptionHeaderFileBuffer->SizeOfImage + SizeBaseRelocationTableSection);
}
//内存对齐
if (AddSecTotal % pOptionHeaderFileBuffer->SectionAlignment)
{
AddSecTotal = (AddSecTotal / pOptionHeaderFileBuffer->SectionAlignment) * pOptionHeaderFileBuffer->SectionAlignment + pOptionHeaderFileBuffer->SectionAlignment;
}
if (!test)
{
printf("pFileBuffer: %#x\n", FileBuffer);
printf("pFileBufferAddSecTotal: %#x\n", AddSecTotal);
}
pMoveBaseRelocationTableTemp = malloc(AddSecTotal);
if (!pMoveBaseRelocationTableTemp)
{
printf("(MoveBaseRelocationTable)apply memory failed.\n");
return 0;
}
memset(pMoveBaseRelocationTableTemp, 0, AddSecTotal);
memcpy(pMoveBaseRelocationTableTemp, pFileBuffer, FileBuffer);
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 pDataDirectory = NULL;
PIMAGE_BASE_RELOCATION pRelocationTable = NULL;
if (!pMoveBaseRelocationTableTemp)
{
printf("(MoveBaseRelocationTable)文件读取失败.\n");
return;
}
//判断是否是有效的MZ标志
if (*((PWORD)pMoveBaseRelocationTableTemp) != IMAGE_DOS_SIGNATURE)
{
printf("(MoveBaseRelocationTable)不是有效的MZ标志\n");
free(pMoveBaseRelocationTableTemp);
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)pMoveBaseRelocationTableTemp;
//判断是否是有效的PE标志
if (*((PDWORD)((DWORD)pMoveBaseRelocationTableTemp + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(MoveBaseRelocationTable)不是有效的PE标志\n");
free(pMoveBaseRelocationTableTemp);
return;
}
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pMoveBaseRelocationTableTemp + 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);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory;
PIMAGE_DATA_DIRECTORY pDataDirectory_RelocTable = pDataDirectory + 5;
PIMAGE_SECTION_HEADER pSectionHeaderTemp = pSectionHeader;
for (DWORD i = 0; i < pPEHeader->NumberOfSections; i++, pSectionHeaderTemp++)
{
//
}
//加节
if (size_surplus_sizeofheader <= (pOptionHeader->SizeOfHeaders - ((DWORD)(pSectionHeaderTemp - pMoveBaseRelocationTableTemp))))
{
//printf("Enough.\n");
//得到最后一个节的信息
pSectionHeaderTemp--;
PIMAGE_SECTION_HEADER pLastSectionHeader = pSectionHeaderTemp;
//填充节
//改节数目
pPEHeader->NumberOfSections = pPEHeader->NumberOfSections + 1;
//填充节表
pSectionHeaderTemp++;
memcpy(pSectionHeaderTemp, pSectionHeader, IMAGE_SIZEOF_SECTION_HEADER);
memcpy(pSectionHeaderTemp, ".movRel", 8);
pSectionHeaderTemp->VirtualAddress = pLastSectionHeader->VirtualAddress + pLastSectionHeader->Misc.VirtualSize;
pSectionHeaderTemp->SizeOfRawData = SizeBaseRelocationTableSection;
pSectionHeaderTemp->PointerToRawData = pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData;
pSectionHeaderTemp->Misc.VirtualSize = SizeBaseRelocationTableSection;
pOptionHeader->SizeOfImage = pOptionHeaderFileBuffer->SizeOfImage + SizeBaseRelocationTableSection;
if ((pSectionHeaderTemp->VirtualAddress) % pOptionHeaderFileBuffer->SectionAlignment)
{
(pSectionHeaderTemp->VirtualAddress) = ((pSectionHeaderTemp->VirtualAddress) / pOptionHeaderFileBuffer->SectionAlignment)*pOptionHeaderFileBuffer->SectionAlignment + pOptionHeaderFileBuffer->SectionAlignment;
}
if ((pSectionHeaderTemp->PointerToRawData) % pOptionHeaderFileBuffer->FileAlignment)
{
(pSectionHeaderTemp->PointerToRawData) = ((pSectionHeaderTemp->PointerToRawData) / pOptionHeaderFileBuffer->FileAlignment)*pOptionHeaderFileBuffer->FileAlignment + pOptionHeaderFileBuffer->FileAlignment;
}
}
else
{
free(pMoveBaseRelocationTableTemp);
printf("Insufficient.\n");
}
if (!pDataDirectory_RelocTable->VirtualAddress)
{
printf("This program has no relocation table.\n");
return 0;
}
printf("Relocation Table Rva: %#x\n", pDataDirectory_RelocTable->VirtualAddress);
DWORD Foa_RelocationTable = RvaToFileOffset(pMoveBaseRelocationTableTemp, pDataDirectory_RelocTable->VirtualAddress);
printf("Relocation Table Foa: %#x\n", Foa_RelocationTable);
pRelocationTable = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pMoveBaseRelocationTableTemp + Foa_RelocationTable);
PVOID pAddInsSction = (PDWORD)((DWORD)pMoveBaseRelocationTableTemp + pSectionHeaderTemp->PointerToRawData);
memcpy(pAddInsSction, pRelocationTable, pDataDirectory_RelocTable->Size);
DWORD NewpRelocationTable = pAddInsSction;
PIMAGE_BASE_RELOCATION pNewpRelocationTable = (PIMAGE_BASE_RELOCATION)pAddInsSction;
if (!test)
{
printf("新添节区的开始地址: %#x\n", ((DWORD)pMoveBaseRelocationTableTemp + pSectionHeaderTemp->PointerToRawData));
}
//测试功能:修改imagebase
DWORD ImageBaseOrg = pOptionHeader->ImageBase;
pOptionHeader->ImageBase += 0x10000000;
DWORD ImageBaseNew = pOptionHeader->ImageBase;
for (DWORD n = 0; pNewpRelocationTable->VirtualAddress != IMAGE_REL_BASED_ABSOLUTE; n++)
{
printf(".....................RelocationTable %#5xth.................................\n", n + 1);
DWORD arrNumber = (pNewpRelocationTable->SizeOfBlock - 8) / 2;
printf("TypeOffset Number: %#x\n", arrNumber);
PDWORD pTypeOffsetOrg = ((PDWORD)pNewpRelocationTable + 2);
PWORD pTypeOffset = (PWORD)pTypeOffsetOrg;
for (DWORD i = 0; i < arrNumber; i++)
{
//printf("pTypeOffset: %#-10x", (WORD)pTypeOffset);
WORD TypeOffset = *pTypeOffset;
TypeOffset = (TypeOffset & 0b111111111111);
DWORD OffsetOrg = pNewpRelocationTable->VirtualAddress + (DWORD)TypeOffset;
//printf("Rva_BaseRelocation: %#-10x", OffsetOrg);
DWORD Foa_OffsetOrg = RvaToFileOffset(pMoveBaseRelocationTableTemp, OffsetOrg);
PDWORD pFoa_Offset = (PDWORD)((DWORD)pMoveBaseRelocationTableTemp + Foa_OffsetOrg);
printf("改基址前Foa_BaseRelocation: %#-10x ", *pFoa_Offset);
*pFoa_Offset = *pFoa_Offset - ImageBaseOrg + ImageBaseNew;
printf("改基址后Foa_BaseRelocation: %#-10x\n", *pFoa_Offset);
pTypeOffset++;
}
pNewpRelocationTable = (PDWORD)((DWORD)pNewpRelocationTable + pNewpRelocationTable->SizeOfBlock);
}
//修改数据目录表信息
pDataDirectory_RelocTable->VirtualAddress = FoaToImageOffset(pMoveBaseRelocationTableTemp, NewpRelocationTable - (DWORD)pMoveBaseRelocationTableTemp);
size_t ret_loc6 = MemeryTOFile(pMoveBaseRelocationTableTemp, AddSecTotal, write_movreloctable_file_path);
if (!ret_loc6)
{
printf("(MoveRelocationTable)store memory failed.\n");
return 0;
}
*pFileBuffer_ExportTable = pMoveBaseRelocationTableTemp; //暂存的数据传给参数后释放
free(pMoveBaseRelocationTableTemp);
pMoveBaseRelocationTableTemp = NULL;
return AddSecTotal;
}
DWORD SizeOfBaseRelocationTable(IN LPVOID* pFileBuffer)
{
// 初始化PE头部结构体
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 pDataDirectory = NULL;
PIMAGE_BASE_RELOCATION pRelocationTable = NULL;
DWORD SizeOfBaseRelocationTableSectionTotal = 0;
// 判断pImageBuffer是否有效
if (!*pFileBuffer)
{
printf("(SizeOfBaseRelocationTable)读取到内存的ImageBuffer无效.\n");
return 0;
}
//判断是不是exe文件
if (*((PWORD)*pFileBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("(SizeOfBaseRelocationTable)不含MZ标志,不是exe文件.\n");
return 0;
}
// 强制结构体类型转换
pDosHeader = (PIMAGE_DOS_HEADER)*pFileBuffer;
if (*((PDWORD)((DWORD)*pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(SizeOfBaseRelocationTable)不是有效的PE标志.\n");
return 0;
}
// 强制结构体类型转换
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);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory;
PIMAGE_DATA_DIRECTORY pDataDirectory_RelocTable = pDataDirectory + 5;
if (!pDataDirectory_RelocTable->VirtualAddress)
{
printf("This program has no relocation table.\n");
return 0;
}
DWORD Foa_RelocationTable = RvaToFileOffset(*pFileBuffer, pDataDirectory_RelocTable->VirtualAddress);
pRelocationTable = (PIMAGE_EXPORT_DIRECTORY)((DWORD)*pFileBuffer + Foa_RelocationTable);
for (DWORD n = 0; pRelocationTable->VirtualAddress != IMAGE_REL_BASED_ABSOLUTE; n++)
{
SizeOfBaseRelocationTableSectionTotal += pRelocationTable->SizeOfBlock;
pRelocationTable = (PDWORD)((DWORD)pRelocationTable + pRelocationTable->SizeOfBlock);
}
if (SizeOfBaseRelocationTableSectionTotal % pOptionHeader->SectionAlignment)
{
SizeOfBaseRelocationTableSectionTotal = (SizeOfBaseRelocationTableSectionTotal / pOptionHeader->SectionAlignment) * pOptionHeader->SectionAlignment + pOptionHeader->SectionAlignment;
}
return SizeOfBaseRelocationTableSectionTotal;
}
int main()
{
LPVOID pFileBuffer = NULL;
LPVOID pNewFileBuffer = NULL;
LPVOID pImageBuffer = NULL;
LPVOID pAddSectionBuffer = NULL;
LPVOID pEnlargerSection = NULL;
LPVOID pMergeSection = NULL;
LPVOID pMoveExportTableBuffer = NULL;
LPVOID pMoveRelocationTableBuffer = NULL;
size_t pRVA = 0x0003123;
size_t pFOA = 0x00020450;
size_t ret1 = ToLeaderPE(file_path, &pFileBuffer); // &pFileBuffer(void**类型) 传递地址对其值可以进行修改
printf("exe->filebuffer 返回值为计算所得文件大小:%#x\n", ret1);
//ReadPEFile(pFileBuffer);
//size_t ret2 = CopyFileBufferToImageBuffer(pFileBuffer, &pImageBuffer);
//printf("filebuffer -> imagebuffer返回值为计算所得文件大小:%#x\n", ret2);
//size_t ret3 = CopyImageBufferToNewBuffer(pImageBuffer, &pNewFileBuffer);
//MemeryTOFile(pNewFileBuffer, ret3, write_file_path);
//int ret_FOA1 = RvaToFileOffset(pFileBuffer, pRVA);
//printf("内存偏移%#x 转换为文件中的偏移:%#x\n", pRVA, ret_FOA1);
//int ret_RVA1 = FoaToImageOffset(pFileBuffer, pFOA);
//printf("文件偏移%#x 转换为内存中的偏移:%#x\n", pFOA, ret_RVA1);
//size_t ret4 = TestAddCodeInDataSec(pImageBuffer, &pNewFileBuffer, ret1);
//size_t ret4 = TestAddCodeInXXXSec(pImageBuffer, &pNewFileBuffer, 3, ret1);
//printf("%#x", ret4);
//size_t ret5 = TestAddSection(file_path, &pFileBuffer, &pAddSectionBuffer);
//printf("TestAddSection Buffer: %#x\n", ret5);
//size_t ret6 = TestEnlargeSection(&pFileBuffer, &pEnlargerSection);
//printf("TestEnlargeSection Buffer: %#x\n", ret6);
//size_t ret7 = TestMergeSection(&pFileBuffer, &pMergeSection);
//printf("TestMergeSection Buffer: %#x\n", ret7);
//LogExportTable(pFileBuffer);
//size_t ret8 = GetFunctionAddrByOrdinals(pFileBuffer, 1);
//printf("GetFunctionAddr is %#x\n", ret8);
//size_t ret9 = GetFunctionAddrByName(pFileBuffer, fun_name);
//printf("GetFunctionAddr is %#x\n", ret9);
//LogBaseRelocationTable(pFileBuffer);
//size_t ret10 = SizeOfExportTableSection(&pFileBuffer);
//printf("SizeOfExportTableSection: %#x\n", ret10);
//size_t ret11=MoveExportTable(pFileBuffer, ret1, &pMoveExportTableBuffer);
//printf("SizeOfExportTableSection: %#x\n", ret11);
//size_t ret12 = SizeOfBaseRelocationTable(&pFileBuffer);
//printf("SizeOfBaseRelocationTableSection: %#x\n", ret12);
size_t ret13 = MoveBaseRelocationTable(pFileBuffer, ret1, &pMoveRelocationTableBuffer);
printf("SizeOfRelocationTableSection: %#x\n", ret13);
free(pFileBuffer);
free(pNewFileBuffer);
free(pImageBuffer);
return 0;
}
3.结果展示: