首页
社区
课程
招聘
[求助]LoadLibrary后无法在IMAGE_IMPORT_DESCRIPTOR中找到相应模块
发表于: 2012-8-6 18:21 16657

[求助]LoadLibrary后无法在IMAGE_IMPORT_DESCRIPTOR中找到相应模块

2012-8-6 18:21
16657
我想通过钩子来拦截一个应用程序调用的dsound api,这个应用程序使用了显式调用方式来调用dsound的api,因此我先将系统的
LoadLibrary替换成我自己写的MyLoadLibrary函数,这样我就可以在应用程序执行LoadLibrary("dsound.dll")的时候将dsound的
api替换成我自己写的函数,简要代码如下:

HMODULE WINAPI MyLoadLibraryA(LPCSTR lpFileName)
{
        WriteToLog("\nhook LoadLibraryA call, name:");
        WriteToLog((char*)lpFileName);
        MyLoadLibraryA_Type fnOld = (MyLoadLibraryA_Type)Kernel32Hook.Functions[0].OrigFn;

        HMODULE hMod = fnOld(lpFileName);

        if(g_bNeedHook && hMod!=NULL)
        {
                if( !DSoundHook.Hooked && stricmp(lpFileName, DSoundHook.Name)==0 )
                {

                        HookImportedFunction("dsound.dll", "DirectSoundCreate", 0, MyDirectSoundCreate );

                }
        }

        return hMod;
}

