| 网站首页 | 资讯 | Hack | 漏洞 | 网管 | 编程 | 培训 | 品黑页 | 软件 | 论坛 | 动画 | 视频 | 经典 | 教学站 | 黑客点睛 | 
服务导航 我要发布 主力频道 空间域名 精华收集 服务器出租 黑客培训 光盘刻录 特色服务 解决方案 我要投诉
您现在的位置: 华夏黑客同盟 >> 编程 >> Vc >> 正文 用户登录 新用户注册
用拷贝钩子实现对文件夹的监控           ★★★ 【字体:
用拷贝钩子实现对文件夹的监控
作者:未知 文章来源:华盟收集 点击数: 更新时间:2007-7-29
ICopyHook是一个用于创建拷贝钩子处理程序COM接口,它决定一个文件夹或者打印机对象是否可以被移动,拷贝,重命名或删除。Shell在执行这些操作之前,会调用ICopyHook接口的CopyCallback方法对它们进行验证。CopyCallback返回一个int值指示Shell是否应该继续执行这个操作。返回值IDYES表示继续,而返回值IDNO和IDCANCEL则表示终止。
一个文件夹对象可以安装多个拷贝钩子处理程序。如果出现这种情况,Shell会依次调用每个处理程序。只有当每个处理程序都返回IDYES时,Shell才真正执行用户请求的操作。
拷贝钩子处理程序的作用是在上述四种操作执行前对它们进行验证,但是Shell并不会把操作的结果通知给拷贝钩子处理程序。而windows提供的API函数FindFirstChangeNotification和FindNextChangeNotification却可以实现这个功能。因此,只有把这种两种方法结合起来,才能对一个文件夹的状态进行完全的监控。
拷贝钩子处理程序实现并不困难,首先创建一个作为进程内组件的COM对象,它只需要暴露一个ICopyHook接口(当然还有IUnknown)。然后用regsrv32.exe注册这个COM组件。最后一步是向Shell注册你的这个拷贝钩子处理程序,方法是在注册表HKEY_CLASSES_ROOT\Directory\Shellex\CopyHookHandlers下创建一个名称任意的sub key,在此sub key中创建一个类型为REG_SZ的项并将你的COM对象的CLSID作为它的默认值就可以了。
下面就是一个拷贝钩子的实现程序
 
// CCopyHook.h 
//CCopyHook类实现了ICopyHook接口,CClassFactory实现了IClassFactory接口
#include <shlobj.h>
class CCopyHook: public ICopyHook
{
public:
            CCopyHook():m_refcnt(0) { }
            STDMETHODIMP QueryInterface(REFIID iid,void** ppvObject);
            STDMETHODIMP_(ULONG) AddRef();
            STDMETHODIMP_(ULONG) Release();
            STDMETHODIMP_(UINT) CopyCallback(HWND hwnd,UINT wFunc,UINT wFlags,
                                                     LPCTSTR pszSrcFile,DWORD dwSrcAttribs,
                                                     LPCTSTR pszDestFile,DWORD dwDestAttribs);
private:
            int m_refcnt;
};
class CClassFactory:public IClassFactory
{
public:
            CClassFactory():m_refcnt(0) {   }
            STDMETHODIMP QueryInterface(REFIID iid,void** ppvObject);
            STDMETHODIMP_(ULONG) AddRef();
            STDMETHODIMP_(ULONG) Release();
            STDMETHODIMP CreateInstance(IUnknown * pUnkOuter,REFIID riid,void ** ppvObject);
            STDMETHODIMP LockServer(BOOL fLock);
private:
            int m_refcnt;
};
 
// CCopyHook.cpp
//CCopyHook对象和CClassFactory对象的实现文件
#include <stdio.h>
#include "CCopyHook.h"
 
extern LONG nLocks;          //对象计数,用于DllCanUnloadNow
 
