编译detour:
下载Detours Express 2.1并安装后,可以在下面的地址找到:
C:Program FilesMicrosoft ResearchDetours Express 2.1src
不过只是源码,没有现成的lib和dll。需要自己编译。
编译很简单,只要运行cmd,在dos窗口里面运行:
------------
cd "C:Program FilesMicrosoft ResearchDetours Express 2.1"
nmake
------------
不过会报下面的错误:
---------------
detoured.rc(10) : fatal error RC1015: cannot open include file 'winver.h'.
NMAKE : fatal error U1077: “"C:Program FilesMicrosoft Visual Studio 8VCbin
rc.EXE"”: 返回代码“0x1”
Stop.
NMAKE : fatal error U1077: “"C:Program FilesMicrosoft Visual Studio 8VCbin
nmake.exe"”: 返回代码“0x2”
Stop.
---------------
只要在运行nmake前先运行一下面这句就不会报错了。
"C:Program FilesMicrosoft Visual Studio 8VCvcvarsall.bat"
即:
------------
cd "C:Program FilesMicrosoft ResearchDetours Express 2.1"
"C:Program FilesMicrosoft Visual Studio 8VCvcvarsall.bat"
nmake
------------
编译大约需要一到两分钟。
我暂时只用到了samples里面的withdll。
下面是withdll.exe的简单介绍。
withdll可以用来根据函数名称替换一个dll中的函数。
并且可以在新的函数中调用回老的函数。
命令行执行:
withdll /d:你写好的dll名称 要attach到的主程序名称
具体用法请参考下文以及参考资料中的内容。
<code>typedef struct _tagREPFUNC
{
const char* pcszName;
void* pfnNewFunc;
void* pfnOldFunc;
} REPFUNC;
REPFUNC RepFuncList[] = {
{"要替换的函数的名字", 你定义的新函数名, 用来存放原函数},
{NULL,NULL,NULL}
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{
g_RepFuncList = (REPFUNC*)RepFuncList;
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourSetIgnoreTooSmall(TRUE);
for (int i=0; NULL!=RepFuncList[i].pcszName ;i++)
{
RepFuncList[i].pfnOldFunc = DetourFindFunction("目标dll名。不用写完整路径。",
RepFuncList[i].pcszName);
if ( NULL==RepFuncList[i].pfnOldFunc )
{
continue;
}
//下面是用你定义的新的函数替换了老的函数,并在替换后把老的函数的地址改变了。
//可以用改变后的地址调用老的函数。
DetourAttach(&RepFuncList[i].pfnOldFunc, RepFuncList[i].pfnNewFunc);
}
DetourTransactionCommit();
}
return TRUE;
}</code>
要注意函数调用约定新旧要完全一致,就是老的函数如果用的是__stdcall,
新的也一定要用__stdcall。
还要注意的一点是你写的dll要有一个def文件如下:
<code>LIBRARY "你的library名称"
EXPORTS
DllMain @1</code>
注意到上面的@。这里是控制导出的名称按序数排列
(Exporting Functions from a DLL by Ordinal Rather Than by Name)。
必须这样,不然withdll会报下列错误:
withdll.exe: Error: %s does not export function with ordinal #1.
参考资料:
<a href="http://hi.baidu.com/lff0305/blog/item/663e133ba693c8e015cecbb2.html">使用Detour库来实现.DLL中函数替换</a>