// Dll -- 要替换的dll名
// FuncName -- 要替换的函数名
// Ordinal -- 函数在Dll中的偏移
// Function -- 我们写的替代函数
PVOID HookImportedFunction(const char *Dll, const char *FuncName, int Ordinal, void *Function)
{
        DWORD oldProtect;
        void *PrevValue=0;

        DWORD image_base = (DWORD)GetModuleHandle(NULL);
        IMAGE_DOS_HEADER *idh = (IMAGE_DOS_HEADER *)image_base;
        IMAGE_FILE_HEADER *ifh = (IMAGE_FILE_HEADER *)(image_base +
                idh->e_lfanew + sizeof(DWORD));
        IMAGE_OPTIONAL_HEADER *ioh = (IMAGE_OPTIONAL_HEADER *)((DWORD)(ifh) +
                sizeof(IMAGE_FILE_HEADER));
        IMAGE_IMPORT_DESCRIPTOR *iid = (IMAGE_IMPORT_DESCRIPTOR *)(image_base +
                ioh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

        VirtualProtect((LPVOID)(image_base +
                ioh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress),
                ioh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size, PAGE_READWRITE,
                &oldProtect);

        while(iid->Name)
        {
                if(stricmp(Dll, (char *)(image_base + iid->Name)) == 0)
                {
                        //trace_printf("Found descriptor: %s\n", dhook->name);
                        IMAGE_THUNK_DATA * pThunk = (IMAGE_THUNK_DATA *)
                                ((DWORD)iid->OriginalFirstThunk + image_base);
                        IMAGE_THUNK_DATA * pThunk2 = (IMAGE_THUNK_DATA *)
                                ((DWORD)iid->FirstThunk + image_base);
                        while(pThunk->u1.AddressOfData)
                        {
                                char * name = 0;
                                int ordinal;
                                // Imported by ordinal only:
                                if(pThunk->u1.Ordinal & 0x80000000)
                                {
                                        ordinal = pThunk->u1.Ordinal & 0xffff;
                                }
                                else    // Imported by name, with ordinal hint
                                {
                                        IMAGE_IMPORT_BY_NAME * pname = (IMAGE_IMPORT_BY_NAME *)
                                                ((DWORD)pThunk->u1.AddressOfData + image_base);
                                        ordinal = pname->Hint;
                                        name = (char *)pname->Name;
                                }

                                if(name != 0 && FuncName && strcmp(name, FuncName) == 0)
                                {
                                        //trace_printf("Found entry name: %s\n", ehook->name);
                                        PrevValue = (void*)pThunk2->u1.Function;
#if _MFC_VER == 0x0600
                                        pThunk2->u1.Function = (DWORD*)Function;
#else
                                        pThunk2->u1.Function = (DWORD)Function;
#endif
                                }
                                else if(ordinal == Ordinal)
                                {
                                        //trace_printf("Found entry ordinal: %s\n", ehook->name);
                                        PrevValue = (void*)pThunk2->u1.Function;
#if _MFC_VER == 0x0600
                                        pThunk2->u1.Function = (DWORD*)Function;
#else
                                        pThunk2->u1.Function = (DWORD)Function;
#endif
                                }

                                pThunk++;
                                pThunk2++;
                        }
                }
                iid++;
        }

        return PrevValue;
}

问题:在遍历执行 if(stricmp(Dll, (char *)(image_base + iid->Name)) == 0) 语句无法找到dsound.dll。

请问高手,问题出现什么地方呢,我已经先调用LoadLibrary将dsound.dll加载到进程中了,为什么无法在
IMAGE_IMPORT_DESCRIPTOR中找到它呢?

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
2
hook错了~~

你应该hook dsound.dll的导出表,而不是exe的导入表~
2012-8-6 18:52
0
雪    币: 211
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
刚才我搜索了下资料,有人说 ”显式加载的DLL在EXE里没留下import表“,如果是这个原因导致无法在exe的import table中找到该dll的信息,那么我想问下,在这种情况下我应该怎么对dsound.dll 中的 DirectSoundCreate 函数进行重定向呢? 望高手不吝赐教, thx。
2012-8-6 19:08
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
4
干嘛不hook dsound.dll 的导出表?
2012-8-6 19:25
0
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
做导出表HOOK吧
2012-8-6 22:01
0
雪    币: 211
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感谢Winker的回答,hook 导出表可以成功,下面是我测试hook EAT的函数:

//
// mod -- 模块句柄
// OA -- 原始函数的地址
// HA -- 替换函数的地址
//
// void* lpOrigDirectSoundCreate8 = NULL;
//
// Usage: EATHook(GetModuleHandle("dsound.dll"),"DirectSoundCreate8",((VOID*)(MyDirectSoundCreate8),((VOID**)(&lpOrigDirectSoundCreate8)));  
//
DWORD EATHook(HMODULE mod,CHAR * FN,VOID* HA,VOID** OA) // Credits: Jimster480
{
        DWORD EATA,OP;
        IMAGE_DOS_HEADER *DOSH = (IMAGE_DOS_HEADER*)mod;
        IMAGE_NT_HEADERS *NTH = NULL;

        if(DOSH->e_magic != IMAGE_DOS_SIGNATURE) return NULL;

        NTH = ((PIMAGE_NT_HEADERS)((DWORD)(DOSH) + (DWORD)(DOSH->e_lfanew)));

        if(NTH->Signature != IMAGE_NT_SIGNATURE) return NULL;

        EATA = NTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
        IMAGE_EXPORT_DIRECTORY *EATP = (IMAGE_EXPORT_DIRECTORY*) ((DWORD)EATA + (DWORD)mod);

        for (DWORD i = 0;i < EATP->NumberOfFunctions;i++)
        {
                DWORD * ENTP = (DWORD*)((DWORD)mod + ((DWORD)EATP->AddressOfNames + (sizeof(DWORD)*i)));

                if(strcmp((char*)((DWORD)mod + *ENTP),FN)== 0)
                {
                        WORD * AONP = (WORD*)((DWORD)mod + ((DWORD)EATP->AddressOfNameOrdinals + (i*sizeof(WORD))));
                        DWORD * AOF  = (DWORD*)((DWORD)mod + ((DWORD)EATP->AddressOfFunctions + (sizeof(DWORD)**AONP)));

                        if(!VirtualProtect(AOF,sizeof(DWORD),PAGE_READWRITE,&OP))
                                return NULL;

                        // 返回原来函数的地址
                        *OA = (void*)(*AOF+DWORD(mod));

                        // 导出表中函数的地址替换成我们编写的函数
                        *AOF = (((DWORD)HA)-DWORD(mod));

                        if(!VirtualProtect(AOF,sizeof(DWORD),OP,&OP))
                                return NULL;

                        return 1;
                }
        }
        return NULL;
}
2012-8-7 11:14
0
游客
登录 | 注册 方可回帖
返回
//