首页
社区
课程
招聘
[讨论]内存加载带mfc 的dll失败问题
发表于: 2015-8-12 09:25 13008

[讨论]内存加载带mfc 的dll失败问题

2015-8-12 09:25
13008
网上下载了一个CMemLoadDll源码,加载windows的dll是没有问题,但是加载mfc的dll时候出现问题,问题是出在了GetModuleFileName函数,返回结果为NULL;
同样的参数我使用loadlibrary加载dll后调用GetModuleFileName是成功的;
请各位大神帮我一下,研究了几天了,没效果呀

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

上传的附件:
收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
我之前也遇到了这个问题,感觉解决起来麻烦,也害怕不稳定。
就放弃MFC改用ATL了,ATL内存加载没问题,带界面的DLL也OK。
2015-8-12 10:30
0
雪    币: 1787
活跃值: (340)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
导入表把这几个函数钩了,换成你自己的,然后返回正确的值,就能起来了。内存加载DLL,用这几个函数,都拿不到正确的句柄(操作你内存加载的DLL的话)。

        (FARPROC)FreeLibrary,
        (FARPROC)FreeLibraryAndExitThread,
        (FARPROC)GetModuleFileNameA,
        (FARPROC)GetModuleFileNameW,
        (FARPROC)GetModuleHandleA,
        (FARPROC)GetModuleHandleW,
        (FARPROC)GetProcAddress,
        (FARPROC)LoadLibraryA,
        (FARPROC)LoadLibraryW,
        (FARPROC)LoadLibraryExA,
        (FARPROC)LoadLibraryExW,
2015-8-12 14:33
0
雪    币: 35
活跃值: (612)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
一样遇到了这问题 楼主是否解决啊  MFC DLL 无法内存加载。
2015-9-25 21:04
0
雪    币: 234
活跃值: (214)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
5
vs2008以下将第一个参数模块基址改为null即可,2012测试失败,其他版本未知
2015-10-6 02:47
0
雪    币: 376
活跃值: (92)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
楼主的钩子函数怎么写呢
2015-12-29 15:05
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
不知道你说的代码是不是和我说的是同一个,我开始在网上找的也是有些能加载有些不能加载。后来找到新版的,就OK了
* Memory DLL loading code
* Version 0.0.3
2015-12-29 21:22
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
8
我知道了,你这样加载DLL,系统的GetModuleFileName是不会识别出来的,这是因为,loadlibrary加载DLL后,会通过PEB,取得当前进程的模块链表,也就是InMemoryOrderLinks结构的地址,这是一个链表,loadlibrary函数会在InMemoryOrderLinks尾部加入这个DLL的HANDLE和文件地址,而GetModuleFileName也会通过PEB,查询到InMemoryOderLinks结构的地址,然后直接通过HANDLE在,在这个链表中查询到对应模块的文件地址,然后直接返回给你,而你自己加载DLL,却没有向InMemoryOrderLinks结构尾部加入这个DLL的HANDLE和文件地址,那么,当GetModuleFileName通过InMemoryOrderLinks结构来寻找对应的文件地址时,自然也不会找得到!

有兴趣的,你可以问我,我是看了WINDOWS 的WRK 2000 泄漏代码中的相应代码时看到的,并且已经被我翻译到了我的程序,通过我的翻译,我就知道了,系统的loadlibrary和GetModuleFileName是怎么执行的,所以看了你的问题,我就马上知道是怎么回事了,因为我在没有看WINDOWS的代码之前,我也遇到了这个问题,但是看了WINDOWS的代码之后,我马上就知道了!
2015-12-30 01:47
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
9
本来还想把自己翻译的WINDOWS的LoadLibrary的源代码发上来给你看看的,可惜我没有实现相对目录的查找,和在系统文件夹查找(其实因为懒癌犯了,懒得去写了),所以不敢发上来献丑,我发一段,我已经完善好的代码给你吧!

