我正在使用MS Detours挂钩FindNextFile()
。我已成功配置Detours库并编写了一个名为“Detuors.dll”的DLL和一个名为“FNFSend.exe”的应用程序。以下是代码:
DLL:
#include <cstdio>
#include <stdio.h>
#include <windows.h>
#include "detours.h"
#pragma comment (lib,"detours.lib")
//Prototypes
extern "C" __declspec(dllexport) BOOL (WINAPI *pFNF)(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData) = FindNextFile;
extern "C" __declspec(dllexport) BOOL WINAPI MyFNF(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData);
//Log File
FILE* pFNFLogFile;
int counter = 0;
INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
switch(Reason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hDLL);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)pFNF, MyFNF);
if(DetourTransactionCommit() == NO_ERROR)
OutputDebugString("FNF() detoured successfully");
else
OutputDebugString("FNF() not detoured");
break;
case DLL_PROCESS_DETACH:
DetourTransactionBegin(); //Detach
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)pFNF, MyFNF);
DetourTransactionCommit();
break;
case DLL_THREAD_ATTACH:
DisableThreadLibraryCalls(hDLL);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)pFNF, MyFNF);
if(DetourTransactionCommit() == NO_ERROR)
OutputDebugString("FNF() detoured successfully");
else
OutputDebugString("FNF() not detoured");
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
//Open file, write contents, close it
extern "C" __declspec(dllexport) int WINAPI MyFNF(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)
{
counter ++;
fopen_s(&pFNFLogFile, "C:\\FNFLog.txt", "a+");
fprintf(pFNFLogFile, "%s\n", counter);
fclose(pFNFLogFile);
return pFNF(hFindFile, lpFindFileData);
}
两个代码编译成功且没有错误。应用程序递归调用FindNextFile()
并且dll将其挂钩并将计数器写入文件。
然后我使用了由detours库本身提供的名为“withdll.exe”的工具来创建一个注入了dll的进程。所以我使用命令将我的dll注入应用程序:
withdll /d:Detuors.dll“C:\ FNFSend.exe”
注入后,该函数被成功挂钩,即文件在dirctory中生成但突然应用程序崩溃。在visual studio中调试之后,我在“output.c”中看到了异常,如下所示:
Unhandled exception at 0x6265984f (msvcr90d.dll) in FNFSend.exe: 0xC0000005:
Access violation reading location 0x00000001.
请帮助纠正问题。
答案 0 :(得分:1)
%s
不是用于打印数字的有效format string。请改用%d
。
通过指定%s
,您告诉fprintf
将地址counter
的内存读取为字符串。您尝试拨打fprintf
的第一个值为1,这就是地址0x00000001
存在访问冲突的原因。