ULONG __stdcall CCopyHook::AddRef(){
            if(m_refcnt==0)
                        nLocks++;
            m_refcnt++;
            return m_refcnt;
}
ULONG __stdcall CCopyHook::Release(){
            int nNewCnt=--m_refcnt;
            if(nNewCnt<=0){
                        nLocks--;
                        delete this;
            }
            return nNewCnt;
}
HRESULT __stdcall CCopyHook::QueryInterface(REFIID iid,void** ppvObject){
            if(iid==IID_IUnknown)
                        *ppvObject=static_cast<IUnknown*>(this);
            else
                        if(iid==IID_IShellCopyHook)
                            *ppvObject=static_cast<ICopyHook*>(this);
            else
                         return E_NOINTERFACE;
            reinterpret_cast<IUnknown*>(*ppvObject)->AddRef();
            return S_OK;
}
//这就是CopyCallback方法,拷贝钩子的所有功能由它实现。参数的具体值参看MSDN
UINT __stdcall CCopyHook::CopyCallback(HWND hwnd,UINT wFunc,UINT wFlags,
                                                     LPCTSTR pszSrcFile,DWORD dwSrcAttribs,
                                                     LPCTSTR pszDestFile,DWORD dwDestAttribs){
            char szMessage[MAX_PATH+14];
            sprintf(szMessage,"对%s进行的操作,是否继续?",pszSrcFile);
            return MessageBox(NULL,szMessage,"确认",MB_YESNO|MB_ICONEXCLAMATION);
}
ULONG __stdcall CClassFactory::AddRef(){
            if(m_refcnt==0)
                        nLocks++;
            m_refcnt++;
            return m_refcnt;
}
ULONG __stdcall CClassFactory::Release(){
            int nNewCnt=--m_refcnt;
            if(nNewCnt<=0){
                        nLocks--;
                        delete this;
            }
            return nNewCnt;
}
HRESULT __stdcall CClassFactory::QueryInterface(REFIID iid,void** ppvObject){
            if(iid==IID_IUnknown)
                        *ppvObject=static_cast<IUnknown*>(this);
            else
                        if(iid==IID_IClassFactory)
                            *ppvObject=static_cast<IClassFactory*>(this);
            else
                         return E_NOINTERFACE;
            reinterpret_cast<IUnknown*>(*ppvObject)->AddRef();
            return S_OK;
}
HRESULT __stdcall CClassFactory::CreateInstance(IUnknown* pUnkownOuter,REFIID riid,void** ppvObj){
            if(pUnkownOuter!=NULL)
                        return CLASS_E_NOAGGREGATION;
            CCopyHook* pObj=new CCopyHook;
            pObj->AddRef();
            HRESULT hr=pObj->QueryInterface(riid,ppvObj);
    pObj->Release();
            return hr;
}
HRESULT __stdcall CClassFactory::LockServer(BOOL fLock){
            if(fLock)
                nLocks++;
            else
                        nLocks--;
            return S_OK;
}
// main.cpp
//主要实现了几个COM对象标准的导出函数。
#include <objbase.h>
#include <olectl.h>
#include "CCopyHook.h"
 
//这是要添加到注册表中的项,注意如果你要使用这段代码,应该用UUIDGEN.exe生成一
//个新的CLSID。
const char* szRegTable[][3]={
{"CLSID\\{7e10a039-fe03-4f9c-b7e1-c5eeeaf53735}",0,"CopyHook"},
{"CLSID\\{7e10a039-fe03-4f9c-b7e1-c5eeeaf53735}\\InProcServer32",0,(const char*)-1},
{"CLSID\\{7e10a039-fe03-4f9c-b7e1-c5eeeaf53735}\\InProcServer32","ThreadingModel","Apartment"},
{"CLSID\\{7e10a039-fe03-4f9c-b7e1-c5eeeaf53735}\\ProgID",0,"webber84.CopyHook.1"},
{"webber84.CopyHook.1",0,"CopyHook"},
{"webber84.CopyHook.1\\CLSID",0,"{7e10a039-fe03-4f9c-b7e1-c5eeeaf53735}"}};
HMODULE hInstance=NULL;
LONG nLocks=0;
BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD ul_reason_for_call,
                       LPVOID lpReserved
                                                             ){
            if(ul_reason_for_call==DLL_PROCESS_ATTACH)
                        hInstance=(HMODULE)hModule;
    return TRUE;
}
STDAPI DllUnregisterServer(){
            HRESULT hr=S_OK;         LONG ret=0;
            int items=sizeof(szRegTable)/sizeof(szRegTable[0]);
            for(int i=items-1;i>=0;i--){
                        const char* szKeyName=szRegTable[i][0];
                        if( (i==items-1) || stricmp(szRegTable[i+1][0],szKeyName)!=0)
                             ret=RegDeleteKey(HKEY_CLASSES_ROOT,szKeyName);
        if(ret!=ERROR_SUCCESS)
                                    hr=SELFREG_E_CLASS;
            }
            return hr;
}
//可重用的DllRegisterServer函数,只要照上面的格式把注册表项放到一个数组中,就可以//用这段代码完成对任意组件的注册。
STDAPI DllRegisterServer(void){
            HRESULT hr=S_OK;
            int items=sizeof(szRegTable)/sizeof(szRegTable[0]);
            char szDllPath[MAX_PATH];
            GetModuleFileName(hInstance,szDllPath,MAX_PATH);
            for(int i=0;i<items && SUCCEEDED(hr);i++){
                        const char* szKeyName=szRegTable[i][0];
                        const char* szValueName=szRegTable[i][1];
                        const char* szValue=szRegTable[i][2];
                        if(szValue==(const char*)-1)
                                    szValue=szDllPath;
                        HKEY hKey;
                        LONG ret=RegCreateKey(HKEY_CLASSES_ROOT,szKeyName,&hKey);
                        if(ret==ERROR_SUCCESS){
                                    RegSetValueEx(hKey,szValueName,0,REG_SZ,(const BYTE*)szValue,
strlen(szValue)+1);
                                    RegCloseKey(hKey);
                        }
                        if(ret!=ERROR_SUCCESS){
                                    hr=SELFREG_E_CLASS;
                                    DllUnregisterServer();
                        }
            }
            return hr;
}
STDAPI DllGetClassObject (REFCLSID rclsid, REFIID riid, void** ppvObj) {
    HRESULT hr = E_OUTOFMEMORY;
    *ppvObj = NULL;
    CClassFactory *pClassFactory = new CClassFactory;
    if (pClassFactory != NULL)
        hr = pClassFactory->QueryInterface(riid, ppvObj);
    return hr;
}
STDAPI DllCanUnloadNow(){
            return nLocks==0 ? S_OK : S_FALSE;
}
责任编辑:华夏编辑6  联系方式  Email:华夏编辑6
电话:51228163
  • 上一篇编程:

  • 下一篇编程:
  • (只显示最新5条。评论内容只代表网友观点,与本站立场无关!)
    姓 名:
    * 游客填写  ·注册用户
    主 页:
    评 分:
    1分 2分 3分 4分 5分
    评论内容:
    验证码: *
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  • 最新hack更新
    最新推荐资讯
    相关编程
    简单监控文件挂马程序
    一个用VB编写的监控别人上网的软
    一个用VB编写的监控别人上网的软
    一个用VB编写的监控别人上网的软
    WINDOWS钩子函数-黑客编程
    编写后台监控软件的技巧
    学习如何编制WINDOWS系统下的钩子
    钩子注入程序
    键盘钩子程序源代码的详解
    实时的监控一个目录
    最新会员软件
    最新推荐视频
    最新推荐动画

    Copyright @ 2005 77169.Net Inc. All rights reserved. 华夏黑客同盟 版权所有
    北京市电信通提供网络带宽

    mailto:webmaster@77169.net
    咨询QQ号:836982 / 59280880
    联系站长 QQ38588913
    热线电话: 86-10-67634029/676229433
    京ICP证041431号