我正在尝试使用弯路钩住文本输出,例如在记事本中。
我写了以下代码。我不会把所有代码放在这里,而是最重要的部分。
DLL部分:
DLLEXPORT LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode < 0) {
return CallNextHookEx(0, nCode, wParam, lParam);
}
if (nCode == HCBT_ACTIVATE)
{
HWND hWnd = (HWND)wParam;
TCHAR szTemp[255];
GetWindowText(hWnd, szTemp, 255);
DetourTransactionBegin();
DetourUpdateThread(hWnd);
DetourAttach(&(PVOID&)Real_DrawText, Mine_DrawText);
DetourTransactionCommit();
DetourTransactionBegin();
DetourUpdateThread(hWnd);
DetourAttach(&(PVOID&)Real_DrawTextEx, Mine_DrawTextEx);
DetourTransactionCommit();
DetourTransactionBegin();
DetourUpdateThread(hWnd);
DetourAttach(&(PVOID&)Real_TextOut, Mine_TextOut);
DetourTransactionCommit();
DetourTransactionBegin();
DetourUpdateThread(hWnd);
DetourAttach(&(PVOID&)Real_ExtTextOut, Mine_ExtTextOut);
DetourTransactionCommit();
}
return 0;
}
客户端部分:
int main(int argc, char* argv[]) {
HOOKPROC hkprcSysMsg;
static HINSTANCE hinstDLL;
static HHOOK hhookSysMsg;
hinstDLL = LoadLibrary(TEXT("dllsample.dll"));
//cout << (hinstDLL == NULL);
hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "_CBTProc@12");
DWORD dw = GetLastError();
//cout << (hkprcSysMsg == NULL);
//cout << dw;
hhookSysMsg = SetWindowsHookEx(
WH_CBT,
hkprcSysMsg,
hinstDLL,
0);
//std::cout << (hhookSysMsg == NULL);
int i;
std::cin >> i;
}
问题是绘制文本的所有4个函数都没有被挂钩。我做错了什么我开始学习弯路,但没有在文档中找到我的问题的答案。
如果需要其他代码部分,我会稍后将它们放在这里。
答案 0 :(得分:1)
DrawText是一个宏,可以转到DrawTextW或DrawTextA,具体取决于UNICODE预处理器设置。所以也许记事本正在打电话给你,而你正在挂另一个?
我认为DrawTextA转发到DrawTextW,所以请尝试直接挂钩。
编辑,下面的示例代码,使用顶部的命令进行编译。运行main.exe。运行sysinternals调试视图以查看输出。
代码编译成一个名为t4.dll的dll和一个名为main.exe的可执行文件,当你运行main.exe时,通过SetWindowHookEx调用将dll加载到每个正在运行的进程中,然后每次调用CBTProc函数在适当的时间线程。
/* t4.cpp
cl.exe /Zi /EHa /c /DUNICODE /D_UNICODE /I "c:/program files/Microsoft Research/Detours Express 2.1/include/" t4.cpp
link /DLL /DEBUG /LIBPATH:"c:/Program Files/Microsoft Visual Studio 10.0/VC/lib" /LIBPATH:"C:\Program Files\Microsoft SDKs\Windows\v7.0A\Lib" /LIBPATH:"c:/program files/Microsoft Research/Detours Express 2.1/lib" t4.obj user32.lib gdi32.lib
link /OUT:main.exe /DEBUG /LIBPATH:"c:/Program Files/Microsoft Visual Studio 10.0/VC/lib" /LIBPATH:"C:\Program Files\Microsoft SDKs\Windows\v7.0A\Lib" /LIBPATH:"c:/program files/Microsoft Research/Detours Express 2.1/lib" t4.obj user32.lib gdi32.lib
*/
#include <iostream>
#define NOMINMAX
#include <string.h>
#include <tchar.h>
#include <windows.h>
#include "detours.h"
#pragma comment(lib, "detours")
#pragma comment(lib, "detoured")
int (WINAPI *Real_DrawText)(HDC hDC, LPCTSTR lpchText, int, LPRECT, UINT) = DrawText;
BOOL (WINAPI *Real_TextOut)(
__in HDC hdc,
__in int nXStart,
__in int nYStart,
__in LPCTSTR lpString,
__in int cbString
) = TextOut;
int (WINAPI *Real_DrawTextEx)(
__in HDC hdc,
__inout LPTSTR lpchText,
__in int cchText,
__inout LPRECT lprc,
__in UINT dwDTFormat,
__in LPDRAWTEXTPARAMS lpDTParams
) = DrawTextEx;
BOOL (WINAPI *Real_ExtTextOut)(
__in HDC hdc,
__in int X,
__in int Y,
__in UINT fuOptions,
__in const RECT *lprc,
__in LPCTSTR lpString,
__in UINT cbCount,
__in const INT *lpDx
) = ExtTextOut;
int WINAPI Mine_DrawText(
__in HDC hDC,
__inout LPCTSTR lpchText,
__in int nCount,
__inout LPRECT lpRect,
__in UINT uFormat
)
{
OutputDebugString(TEXT("DrawText"));
OutputDebugString(lpchText);
return Real_DrawText(hDC, lpchText, nCount, lpRect, uFormat);
}
BOOL WINAPI Mine_TextOut(
__in HDC hdc,
__in int nXStart,
__in int nYStart,
__in LPCTSTR lpString,
__in int cbString
)
{
OutputDebugString(TEXT("TextOut"));
OutputDebugString(lpString);
return Real_TextOut(hdc, nXStart, nYStart, lpString, cbString);
}
int WINAPI Mine_DrawTextEx(
__in HDC hdc,
__inout LPTSTR lpchText,
__in int cchText,
__inout LPRECT lprc,
__in UINT dwDTFormat,
__in LPDRAWTEXTPARAMS lpDTParams
)
{
OutputDebugString(TEXT("DrawTextEx"));
OutputDebugString(lpchText);
return Real_DrawTextEx(hdc, lpchText, cchText, lprc, dwDTFormat, lpDTParams);
}
BOOL WINAPI Mine_ExtTextOut(
__in HDC hdc,
__in int X,
__in int Y,
__in UINT fuOptions,
__in const RECT *lprc,
__in LPCTSTR lpString,
__in UINT cbCount,
__in const INT *lpDx
)
{
OutputDebugString(TEXT("ExtTextOut"));
OutputDebugString(lpString);
return Real_ExtTextOut( hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx );
}
#define DLLEXPORT extern "C" __declspec(dllexport)
static DWORD dwTlsIndex; // address of shared memory
// Stores a DWORD in thread local storage
BOOL WINAPI StoreData(DWORD dw)
{
LPVOID lpvData;
DWORD * pData; // The stored memory pointer
lpvData = TlsGetValue(dwTlsIndex);
if (lpvData == NULL)
{
lpvData = (LPVOID) LocalAlloc(LPTR, 256);
if (lpvData == NULL)
return FALSE;
if (!TlsSetValue(dwTlsIndex, lpvData))
return FALSE;
}
pData = (DWORD *) lpvData; // Cast to my data type.
// In this example, it is only a pointer to a DWORD
// but it can be a structure pointer to contain more complicated data.
(*pData) = dw;
return TRUE;
}
// Retrieve a DWORD from thread local storage
BOOL WINAPI GetData(DWORD *pdw)
{
LPVOID lpvData;
DWORD * pData; // The stored memory pointer
lpvData = TlsGetValue(dwTlsIndex);
if (lpvData == NULL)
return FALSE;
pData = (DWORD *) lpvData;
(*pdw) = (*pData);
return TRUE;
}
DLLEXPORT LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0) {
return CallNextHookEx(0, nCode, wParam, lParam);
}
// Get a flag indicating if we're already detoured.
DWORD detoured=false;
GetData(&detoured);
// If the window is activating and we're not detoured...
if (nCode == HCBT_ACTIVATE && !detoured)
{
OutputDebugString(TEXT("CBTProc"));
HWND hWnd = (HWND)wParam;
// get window title
TCHAR szTemp[256];
int rc = GetWindowText(hWnd, szTemp, 255);
if (rc != 0)
{
OutputDebugString(szTemp);
// hook notepad functions.
if (_tcsstr(szTemp, TEXT("Notepad"))!=0)
{
OutputDebugString(TEXT("Detouring"));
HANDLE hThread = GetCurrentThread();
DetourTransactionBegin();
DetourUpdateThread(hThread);
DetourAttach(&(PVOID&)Real_DrawText, Mine_DrawText);
DetourAttach(&(PVOID&)Real_TextOut, Mine_TextOut);
DetourAttach(&(PVOID&)Real_DrawTextEx, Mine_DrawTextEx);
DetourAttach(&(PVOID&)Real_ExtTextOut, Mine_ExtTextOut);
DetourTransactionCommit();
StoreData(true);
}
}
}
return 0;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, // DLL module handle
DWORD fdwReason, // reason called
LPVOID lpvReserved) // reserved
{
LPVOID lpvData;
BOOL fIgnore;
switch (fdwReason)
{
// The DLL is loading due to process
// initialization or a call to LoadLibrary.
case DLL_PROCESS_ATTACH:
OutputDebugString(TEXT("DLL_PROCESS_ATTACH"));
// Allocate a TLS index.
if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
return FALSE;
// No break: Initialize the index for first thread.
// The attached process creates a new thread.
case DLL_THREAD_ATTACH:
OutputDebugString(TEXT("DLL_THREAD_ATTACH"));
// Initialize the TLS index for this thread.
lpvData = (LPVOID) LocalAlloc(LPTR, 256);
if (lpvData != NULL)
fIgnore = TlsSetValue(dwTlsIndex, lpvData);
break;
// The thread of the attached process terminates.
case DLL_THREAD_DETACH:
{
OutputDebugString(TEXT("DLL_THREAD_DETACH"));
DWORD detoured=false;
GetData(&detoured);
if(detoured)
{
OutputDebugString(TEXT("Un-Detouring"));
HANDLE hThread = GetCurrentThread();
DetourTransactionBegin();
DetourUpdateThread(hThread);
DetourDetach(&(PVOID&)Real_DrawText, Mine_DrawText);
DetourDetach(&(PVOID&)Real_TextOut, Mine_TextOut);
DetourDetach(&(PVOID&)Real_DrawTextEx, Mine_DrawTextEx);
DetourDetach(&(PVOID&)Real_ExtTextOut, Mine_ExtTextOut);
DetourTransactionCommit();
}
// Release the allocated memory for this thread.
lpvData = TlsGetValue(dwTlsIndex);
if (lpvData != NULL)
LocalFree((HLOCAL) lpvData);
break;
}
// DLL unload due to process termination or FreeLibrary.
case DLL_PROCESS_DETACH:
OutputDebugString(TEXT("DLL_PROCESS_DETACH"));
// Release the allocated memory for this thread.
lpvData = TlsGetValue(dwTlsIndex);
if (lpvData != NULL)
LocalFree((HLOCAL) lpvData);
// Release the TLS index.
TlsFree(dwTlsIndex);
break;
default:
break;
}
return TRUE;
}
int main(int argc, char* argv[])
{
HOOKPROC hkprcSysMsg;
HHOOK hhookSysMsg;
HINSTANCE dll = LoadLibrary(TEXT("t4.dll"));
hkprcSysMsg = (HOOKPROC)GetProcAddress(dll, "_CBTProc@12");
DWORD dw = GetLastError();
hhookSysMsg = SetWindowsHookEx(
WH_CBT,
hkprcSysMsg,
dll,
0);
int i;
std::cin >> i;
UnhookWindowsHookEx(hhookSysMsg);
}