// PeLoader.cpp : 定义 DLL 应用程序的导出函数。
//
#include "PeLoader.h"
LPBYTE WINAPI _LoadLibrary(LPBYTE LpLibData,FRCALLBACK pFR_CallBack,DWORD pFR_lParam)
{
if (!LpLibData)
return NULL;
PIMAGE_DOS_HEADER LpDosHeader = (PIMAGE_DOS_HEADER)LpLibData;
PIMAGE_NT_HEADERS LpNtHeader = (PIMAGE_NT_HEADERS)(LpLibData + LpDosHeader->e_lfanew);
//
// 检查有效性
//
if (LpDosHeader->e_magic != IMAGE_DOS_SIGNATURE) // MZ
return NULL;
if (LpNtHeader->Signature != IMAGE_NT_SIGNATURE) // PE
return NULL;
if (!(LpNtHeader->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) // 可执行
return NULL;
//
// 计算映像大小
//
PIMAGE_SECTION_HEADER SectionHeader;
DWORD SizeOfImage = LpNtHeader->OptionalHeader.SizeOfImage;
for (int i=0;i<LpNtHeader->FileHeader.NumberOfSections;i++)
{
SectionHeader = (PIMAGE_SECTION_HEADER)(LpLibData
+ LpDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)
+ i * sizeof(IMAGE_SECTION_HEADER));
SizeOfImage = MAX(SizeOfImage,GetAlignedSize(
SectionHeader->VirtualAddress + MAX(SectionHeader->SizeOfRawData,
SectionHeader->Misc.VirtualSize),LpNtHeader->OptionalHeader.SectionAlignment));
}
if (!SizeOfImage)
return NULL;
//
// 分配内存, 拷贝数据
//
LPBYTE hLibModule = (LPBYTE)VirAlloc((LPVOID)LpNtHeader->OptionalHeader.ImageBase,SizeOfImage);
if (!hLibModule)
return NULL;
memcpy(hLibModule,LpLibData,LpDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)
+ LpNtHeader->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER));
for (int i=0;i<LpNtHeader->FileHeader.NumberOfSections;i++)
{
SectionHeader = (PIMAGE_SECTION_HEADER)(LpLibData + LpDosHeader->e_lfanew
+ sizeof(IMAGE_NT_HEADERS) + i * sizeof(IMAGE_SECTION_HEADER));
if (SectionHeader->SizeOfRawData && SectionHeader->VirtualAddress)
memcpy(hLibModule+SectionHeader->VirtualAddress,LpLibData
+ SectionHeader->PointerToRawData,SectionHeader->SizeOfRawData);
}
//
// 重定位
//
if (LpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size)
DoRelocation((DWORD)hLibModule);
//
// 填充导入表
//
if (LpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size)
{
if (!FillRavAddress((DWORD)hLibModule,pFR_CallBack,pFR_lParam))
{
VirFree(hLibModule);
return NULL;
}
}
//
// 执行入口代码
//
if (LpNtHeader->FileHeader.Characteristics & IMAGE_FILE_DLL) // 是否为 DLL
{
DLLMAIN _DllMain = (DLLMAIN)(hLibModule + LpNtHeader->OptionalHeader.AddressOfEntryPoint);
if (!_DllMain(NULL,DLL_PROCESS_ATTACH,NULL))
{
_DllMain(NULL,DLL_PROCESS_DETACH,NULL);
VirFree(hLibModule);
return NULL;
}
}
return hLibModule;
}
BOOL WINAPI _FreeLibrary(LPBYTE hLibModule)
{
if (!hLibModule)
return false;
PIMAGE_DOS_HEADER LpDosHeader = (PIMAGE_DOS_HEADER)hLibModule;
PIMAGE_NT_HEADERS LpNtHeader = (PIMAGE_NT_HEADERS)(hLibModule + LpDosHeader->e_lfanew);
//
// 执行入口代码
//
if (LpNtHeader->FileHeader.Characteristics & IMAGE_FILE_DLL) // 是否为 DLL
{
DLLMAIN _DllMain = (DLLMAIN)(hLibModule + LpNtHeader->OptionalHeader.AddressOfEntryPoint);
_DllMain(0,DLL_PROCESS_DETACH,0);
}
return VirFree(hLibModule);
}
FARPROC WINAPI _GetProcAddress(LPBYTE hLibModule,LPCSTR lpProcName)
{
if (!hLibModule || !lpProcName)
return NULL;
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hLibModule;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(hLibModule + pDosHeader->e_lfanew);
if (!pNtHeader->OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) // 是否存在导出表
return NULL;
PIMAGE_EXPORT_DIRECTORY pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(hLibModule
+ pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
PDWORD AddressOfNames = (PDWORD)(hLibModule + pExportDirectory->AddressOfNames);
PDWORD AddressOfFunctions = (PDWORD)(hLibModule + pExportDirectory->AddressOfFunctions);
PWORD AddressOfNameOrdinals = (PWORD)(hLibModule + pExportDirectory->AddressOfNameOrdinals);
LPSTR pProcName;
DWORD Ordinals = (DWORD)lpProcName - pExportDirectory->Base;
//
// 寻找指定函数
//
if (Ordinals>=0 && Ordinals<=pExportDirectory->NumberOfFunctions) // 是否为序号
{
return (FARPROC)(hLibModule + AddressOfFunctions[Ordinals]);
}
else // 以名称导出的函数
{
Ordinals = 0;
for (DWORD i=0;i<pExportDirectory->NumberOfNames;i++)
{
pProcName = (LPSTR)(hLibModule + AddressOfNames[i]);
Ordinals = AddressOfNameOrdinals[i];
if (Ordinals>=0 && Ordinals<=pExportDirectory->NumberOfFunctions)
{
if (!strcmp(lpProcName,pProcName))
{
return (FARPROC)(hLibModule + AddressOfFunctions[Ordinals]);
}
}
}
}
return NULL;
}
DWORD WINAPI _GetEntryPoint(LPBYTE hLibModule)
{
return (DWORD)(hLibModule + ((PIMAGE_NT_HEADERS)(hLibModule
+ ((PIMAGE_DOS_HEADER)hLibModule)->e_lfanew))->OptionalHeader.AddressOfEntryPoint);
}
LPVOID VirAlloc(LPVOID LpAddress,SIZE_T DwSize)
{
LPVOID pMem;
//
// 分配内存
//
pMem = VirtualAlloc(LpAddress,DwSize, // 指定基址
MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
if (!pMem)
pMem = VirtualAlloc(NULL,DwSize, // 随机基址
MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
return pMem;
}
BOOL VirFree(LPVOID LpAddress)
{
//
// 释放内存
//
return VirtualFree(LpAddress,NULL,MEM_RELEASE);
}
UINT GetAlignedSize(UINT Origin,UINT Alignment)
{
//
// 计算对齐后大小
//
return (Origin + Alignment - 1) / Alignment * Alignment;
}
VOID DoRelocation(DWORD NewBase)
{
PIMAGE_DOS_HEADER LpDosHeader = (PIMAGE_DOS_HEADER)NewBase;
PIMAGE_NT_HEADERS LpNtHeader = (PIMAGE_NT_HEADERS)(NewBase + LpDosHeader->e_lfanew);
DWORD Delta = NewBase - LpNtHeader->OptionalHeader.ImageBase;
DWORD Offset = LpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
PIMAGE_BASE_RELOCATION LpBaseRelocation = (PIMAGE_BASE_RELOCATION)(NewBase + Offset);
short LocData;
DWORD Address;
//
// 重定位
//
do
{
for (DWORD i=0;i<(LpBaseRelocation->SizeOfBlock-8)/2;i++)
{
LocData = *((PWORD)(NewBase + Offset + 8 + i * 2));
if ((LocData & 61440) == 12288)
{
Address = NewBase + LpBaseRelocation->VirtualAddress + (LocData & 4095);
*((PDWORD)Address) = *((PDWORD)Address) + Delta;
}
}
Offset += LpBaseRelocation->SizeOfBlock;
LpBaseRelocation = (PIMAGE_BASE_RELOCATION)(NewBase + Offset);
}while(LpBaseRelocation->VirtualAddress);
}
BOOL FillRavAddress(DWORD ImageBase,FRCALLBACK pFR_CallBack,DWORD pFR_lParam)
{
PIMAGE_DOS_HEADER LpDosHeader = (PIMAGE_DOS_HEADER)ImageBase;
PIMAGE_NT_HEADERS LpNtHeader = (PIMAGE_NT_HEADERS)(ImageBase + LpDosHeader->e_lfanew);
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(ImageBase + LpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
DWORD dwRealIAT;
HMODULE hModule;
LPCSTR pModuleName;
int i,j=0;
DWORD dwProcName;
LPCSTR pProcName;
DWORD dwFunction;
char pStr[64+1];
BOOL bRet = TRUE;
//
// 填充导入表
//
while (ImportDescriptor[j].FirstThunk)
{
pModuleName = (LPCSTR)(ImageBase // 模块名
+ ImportDescriptor[j].Name);
hModule = LoadLibraryA(pModuleName);
i = 0;
while (((PDWORD)(ImageBase + ImportDescriptor[j].FirstThunk))[i])
{
if (((PDWORD)(ImageBase + ImportDescriptor[j].OriginalFirstThunk))[i])
dwRealIAT = ((PDWORD)(ImageBase + ImportDescriptor[j].OriginalFirstThunk))[i];
else
dwRealIAT = ((PDWORD)(ImageBase + ImportDescriptor[j].FirstThunk))[i];
if (dwRealIAT & IMAGE_ORDINAL_FLAG32) // 是否为序号
{
dwProcName = dwRealIAT & 65535;
wsprintfA(pStr,"%d",dwProcName);
pProcName = pStr;
}
else // 符号
pProcName = // 函数名
(LPCSTR)(dwProcName = ImageBase + dwRealIAT + 2);