最近在学习PE,今天最后一节课做完了,代码很丑,很粗糙,有很多需要改的地方
下面是所有代码,全部经过编译
#include <stdio.h>
#include <stdlib.h>
#include "string.h"
#include <windows.h>
#define path "D:\\xx\\xx.exe"
#define path1 "D:\\xx\\xx.exe"
#define path2 "D:\\xx\\xx.exe"
#define CodeLength 0x12
//DWORD FileAlignment(int n);
/*参数:n是一个16进制数,代表要处理多大字节
* 返回值为:通过文件对齐后的大小(200h)
*/
//DWORD ImageAlignment(int n);
/*参数:n是一个16进制数,代表要处理多大字节
* 返回值为:通过内存对齐后的大小(1000h)
*/
//DWORD FileToFileBuffer(IN LPSTR lpszFile, OUT LPVOID* FileBuffer);
/*参数:lpszFile是要操作的路径
* 返回值为:生成文件大小
*/
//DWORD FileToBigFileBuffer(IN LPSTR lpszFile,IN int k, OUT LPVOID* FileBuffer);
/*参数:k是一个16进制数,代表要新增的节大小,lpszFile是路径,返回一个内存空间
* 返回值为:生成文件大小
*/
//DWORD FileBufferToBigImageBuffer(IN LPVOID pFileBuffer, int a, OUT LPVOID* pImageBuffer);
/*参数:a是一个16进制数,代表要新增的节大小,或者扩大节的增量
* 返回值为:生成pImageBuffer大小
*/
//DWORD FileBufferToImageBuffer(IN LPVOID pFileBuffer, OUT LPVOID* pImageBuffer);
/*参数:文件内存大小作为参数
* 返回值为:生成ImageBuffer大小
*/
//DWORD ImageBufferToNewBuffer(IN LPVOID pImageBuffer, OUT LPVOID* pNewBuffer);
/*参数:image内存大小作为参数
* 返回值为:pNewBuffer生成大小
*/
//DWORD MemeryTOFile(IN LPVOID pMemBuffer, IN size_t size, OUT LPSTR lpszFile);
/*参数:文件内存大小作为参数
* 返回值为:生成ImageBuffer大小
*/
//void addshellcodewhere(int n);
//参数为在第几节生成shellcode
//void addBigshellcodewhere(int n);
//参数为在第几节生成shellcode(加过节,shellcode直接存在该节首部)
//void addnewsec(int n);
//n为要新增节的大小
//void BiggerLastSec(int n);
//扩大最后一个节,n为要扩大多少
//void printdatadirectory(char* n);
//n为路径,打印目录项
//DWORD RvaToFoa(IN DWORD rva);
//参数为在内存的偏移,返回对应foa的值,也就是在文件中的偏移
//void PrintExportDirectory();
//打印导出表信息
//DWORD GetFunctionAddrByName(IN LPVOID FileBuffer, IN LPSTR FunctionName);
//通过导出表函数名称,来找到该函数地址,FunctionName为函数名
//DWORD GetFunctionAddrByOrdinals(IN LPVOID FileBuffer, IN DWORD FunctionOrdinals);
//通过导出表函数序号,来找到该函数地址,FunctionOrdinals为序号
//void PrintRelocationTable();
//打印重定位表
//void TestMoveExport();
//移动导出表
//void TestMoveReloca();
//移动重定位表(有可能出现问题,多malloc一些空间)
//void changeImageBase(IN DWORD Number);
//改变ImageBase让重定位表依然可以使用,Number为ImageBase增加多大
//void printfImportTable();
//打印导入表
//void printboundimporttable();
//打印绑定导入表
//void injectImportTable(IN LPVOID FileBuffer);
//FileBuffer是exe,把injectiondll注入到exe,也可以改成其他dll
BYTE ShellCode[] =
{
0x6A,00,0x6A,00,0x6A,00,0x6A,00,
0xE8,00,00,00,00,
0xE9,00,00,00,00
};
DWORD FileAlignment(int n)
{
DWORD i;
if (n % 0x200 != 0)
{
i = n / 0x200 + 1;
i = i * 0x200;
return i;
}
else
{
i = n / 0x200;
i = i * 0x200;
return i;
}
}
DWORD ImageAlignment(int n)
{
DWORD i;
if (n % 0x1000 != 0)
{
i = n / 0x1000 + 1;
i = i * 0x1000;
return i;
}
else
{
i = n / 0x1000;
i = i * 0x1000;
return i;
}
}
DWORD FileToFileBuffer(IN LPSTR lpszFile, OUT LPVOID* FileBuffer)
{
FILE* pFile = NULL;
LPVOID ptempFileBuffer = NULL;
DWORD fileSize = 0;
//打开文件
pFile = fopen(lpszFile, "rb");
//判断文件是否打开
if (!pFile)
{
printf("无法打开文件");
return 0;
}
//malloc文件大小
fseek(pFile, 0, SEEK_END);
fileSize = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
ptempFileBuffer = malloc(fileSize);
//判断是否申请空间成功
if (!ptempFileBuffer)
{
printf("分配空间失败");
fclose(pFile);
return 0;
}
size_t n = fread(ptempFileBuffer, fileSize, 1, pFile);
//判断是否拷贝成功
if (!n)
{
printf("拷贝数据失败");
free(ptempFileBuffer);
fclose(pFile);
return 0;
}
*FileBuffer = ptempFileBuffer;
ptempFileBuffer = NULL;
fclose(pFile);
return fileSize;
}
DWORD FileToBigFileBuffer(IN LPSTR lpszFile,int k,OUT LPVOID* FileBuffer)
{
FILE* pFile = NULL;
LPVOID ptempFileBuffer = NULL;
DWORD fileSize = 0;
//打开文件
pFile = fopen(lpszFile, "rb");
//判断文件是否打开
if (!pFile)
{
printf("无法打开文件");
return 0;
}
//malloc文件大小
fseek(pFile, 0, SEEK_END);
fileSize = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
ptempFileBuffer = malloc(fileSize+ FileAlignment(k));
//判断是否申请空间成功
if (!ptempFileBuffer)
{
printf("分配空间失败");
fclose(pFile);
return 0;
}
size_t n = fread(ptempFileBuffer, fileSize, 1, pFile);
//判断是否拷贝成功
if (!n)
{
printf("拷贝数据失败");
free(ptempFileBuffer);
fclose(pFile);
return 0;
}
*FileBuffer = ptempFileBuffer;
ptempFileBuffer = NULL;
fclose(pFile);
return fileSize;
}
DWORD FileBufferToBigImageBuffer(IN LPVOID pFileBuffer,int a, OUT LPVOID* pImageBuffer)
{
if (pFileBuffer == NULL)
{
printf("PE文件读取失败");
return 0;
}
if (*(PWORD)pFileBuffer != IMAGE_DOS_SIGNATURE)
{
printf("不是有效的MZ头");
return 0;
}
LPVOID p1ImageBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
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);
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);
p1ImageBuffer = malloc((DWORD)(pOptionHeader->SizeOfImage+ImageAlignment(a)));
if (!p1ImageBuffer)
{
printf("申请ImageBuffer堆空间失败");
return 0;
}
memset(p1ImageBuffer, 0, (DWORD)(pOptionHeader->SizeOfImage + ImageAlignment(a)));
memcpy(p1ImageBuffer, pFileBuffer, pOptionHeader->SizeOfHeaders);
PIMAGE_SECTION_HEADER ptempSectionHeader = pSectionHeader;
for (int k = 0; k < pPEHeader->NumberOfSections; k++)
{
memcpy((void*)((DWORD)p1ImageBuffer + ptempSectionHeader->VirtualAddress), (void*)((DWORD)pFileBuffer + ptempSectionHeader->PointerToRawData), ptempSectionHeader->SizeOfRawData);
//printf("%x\n", ptempSectionHeader->SizeOfRawData);
ptempSectionHeader++;
}
*pImageBuffer = p1ImageBuffer;
ptempSectionHeader = NULL;
return pOptionHeader->SizeOfImage;
}
DWORD FileBufferToImageBuffer(IN LPVOID pFileBuffer, OUT LPVOID* pImageBuffer)
{
if (pFileBuffer == NULL)
{
printf("PE文件读取失败");
return 0;
}
if (*(PWORD)pFileBuffer != IMAGE_DOS_SIGNATURE)
{
printf("不是有效的MZ头");
return 0;
}
LPVOID p1ImageBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
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);
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);
p1ImageBuffer = malloc(pOptionHeader->SizeOfImage);
if (!p1ImageBuffer)
{
printf("申请ImageBuffer堆空间失败");
return 0;
}
memset(p1ImageBuffer, 0, pOptionHeader->SizeOfImage);
memcpy(p1ImageBuffer, pFileBuffer, pOptionHeader->SizeOfHeaders);
PIMAGE_SECTION_HEADER ptempSectionHeader = pSectionHeader;
for (int k = 0; k < pPEHeader->NumberOfSections; k++)
{
memcpy((void*)((DWORD)p1ImageBuffer+ ptempSectionHeader->VirtualAddress), (void*)((DWORD)pFileBuffer + ptempSectionHeader->PointerToRawData), ptempSectionHeader->SizeOfRawData);
//printf("%x\n", ptempSectionHeader->SizeOfRawData);
ptempSectionHeader++;
}
*pImageBuffer = p1ImageBuffer;
ptempSectionHeader = NULL;
return pOptionHeader->SizeOfImage;
}
DWORD ImageBufferToNewBuffer(IN LPVOID pImageBuffer, OUT LPVOID* pNewBuffer)
{
if (!pImageBuffer)
{
printf("PE文件读取失败");
return 0;
}
if (*(PWORD)pImageBuffer != IMAGE_DOS_SIGNATURE)
{
printf("不是有效的MZ头");
free(pImageBuffer);
return 0;
}
DWORD FileSize = 0;
LPVOID ptempNewBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + 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 ptempSectionHeader = pSectionHeader;
if (*(PDWORD)((DWORD)pImageBuffer + pDosHeader->e_lfanew) != IMAGE_NT_SIGNATURE)
{
printf("不是有效的PE签名");
free(pImageBuffer);
return 0;
}
for (int i = 0; i < pPEHeader->NumberOfSections; i++, ptempSectionHeader++);
ptempSectionHeader--;
FileSize = ptempSectionHeader->PointerToRawData + ptempSectionHeader->SizeOfRawData;
ptempNewBuffer = malloc(FileSize);
if (!ptempNewBuffer)
{
printf("申请pNewBuffer堆空间失败");
return 0;
}
memset(ptempNewBuffer, 0, FileSize);
memcpy(ptempNewBuffer, pImageBuffer, pOptionHeader->SizeOfHeaders);
PIMAGE_SECTION_HEADER ptemp1SectionHeader = pSectionHeader;
for (DWORD n = 0; n < pPEHeader->NumberOfSections; n++)
{
memcpy((void*)((DWORD)ptempNewBuffer+ptemp1SectionHeader->PointerToRawData), (void*)((DWORD)pImageBuffer + ptemp1SectionHeader->VirtualAddress), ptemp1SectionHeader->SizeOfRawData);
//printf("%x\n", ptemp1SectionHeader->SizeOfRawData);
ptemp1SectionHeader++;
}
*pNewBuffer = ptempNewBuffer;
ptemp1SectionHeader = NULL;
return FileSize;
}
DWORD MemeryTOFile(IN LPVOID pMemBuffer, IN size_t size, OUT LPSTR lpszFile)
{
FILE* pFile = NULL;
if (!pMemBuffer)
{
printf("读取内存失败");
return 0;
}
pFile = fopen(lpszFile, "wb");
if (!pFile)
{
printf("创建exe失败");
return 0;
}
size_t n = fwrite(pMemBuffer, size, 1, pFile);
if (!n)
{
printf("存盘失败");
free(pMemBuffer);
fclose(pFile);
pFile = NULL;
return 0;
}
free(pMemBuffer);
fclose(pFile);
pFile = NULL;
return 1;
}
void addshellcodewhere(int n)
//参数n为shellcode加到第n节
{
LPVOID FileBuffer = NULL;
LPVOID ImageBuffer = NULL;
LPVOID NewBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PBYTE CodeBegin = NULL;
DWORD Size = 0;
FileToFileBuffer((CHAR*)path1, &FileBuffer);
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return;
}
FileBufferToImageBuffer(FileBuffer, &ImageBuffer);
if (!ImageBuffer)
{
printf("FileBUffer->ImageBuffer失败");
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)ImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + 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);
if (n > pPEHeader->NumberOfSections)
{
printf("没有这个节");
return;
}
PIMAGE_SECTION_HEADER ptempSectionHeader = pSectionHeader;
ptempSectionHeader = ptempSectionHeader + n - 1;
//printf("%s", ptempSectionHeader->Name);
if (((ptempSectionHeader->SizeOfRawData) - (ptempSectionHeader->Misc.VirtualSize)) < CodeLength)
{
printf("shellcode代码存不下");
free(FileBuffer);
free(ImageBuffer);
return;
}
ptempSectionHeader->Characteristics = pSectionHeader->Characteristics | ptempSectionHeader->Characteristics;
CodeBegin = (PBYTE)((DWORD)ImageBuffer + ptempSectionHeader->VirtualAddress + ptempSectionHeader->Misc.VirtualSize);
//printf("%x", (DWORD)CodeBegin);
memcpy(CodeBegin, ShellCode, CodeLength);
//修改E8(CALL)
DWORD E8address = (DWORD)&MessageBox - (pOptionHeader->ImageBase + (((DWORD)CodeBegin + 0xD) - (DWORD)ImageBuffer));
//printf("%x\n", CodeBegin);
//printf("%x", ImageBuffer);
*(PDWORD)((DWORD)CodeBegin + 0x9) = E8address;
//修改E9(JMP)
DWORD E9address = pOptionHeader->AddressOfEntryPoint - ((DWORD)CodeBegin + 0x12 - (DWORD)pDosHeader);
*(PDWORD)((DWORD)CodeBegin + 0xE) = E9address;
//修改OEP
pOptionHeader->AddressOfEntryPoint = (DWORD)CodeBegin - (DWORD)ImageBuffer;
Size = ImageBufferToNewBuffer(ImageBuffer, &NewBuffer);
if (Size == 0 || !NewBuffer)
{
printf("ImageBuffer->NewBuffer失败");
free(FileBuffer);
free(ImageBuffer);
return;
}
BOOL isok = MemeryTOFile(NewBuffer, Size, (char*)path);
if (isok)
{
printf("存盘成功");
return;
}
else
{
printf("存盘失败");
}
free(NewBuffer);
free(ImageBuffer);
free(FileBuffer);
}
void addBigshellcodewhere(int n)
//将shellcode加到新增节中,n为新增节
{
LPVOID FileBuffer = NULL;
LPVOID ImageBuffer = NULL;
LPVOID NewBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PBYTE CodeBegin = NULL;
DWORD Size = 0;
FileToFileBuffer((CHAR*)path, &FileBuffer);
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return;
}
FileBufferToImageBuffer(FileBuffer, &ImageBuffer);
if (!ImageBuffer)
{
printf("FileBUffer->ImageBuffer失败");
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)ImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + 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);
if (n > pPEHeader->NumberOfSections)
{
printf("没有这个节");
return;
}
PIMAGE_SECTION_HEADER ptempSectionHeader = pSectionHeader;
ptempSectionHeader = ptempSectionHeader + n - 1;
ptempSectionHeader->Characteristics = pSectionHeader->Characteristics | ptempSectionHeader->Characteristics;
CodeBegin = (PBYTE)((DWORD)ImageBuffer + ptempSectionHeader->VirtualAddress);
//printf("%x", (DWORD)CodeBegin);
memcpy(CodeBegin, ShellCode, CodeLength);
//修改E8(CALL)
DWORD E8address = (DWORD)&MessageBox - (pOptionHeader->ImageBase + (((DWORD)CodeBegin + 0xD) - (DWORD)ImageBuffer));
//printf("%x\n", CodeBegin);
//printf("%x", ImageBuffer);
*(PDWORD)((DWORD)CodeBegin + 0x9) = E8address;
//修改E9(JMP)
DWORD E9address = pOptionHeader->AddressOfEntryPoint - ((DWORD)CodeBegin + 0x12 - (DWORD)pDosHeader);
*(PDWORD)((DWORD)CodeBegin + 0xE) = E9address;
//修改OEP
pOptionHeader->AddressOfEntryPoint = (DWORD)CodeBegin - (DWORD)ImageBuffer;
Size = ImageBufferToNewBuffer(ImageBuffer, &NewBuffer);
if (Size == 0 || !NewBuffer)
{
printf("ImageBuffer->NewBuffer失败");
free(FileBuffer);
free(ImageBuffer);
return;
}
BOOL isok = MemeryTOFile(NewBuffer, Size, (char*)path2);
if (isok)
{
printf("存盘成功");
}
else
{
printf("存盘失败");
}
free(NewBuffer);
free(ImageBuffer);
free(FileBuffer);
}
void addnewsec(int n)
//新增一个节,n为生成多大新增节
{
LPVOID FileBuffer = NULL;
LPVOID ImageBuffer = NULL;
LPVOID NewBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
DWORD Size = 0;
FileToBigFileBuffer((CHAR*)path1,n, &FileBuffer);
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return;
}
FileBufferToBigImageBuffer(FileBuffer, n,&ImageBuffer);
if (!ImageBuffer)
{
printf("FileBUffer->ImageBuffer失败");
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)ImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + 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 ptempSectionHeader = pSectionHeader;
for (int i = 0; i < pPEHeader->NumberOfSections; i++, ptempSectionHeader++);
if ((pOptionHeader->SizeOfHeaders - ((DWORD)ptempSectionHeader - (DWORD)pDosHeader)) < 80)
{
printf("空间不够");
return;
}
memcpy(ptempSectionHeader, pSectionHeader,40);
pPEHeader->NumberOfSections = (DWORD)pPEHeader->NumberOfSections + 1;
//printf("%x\n", pPEHeader->NumberOfSections);
pOptionHeader->SizeOfImage = (DWORD)pOptionHeader->SizeOfImage + n;
//printf("%x\n", pOptionHeader->SizeOfImage);
ptempSectionHeader->Misc.VirtualSize = n;
//printf("%x\n", ptempSectionHeader->Misc.VirtualSize);
PIMAGE_SECTION_HEADER ptempSectionHeader1 = ptempSectionHeader-1;
//判断内存大小和对齐后文件中大小,谁大加谁
if (ptempSectionHeader1->Misc.VirtualSize > ptempSectionHeader1->SizeOfRawData)
{
ptempSectionHeader->VirtualAddress = ptempSectionHeader1->VirtualAddress + ImageAlignment(ptempSectionHeader1->Misc.VirtualSize);
}
else
{
ptempSectionHeader->VirtualAddress = ptempSectionHeader1->VirtualAddress + ImageAlignment(ptempSectionHeader1->SizeOfRawData);
}
ptempSectionHeader->SizeOfRawData = FileAlignment(n);
ptempSectionHeader->PointerToRawData = ptempSectionHeader1->PointerToRawData + ptempSectionHeader1->SizeOfRawData;
Size = ImageBufferToNewBuffer(ImageBuffer, &NewBuffer);
if (Size == 0 || !NewBuffer)
{
printf("ImageBuffer->NewBuffer失败");
free(FileBuffer);
free(ImageBuffer);
return;
}
BOOL isok = MemeryTOFile(NewBuffer, Size, (char*)path);
if (isok)
{
printf("存盘成功");
}
else
{
printf("存盘失败");
}
free(NewBuffer);
free(ImageBuffer);
free(FileBuffer);
}
void BiggerLastSec(int n)
//扩大最后一个节,n为扩大增量
{
LPVOID FileBuffer = NULL;
LPVOID ImageBuffer = NULL;
LPVOID NewBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
DWORD Size = 0;
FileToFileBuffer((CHAR*)path1, &FileBuffer);
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return;
}
FileBufferToBigImageBuffer(FileBuffer, n, &ImageBuffer);
if (!ImageBuffer)
{
printf("FileBUffer->ImageBuffer失败");
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)ImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + 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 ptempSectionHeader = pSectionHeader;
for (int i = 0; i < pPEHeader->NumberOfSections; i++, ptempSectionHeader++);
ptempSectionHeader--;
//printf("%s", ptempSectionHeader->Name);
ptempSectionHeader->Characteristics = ptempSectionHeader->Characteristics | pSectionHeader->Characteristics;
if (ptempSectionHeader->Misc.VirtualSize > ptempSectionHeader->SizeOfRawData)
{
ptempSectionHeader->Misc.VirtualSize = n + ptempSectionHeader->Misc.VirtualSize;
ptempSectionHeader->Misc.VirtualSize = ImageAlignment(ptempSectionHeader->Misc.VirtualSize);
ptempSectionHeader->SizeOfRawData = ptempSectionHeader->Misc.VirtualSize;
}
else
{
ptempSectionHeader->SizeOfRawData = n + ptempSectionHeader->SizeOfRawData;
ptempSectionHeader->SizeOfRawData = ImageAlignment(ptempSectionHeader->SizeOfRawData);
ptempSectionHeader->Misc.VirtualSize = ptempSectionHeader->SizeOfRawData;
}
pOptionHeader->SizeOfImage = pOptionHeader->SizeOfImage + ImageAlignment(n);
Size = ImageBufferToNewBuffer(ImageBuffer, &NewBuffer);
if (Size == 0 || !NewBuffer)
{
printf("ImageBuffer->NewBuffer失败");
free(FileBuffer);
free(ImageBuffer);
return;
}
BOOL isok = MemeryTOFile(NewBuffer, Size, (char*)path);
if (isok)
{
printf("存盘成功");
}
else
{
printf("存盘失败");
}
free(NewBuffer);
free(ImageBuffer);
free(FileBuffer);
}
void TogetherSec()
{
LPVOID FileBuffer = NULL;
LPVOID ImageBuffer = NULL;
LPVOID NewBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
DWORD Size = 0;
FileToFileBuffer((CHAR*)path1, &FileBuffer);
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return;
}
FileBufferToImageBuffer(FileBuffer, &ImageBuffer);
if (!ImageBuffer)
{
printf("FileBUffer->ImageBuffer失败");
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)ImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + 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 ptempSectionHeader = pSectionHeader;
PIMAGE_SECTION_HEADER ptempSectionHeader1 = pSectionHeader;
for (int i = 0; i < pPEHeader->NumberOfSections; i++, ptempSectionHeader++);
ptempSectionHeader--;
DWORD Max = ptempSectionHeader->SizeOfRawData > ptempSectionHeader->Misc.VirtualSize ? ptempSectionHeader->SizeOfRawData : ptempSectionHeader->Misc.VirtualSize;
pSectionHeader->SizeOfRawData = ptempSectionHeader->VirtualAddress + Max - ImageAlignment(pOptionHeader->SizeOfHeaders);
pSectionHeader->Misc.VirtualSize = ptempSectionHeader->VirtualAddress + Max - ImageAlignment(pOptionHeader->SizeOfHeaders);
for (int i = 0; i < pPEHeader->NumberOfSections; i++)
{
pSectionHeader->Characteristics = ptempSectionHeader1->Characteristics | pSectionHeader->Characteristics;
ptempSectionHeader1++;
}
pPEHeader->NumberOfSections = 1;
Size = ImageBufferToNewBuffer(ImageBuffer, &NewBuffer);
if (Size == 0 || !NewBuffer)
{
printf("ImageBuffer->NewBuffer失败");
free(FileBuffer);
free(ImageBuffer);
return;
}
BOOL isok = MemeryTOFile(NewBuffer, Size, (char*)path);
if (isok)
{
printf("存盘成功");
}
else
{
printf("存盘失败");
}
free(NewBuffer);
free(ImageBuffer);
free(FileBuffer);
}
void printdatadirectory(char* n)
{
LPVOID FileBuffer = NULL;
LPVOID ImageBuffer = NULL;
LPVOID NewBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PBYTE CodeBegin = NULL;
DWORD Size = 0;
FileToFileBuffer(n, &FileBuffer);
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return;
}
FileBufferToImageBuffer(FileBuffer, &ImageBuffer);
if (!ImageBuffer)
{
printf("FileBUffer->ImageBuffer失败");
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)ImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
printf("*************************导出表**************************\n");
printf("内存偏移:%x\n", pOptionHeader->DataDirectory[0].VirtualAddress);
printf("大小:%x\n", pOptionHeader->DataDirectory[0].Size);
//...
free(FileBuffer);
free(ImageBuffer);
}
DWORD RvaToFoa(IN LPSTR PATH,IN DWORD rva)
//参数为内存偏移,返回文件偏移
{
LPVOID FileBuffer = NULL;
LPVOID ImageBuffer = NULL;
DWORD Foa = 0;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
FileToFileBuffer(PATH, &FileBuffer);
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return 0;
}
FileBufferToImageBuffer(FileBuffer, &ImageBuffer);
if (!ImageBuffer)
{
printf("FileBUffer->ImageBuffer失败");
return 0;
}
pDosHeader = (PIMAGE_DOS_HEADER)ImageBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + 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 ptempSectionHeader = pSectionHeader;
PIMAGE_SECTION_HEADER ptempSectionHeader1 = pSectionHeader;
for (int i = 0; i < pPEHeader->NumberOfSections; i++, ptempSectionHeader++);
//printf("%x\n", FileAlignment(((DWORD)ptempSectionHeader - (DWORD)ImageBuffer)));
if (rva <= FileAlignment(((DWORD)ptempSectionHeader - (DWORD)ImageBuffer)))
{
Foa = rva;
free(FileBuffer);
free(ImageBuffer);
return Foa;
}
for (int k = 0; k < pPEHeader->NumberOfSections-1; k++)
{
if (ptempSectionHeader1->VirtualAddress < rva && rva < (ptempSectionHeader1 + 1)->VirtualAddress)
{
Foa = ptempSectionHeader1->PointerToRawData + (rva - ptempSectionHeader1->VirtualAddress);
free(FileBuffer);
free(ImageBuffer);
return Foa;
}
if (ptempSectionHeader1->VirtualAddress == rva)
{
Foa = ptempSectionHeader1->PointerToRawData;
free(FileBuffer);
free(ImageBuffer);
return Foa;
}
ptempSectionHeader1++;
}
if (ptempSectionHeader1->VirtualAddress <= rva)
{
Foa = ptempSectionHeader1->PointerToRawData + (rva - ptempSectionHeader1->VirtualAddress);
free(FileBuffer);
free(ImageBuffer);
return Foa;
}
free(FileBuffer);
free(ImageBuffer);
return 0;
}
DWORD FoaToRva(IN LPSTR PATH,IN DWORD Foa)
{
LPVOID FileBuffer = NULL;
DWORD Rva = 0;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
FileToFileBuffer(PATH, &FileBuffer);
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return 0;
}
pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + 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 ptempSectionHeader = pSectionHeader;
PIMAGE_SECTION_HEADER ptempSectionHeader1 = pSectionHeader;
for (int i = 0; i < pPEHeader->NumberOfSections; i++, ptempSectionHeader++);
//printf("%x\n", FileAlignment(((DWORD)ptempSectionHeader - (DWORD)ImageBuffer)));
if (Foa <= FileAlignment(((DWORD)ptempSectionHeader - (DWORD)FileBuffer)))
{
Rva = Foa;
free(FileBuffer);
return Rva;
}
for (int k = 0; k < pPEHeader->NumberOfSections-1; k++)
{
if (ptempSectionHeader1->PointerToRawData < Foa && Foa < (ptempSectionHeader1 + 1)->PointerToRawData)
{
Rva = ptempSectionHeader1->VirtualAddress + (Foa - ptempSectionHeader1->PointerToRawData);
free(FileBuffer);
return Rva;
}
if (ptempSectionHeader1->PointerToRawData == Foa)
{
Rva = ptempSectionHeader1->VirtualAddress;
free(FileBuffer);
return Rva;
}
ptempSectionHeader1++;
}
if (ptempSectionHeader1->PointerToRawData <= Foa)
{
Rva = ptempSectionHeader1->VirtualAddress + (Foa - ptempSectionHeader1->PointerToRawData);
free(FileBuffer);
return Rva;
}
free(FileBuffer);
return 0;
}
void PrintExportDirectory()
{
LPVOID FileBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_EXPORT_DIRECTORY pexport = NULL;
DWORD FileAddress = NULL;
PDWORD AddressName = NULL;
PWORD AddressOrdinals = NULL;
PDWORD AddressFunction = NULL;
FileToFileBuffer((char*)path1, &FileBuffer);
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
FileAddress = RvaToFoa((char*)path1,pOptionHeader->DataDirectory[0].VirtualAddress) + (DWORD)FileBuffer;
pexport = (PIMAGE_EXPORT_DIRECTORY)FileAddress;
AddressOrdinals = (PWORD)(RvaToFoa((char*)path1,pexport->AddressOfNameOrdinals)+(DWORD)FileBuffer);
AddressName = (PDWORD)(RvaToFoa((char*)path1, pexport->AddressOfNames) + (DWORD)FileBuffer);
AddressFunction = (PDWORD)(RvaToFoa((char*)path1, pexport->AddressOfFunctions) + (DWORD)FileBuffer);
printf("Characteristics:%x\n", pexport->Characteristics);
printf("timedatestamp:%x\n", pexport->TimeDateStamp);
printf("Name:%x\n", pexport->Name);
printf("Base:%x\n", pexport->Base);
printf("NumberOfFunctions:%x\n", pexport->NumberOfFunctions);
printf("NumberOfNames:%x\n", pexport->NumberOfNames);
printf("AddressOfFunctions(函数地址):%x\n", pexport->AddressOfFunctions);
printf("AddressOfNameOrdinals(序号):%x\n", pexport->AddressOfNameOrdinals);
printf("AddressOfNames(存储的是名字的地址):%x\n", pexport->AddressOfNames);
printf("*************函数地址表**************\n");
for (DWORD i = 0; i < pexport->NumberOfFunctions; i++)
{
printf("函数地址:%x\n", *AddressFunction);
AddressFunction++;
}
printf("*************函数序号表**************\n");
for (DWORD k = 0; k < pexport->NumberOfNames; k++)
{
printf("序号:%x\n", *AddressOrdinals);
AddressOrdinals++;
}
printf("*************函数名称表**************\n");
for (DWORD l = 0; l < pexport->NumberOfNames; l++)
{
printf("函数名称:%s\n", (DWORD)FileBuffer + RvaToFoa((char*)path1, *AddressName));
AddressName++;
}
}
DWORD GetFunctionAddrByName(IN LPVOID FileBuffer,IN LPSTR FunctionName)
{
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return NULL;
}
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PDWORD pexport = NULL;
PIMAGE_EXPORT_DIRECTORY FileAddress = NULL;
PWORD OrdinalsAddress = NULL;
PDWORD FunctionAddress = NULL;
DWORD i = 0;
pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
//printf("%x\n", pOptionHeader->DataDirectory[0].VirtualAddress);
FileAddress = (PIMAGE_EXPORT_DIRECTORY)(RvaToFoa((char*)path1, pOptionHeader->DataDirectory[0].VirtualAddress) + (DWORD)FileBuffer);
pexport = (PDWORD)(RvaToFoa((char*)path1, FileAddress->AddressOfNames)+(DWORD)FileBuffer);
for (i = 0; i < FileAddress->NumberOfNames; i++, pexport++)
{
//P是要即将遍历函数名称的地址
LPSTR p = (LPSTR)((DWORD)FileBuffer + RvaToFoa((char*)path1, *pexport));
//printf("%x\n",&FunctionName);
//printf("%x\n", p);
if (!strcmp(FunctionName,p))
{
break;
}
}
if (i == FileAddress->NumberOfNames)
{
return 0;
}
OrdinalsAddress = (PWORD)RvaToFoa((char*)path1, FileAddress->AddressOfNameOrdinals);
OrdinalsAddress = OrdinalsAddress + i;
//printf("%x\n", *(PWORD)((DWORD)FileBuffer +(DWORD)OrdinalsAddress));
FunctionAddress = (PDWORD)RvaToFoa((char*)path1, FileAddress->AddressOfFunctions);
FunctionAddress = (PDWORD)((DWORD)FileBuffer + (DWORD)(FunctionAddress + *(PWORD)((DWORD)FileBuffer + (DWORD)OrdinalsAddress)));
//printf("%x\n", *FunctionAddress);
FileAddress = NULL;
OrdinalsAddress = NULL;
//这里的FunctionAddress是RVA
return *FunctionAddress;
}
DWORD GetFunctionAddrByOrdinals(IN LPVOID FileBuffer, IN DWORD FunctionOrdinals)
{
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return NULL;
}
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_EXPORT_DIRECTORY FileAddress = NULL;
PDWORD FunctionAddress = NULL;
pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
FileAddress = (PIMAGE_EXPORT_DIRECTORY)(RvaToFoa((char*)path1, pOptionHeader->DataDirectory[0].VirtualAddress) + (DWORD)FileBuffer);
FunctionAddress = (PDWORD)(RvaToFoa((char*)path1, FileAddress->AddressOfFunctions) + (DWORD)FileBuffer);
FunctionAddress = FunctionAddress + (FunctionOrdinals - FileAddress->Base);
printf("%x\n", *FunctionAddress);
return *FunctionAddress;
}
void PrintRelocationTable()
{
LPVOID FileBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_DATA_DIRECTORY DataAddress = NULL;
PIMAGE_BASE_RELOCATION AddressReloc = NULL;
//指向具体项的指针
PWORD p = NULL;
FileToFileBuffer((char*)path1, &FileBuffer);
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
DataAddress = pOptionHeader->DataDirectory;
AddressReloc = (PIMAGE_BASE_RELOCATION)((DWORD)FileBuffer+RvaToFoa((char*)path1, (DataAddress+5)->VirtualAddress));
for (DWORD i = 0; AddressReloc->VirtualAddress || AddressReloc->SizeOfBlock; i++)
{
printf("****************第%x块*****************\n",i+1);
printf("VirtualAddress:%x\n", AddressReloc->VirtualAddress);
printf("SizeOfBlock:%x\n", AddressReloc->SizeOfBlock);
p = (PWORD)AddressReloc + 4;
//定位到具体项
for (DWORD k = 0; k < (AddressReloc->SizeOfBlock - 8) / 2; k++,p++)
{
printf("地址:%x,属性:%x\n", AddressReloc ->VirtualAddress+(0xFFF & *p),(0xF000 & *p)>>12);
}
AddressReloc = (PIMAGE_BASE_RELOCATION)((DWORD)AddressReloc + AddressReloc->SizeOfBlock);
}
}
void TestMoveExport()
{
LPVOID FileBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_EXPORT_DIRECTORY pexport = NULL;
DWORD FileSize = NULL;
PDWORD FileAddress = NULL;
PDWORD AddressName = NULL;
PWORD AddressOrdinals = NULL;
PDWORD AddressFunction = NULL;
//FileToFileBuffer((char*)path1, &pFileBuffer);
FileToFileBuffer((char*)path, &FileBuffer);
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + 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);
pexport = (PIMAGE_EXPORT_DIRECTORY)(RvaToFoa((char*)path, pOptionHeader->DataDirectory[0].VirtualAddress) + (DWORD)FileBuffer);
AddressFunction = (PDWORD)(RvaToFoa((char*)path, pexport->AddressOfFunctions) + (DWORD)FileBuffer);
AddressOrdinals = (PWORD)(RvaToFoa((char*)path, pexport->AddressOfNameOrdinals) + (DWORD)FileBuffer);
AddressName = (PDWORD)(RvaToFoa((char*)path, pexport->AddressOfNames) + (DWORD)FileBuffer);
PIMAGE_SECTION_HEADER ptempSectionHeader = pSectionHeader;
//PIMAGE_SECTION_HEADER ptempSectionHeader1 = pSectionHeader;
for (int i = 0; i < pPEHeader->NumberOfSections; i++, ptempSectionHeader++);
ptempSectionHeader--;
FileSize = ptempSectionHeader->PointerToRawData + ptempSectionHeader->SizeOfRawData;
///printf("%x\n", RvaToFoa(ptempSectionHeader->VirtualAddress));
FileAddress = (PDWORD)((DWORD)FileBuffer + RvaToFoa((char*)path, ptempSectionHeader->VirtualAddress));
memcpy(FileAddress, AddressFunction, pexport->NumberOfFunctions * 4);
memcpy(FileAddress+pexport->NumberOfFunctions, AddressOrdinals, pexport->NumberOfNames * 2);
PWORD pAddressName = PWORD(FileAddress + pexport->NumberOfFunctions);
memcpy((pAddressName + pexport->NumberOfNames), AddressName, pexport->NumberOfNames * 4);
LPSTR NewAddress = (LPSTR)(PDWORD(pAddressName + pexport->NumberOfNames)+ pexport->NumberOfNames);
LPSTR NewtempAddress =NewAddress;
for (DWORD i = 0; i < pexport->NumberOfNames; i++, AddressName++)
{
//P是要即将遍历函数名称的地址
LPSTR p = (LPSTR)((DWORD)FileBuffer + RvaToFoa((char*)path, *AddressName));
//printf("%x\n", strlen(p));
memcpy(NewtempAddress, p, strlen(p));
NewtempAddress = NewtempAddress + strlen(p) + 1;
}
memcpy(NewtempAddress, pexport, 40);
pOptionHeader->DataDirectory[0].VirtualAddress = FoaToRva((char*)path, (DWORD)NewAddress-(DWORD)FileBuffer);
pexport->AddressOfFunctions = FoaToRva((char*)path, (DWORD)FileAddress - (DWORD)FileBuffer);
pexport->AddressOfNameOrdinals = FoaToRva((char*)path, (DWORD)(FileAddress + pexport->NumberOfFunctions) - (DWORD)FileBuffer);
pexport->AddressOfNames = FoaToRva((char*)path, (DWORD)(pAddressName + pexport->NumberOfNames) - (DWORD)FileBuffer);
BOOL isok = MemeryTOFile(FileBuffer, FileSize, (char*)path2);
if (isok)
{
printf("存盘成功");
}
else
{
printf("存盘失败");
}
pDosHeader = NULL;
pNTHeader = NULL;
pPEHeader = NULL;
pOptionHeader = NULL;
pSectionHeader = NULL;
pexport = NULL;
FileAddress = NULL;
AddressName = NULL;
AddressOrdinals = NULL;
AddressFunction = NULL;
}
void TestMoveReloca()
{
LPVOID FileBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_BASE_RELOCATION preloca = NULL;
PDWORD FileAddress = NULL;
DWORD FileSize = NULL;
FileToFileBuffer((char*)path, &FileBuffer);
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + 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);
preloca = (PIMAGE_BASE_RELOCATION)(RvaToFoa((char*)path, pOptionHeader->DataDirectory[5].VirtualAddress) + (DWORD)FileBuffer);
PIMAGE_SECTION_HEADER ptempSectionHeader = pSectionHeader;
PIMAGE_BASE_RELOCATION ptempreloca = preloca;
for (int i = 0; i < pPEHeader->NumberOfSections - 1; i++, ptempSectionHeader++);
while(ptempreloca->VirtualAddress || ptempreloca->SizeOfBlock)
{
if (((PIMAGE_BASE_RELOCATION)((DWORD)ptempreloca + ptempreloca->SizeOfBlock))->VirtualAddress !=0)
{
ptempreloca = (PIMAGE_BASE_RELOCATION)((DWORD)ptempreloca + ptempreloca->SizeOfBlock);
}
else
{
break;
}
}
FileSize = ptempSectionHeader->PointerToRawData + ptempSectionHeader->SizeOfRawData;
FileAddress = (PDWORD)((DWORD)FileBuffer + ptempSectionHeader->PointerToRawData);
memcpy(FileAddress, preloca, (ptempreloca->VirtualAddress - preloca->VirtualAddress + ptempreloca->SizeOfBlock));
pOptionHeader->DataDirectory[5].VirtualAddress = FoaToRva((char*)path, (DWORD)FileAddress);
BOOL isok = MemeryTOFile(FileBuffer, FileSize, (char*)path2);
if (isok)
{
printf("存盘成功");
}
else
{
printf("存盘失败");
}
pDosHeader = NULL;
pNTHeader = NULL;
pPEHeader = NULL;
pOptionHeader = NULL;
pSectionHeader = NULL;
preloca = NULL;
FileAddress = NULL;
}
void changeImageBase(IN DWORD Number)
{
LPVOID FileBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_BASE_RELOCATION preloca = NULL;
DWORD FileSize = NULL;
FileToFileBuffer((char*)path, &FileBuffer);
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
pOptionHeader->ImageBase = pOptionHeader->ImageBase + Number;
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
preloca = (PIMAGE_BASE_RELOCATION)(RvaToFoa((char*)path, pOptionHeader->DataDirectory[5].VirtualAddress) + (DWORD)FileBuffer);
PIMAGE_BASE_RELOCATION ptempreloca = preloca;
PIMAGE_SECTION_HEADER ptempSectionHeader = pSectionHeader;
for (int i = 0; i < pPEHeader->NumberOfSections - 1; i++, ptempSectionHeader++);
FileSize = ptempSectionHeader->PointerToRawData + ptempSectionHeader->SizeOfRawData;
while (ptempreloca->VirtualAddress || ptempreloca->SizeOfBlock)
{
*(PDWORD)ptempreloca = ptempreloca->VirtualAddress + Number;
ptempreloca = (PIMAGE_BASE_RELOCATION)((DWORD)ptempreloca + ptempreloca->SizeOfBlock);
}
BOOL isok = MemeryTOFile(FileBuffer, FileSize, (char*)path2);
if (isok)
{
printf("存盘成功");
}
else
{
printf("存盘失败");
}
pDosHeader = NULL;
pNTHeader = NULL;
pPEHeader = NULL;
pOptionHeader = NULL;
pSectionHeader = NULL;
preloca = NULL;
}
void printfImportTable()
{
LPVOID FileBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_IMPORT_DESCRIPTOR pImport = NULL;
//OriginalFirstThunk
PDWORD OriginalFT = NULL;
//FirstThunk
PDWORD FT = NULL;
PIMAGE_IMPORT_BY_NAME pName = NULL;
DWORD FileAddress = NULL;
FileToFileBuffer((char*)path1, &FileBuffer);
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
FileAddress = RvaToFoa((char*)path, pOptionHeader->DataDirectory[1].VirtualAddress) + (DWORD)FileBuffer;
pImport = (PIMAGE_IMPORT_DESCRIPTOR)FileAddress;
for (;pImport->FirstThunk || pImport->OriginalFirstThunk;pImport++)
{
printf("******************************************\n");
printf("dll名称:%s\n", (DWORD)FileBuffer+RvaToFoa((char*)path, pImport->Name));
printf("******************************************\n");
printf("INT(Import name table)表首地址:%x\n", pImport->OriginalFirstThunk);
OriginalFT = (PDWORD)((DWORD)FileBuffer + RvaToFoa((char*)path, pImport->OriginalFirstThunk));
FT = (PDWORD)((DWORD)FileBuffer + RvaToFoa((char*)path, pImport->FirstThunk));
while (*OriginalFT)
{
if ((*OriginalFT) & 0x80000000)
{
printf("按序号导入:%x\n", (*OriginalFT) & 0x0FFF);
}
else
{
pName = (PIMAGE_IMPORT_BY_NAME)((DWORD)FileBuffer+RvaToFoa((char*)path, *OriginalFT));
printf("按名字导入hint/name:%x-%s\n", pName->Hint,pName->Name);
}
OriginalFT++;
}
printf("******************************************\n");
printf("IAT(Import Address table)表首地址:%x\n", pImport->FirstThunk);
while (*FT)
{
if ((*FT) & 0x80000000)
{
printf("按序号导入:%x\n", *FT & 0x7FFFFFFF);
}
else
{
pName = (PIMAGE_IMPORT_BY_NAME)((DWORD)FileBuffer + RvaToFoa((char*)path, *FT));
printf("按名字导入hint/name:%x-%s\n", pName->Hint, pName->Name);
}
FT++;
}
}
free(FileBuffer);
}
void printboundimporttable()
{
LPVOID FileBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_IMPORT_DESCRIPTOR pImport = NULL;
PIMAGE_BOUND_IMPORT_DESCRIPTOR pBoundImport = NULL;
PIMAGE_BOUND_IMPORT_DESCRIPTOR ptempBoundImport = NULL;
PIMAGE_BOUND_FORWARDER_REF ptempBoundImport1 = NULL;
//OriginalFirstThunk
PDWORD OriginalFT = NULL;
//FirstThunk
PDWORD FT = NULL;
PIMAGE_IMPORT_BY_NAME pName = NULL;
DWORD FileAddress = NULL;
FileToFileBuffer((char*)path1, &FileBuffer);
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
FileAddress = RvaToFoa((char*)path1, pOptionHeader->DataDirectory[1].VirtualAddress) + (DWORD)FileBuffer;
pImport = (PIMAGE_IMPORT_DESCRIPTOR)FileAddress;
pBoundImport = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)(RvaToFoa((char*)path1, pOptionHeader->DataDirectory[11].VirtualAddress) + (DWORD)FileBuffer);
ptempBoundImport = pBoundImport;
while (pBoundImport->OffsetModuleName && pBoundImport->TimeDateStamp)
{
if (pImport->TimeDateStamp != 0)
{
printf("时间戳:%x\n", ptempBoundImport->TimeDateStamp);
printf("名称:%s\n", (PBYTE)((DWORD)ptempBoundImport + ptempBoundImport->OffsetModuleName));
printf("该dll还用到%x个其他dll\n", ptempBoundImport->NumberOfModuleForwarderRefs);
ptempBoundImport1 = (PIMAGE_BOUND_FORWARDER_REF)(ptempBoundImport++);
for (DWORD i = 0; i < pBoundImport->NumberOfModuleForwarderRefs; i++, ptempBoundImport1++)
{
printf("时间戳:%x\n", ptempBoundImport1->TimeDateStamp);
printf("名称:%s\n", (PBYTE)((DWORD)pBoundImport + ptempBoundImport1->OffsetModuleName));
}
}
}
free(FileBuffer);
}
void injectImportTable(IN LPVOID FileBuffer)
//FileBuffer已经新增节过
{
if (!FileBuffer)
{
printf("File->FileBuffer失败");
return;
}
//将injectiondll注入到cs里
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;
PDWORD pSectionAddress = NULL;
PIMAGE_IMPORT_DESCRIPTOR pImport = NULL;
PIMAGE_IMPORT_DESCRIPTOR ptempImport = NULL;
PIMAGE_IMPORT_DESCRIPTOR ptempImport1 = NULL;
LPSTR pFunctionName = NULL;
LPSTR pDllName = NULL;
PDWORD AddressName = NULL;
PIMAGE_IMPORT_BY_NAME pName = NULL;
DWORD FileSize = NULL;
DWORD FileAddress = NULL;
PDWORD AddressINT = NULL;
PDWORD AddressIAT = NULL;
pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + 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);
FileAddress = RvaToFoa((char*)path, pOptionHeader->DataDirectory[1].VirtualAddress) + (DWORD)FileBuffer;
pImport = (PIMAGE_IMPORT_DESCRIPTOR)FileAddress;
PIMAGE_IMPORT_DESCRIPTOR pindexImport = pImport;
for (int i = 1; i < pPEHeader->NumberOfSections; i++, pSectionHeader++);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!这行一定要改,别说之前用的第一个节的属性,我就是最开始用的第一个节的属性,一直没法运行,最后改了就可以了
pSectionHeader->Characteristics = 0xc0000040;
FileSize = pSectionHeader->PointerToRawData + pSectionHeader->SizeOfRawData;
//定位到新增节的起始位置
pSectionAddress = (PDWORD)((DWORD)FileBuffer + pSectionHeader->PointerToRawData);
while (pindexImport->FirstThunk || pindexImport->OriginalFirstThunk)
{
memcpy(pSectionAddress, pindexImport, 20);
pSectionAddress = pSectionAddress + 5;
pindexImport++;
}
ptempImport = (PIMAGE_IMPORT_DESCRIPTOR)pSectionAddress;
ptempImport1 = ptempImport + 2;//要留20个0字节表示导入表没了
//追加分别为8个字节的INT表,IAT表
AddressINT = (PDWORD)ptempImport1;
AddressIAT = AddressINT + 2;
//追加一个IMAGE_IMPORT_BY_NAME 结构,前2个字节是0 后面是函数名称字符串
pName = (PIMAGE_IMPORT_BY_NAME)(AddressIAT + 2);
pFunctionName = (LPSTR)((DWORD)pName + 2);
LPSTR ptempFunctionName = pFunctionName;
//函数名是你要使用的dll中的函数名
LPCSTR FunctionName = "ExportFunction";
for (int x = 0; x < strlen(FunctionName); x++, ptempFunctionName++)
{
*ptempFunctionName = FunctionName[x];
}
//将IMAGE_IMPORT_BY_NAME结构的RVA赋值给INT和IAT表中的第一项
*AddressINT = FoaToRva((char*)path, ((DWORD)pName - (DWORD)FileBuffer));
*AddressIAT = FoaToRva((char*)path, ((DWORD)pName - (DWORD)FileBuffer));
//分配空间存储DLL名称字符串 并将该字符串的RVA赋值给Name属性
pDllName = (LPSTR)((DWORD)pName + strlen(FunctionName)+1+2);
LPSTR ptempDllName = pDllName;//因为等会pDllName会走到字符串结尾,就新定义一个让pDllName在字符串首部
//dll名是需要用到的dll名称
LPCSTR DllName = "InjectDll.dll";
for (int i = 0; i < strlen(DllName); i++, ptempDllName++)
{
*ptempDllName = DllName[i];
}
ptempImport->Name = FoaToRva((char*)path, (DWORD)pDllName -(DWORD)FileBuffer);
ptempImport->OriginalFirstThunk = FoaToRva((char*)path, (DWORD)AddressINT-(DWORD)FileBuffer);
ptempImport->FirstThunk = FoaToRva((char*)path, (DWORD)AddressIAT - (DWORD)FileBuffer);
pOptionHeader->DataDirectory[1].VirtualAddress = pSectionHeader->VirtualAddress;
pOptionHeader->DataDirectory[1].Size = pOptionHeader->DataDirectory[1].Size + 0x10000;
BOOL isok = MemeryTOFile(FileBuffer, FileSize, (char*)path2);
if (isok)
{
printf("存盘成功");
}
else
{
printf("存盘失败");
}
}