首页
社区
课程
招聘
[原创]LoadLibrary C版本
发表于: 2009-3-8 17:05 14889

[原创]LoadLibrary C版本

2009-3-8 17:05
14889

继续前边2贴,现把LOADLIBRARY也一并贴上。

HMODULE __stdcall MyLoadLibraryA(char *szDllName)
{
        void *pFileAddr;//文件隐射基地址
        void *pImageBase;//加载DLL的基地址,作为返回数
        IMAGE_DOS_HEADER *pDosHead;
        IMAGE_OPTIONAL_HEADER *pOPHead;
        IMAGE_FILE_HEADER  *pFileHead;
        DWORD dwSecNum;
        IMAGE_SECTION_HEADER *pSecInfo;
        IMAGE_IMPORT_DESCRIPTOR *pIID;
        LPTHREAD_START_ROUTINE OEP;
        IMAGE_BASE_RELOCATION *pIBR;
        DWORD dwDllRVA;           //实际装载地址与建议装载地址差。
        HANDLE hFile = ::CreateFile(szDllName,GENERIC_READ,0,NULL,OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,NULL);
        if (hFile==INVALID_HANDLE_VALUE)
        {
                AfxMessageBox("Can't open file");
                return 0;
        }
        HANDLE hMaping = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
        pFileAddr = MapViewOfFile(hMaping,FILE_MAP_READ,0,0,0);
               
        pDosHead = (IMAGE_DOS_HEADER*)pFileAddr;
        pFileHead = (IMAGE_FILE_HEADER*)(pDosHead->e_lfanew+4 +(DWORD)pFileAddr);
       
        pOPHead = (IMAGE_OPTIONAL_HEADER*)((DWORD)pFileHead +
                sizeof(_IMAGE_FILE_HEADER));

        //申请内存,建立DLL内存空间,并COPY DLL
        pImageBase = VirtualAlloc(NULL,pOPHead->SizeOfImage,MEM_COMMIT
                ,PAGE_EXECUTE_READWRITE);
        if (pImageBase == NULL)
        {
                AfxMessageBox("分配空间失败");
                return 0;
        }
        dwDllRVA = (DWORD)pImageBase - pOPHead->ImageBase;
        pSecInfo = (IMAGE_SECTION_HEADER*)((DWORD)pOPHead + pFileHead->SizeOfOptionalHeader) ;
        dwSecNum = pFileHead->NumberOfSections;
        //COPY文件头
        DWORD dwFileSize = pOPHead->SizeOfHeaders;
        memcpy(pImageBase,pFileAddr,dwFileSize);
       
        //COPY区段
        for (DWORD i = 0; i < dwSecNum; i++)
        {
                void *des,*sour;
                des = (void*)(pSecInfo->VirtualAddress + (DWORD)pImageBase);
                sour = (void*)(pSecInfo->PointerToRawData + (DWORD)pFileAddr);
                memcpy(des,sour,pSecInfo->Misc.VirtualSize);
                pSecInfo++;               
        }
        OEP = (LPTHREAD_START_ROUTINE)(pOPHead->AddressOfEntryPoint +
                (DWORD)pImageBase);

    //  修正重定位表。
        pIBR = (IMAGE_BASE_RELOCATION*)(pOPHead->DataDirectory[5].VirtualAddress + (DWORD)pImageBase);
        while (pIBR->VirtualAddress)
        {
                WORD *pTypeOffset = (WORD*)((DWORD)pIBR+ 8);

                for (i = 0; i < pIBR->SizeOfBlock - 8; i += 2)
                {
                        //pTypeOffset[i] & 0Xf000 == 0x3000 结果不对,郁闷。
                        if (pTypeOffset[i] >>12 == 3)
                        {
                                DWORD nTmp =((DWORD) pTypeOffset[i]) & 0xfff;
                                DWORD *pReloc = (DWORD*)(nTmp +(DWORD) pImageBase + pIBR->VirtualAddress);
                                 *pReloc = *pReloc + dwDllRVA;                               
                        }                         
                }
                pIBR = (IMAGE_BASE_RELOCATION*)(pIBR->SizeOfBlock + (DWORD)pIBR);
        }

        //填充IAT表
        pIID = (IMAGE_IMPORT_DESCRIPTOR*)((pOPHead->DataDirectory[1].VirtualAddress)
                + (DWORD)pImageBase);
        while (pIID->Name != 0)
        {
                char *pDllName;
                char *pFacName;
               
                HMODULE hDll;
                IMAGE_THUNK_DATA32 *pIDT,*pIAT;
                PIMAGE_IMPORT_BY_NAME *pImByName;
                pDllName = (char*)((DWORD)(pIID->Name) + (DWORD)pImageBase);
                hDll = LoadLibrary((LPCSTR)pDllName);
                pIDT = (IMAGE_THUNK_DATA32*)(pIID->OriginalFirstThunk +
                        (DWORD)pImageBase);
                pIAT = (IMAGE_THUNK_DATA32*)(pIID->FirstThunk + (DWORD)pImageBase);
               
                while (*(DWORD*)pIDT != 0)
                {
                        pImByName = (PIMAGE_IMPORT_BY_NAME*)((DWORD)(pIDT->u1.AddressOfData)
                                + (DWORD)pImageBase);
                        pFacName =(char*)pImByName+2;
                        pIAT->u1.Function = (PDWORD)GetProcAddress(hDll,pFacName);
                        pIDT++ ;
                }
                pIID++;
        }
//调用DLLMAIN
        _asm
        {
                pushad;
                push 0;
                push DLL_PROCESS_ATTACH;
                push pImageBase;
                call OEP;
                add esp,0x4;     //DLLMAIN未平衡堆栈。
                popad
        }
       
        return (HMODULE)pImageBase;
       

}

