一.遇见的问题
项目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)
解决方法:
2.
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的命令行下编译开一个cmd,执行c:\...vc98\bin\vcvars32.bat
再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.youkuaiyun.com/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函数中