首页
社区
课程
招聘
[旧帖] 请教高人,我的代码出什么问题了,内存加载DLL初始化DLL入口函数的时候卡死 0.00雪花
发表于: 2013-12-2 20:00 2728

[旧帖] 请教高人,我的代码出什么问题了,内存加载DLL初始化DLL入口函数的时候卡死 0.00雪花

2013-12-2 20:00
2728
这个代码只支持WIN32方式编译出来的DLL,MFC的应该是不支持的

BOOL C内存加载DLLDlg::MyLoadDll(LPCTSTR mDllPath)
{
//////////把DLL文件读取到内存中/////////////////////;
    CFile mFile;
    if (!mFile.Open(mDllPath,CFile::modeRead))
    {
        return FALSE;
    }
    DWORD nFileSize = (DWORD)mFile.GetLength();
    PBYTE bTemp = new BYTE[nFileSize];
    ZeroMemory(bTemp,nFileSize);
    mFile.Read(bTemp,nFileSize);
    mFile.Close();

    PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)bTemp;
    PIMAGE_NT_HEADERS pImageNtHeaders = (PIMAGE_NT_HEADERS)(pImageDosHeader->e_lfanew+(DWORD)bTemp);
    if ((pImageDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)||
        (pImageNtHeaders->Signature!=IMAGE_NT_SIGNATURE))
    {
        return FALSE;
    }
///////////////////申请内存加载DLL的空间///////////////////////////////;   
    PBYTE pDllBase = new BYTE[pImageNtHeaders->OptionalHeader.SizeOfImage];
    ZeroMemory(pDllBase,pImageNtHeaders->OptionalHeader.SizeOfImage);

///////////////////拷贝文件头////////////////////////////;
    memcpy(pDllBase,pImageDosHeader,pImageNtHeaders->OptionalHeader.SizeOfHeaders);

///////////////////转换DOS头和NT头地址以备释放bTemp内存//////////////////;
    pImageDosHeader = (PIMAGE_DOS_HEADER)pDllBase;
    pImageNtHeaders = (PIMAGE_NT_HEADERS)(pImageDosHeader->e_lfanew+(DWORD)pDllBase);

///////////////////按照内存加载方式拷贝区段数据/////////////////////////;
    PIMAGE_SECTION_HEADER pImageSectionHeader = (PIMAGE_SECTION_HEADER)(
        pImageDosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS)+(DWORD)pDllBase);
    while (pImageSectionHeader->VirtualAddress!=0)
    {
        DWORD nSize = MAKEMAX(pImageSectionHeader->Misc.VirtualSize,pImageSectionHeader->SizeOfRawData);
        memcpy((PVOID)((DWORD)pDllBase+pImageSectionHeader->VirtualAddress),
            (PVOID)((DWORD)bTemp+pImageSectionHeader->PointerToRawData),nSize);
        DWORD flOldProtect = 0;
        VirtualProtect((PVOID)((DWORD)pDllBase+pImageSectionHeader->VirtualAddress),
            nSize,PAGE_EXECUTE_READWRITE,&flOldProtect);
        Sleep(100);
        pImageSectionHeader++;
    }

/////////////////////////释放bTemp内存//////////////////;
    delete[]bTemp;

////////////////////////基址重定位/////////////////////;
    PIMAGE_DATA_DIRECTORY pImageDataDir = (PIMAGE_DATA_DIRECTORY)
        (&(pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]));

    PIMAGE_BASE_RELOCATION pImageBaseRelocation = (PIMAGE_BASE_RELOCATION)
        (pImageDataDir->VirtualAddress+(DWORD)pDllBase);
    while (pImageDataDir->Size>0)
    {
        DWORD BlockRva=0;
        int nCont = (pImageBaseRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION))/sizeof(WORD);
        WORD *pBlock = (WORD*)((DWORD)pImageBaseRelocation+sizeof(IMAGE_BASE_RELOCATION));
        for (int i=0;i<nCont;i++)
        {
            WORD wTemp = pBlock[i];
            
            if (pBlock[i]>>12==IMAGE_REL_BASED_HIGHLOW)
            {
                BlockRva = ((DWORD)(wTemp&0xfff) + (DWORD)pDllBase )+ pImageBaseRelocation->VirtualAddress;
                *(DWORD*)BlockRva += ((DWORD)pDllBase - pImageNtHeaders->OptionalHeader.ImageBase);
            }
        }
        pImageDataDir->Size -= pImageBaseRelocation->SizeOfBlock;
        pImageBaseRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pImageBaseRelocation+pImageBaseRelocation->SizeOfBlock);
    }

////////////////////////修复IAT表/////////////////////;
    pImageDataDir = (PIMAGE_DATA_DIRECTORY)
        (&(pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]));
    PIMAGE_IMPORT_DESCRIPTOR pImageImportDes = (PIMAGE_IMPORT_DESCRIPTOR)(
        pImageDataDir->VirtualAddress+(DWORD)pDllBase);
    char *pName = NULL;
    while (pImageImportDes->OriginalFirstThunk!=0)
    {
        pName = (char *)(pImageImportDes->Name+(DWORD)pDllBase);//导入DLL名称;
        PIMAGE_THUNK_DATA pImageOriginalThunk = (PIMAGE_THUNK_DATA)(pImageImportDes->OriginalFirstThunk+(DWORD)pDllBase);
        PIMAGE_THUNK_DATA pImageFirstThunk = (PIMAGE_THUNK_DATA)(pImageImportDes->FirstThunk+(DWORD)pDllBase);
        DWORD dTemp = pImageOriginalThunk->u1.Function;
        HMODULE hMod = LoadLibraryA(pName);
        if (!hMod)
        {
            delete[]pDllBase;
            return FALSE;
        }
        while (pImageOriginalThunk->u1.Function>0)
        {
            DWORD mFuncAddr = 0;
            if (dTemp>>31==0)
            {
                PIMAGE_IMPORT_BY_NAME pImageImportByName = (PIMAGE_IMPORT_BY_NAME)(
                    pImageOriginalThunk->u1.Function+(DWORD)pDllBase);
                pName = pImageImportByName->Name;
                mFuncAddr = (DWORD)GetProcAddress(hMod,pName);
            }else
            {
                mFuncAddr = (DWORD)GetProcAddress(hMod,(char *)(pImageOriginalThunk->u1.Ordinal^0x7FFFFF));
            }
            pImageFirstThunk->u1.Function = mFuncAddr;
            pImageOriginalThunk++;
            pImageFirstThunk++;
        }
        pImageImportDes++;
    }
     
    m_dllMain=(myDllMain)(pImageNtHeaders->OptionalHeader.AddressOfEntryPoint+     (DWORD)pDllBase);
    m_dllMain((HINSTANCE)pDllBase,DLL_PROCESS_ATTACH,NULL);
//    delete[]pDllBase;
    return TRUE;
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
高人,高人,都到什么地方去了?
2013-12-3 13:19
0
雪    币: 12
活跃值: (767)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
一直在寻找完美的reload dll的代码
2013-12-3 13:24
0
游客
登录 | 注册 方可回帖
返回
//