win7(x64)环境hook IFileOperation的问题
DPCIP 2012-05-09 03:28:48 由于想监控程序自身目录不被删除,在网上搜索发现WIN7下资源管理器是调用IFileOperation,在CSDN又看到已有人实现,请想采用这一方法,但是目前代码只能实现HOOK DeleteItem,弹出对话框,但继续弹出确认是否删除对话框;如果加上HOOK DeleteItem,则没有任何反应。
代码如下:FOH.CPP
// foh.cpp : 定义 DLL 应用程序的导出函数。
//参考http://topic.csdn.net/u/20120131/11/10056e46-a565-4aa9-9c4e-5ecd84d0ced7.html进行的修改
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <winbase.h>
#include <ShellAPI.h>
#include <Shobjidl.h>
#include "foh.h"
#ifndef COM_HOOK_H
#define COM_HOOK_H
#define QueryInterface_Index 0
#define AddRef_Index (QueryInterface_Index + 1)
#define Release_Index (AddRef_Index + 1)
#define Advice_Index (Release_Index + 1)
#define Unadvise_Index (Advice_Index + 1)
#define SetOperationFlags_Index (Unadvise_Index + 1)
#define SetProgressMessage_Index (SetOperationFlags_Index + 1)
#define SetProgressDialog_Index (SetProgressMessage_Index + 1)
#define SetProperties_Index (SetProgressDialog_Index + 1)
#define SetOwnerWindow_Index (SetProperties_Index + 1)
#define ApplyPropertiesToItem_Index (SetOwnerWindow_Index + 1)
#define ApplyPropertiesToItems_Index (ApplyPropertiesToItem_Index + 1)
#define RenameItem_Index (ApplyPropertiesToItems_Index + 1)
#define RenameItems_Index (RenameItem_Index + 1)
#define MoveItem_Index (RenameItems_Index + 1)
#define MoveItems_Index (MoveItem_Index + 1)
#define CopyItem_Index (MoveItems_Index + 1)
#define CopyItems_Index (CopyItem_Index + 1)
#define DeleteItem_Index (CopyItems_Index + 1)
#define DeleteItems_Index (DeleteItem_Index + 1)
#define NewItem_Index (DeleteItems_Index + 1)
#define PerformOperations_Index (NewItem_Index + 1)
#define GetAnyOperationAborted_Index (PerformOperations_Index + 1)
#endif
#define HOOK(a, b) b##_old = (Real_Detour##b)HookVtbl(a, 0, b##_Index, (int)(PBYTE)New##b)
int HookVtbl(void* pObject, unsigned int classIdx, unsigned int methodIdx, int newMethod);
typedef void (WINAPI *pFunc)(VOID);
bool isHook=0;
typedef HRESULT (WINAPI* Real_DetourDeleteItem)(IShellItem *psiItem,IFileOperationProgressSink *pfopsItem);
static Real_DetourDeleteItem DeleteItem_old=NULL;
HRESULT WINAPI NewDeleteItem(IShellItem *psiItem,IFileOperationProgressSink *pfopsItem);
typedef HRESULT (WINAPI* Real_DetourDeleteItems)(IFileOperation * This,IUnknown *punkItems);
static Real_DetourDeleteItems DeleteItems_old=NULL;
HRESULT WINAPI NewDeleteItems(IFileOperation * This,IUnknown *punkItems);
HRESULT WINAPI NewDeleteItem(IShellItem *psiItem,IFileOperationProgressSink *pfopsItem)
{
::MessageBoxW(NULL,L"hellp world!",L"NewDeleteItem",MB_OK);
HRESULT hr=S_OK;
//hr=DeleteItem_old(psiItem,pfopsItem);
return hr;
}
HRESULT WINAPI NewDeleteItems(IFileOperation * This,IUnknown *punkItems)
{
::MessageBoxW(NULL,L"hellp world!",L"NewDeleteItems",MB_OK);
HRESULT hr=S_OK;
//hr=DeleteItems_old(This,punkItems);
return hr;
}
int HookVtbl(void* pObject, unsigned int classIdx, unsigned int methodIdx, int newMethod)
{
int** vtbl = (int**)pObject;
DWORD oldProtect = 0;
int oldMethod = vtbl[classIdx][methodIdx];
VirtualProtect(vtbl[classIdx] + sizeof(int*) * methodIdx, sizeof(int*), PAGE_READWRITE, &oldProtect);
vtbl[classIdx][methodIdx] = newMethod;
VirtualProtect(vtbl[classIdx] + sizeof(int*) * methodIdx, sizeof(int*), oldProtect, &oldProtect);
return oldMethod;
}
void SetHook(BOOL flag)
{
if(isHook==flag)
return;
if (flag)
{
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (SUCCEEDED(hr))
{
IFileOperation *pInterface=NULL;
hr = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_IFileOperation,(LPVOID FAR *)&pInterface);
if (SUCCEEDED(hr))
{
::MessageBox(NULL,"begin","FOH",MB_OK);
HOOK(pInterface,DeleteItem);
isHook=1;
}
}
}
else
{
isHook=0;
}
}
__declspec(dllexport) void myfun()
{
return;
}
///dllmain.cpp
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
SetHook(TRUE);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
SetHook(FALSE);
break;
}
return TRUE;
}