首页
社区
课程
招聘
[求助]已知a.exe会调用b.dll中的xxx函数,请问我可以hook xxx函数来获取传递给xxx函数的参数吗?
发表于: 2015-9-24 21:07 5368

[求助]已知a.exe会调用b.dll中的xxx函数,请问我可以hook xxx函数来获取传递给xxx函数的参数吗?

2015-9-24 21:07
5368
已知a.exe会调用b.dll中的xxx函数,请问我可以hook xxx函数来获取传递给xxx函数的参数吗?

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

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 4560
活跃值: (1002)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
必须可以
2015-9-24 21:24
0
雪    币: 5467
活跃值: (1430)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
可以呀,可以用IAT HOOK或EAT HOOK,很好玩的。
2015-9-24 21:25
0
雪    币: 182
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
能不能详细点啊,谢谢了啊!我说的dll是第三方的,不是MS的,谢谢!
2015-9-24 21:47
0
雪    币: 5467
活跃值: (1430)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
知道呀,IAT是针对a.exe的,一般a.exe要调用b.dll的话,会把需要用到的DLL及函数写到IAT里,在程序启动的时候,系统就会根据IAT表把相应的DLL加载到a.exe的内存空间中,这个时候我们把iat修改成我们自己的DLL和函数地址,那系统就睁眼瞎了,那a.exe调用b.dll中的函数时,由于地址被我们改掉了,就直接调用我们的DLL函数了。

EAT是针对DLL的,每个DLL导出的函数都有一个地址,这个地址就在EAT里,如果我们把b.dll中的EAT表中指定函数地址改成我们自己的函数地址,那就实现了IAT一样的功能,顺便给你二个IAT和EAT的C++代码参考。

/************************************************************************/  
/* 函数说明:对DLL加载前进行EAT HOOK指定函数                                      
/* 参    数:DLL模块句柄、HOOK的导出函数名、HOOK后的代理函数地址、是否采用名称查找                                 
/* 返 回 值:成功返回真实的导出函数地址,否则返回NULL   
/* By:浙江螃蟹   2015.08.04                              
/************************************************************************/  
LPVOID __stdcall EATHook(HMODULE hMod,char *szApiName,LPVOID lpHookRoutine,BOOL byname)
{
        LPVOID lpOldAddr = NULL;
        PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
        PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)((DWORD)hMod + pDosHdr->e_lfanew);
        PIMAGE_EXPORT_DIRECTORY pExpDir = (PIMAGE_EXPORT_DIRECTORY)((DWORD)hMod + pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
        WORD *pwOrds = (WORD*)((DWORD)hMod + pExpDir->AddressOfNameOrdinals);
        DWORD *pdwRvas = (DWORD*)((DWORD)hMod + pExpDir->AddressOfFunctions);
        DWORD *pdwNames = (DWORD*)((DWORD)hMod + pExpDir->AddressOfNames);
        if(byname) //采用函数名进行EAT HOOK处理程序块
        {
                int i = 0;
                char *pszApiName = NULL;
                for (i=0;i<pExpDir->NumberOfNames;i++)
                {
                        pszApiName = (char *)((DWORD)hMod + pdwNames[i]);
                        if ((pszApiName!=NULL)&&(_stricmp(szApiName,pszApiName) == 0 ))
                                {
                                        DWORD dwOldProtect;
                                        pdwRvas=pdwRvas+pwOrds[i];
                                        lpOldAddr = (LPVOID)((DWORD)hMod+(*pdwRvas));
                                        //printf("messagebox的旧地址是 : %s.0x%08X.\n ",pszApiName,lpOldAddr);
                                        DWORD dwDelta = (DWORD)lpHookRoutine - (DWORD)hMod;
                                        //printf("偏移地址是 : 0x%08X. \n",dwDelta);
                                        VirtualProtectEx(GetCurrentProcess(),pdwRvas,sizeof(DWORD),PAGE_READWRITE,&dwOldProtect);
                                        *pdwRvas = dwDelta;
                                        break;
                                }
                }
                return lpOldAddr;
        }
        else  //采用序号调用的EAT HOOK处理程序块
        {
                return NULL;
        }
}
/*EAT HOOK后的代理函数示例
int __stdcall HookMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType)
{
        return OldMessageBoxA(hWnd,lpText,"EAT Hook Demo",uType);
}
*/