用此函数加载的DLL。有部分API会发生问题。比如:GetProcAddress,GetModulHandle。另外,本函数也没有考虑TLS的处理。等以后有时间在慢慢修补吧。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (12)
雪    币: 210
活跃值: (11)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
顶,光哥的代码真漂亮
2009-3-10 02:55
0
雪    币: 62
活跃值: (72)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
3
学习之,收藏之
2009-3-10 21:19
0
雪    币: 378
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
原来是光哥啊...
膜拜下
2009-3-15 21:50
0
雪    币: 334
活跃值: (22)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
有一点疑问,为什么MyLoadLibrary里还要调用LoadLibrary呢?
2009-4-7 17:20
0
雪    币: 86
活跃值: (34)
能力值: ( LV2,RANK:150 )
在线值:
发帖
回帖
粉丝
6
.....那就要改成递归了啊。。。其实这个代码还有好多问题。。。没考虑序号导入的方式,没有HOOK GetProcAddress,另外修正重定位部分也有点问题,我用MFC DLL测试,总是有部分没有修正,奇怪。。。也懒的修改了。。
2009-4-7 19:11
0
雪    币: 197
活跃值: (52)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
7
。。。先实现GetProcAddress,简单些。。。。loadlibrary好复杂
2009-4-12 02:12
0
雪    币: 37
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
是啊!最好自己先实现GetProcAddress比较点!
2009-4-30 01:00
0
雪    币: 6
活跃值: (133)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
下次我写个myqq,思路,先把先在的qq打包,然后资源释放,执行,myqq  1.0 ok
2009-6-11 21:33
0
雪    币: 1829
活跃值: (1377)
能力值: (RANK:50 )
在线值:
发帖
回帖
粉丝
10
估计QQ跑不起来,除非你修改一些API的实现,或者是模拟进程环境还有页表结构。
2009-6-12 11:16
0
雪    币: 86
活跃值: (34)
能力值: ( LV2,RANK:150 )
在线值:
发帖
回帖
粉丝
11
,楼上的楼上的意思,是把QQ打包,然后作为2进制放入资源中,他的程序运行的时候,先把资源释放到临时文件中,然后CREATEPROCESS。。。。。不知道我猜对了否。。。。
2009-6-12 22:13
0
雪    币: 219
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
这个好无聊啊,直接说整一个RAR自解压算了。。。。
2009-6-30 00:20
0
雪    币: 2
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
学习了
2023-7-9 12:30
0
游客
登录 | 注册 方可回帖
返回
//