看看吧!这是我按照WINDOWS 泄漏的源代码,做的一个GetModuleFileName函数,看完了你就应该知道是怎么做到的了
DWORD
WINAPI
GetDllModuleFileNameA(
    __in_opt HMODULE hModule,
    __out_ecount_part(nSize, return + 1) LPSTR lpFilename,
    __in     DWORD nSize
    )
{
        NTSTATUS Status = 0;
        DWORD Return = 0;
        ULONG Size=0;
        ANSI_STRING AnsiString;
        UNICODE_STRING UnicodeString;
        //::RtlInitAnsiString(&DestinationString,lpFilename);
        AnsiString.Buffer=lpFilename;
        AnsiString.Length=nSize;
        AnsiString.MaximumLength=nSize+1;
        //memset(lpFilename,'1',nSize);
        Size=::RtlAnsiStringToUnicodeSize(&AnsiString);
        UnicodeString.Buffer=(PWSTR)::RtlAllocateHeap(::GetProcessHeap(),HEAP_ZERO_MEMORY,Size);
        UnicodeString.MaximumLength=Size;
        UnicodeString.Length=0;
        if(UnicodeString.Buffer)
        {
                Return=GetDllModuleFileNameW(hModule,UnicodeString.Buffer,UnicodeString.MaximumLength);
                if(Return!=0)
                {
                        UnicodeString.Length=Return;
                        Status=::RtlUnicodeStringToAnsiString(&AnsiString,&UnicodeString,TRUE);
                        if(Status==0)
                        {
                                //Status
                                if(AnsiString.Length>nSize)
                                {
                                        SetLastError(ERROR_DS_USER_BUFFER_TO_SMALL );
                        ::SetLastError(BaseNtStatusToDosError(Status));
                        ::RtlFreeAnsiString(&AnsiString);
                        return 0;
                                }
                                ::memcpy(lpFilename,AnsiString.Buffer,AnsiString.Length);
                                Return=AnsiString.Length;
                        }
                        //Return=::RtlUnicodeStringToAnsiSize(&UnicodeString);
                        ::SetLastError(BaseNtStatusToDosError(Status));
                        ::RtlFreeAnsiString(&AnsiString);
                }
                ::RtlFreeHeap(::GetProcessHeap(),HEAP_ZERO_MEMORY,UnicodeString.Buffer);
        }
        return Return;
}
DWORD
WINAPI
GetDllModuleFileNameW(
    __in_opt HMODULE hModule,
    __out_ecount_part(nSize, return + 1) LPWSTR lpFilename,
    __in     DWORD nSize
    )
{
        NTSTATUS Status = 0;
        UNICODE_STRING UnicodeString;
        UnicodeString.Buffer=lpFilename;
        UnicodeString.Length=0;
        UnicodeString.MaximumLength=nSize;
        ULONG ReturnLength;
        PROCESS_BASIC_INFORMATION m_ProcessBasicInformation={0};
        //RtlInitUnicodeString(&DllModuleNameString,DllModuleName);
        Status=NtQueryInformationProcess(::GetCurrentProcess(),ProcessBasicInformation,&m_ProcessBasicInformation,sizeof(m_ProcessBasicInformation),&ReturnLength);
                if(!NT_SUCCESS(Status))
        {
                ::SetLastError(BaseNtStatusToDosError(Status));
                return 0;
        }
                SuspendOtherThread(TRUE);
    PLIST_ENTRY InMemoryOrderModuleList=&m_ProcessBasicInformation.PebBaseAddress->Ldr->InMemoryOrderModuleList;
        PLIST_ENTRY LastList=InMemoryOrderModuleList->Flink;
        while(LastList!=InMemoryOrderModuleList)
        {
            UNICODE_STRING m_DllNameString;
                        PLDR_DATA_TABLE_ENTRY LdrData=CONTAINING_RECORD(LastList,LDR_DATA_TABLE_ENTRY,InMemoryOrderLinks);
                        if(LdrData->DllBase==hModule)
                        {
                                SuspendOtherThread(FALSE);
                                if(UnicodeString.MaximumLength<LdrData->FullDllName.Length+2)
                                {
                                        SetLastError(ERROR_DS_USER_BUFFER_TO_SMALL );
                                        return 0;
                                }
                                UnicodeString.Length=LdrData->FullDllName.Length;
                                RtlCopyUnicodeString(&UnicodeString,&LdrData->FullDllName);
                                return LdrData->FullDllName.Length;
                        }
                        LastList=LastList->Flink;
        }
        SuspendOtherThread(FALSE);
        return 0;
}
2015-12-30 03:25
0
雪    币: 6
活跃值: (556)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
测试HOOK GetModuleFileName也没用,还有其它函数也需要处理
2022-2-25 20:55
0
游客
登录 | 注册 方可回帖
返回
//