/************************************************************************/  
/* 函数说明:对程序进行IAT HOOK指定函数                                      
/* 参    数:DLL模块名称、HOOK的导出函数名、HOOK后的代理函数地址                                 
/* 返 回 值:成功返回TRUE,否则返回FALSE  
/* By:浙江螃蟹   2015.08.04                              
/************************************************************************/
BOOL __stdcall IATHook(LPCSTR pDLLName,LPCSTR pszApiname, PDWORD pNewAddr)
{       
        HMODULE hModule=NULL;
        PIMAGE_DOS_HEADER pIMAGE_DOS_HEADER=NULL;
        PIMAGE_NT_HEADERS pNTHeader=NULL;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader=NULL;
        PIMAGE_DATA_DIRECTORY DataDirectory=NULL;
        PIMAGE_IMPORT_DESCRIPTOR pImportHeader=NULL;
        PIMAGE_IMPORT_DESCRIPTOR pDllModule=NULL;
        LPSTR pModuleLabel=NULL;
        PIMAGE_THUNK_DATA pThunkData=NULL;
        DWORD OldProtect;
        LPVOID lpaddr;

        HMODULE hmod=GetModuleHandleA(pDLLName);
        PDWORD pOldAddr=(PDWORD)GetProcAddress(hmod,pszApiname);

        hModule=GetModuleHandle(NULL);
        pIMAGE_DOS_HEADER=(PIMAGE_DOS_HEADER)hModule;

        if(pIMAGE_DOS_HEADER->e_magic==IMAGE_DOS_SIGNATURE)
        {
                pNTHeader=(PIMAGE_NT_HEADERS)((DWORD)pIMAGE_DOS_HEADER+(DWORD)pIMAGE_DOS_HEADER->e_lfanew);
                if (pNTHeader->Signature==IMAGE_NT_SIGNATURE)
                {
                        pOptionalHeader=(PIMAGE_OPTIONAL_HEADER32)&(pNTHeader->OptionalHeader);
                        DataDirectory=pOptionalHeader->DataDirectory;
                        pImportHeader=(PIMAGE_IMPORT_DESCRIPTOR)((DWORD)hModule+DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
                }
                else
                        return FALSE;
        }
        else
                return FALSE;
        while(pImportHeader->Name!=NULL)
        {
                pModuleLabel=(LPSTR)((DWORD)hModule+(DWORD)pImportHeader->Name);
                if(*pModuleLabel==*pDLLName)
                {
                        pDllModule=pImportHeader;
                        pThunkData=(PIMAGE_THUNK_DATA)((DWORD)hModule+(DWORD)pDllModule->FirstThunk);
                        while(pThunkData->u1.Function!=NULL)
                        {
                                if(pOldAddr==(PVOID)pThunkData->u1.Function)
                                {
                                        MEMORY_BASIC_INFORMATION  mbi;
                                        lpaddr=&pThunkData->u1.Function;
                                        VirtualQuery(lpaddr,&mbi,sizeof(mbi));
                                        VirtualProtect(lpaddr,sizeof(PDWORD),PAGE_READWRITE,&OldProtect);
                                        WriteProcessMemory(GetCurrentProcess(),lpaddr,&pNewAddr, sizeof(PDWORD), NULL);
                                        VirtualProtect(&pThunkData->u1.Function,sizeof(PDWORD),OldProtect,&OldProtect);
                                        return TRUE;
                                }
                                else
                                        pThunkData++;
                        }
                }
                pImportHeader++;
        }
        return FALSE;
}
2015-9-24 22:15
0
雪    币: 1258
活跃值: (1434)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
你就问“ 我可以 HOOK 一个 函数, 获取 函数参数吗?”

你去 a.exe 的函数 中 IAT 勾取那个模块中的 函数地址。

如果人家是 LoadLibrary 动态调用的话,那就 GerModuleHandle, 然后 GerProcAddress

要么 挂钩IAT ,要么 Inline HOOK
2015-9-24 22:17
0
雪    币: 35
活跃值: (612)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
哥们代码不少 分享个支持MFC的 内存加载的
2015-9-25 03:42
0
雪    币: 2325
活跃值: (4832)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
EATHOOK  没效果啊·!!
2015-9-29 15:25
0
雪    币: 5467
活跃值: (1430)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
EAT HOOK必须要知道这个a.exe程序是怎么加载b.dll的,并且在他加截b.dll前,由你来加载b.dll,并进行eat hook,

我一般是采用APC HOOKa.exe程序,让a.exe程序加载b.dll,然后eat hook。
2015-9-30 22:38
0
游客
登录 | 注册 方可回帖
返回
//