现在的位置: 首页 > 综合 > 正文

Hook SHFileOperation实现文件监控

2013年04月14日 ⁄ 综合 ⁄ 共 2501字 ⁄ 字号 评论关闭

转载注明出处

http://blog.csdn.net/xugangjava/article/details/6750536

比较简单直接源代码加注释

// 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

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

(在2003更高版本中用这种方法会蓝屏的,因为文件操作的方法改为了com里面的方法)

附源代码:

http://download.csdn.net/detail/xugangjava/4047216

抱歉!评论已关闭.