linboqing 2016-10-14 03:15 采纳率: 50%
浏览 1237
已采纳

textout 钩子函数为何无法触发

我从网上下了部分代码,写了一个钩子函数获取textout输出内容。一个是包含钩子函数的DLL程序包,另一个应用程序安装了改钩子,调用了TextOut之后。
DLL里的TextOut钩子函数未被调用,请大侠指点一下问题出在哪儿?
附DLL 钩子程序包。
CPP部分:
#include "stdafx.h"

#include "hook.h"

#include "winuser.h"
#include

#include

#pragma comment(lib,"ImageHlp") //定义全局共享数据段

#pragma data_seg("Shared")

HMODULE hmodDll=NULL;

HHOOK hHook=NULL;

#pragma data_seg()

#pragma comment(linker,"/Section:Shared,rws") //设置全局共享数据段的属性

//dll的入口点

BOOL APIENTRY DllMain( HMODULE hModule,

DWORD ul_reason_for_call,

LPVOID lpReserved

)

{

switch(ul_reason_for_call)

{

case DLL_PROCESS_ATTACH:

break;
case DLL_PROCESS_DETACH:

break;
}

hmodDll=hModule;   
return TRUE;   

}

void WINAPI HookOneAPI(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,

PROC pfnDummyFuncAddress,HMODULE hModCallerModule)

{

ULONG size;

//获取指向PE文件中的Import中IMAGE_DIRECTORY_DESCRIPTOR数组的指针   
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)   
ImageDirectoryEntryToData(hModCallerModule,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&size);   

if (pImportDesc == NULL)   
    return;   

//查找记录,看看有没有我们想要的DLL
for (;pImportDesc->Name;pImportDesc++)   
{   
    LPSTR pszDllName = (LPSTR)((PBYTE)hModCallerModule+pImportDesc->Name);   

    if (lstrcmpiA(pszDllName,pszCalleeModuleName) == 0)   
        break;   
}   

if (pImportDesc->Name == NULL)   return;

//寻找我们想要的函数   
PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)((PBYTE)hModCallerModule+pImportDesc->FirstThunk);

for (;pThunk->u1.Function;pThunk++)   
{   
    //ppfn记录了与IAT表项相应的函数的地址   
    PROC * ppfn= (PROC *)&pThunk->u1.Function;
    if (*ppfn == pfnOriginApiAddress)    
    {   
        //如果地址相同,也就是找到了我们想要的函数,进行改写,将其指向我们所定义的函数
        WriteProcessMemory(GetCurrentProcess(),ppfn,&(pfnDummyFuncAddress),   
        sizeof(pfnDummyFuncAddress),NULL);  

        return;   
    }
}

}

//查找所挂钩的进程所应用的dll模块的

BOOL WINAPI HookAllAPI (LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,

PROC pfnDummyFuncAddress,HMODULE hModCallerModule)

{

if (pszCalleeModuleName == NULL) return FALSE;
if (pfnOriginApiAddress == NULL) return FALSE;

MEMORY_BASIC_INFORMATION mInfo;   
HMODULE hModHookDLL;   
HANDLE hSnapshot;   
MODULEENTRY32 me = {sizeof(MODULEENTRY32)};   

//MODULEENTRY32:描述了一个被指定进程所应用的模块的struct
VirtualQuery(HookOneAPI,&mInfo,sizeof(mInfo));
hModHookDLL=(HMODULE)mInfo.AllocationBase;

hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
BOOL bOk = Module32First(hSnapshot,&me);
if (bOk == FALSE) return FALSE;

while (bOk)
{   
    if (me.hModule != hModHookDLL)
    {   
        hModCallerModule = me.hModule;//赋值
        //me.hModule:指向当前被挂钩进程的每一个模块
        HookOneAPI(pszCalleeModuleName,pfnOriginApiAddress,   
         pfnDummyFuncAddress,hModCallerModule);   
    }
    bOk = Module32Next(hSnapshot,&me);   
}   

return TRUE;

}

//通过使pfnDummyFuncAddress与pfnOriginApiAddress相等的方法,取消对IAT的修改

