HMODULE LoadDll(
LPCSTR lpLibFileName
)
{
DWORD dwFileSize = 0;
DWORD dwpRelocationAddress = 0;
DWORD dwImportAddress = 0;
DWORD dwOffset = 0;
DWORD dwDllCount = 0;
fstream file;
LPVOID pBuffer = 0;
file.open(lpLibFileName, ios::in | ios::binary);
if (!file.is_open())
{
cout << "打开文件失败" << endl;
return 0;
}
//DOS
file.read((char*)&DOS, sizeof(IMAGE_DOS_HEADER));
//PE
file.seekp(DOS.e_lfanew+4, ios::beg);
file.read((char*)&PE, sizeof(IMAGE_FILE_HEADER));
//OPTIONAL
file.seekp(DOS.e_lfanew+0x18, ios::beg);
file.read((char*)&OPTIONAL1, sizeof(IMAGE_OPTIONAL_HEADER));
//SECTIONS
file.seekp(DOS.e_lfanew + 0x18 + PE.SizeOfOptionalHeader, ios::beg);
file.read((char*)&SECTIONS, sizeof(IMAGE_SECTION_HEADER)*PE.NumberOfSections);
file.seekp(0, ios::end);
dwFileSize = file.tellp();
file.seekp(0, ios::beg);
//申请文件缓冲区
char* fileBuffer = new char[dwFileSize];
//清空缓冲区
memset(fileBuffer, 0, dwFileSize);
file.read(fileBuffer, dwFileSize);
//申请内存缓冲区
pBuffer=VirtualAlloc(0, OPTIONAL1.SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (pBuffer == 0)
{
cout << "申请内存失败" << endl;
}
//清空缓冲区
memset(pBuffer, 0, OPTIONAL1.SizeOfImage);
//插入头+节区大小
memcpy((char*)pBuffer + 0, fileBuffer + 0, OPTIONAL1.SizeOfHeaders);
//循环遍历节区拉伸
for (int i = 0; i < PE.NumberOfSections; i++)
{
memcpy((char*)pBuffer + SECTIONS[i].VirtualAddress, fileBuffer + SECTIONS[i].PointerToRawData, SECTIONS[i].SizeOfRawData);
}
//修复重定位
dwpRelocationAddress = (DWORD)pBuffer + OPTIONAL1.DataDirectory[5].VirtualAddress;
while (TRUE)
{
memcpy(&Relocation, (char*)dwpRelocationAddress + dwOffset, sizeof(IMAGE_BASE_RELOCATION));
if (Relocation.SizeOfBlock == 0 && Relocation.VirtualAddress == 0)
{
break;
}
for (int i = 0; i < (Relocation.SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);i++)
{
WORD wValue = 0;
memcpy(&wValue, (char*)dwpRelocationAddress + dwOffset + 8 + i * sizeof(WORD), sizeof(WORD));
if ((wValue & 0xF000) == 0x3000)
{
DWORD dwRva = Relocation.VirtualAddress + (wValue & 0x0FFF);
DWORD Value = 0;
memcpy(&Value, (char*)((DWORD)pBuffer + dwRva), sizeof(DWORD));
Value = Value - OPTIONAL1.ImageBase;
Value = Value + (DWORD)pBuffer;
memcpy((char*)((DWORD)pBuffer + dwRva),&Value, sizeof(DWORD));
}
}
dwOffset += Relocation.SizeOfBlock;
}
//修复导入表
dwImportAddress= (DWORD)pBuffer + OPTIONAL1.DataDirectory[1].VirtualAddress;
while (TRUE)
{
memcpy(&DESCRIPTOR, (char*)dwImportAddress + dwDllCount * sizeof(IMAGE_IMPORT_DESCRIPTOR), sizeof(IMAGE_IMPORT_DESCRIPTOR));
if (DESCRIPTOR.Characteristics == 0 && DESCRIPTOR.FirstThunk == 0 &&
DESCRIPTOR.ForwarderChain == 0 && DESCRIPTOR.Name == 0 && DESCRIPTOR.OriginalFirstThunk == 0
&& DESCRIPTOR.TimeDateStamp == 0)
{
break;
}
char szDllName[128] = { 0 };
strcpy(szDllName, (char*)DESCRIPTOR.Name + (DWORD)pBuffer);
HMODULE hDllHandle = LoadLibraryA(szDllName);
if (hDllHandle == NULL)
{
break;
}
DWORD dwOriginalFirtsThunk = DESCRIPTOR.OriginalFirstThunk+ (DWORD)pBuffer;
DWORD FirstThunk = DESCRIPTOR.FirstThunk+ (DWORD)pBuffer;
DWORD dwApiCount = 0;
while (TRUE)
{
char szBuffer[256] = { 0 };
DWORD dwpApiNameAddress = dwOriginalFirtsThunk + dwApiCount * sizeof(DWORD);
dwpApiNameAddress = *(DWORD*)dwpApiNameAddress;
DWORD dwApiAddress = 0;
if (dwpApiNameAddress == 0)
{
break;
}
dwpApiNameAddress += 2+ (DWORD)pBuffer;
strcpy(szBuffer, (char*)dwpApiNameAddress);
dwApiAddress= (DWORD)GetProcAddress(hDllHandle, szBuffer);
if (dwApiAddress == 0)
{
break;
}
*(DWORD*)(FirstThunk+ dwApiCount * sizeof(DWORD)) = dwApiAddress;
dwApiCount++;
}
dwDllCount++;
}
return (HMODULE)pBuffer;
}