一.遇见的问题
项目detours使用2.1版本
project->settings->general 设置为use mfc in a library
在win32 console application建项目可能用到了mfc东西,自然要加点东西
1
Linking...
nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in libcpmtd.lib(delop.obj)
Debug/detours.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.
detours.exe - 2 error(s), 0 warning(s)
解决方法:
VC6 各link错误解决
错误1:
LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
在project-setting-link里找到project options 去掉里面的/subsystem:console
错误2:
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endt...
将工程设置为Using MFC in a static library
错误3:
libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
在project-setting-link里找到project options 将里面的/subsystem:console 改为/subsystem:windows
3..如果是 dll的动态链接库工程报
e:\学习\c++程序\hd\detours.h(20) : error C2146: syntax error : missing ';' before identifier 'ULONG_PTR'
e:\学习\c++程序\hd\detours.h(20) : fatal error C1004: unexpected end of file found
解决:在#include "detours.h" 前加上一句#include <windows.h> 或 "#include <afxwin.h>
二 编译连接,编译detours
vc2003编译的lib不能用于vc6
你要在vc6中使用可以在vc6的命令行下编译再cd到你的Detours的src目录执行nmake即可。
例子代码
#include "stdafx.h" #include "DetourHook.h" #include <detours.h> #pragma comment(lib, "detours.lib") #pragma comment(lib, "detoured.lib") static int (WINAPI* OLD_MessageBoxW)(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType)=MessageBoxW; int WINAPI NEW_MessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType) { //修改输入参数,调用原函数 int ret=OLD_MessageBoxW(hWnd,L"输入参数已修改",L"[测试]",uType); return ret; } VOID Hook() { DetourRestoreAfterWith(); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); //这里可以连续多次调用DetourAttach,表明HOOK多个函数 DetourAttach(&(PVOID&)OLD_MessageBoxW,NEW_MessageBoxW); DetourTransactionCommit(); } VOID UnHook() { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); //这里可以连续多次调用DetourDetach,表明撤销多个函数HOOK DetourDetach(&(PVOID&)OLD_MessageBoxW,NEW_MessageBoxW); DetourTransactionCommit(); } int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { MessageBoxW(0,L"正常消息框",L"测试",0); Hook(); MessageBoxW(0,L"正常消息框",L"测试",0); UnHook(); return 0; }
补充连接http://www.cnitblog.com/cc682/archive/2009/05/28/58883.html
http://blog.csdn.net/zhsp1029/article/details/4195139
补充:全局拦截函数
main.cpp
#include <Windows.h> void main(){ HMODULE hDll = NULL; if (hDll==NULL) { hDll=LoadLibrary("DLL.dll"); } MessageBox(0,"testhook","測試start",0); }
dll.dll
#include "stdafx.h" #include "detours.h" #include <Winsock2.h> #pragma comment(lib, "Ws2_32.lib") #pragma comment(lib, "detours.lib") #pragma comment(lib, "detoured.lib") VOID UnHook(); HANDLE m_hModule=0; //static int (WINAPI* OLD_MessageBoxW)(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType)=MessageBoxW; static SOCKET (WINAPI* OLD_MessageBox)(int af,int type,int protocol)=socket; //static int (WINAPI* pSend)(SOCKET s, const char* buf, int len, int flags)=send; //int WINAPI NEW_MessageBox(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType) int WINAPI NEW_MessageBox(int af,int type,int protocol) { //修改?入参数,?用原函数 int ret=MessageBoxW(NULL,L"輸入参数已修改",L"[測試]",MB_OK); UnHook(); return ret; } VOID Hook() { DetourRestoreAfterWith(); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); //?里可以??多次?用DetourAttach,表明HOOK多个函数 DetourAttach(&(PVOID&)OLD_MessageBox,NEW_MessageBox); DetourTransactionCommit(); } VOID UnHook() { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); //?里可以??多次?用DetourDetach,表明撤?多个函数HOOK DetourDetach(&(PVOID&)OLD_MessageBox,NEW_MessageBox); DetourTransactionCommit(); } LRESULT CALLBACK CBTProc( int nCode, // hook code WPARAM wParam, // depends on hook code LPARAM lParam // depends on hook code ){ //MessageBox(0,"進入鉤子","測試",0); return CallNextHookEx((HHOOK)m_hModule,nCode,wParam,lParam); } // int APIENTRY _tWinMain(HINSTANCE hInstance, // HINSTANCE hPrevInstance, // LPTSTR lpCmdLine, // int nCmdShow) // { // // MessageBoxW(0,L"正常消息框",L"測試",0); // Hook(); // // MessageBoxW(0,L"正常消息框",L"測試",0); // // UnHook(); // // MessageBoxW(0,L"正常消息框",L"測試",0); // //send(socket()) // //HHOOK hhk=SetWindowsHookEx(WH_CBT,CBTProc,0,0); // //CallNextHookEx(hhk,WH_CBT,0,0); // int i=0; // // while (true) // // { // // if (i==300) // // { // // MessageBoxW(0,L"準備進入鉤子",L"測試",0); // // } // // i++; // // } // return 0; // // } BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: m_hModule=hModule; SetWindowsHookEx(WH_CBT,(HOOKPROC)CBTProc,(HINSTANCE)m_hModule,0); Hook(); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: //UnhookWindowsHookEx((HHOOK)m_hModule); UnHook(); break; } return TRUE; }
SetWindowsHookEx(WH_CBT,(HOOKPROC)CBTProc,(HINSTANCE)m_hModule,0);
和
UnhookWindowsHookEx((HHOOK)m_hModule);最好写在main函数中