BOOL WINAPI UnhookAllAPIHooks(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,

PROC pfnDummyFuncAddress,HMODULE hModCallerModule)

{

PROC temp;

temp = pfnOriginApiAddress;

pfnOriginApiAddress = pfnDummyFuncAddress;

pfnDummyFuncAddress = temp;

return HookAllAPI(pszCalleeModuleName,pfnOriginApiAddress,   
                pfnDummyFuncAddress,hModCallerModule);   

}

//钩子子程。与其它钩子子程不大相同,没做什么有意义的事情,继续调用下一个钩子子程,形成循环
LRESULT CALLBACK GetMsgProc(int code,WPARAM wParam,LPARAM lParam)

{

return CallNextHookEx(hHook,code,wParam,lParam);

}

void __declspec(dllexport) WINAPI InstallHook(BOOL IsHook,DWORD dwThreadId)

{

if(IsHook)
{

hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)GetMsgProc,hmodDll,dwThreadId);

//GetProcAddress(GetModuleHandle("GDI32.dll"),"ExtTextOutA"):取得要钩的函数在所在dll中的地址

    HookAllAPI("GDI32.dll",GetProcAddress(GetModuleHandle("GDI32.dll"),   
    "TextOutW"),(PROC)&H_TextOutW,NULL);   

    HookAllAPI("GDI32.dll",GetProcAddress(GetModuleHandle("GDI32.dll"),   
    "TextOutA"),(PROC)&H_TextOutA,NULL);   
}   
else
{   
    UnInstallHook();   
    //Beep(440,1000);
    UnhookAllAPIHooks("GDI32.dll",GetProcAddress(GetModuleHandle("GDI32.dll"),   
    "TextOutA"),(PROC)&H_TextOutA,NULL);   
    UnhookAllAPIHooks("GDI32.dll",GetProcAddress(GetModuleHandle("GDI32.dll"),   
    "TextOutW"),(PROC)&H_TextOutW,NULL);   
}   

}

//卸载钩子

BOOL WINAPI UnInstallHook()
{

UnhookWindowsHookEx(hHook);

return TRUE;

}

/*======================TextOutA/W 接口函数=========================================*/
BOOL WINAPI H_TextOutA(HDC hdc,int nXStart,int nYStart,LPCSTR lpString,int cbString)

{

MessageBox(NULL,"textout captured!!!","test",MB_OK);
TextOut(hdc,nXStart,nYStart,LPCSTR(lpString),cbString);//返回原来的函数,以显示字符

return TRUE;

}

BOOL WINAPI H_TextOutW(HDC hdc,int nXStart,int nYStart,LPCSTR lpString,int cbString)

{

MessageBox(NULL,"TextOutW","APIHook_Dll ---rivershan",MB_OK);

TextOut(hdc,nXStart,nYStart,LPCSTR(lpString),cbString);//返回原来的函数,以显示字符

return TRUE;

}

H文件部分:
#ifdef HOOK_EXPORTS
#define HOOK_API __declspec(dllexport)
#else
#define HOOK_API __declspec(dllimport)
#endif

extern HOOK_API int nHook;

HOOK_API int fnHook(void);
void __declspec(dllexport) WINAPI InstallHook(BOOL,DWORD);
BOOL WINAPI UnInstallHook();
LRESULT CALLBACK GetMsgProC(int code,WPARAM wParam,LPARAM lParam);
void WINAPI HookOneAPI(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
PROC pfnDummyFuncAddress,HMODULE hModCallerModule);
BOOL WINAPI HookAllAPI(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
PROC pfnDummyFuncAddress,HMODULE hModCallerModule);
BOOL WINAPI UnhookAllAPIHooks(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
PROC pfnDummyFuncAddress,HMODULE hModCallerModule);
BOOL WINAPI H_TextOutA(HDC, int, int, LPCSTR, int);
BOOL WINAPI H_TextOutW(HDC, int, int, LPCSTR, int);

  • 写回答

1条回答 默认 最新

  • dabocaiqq 2016-10-16 05:52
    关注
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler