如何hook到拷贝文件的操作???急急!!

xiaoxx 2003-09-24 08:49:50
是这样的,我想在程序中hook到文件拷贝的操作,这样接下来接管
文件操作的过程,控制是否容许对文件的操作,这该如何实现??
是否要hook windows的 api,是的话应该hook哪几个?如何hook?
多谢各位兄弟了!
...全文
229 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
mint 2003-09-27
  • 打赏
  • 举报
回复
api hook ,请看程序员2002年第2期(好象是,翻下合定本吧),此文章是翻译的,原文内容相当清楚.
xiaoxx 2003-09-26
  • 打赏
  • 举报
回复
mint:十分感谢你,能不能介绍一个hook api。
因为我还要处理这个问题,就是接管文件打开的操作,我接下来做相映操作,比如加解密。
谢了
NowCan 2003-09-26
  • 打赏
  • 举报
回复
收下了。
mint 2003-09-25
  • 打赏
  • 举报
回复
呵呵,以上是我借花而已
mint 2003-09-25
  • 打赏
  • 举报
回复
DEFINE_GUID( CLSID_CopyHook, 0xebf1799aL, 0x3e97, 0x493a, 0x91, 0x1d, 0xac, 0x93, 0xe2, 0xf6, 0xe7, 0x61 );

class CCopyHook : public ICopyHook,
IShellExtInit
{
protected:
ULONG m_cRef;
LPDATAOBJECT m_pDataObj;

public:
CCopyHook();
virtual ~CCopyHook();

//IUnknown members
STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();

//IShellExtInit methods
STDMETHODIMP Initialize(LPCITEMIDLIST pIDFolder,
LPDATAOBJECT pDataObj,
HKEY hKeyID);

//ICopyHook method
STDMETHODIMP_(UINT) CopyCallback(HWND hwnd,
UINT wFunc,
UINT wFlags,
LPCSTR pszSrcFile,
DWORD dwSrcAttribs,
LPCSTR pszDestFile,
DWORD dwDestAttribs);

};

class CCopyHookClassFactory : public IClassFactory
{
protected:
ULONG m_cRef;

public:
CCopyHookClassFactory();
virtual ~CCopyHookClassFactory();

//IUnknown members
STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();

//IClassFactory members
STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID FAR *);
STDMETHODIMP LockServer(BOOL);

};



#define INITGUID
#include <initguid.h>
#include <shlguid.h>
#include "CopyHook.h"
#pragma data_seg()

// Dll's Global variables
UINT g_nDllRefCount = 0; // Reference count of this DLL
HINSTANCE g_hThisDll = NULL; // Handle to this DLL

extern "C" int APIENTRY DllMain(HINSTANCE hInstance,
DWORD dwReason,
LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// Extension DLL one-time initialization
g_hThisDll = hInstance;
}

return 1; // ok
}

STDAPI DllCanUnloadNow(void)
{
if ( g_nDllRefCount == 0 )
return S_OK;
else
return S_FALSE;
}

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut)
{
CCopyHookClassFactory *pcf;

*ppvOut = NULL;
if (IsEqualIID(rclsid, CLSID_CopyHook))
{
pcf = new CCopyHookClassFactory;
return pcf->QueryInterface(riid, ppvOut);
}

return CLASS_E_CLASSNOTAVAILABLE;
}



////////////////////////////////////////
// -------- CCopyHookClassFactory ------
////////////////////////////////////////
CCopyHookClassFactory::CCopyHookClassFactory()
{
m_cRef = 0L;
g_nDllRefCount++;
}

CCopyHookClassFactory::~CCopyHookClassFactory()
{
g_nDllRefCount--;
}

STDMETHODIMP CCopyHookClassFactory::QueryInterface(REFIID riid,
LPVOID FAR *ppv)
{
*ppv = NULL;

// note: Any interface on this object is the object pointer
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
{
*ppv = (LPCLASSFACTORY)this;
AddRef();
return NOERROR;
}

return E_NOINTERFACE;
}

STDMETHODIMP_(ULONG) CCopyHookClassFactory::AddRef()
{
return ++m_cRef;
}

STDMETHODIMP_(ULONG) CCopyHookClassFactory::Release()
{
if (--m_cRef)
return m_cRef;

delete this;
return 0L;
}

STDMETHODIMP CCopyHookClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
REFIID riid,
LPVOID *ppvObj)
{
*ppvObj = NULL;

// don't support aggregation
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;

CCopyHook *pCopyHook = new CCopyHook();
if (NULL == pCopyHook)
return E_OUTOFMEMORY;

return pCopyHook->QueryInterface(riid, ppvObj);
}


STDMETHODIMP CCopyHookClassFactory::LockServer(BOOL fLock)
{
return NOERROR;
}






//////////////////////////////////////////
// ----------- CCopyHook ----------------
//////////////////////////////////////////
CCopyHook::CCopyHook()
{
m_cRef = 0L;
m_pDataObj = NULL;

g_nDllRefCount++;
}

CCopyHook::~CCopyHook()
{
if (m_pDataObj)
m_pDataObj->Release();

g_nDllRefCount--;
}

STDMETHODIMP CCopyHook::QueryInterface(REFIID riid, LPVOID FAR *ppv)
{
*ppv = NULL;

if ( IsEqualIID(riid, IID_IShellExtInit) || IsEqualIID(riid, IID_IUnknown) )
{
*ppv = (LPSHELLEXTINIT)this;
}
else if (IsEqualIID(riid, IID_IShellCopyHook))
{
*ppv = (LPCOPYHOOK)this;
}

if (*ppv)
{
AddRef();
return NOERROR;
}

return E_NOINTERFACE;
}

STDMETHODIMP_(ULONG) CCopyHook::AddRef()
{
return ++m_cRef;
}

STDMETHODIMP_(ULONG) CCopyHook::Release()
{
if (--m_cRef)
return m_cRef;

delete this;
return 0L;
}

STDMETHODIMP CCopyHook::Initialize(LPCITEMIDLIST pIDFolder,
LPDATAOBJECT pDataObj,
HKEY hRegKey)
{
// Initialize can be called more than once
if (m_pDataObj)
m_pDataObj->Release();

// duplicate the object pointer and registry handle
if (pDataObj)
{
m_pDataObj = pDataObj;
pDataObj->AddRef();
}

return NOERROR;
}

STDMETHODIMP_(UINT) CCopyHook::CopyCallback(HWND hwnd,
UINT wFunc,
UINT wFlags,
LPCSTR pszSrcFile,
DWORD dwSrcAttribs,
LPCSTR pszDestFile,
DWORD dwDestAttribs)
{

// int ret;

// ret = MessageBox( NULL, "Are you sure?",
// "CopyHook Sample", MB_YESNOCANCEL | MB_ICONQUESTION );
return IDCANCEL;
}
mint 2003-09-25
  • 打赏
  • 举报
回复
两种方案!
1.api hook ,难度大.
2.外壳扩展,难度小点.

Windows外壳扩展是这样实现的。首先要编写外壳扩展程序,一个外壳扩展程序是基于COM(Component Object Model)组件模型的。外壳是通过接口(Interface)来访问对象的。外壳扩展被设计成32位的进程中服务器程序,并且都是以动态链接库的形式为操作系统提供服务的。

写好外壳扩展程序后,必须将它们注册才能生效。所有的外壳扩展都必须在Windows注册表的HKEY_CLASSES_ROOT\CLSID键之下进行注册。在该键下面可以找到许多名字像{ACDE002F-0000-0000-C000-000000000046}的键,这类键就是全局唯一类标识符。每一个外壳扩展都必须有一个全局唯一类标识符,Windows正是通过此唯一类标识符来找到外壳扩展处理程序的。在类标识符之下的InProcServer32子键下记录着外壳扩展动态链接库在系统中的位置。



Windows系统支持以下7类的外壳扩展功能:

(1)Context menu handlers向特定类型的文件对象增添上下文相关菜单;

(2)Drag-and-drop handlers用来支持当用户对某种类型的文件对象进行拖放操作时的OLE数据传输;

(3)Icon handlers用来向某个文件对象提供一个特有的图标,也可以给某一类文件对象指定图标;

(4)Property sheet handlers给文件对象增添属性页,属性页可以为同一类文件对象所共有,也可以给一个文件对象指定特有的属性页;

(5)Copy-hook handlers在文件夹对象或者打印机对象被拷贝、移动、删除和重命名时,就会被系统调用,通过为Windows增加Copy-hook handlers,可以允许或者禁止其中的某些操作;

(6)Drop target handlers在一个对象被拖放到另一个对象上时,就会被系统被调用;

(7)Data object handlers在文件被拖放、拷贝或者粘贴时,就会被系统被调用。
文件夹保护功能就是通过上面的第5类,既Copy-hook handlers来实现的。一个支持Copy-hook handlers的程序除了上面提到的要在注册表的HKEY_CLASSES_ROOT\CLSID下注册之外,还需要在HKEY_CLASSES_ROOT\Directory\shellex\CopyHookHandlers\下注册服务器程序的类。

由于Windows外壳服务器程序是基于COM组件模型的,所以编写外壳程序就是构造一个COM对象的过程.
利用Delphi编写Copy-hook handle需要实现ICopyHook接口。ICopyHook是一个十分简单的接口,要实现的只有CopyCallBack方法。ICopyHook的CopyCallBack方法的定义如下:

UINT CopyCallback(

HWND hwnd, file://Handle of the parent window for displaying UI objects

UINT wFunc, file://Operation to perform.

UINT wFlags, file://Flags that control the operation

LPCSTR pszSrcFile, file://Pointer to the source file

DWORD dwSrcAttribs, file://Source file attributes

LPCSTR pszDestFile, file://Pointer to the destination file

DWORD dwDestAttribs file://Destination file attributes

);

其中的参数hwnd是一个窗口句柄,Copy-hook handle以此为父窗口。参数wFunc指定要被执行的操作,其取值为下表中所列之一:

常量 取值 含义

FO_COPY $2 复制由pszSrcFile指定的文件到由pszDestFile指定的位置。

FO_DELETE $3 删除由pszSrcFile指定的文件。

FO_MOVE $1 移动由pszSrcFile指定的文件到由pszDestFile指定的位置。

FO_RENAME $4 重命名由pszSrcFile指定的文件到由pszDestFile指定的文件名。

PO_DELETE $13 删除pszSrcFile指定的打印机。

PO_PORTCHANGE $20 改变打印机端口。PszSrcFile和pszDestFile为两个以Null结尾的字符串,分别指定当前和新的打印机端口名。

PO_RENAME $14 重命名由pszSrcFile指定的打印机端口。

PO_REN_PORT $34 PO_RENAME和PO_PORTCHANGE的组合。



参数wFlags指定操作的标志;参数pszSrcFile和pszDestFile指定源文件夹和目标文件夹。参数dwSrcAttribs和dwDesAttribs指定源文件夹和目标文件夹的属性。函数返回值可以为IDYES、IDNO和IDCANCEL。分别指示Windows外壳允许操作、阻止操作,但是其他操作继续、阻止当前操作,取消为执行的操作。



fbmsf 2003-09-24
  • 打赏
  • 举报
回复
知道点大概

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