模拟LoadLibary 做一个LoadDll

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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值