#include<iostream>
#include<malloc.h>
#include<Windows.h>
#include<tchar.h>
#include<string.h>
#pragma warning(disable:4996)
#pragma warning(disable:6387)
using namespace std;
int filelen(FILE* pfile)
{
fseek(pfile, 0, SEEK_END);
int result = ftell(pfile);
rewind(pfile);
return result;
}
int Align(int x, int y)
{
if (x % y == 0)
{
return int(x / y)*y;
}
else
{
return int(x / y)*y + y;
}
}
int rvaTofoa(int rva, char* buffer)
{
PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
int opHeaderLen = int(pFH->SizeOfOptionalHeader);
PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
if (rva <= int(pOH->SizeOfHeaders))
{
return rva;
}
else
{
for (int i = 0; i < int(pFH->NumberOfSections); i++)
{
if ((rva >= int(pSecH[i].VirtualAddress)) &&( rva <= int(pSecH[i].VirtualAddress + pSecH[i].Misc.VirtualSize)))
{
return rva - pSecH[i].VirtualAddress + pSecH[i].PointerToRawData;
}
}
}
printf(" rvaTofoa error\r\n");
return 0;
}
int foaTorva(int foa, char* buffer)
{
PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
int opHeaderLen = int(pFH->SizeOfOptionalHeader);
PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
if (foa <= int(pOH->SizeOfHeaders))
{
return foa;
}
else
{
for (int i = 0; i < int(pFH->NumberOfSections); i++)
{
if ((foa >= int(pSecH[i].PointerToRawData)) && (foa <= int(pSecH[i].PointerToRawData + pSecH[i].SizeOfRawData)))
{
return foa - pSecH[i].PointerToRawData + pSecH[i].VirtualAddress;
}
}
}
printf(" foaTorva error\r\n");
return 0;
}
/*
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics; // 未使用
DWORD TimeDateStamp; // 时间戳
WORD MajorVersion; // 未使用
WORD MinorVersion; // 未使用
DWORD Name; // 指向该导出表文件名字符串
DWORD Base; // 导出函数起始序号
DWORD NumberOfFunctions; // 所有导出函数的个数
DWORD NumberOfNames; // 以函数名字导出的函数个数
DWORD AddressOfFunctions; // 导出函数地址表RVA
DWORD AddressOfNames; // 导出函数名称表RVA
DWORD AddressOfNameOrdinals; // 导出函数序号表RVA
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
*/
void printExportDir(PIMAGE_EXPORT_DIRECTORY pED,char* buffer)
{
int nameFAddress = rvaTofoa(pED->Name, buffer);
char* name = buffer + nameFAddress;
printf("导出表文件名字为:%s\r\n", name);
printf("Characteristics: %08x\r\n", pED->Characteristics);
printf("TimeDateStamp: %08x\r\n", pED->TimeDateStamp);
printf("MajorVersion: %04x\r\n", pED->MajorVersion);
printf("MinorVersion: %04x\r\n", pED->MinorVersion);
printf("Name: %08x\r\n", pED->Name);
printf("Base: %08x\r\n", pED->Base);
printf("NumberOfFunctions: %08x\r\n", pED->NumberOfFunctions);
printf("NumberOfNames: %08x\r\n", pED->NumberOfNames);
printf("AddressOfFunctions: %08x\r\n", pED->AddressOfFunctions);
printf("AddressOfNames: %08x\r\n", pED->AddressOfNames);
printf("AddressOfNameOrdinals: %08x\r\n", pED->AddressOfNameOrdinals);
}
int GetFunctionAddrByName(char* buffer, char* name)
{
PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
int opHeaderLen = int(pFH->SizeOfOptionalHeader);
PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
PIMAGE_DATA_DIRECTORY pDD = (PIMAGE_DATA_DIRECTORY)(pOH->DataDirectory);
int exportVAddress = pDD->VirtualAddress;
//printf("%08x\r\n", exportAddress);
int exportFAddress = rvaTofoa(exportVAddress, buffer);
PIMAGE_EXPORT_DIRECTORY pED = (PIMAGE_EXPORT_DIRECTORY)(buffer + exportFAddress);
//先在DWORD AddressOfNames; // 导出函数名称表RVA中寻找
int* FAddressOfNames = (int*)(rvaTofoa(pED->AddressOfNames,buffer)+buffer);//先得到函数名表在文件中的地址
printf("函数名表在文件中的地址%08x\r\n", rvaTofoa(pED->AddressOfNames, buffer));
int num = -1;
for (int i = 0; i < int(pED->NumberOfNames); i++)
{
//从中取出函数名的rva地址
int rvaOfname = (int) * (FAddressOfNames + i);
//转化为函数名在文件中地址
char* fileOfname = (char*)(buffer + rvaTofoa(rvaOfname, buffer));
printf("%s\r\n", fileOfname);
if (strcmp(fileOfname, name) == 0)
{
num = i;
break;
}
}
printf("%d\r\n", num);
//用获得的索引从序号表中找函数的序号 此处易错类型为word
WORD ord = *((WORD*)(rvaTofoa(pED->AddressOfNameOrdinals,buffer) + buffer) + num);
printf("%d\r\n", ord);
//用查到的序号查函数地址
int add = *((int*)(rvaTofoa(pED->AddressOfFunctions,buffer) + buffer) + ord);
return add;
}
int GetFunctionAddrByOrdinals(char* buffer, int num)
{
PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
int opHeaderLen = int(pFH->SizeOfOptionalHeader);
PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
PIMAGE_DATA_DIRECTORY pDD = (PIMAGE_DATA_DIRECTORY)(pOH->DataDirectory);
int exportVAddress = pDD->VirtualAddress;
int exportFAddress = rvaTofoa(exportVAddress, buffer);
PIMAGE_EXPORT_DIRECTORY pED = (PIMAGE_EXPORT_DIRECTORY)(buffer + exportFAddress);
int ordbase = pED->Base;
int ord = num - ordbase;
int add = *((int*)(rvaTofoa(pED->AddressOfFunctions, buffer) + buffer) + ord);
return add;
}
void printReloc(char* buffer)
{
PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
int opHeaderLen = int(pFH->SizeOfOptionalHeader);
PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
PIMAGE_DATA_DIRECTORY pDD = (PIMAGE_DATA_DIRECTORY)(pOH->DataDirectory);
int relocVAddress = pDD[5].VirtualAddress;
//printf("%08x\r\n", relocVAddress);
PIMAGE_BASE_RELOCATION pBR = (PIMAGE_BASE_RELOCATION)(rvaTofoa(relocVAddress, buffer) + buffer);
//printf("%08x\r\n", rvaTofoa(relocVAddress, buffer));
for (int i = 0; (int*)pBR->VirtualAddress != 0; i++)
{
printf("===========BASEreloc[%d]==========\r\n", i);
printf("VirtualAddress:%08x\r\n", pBR->VirtualAddress);
printf("SizeofBlock:%08x\r\n", pBR->SizeOfBlock);
int SizeofBlock = pBR->SizeOfBlock;
int num = (SizeofBlock - 8) / 2;
PWORD p = (PWORD)((char*)pBR + 8);
for (int j = 0; j < num; j++)
{
int type = (*(p + j) & 0xF000) >> 12;
int Address = (*(p + j) & 0x0FFF)+ pBR->VirtualAddress;
printf("type:%x Address:%08x\r\n", type, Address);
}
pBR=(PIMAGE_BASE_RELOCATION)((char*)pBR+pBR->SizeOfBlock);
}
}
char* AddNewSection(char* buffer, int newLen,int len)
{
PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
int opHeaderLen = int(pFH->SizeOfOptionalHeader);
PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
int numOfsection = pFH->NumberOfSections;
//修改节的数目
pFH->NumberOfSections = numOfsection + 1;
int agoImageSize = pOH->SizeOfImage;
pOH->SizeOfImage = pOH->SizeOfImage + newLen - len;
int space = 0;
int ord = 0;
for (int i = 0; i < numOfsection; i++)
{
if (strcmp((char*) & (pSecH[i].Name), ".text") == 0)
{
ord = i;
}
}
//cout << ord << endl;
space = int(buffer)+pSecH[ord].PointerToRawData - int( & pSecH[numOfsection]);
//cout << hex<<space << endl;
if (space < 80)
{
cout << "space not enough" << endl;
exit(0);
}
memcpy(&pSecH[numOfsection], &pSecH[ord], 0x28);
char* name = (char*)(&pSecH[numOfsection].Name);
memcpy(name, ".NewSec", 7);
pSecH[numOfsection].Misc.VirtualSize = newLen - len;
pSecH[numOfsection].PointerToRawData = len;
pSecH[numOfsection].SizeOfRawData = newLen - len;
pSecH[numOfsection].VirtualAddress = agoImageSize;
char* newbuffer = NULL;
newbuffer = (char*)malloc(newLen * sizeof(char));
memcpy(newbuffer, buffer, len);
return newbuffer;
}
void moveExport(char* buffer)
{
PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
int opHeaderLen = int(pFH->SizeOfOptionalHeader);
PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
PIMAGE_DATA_DIRECTORY pDD = (PIMAGE_DATA_DIRECTORY)(pOH->DataDirectory);
int vaOfexport = pDD[0].VirtualAddress;
int numOfsec = pFH->NumberOfSections;
PIMAGE_EXPORT_DIRECTORY pED = (PIMAGE_EXPORT_DIRECTORY)(buffer + rvaTofoa(vaOfexport, buffer));
// 复制AddressOfFunctions
int numofFun = pED->NumberOfFunctions;
int VAofFuntable = pED->AddressOfFunctions;
char* FAofFuntable = buffer + rvaTofoa(VAofFuntable, buffer);
int numOfsecs = pFH->NumberOfSections;
char* begin = pSecH[numOfsecs - 1].PointerToRawData+buffer;
memcpy(begin, FAofFuntable, numofFun * 4);
//复制AddressOfNameOrdinals
int numofname = pED->NumberOfNames;
int VAofNameOrdinals = pED->AddressOfNameOrdinals;
char* FAofNameOrdinals = buffer + rvaTofoa(VAofNameOrdinals, buffer);
char* ordbegin = begin +numofFun*4;
memcpy(ordbegin, FAofNameOrdinals, numofname * 2);
//复制AddressOfNames
int VAofAddressOfNames = pED->AddressOfNames;
char* FAofAddressOfNames = buffer + rvaTofoa(VAofAddressOfNames, buffer);
char* nameAbegin = ordbegin + numofname * 2;
memcpy(nameAbegin, FAofAddressOfNames, numofname*4);
//复制函数名并修正AddressOfNames
char* namebegin = nameAbegin + numofname * 4;
for (int j = 0; j < numofname; j++)
{
//得到某个函数名虚拟地址
int VAofname = *((int*)FAofAddressOfNames + j);
//得到其文件地址
char* FAofname = buffer + rvaTofoa(VAofname, buffer);
//计算其长度,记得保留\0的位置
int namelen = strlen(FAofname)+1;
//复制过去
memcpy(namebegin, FAofname, namelen);
//复制过去之后,计算其虚拟地址
int VAnamebegin = (int)foaTorva(int(namebegin-buffer), buffer);
//修正
int* nameAddress = (int*)(nameAbegin + 4 * j);
*nameAddress = VAnamebegin;
namebegin = namebegin + namelen;
}
//复制IMAGE_EXPORT_DIRECTORY
memcpy(namebegin, (char*)pED, sizeof(IMAGE_EXPORT_DIRECTORY) / sizeof(char));
//修正IMAGE_EXPORT_DIRECTORY
pED->AddressOfFunctions = pSecH[numOfsecs - 1].PointerToRawData;
pED->AddressOfNameOrdinals = pSecH[numOfsecs - 1].PointerToRawData + numofFun * 4;
pED->AddressOfNames = pSecH[numOfsecs - 1].PointerToRawData + numofFun * 4 + numofname * 2;
//修改目录项中的值
pDD[0].VirtualAddress = (int)foaTorva(int(namebegin - buffer), buffer);
}
int main()
{
FILE* pfile = fopen("C://Users//52511//Desktop//1.dll","rb");
FILE* pfile1 = fopen("C://Users//52511//Desktop//2.dll", "wb");
char* buffer = NULL;
int len = filelen(pfile);
buffer = (char*)malloc(len * sizeof(char));
if (buffer == NULL)
{
exit(0);
}
memset(buffer, 0, len);
fread(buffer, 1, len, pfile);
PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
int opHeaderLen = int(pFH->SizeOfOptionalHeader);
PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
int sectionLen = 0x1000;
int newLen = len + sectionLen;
char* newbuffer = AddNewSection(buffer, newLen, len);
moveExport(newbuffer);
fwrite(newbuffer, 1, newLen, pfile1);
return 0;
}
移动导出表
最新推荐文章于 2024-07-15 21:01:41 发布