Hook SHFileOperation实现文件监控

// dllmain.cpp : DllMain 的实现。
CFileWatchDllModule _AtlModule;
 
//保存原函数的地址,对于不需要保护的程序,调用原函数
PVOID g_pOldSHFileOperationW=NULL;
PVOID g_pOldSHFileOperationA=NULL;
 
 
//  SHFileOperation 函数 win7以前系统删除文件均通过该函数
typedef int (WINAPI *PfuncOldSHFileOperationA)(LPSHFILEOPSTRUCTA lpFileOp);
typedef int (WINAPI *PfuncOldSHFileOperationW)(LPSHFILEOPSTRUCTW lpFileOp);
 
 
// 需要挂钩的程序
int WINAPI ZwNewSHFileOperationA(LPSHFILEOPSTRUCTA lpFileOp);
int WINAPI ZwNewSHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp);
 
 
 
int WINAPI ZwNewSHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
{
        //自己的拦截逻辑,直接拦截返回false ,否则返回原函数调用
return ((PfuncOldSHFileOperationW)g_pOldSHFileOperationW)(lpFileOp);//不是需要保护的文件 放行
}
 
 
 
int WINAPI ZwNewSHFileOperationA(LPSHFILEOPSTRUCTA lpFileOp)
{
        //自己的拦截逻辑,直接拦截返回false ,否则返回原函数调用
return ((PfuncOldSHFileOperationA)g_pOldSHFileOperationA)(lpFileOp);
}
 
//安装Hook
BOOL WINAPI SetHookOnSHFileOperation()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());//得到当前线程
g_pOldSHFileOperationW=DetourFindFunction("shell32.dll","SHFileOperationW");//查询函数地址
g_pOldSHFileOperationA=DetourFindFunction("shell32.dll","SHFileOperationA");
DetourAttach(&g_pOldSHFileOperationW, ZwNewSHFileOperationW);//挂钩函数
DetourAttach(&g_pOldSHFileOperationA, ZwNewSHFileOperationA);
LONG ret=DetourTransactionCommit();//提交更改
return ret==NO_ERROR;
}
 
//卸载Hook
BOOL WINAPI DropHookOnSHFileOperation()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&g_pOldSHFileOperationW, ZwNewSHFileOperationW);
DetourDetach(&g_pOldSHFileOperationA, ZwNewSHFileOperationA);
LONG ret=DetourTransactionCommit();
return ret==NO_ERROR;
}
 
 
static HMODULE s_hDll;
 
HMODULE WINAPI Detoured()
{
return s_hDll;
}
 
 
// DLL 入口点
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
(void)lpReserved;
switch(dwReason) 
{
case DLL_PROCESS_ATTACH:
s_hDll = hInstance;
DisableThreadLibraryCalls(hInstance);
SetHookOnSHFileOperation();//HOOK
break;
case DLL_THREAD_ATTACH:
break;
case DLL_PROCESS_DETACH:
DropHookOnSHFileOperation();//UNHOOK
break;
case DLL_THREAD_DETACH:
break;
}
return _AtlModule.DllMain(dwReason, lpReserved); 
}

下面以2003的服务器来实验
将原程序编译为dll文件 我的编译出来是FileWatchDll.dll

cmd 运行regedit

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows

AppInit_DLLs=改为(dll文件所在路径)\FileWatchDll.dll,所有进程加载时预先加载这个dll

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows

LoadAppInit_DLLs=1  是否(1/0)加载AppInit_DLLs中设置的dll


重新器动后,当删除受监控的文件时弹出警告框,然后无法删除该文件

发表评论

邮箱地址不会被公开。 必填项已用*标注