通过安装系统钩子来实现文件防删(Hook Tech)附源代码

                      图/文 赵显阳

钩子是WINDOWS中消息处理机制的一个要点,通过安装各种钩子,应用程序能够设置相应的子例程来监视系统里的消息传递以及在这些消息到达目标窗口程序之前处理它们。 钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息 ,鼠标钩子可以截获鼠标消息,外壳钩子可以截获启动和关闭应用程序的消息,日志钩 子可以监视和记录输入事件。钩子分为线程专用钩子和全局钩子,线程专用钩子只监视 指定的线程,要监视系统中的所有线程,必须用到全局钩子。对于全局钩子,钩子函数 必须包含在独立的动态链接库(DLL)中,这样才能被各种相关联的应用程序调用。 在windows资源管理器中,执行删除是调用的shell32.dll文件导出的SHFileOperationW这个函数,只要对该函数进行挂钩处理,就可以实现文件防删。
函数SHFileOperation根据Win32程序员参考介绍,是这样描述的:
Performs a copy, move, rename, or delete operation on a file system object.
WINSHELLAPI int WINAPI SHFileOperation(
    LPSHFILEOPSTRUCT lpFileOp    
   );    
Parameters
lpFileOp
Pointer to an SHFILEOPSTRUCT structure that contains information the function needs to carry out the operation.
Return Values
Returns zero if successful or nonzero if an error occurs.
翻译一下:在文件系统上执行复制,移动,重命名,删除等操作,该函数有一个参数lpFileOp,是一个指向SHFILEOPSTRUCT结构的指针,包含了文件操作的相关数据,返回值为0表示执行成功,否则执行失败。
SHFileOPSTRUCT 结构体的定义如下:
Typedef struct _SHFILEOPSTRUCT { //shfos
  HWND  hwnd ;//显示状态信息窗口的句柄,一般设为主窗体的句柄。
  UINT   wFunc;//要执行的操作。
  LPCSTR  pFrom;//源文件或目录
  LPCSTR  pTo;  //目标文件或目录
  FileOP_FLAGS fFlags;//控制文件操作的标志
  BOOL  fAnyOperationsAborted;//操作是否放弃
  LPVOID hNameMappings;//文件名映射对象的句柄
  LPCSTR lpszProgressTitle;//进度条标题
  } SHFILEOPSTRUCT , FAR *LPSHFILEOPSTRUCT
Delphi 用记录对此结构进行了两种封装,ANSI和UNICODE
下面写一段代码,来删除c:\delFiles目录下的文件
打开delphi 新建一个工程,DelFile
在“删除”按钮的OnClick事件中加入如下代码,用于执行删除操作:
procedure TForm1.Button1Click(Sender: TObject);
var
  OpStruc:TSHFileOpStruct;
  FromBuf:Array[0..128] of Char;
begin
  FillChar(FromBuf,Sizeof(FromBuf),0);
  StrPCopy(FromBuf,Pchar(Edit1.Text));
  //开始填充OpStruc记录
  with OpStruc do
  begin
    Wnd:=Handle;
    wFunc:=FO_Delete;
    pFrom:=@FromBuf;
    pTo:=nil;
    fFlags:=FOF_NOCONFIRMATION;
    lpszProgressTitle:='正在删除';
  end;
  if SHFileOperation(OpStruc)=0 then
  //执行成功
  MessageBox(Handle,'删除完毕。','删除信息',MB_OK+MB_ICONINFORMATION);
end;
删除时(wFunc参数设为FO_Delete)如果想将文件或目录放到回收站(fFlags参
数设置为FOF_ALLOWUNDO)则应该给出文件的绝对路径名,否则可能无法恢复。对于多个
文件的操作,文件名之间要以#0)字符分隔,整个字符串以两个# 0 结束。


                图1
点击”delFile”按钮,文件被删除了,如图1。
该方法调用了SHFileOperationW函数,只要拦截该函数调用就可以防止文件被删除。
思路:其实比较简单,还是利用DLL,首写跟据API函数SHFileOperationW的结构自已编写两个与这两个API一样的函数,再利用GetProcAddress获取系统的那两个API函数入口地址,最后用WriteProcessMemory将你写的函数的地址替换掉原来系统的函数地址。这样所有调用这个函数的应用程序都将先执行你的函数。
下面是一个Dll用于全局挂钩SHFileOperationW函数的关键代码。
1.    function NewSHFileOperationW(const lpFileOp: TSHFileOpStructW): Integer;stdcall;
2.    type
3.    TNewSHFileOperationW = function (const lpFileOp: TSHFileOpStructW):Integer; stdcall;
4.    begin
5.    if Pos('calc.exe',lpFileOp.pFrom)>0 then begin
a)    showmessage('(hooked)SHFileOperationW-无法删除:'+ lpFileOp.pFrom);
b)    result := 1;
c)    exit;
6.    end;
7.    Hook[1].UnHook;
8.    Result := TNewSHFileOperationW(Hook[1].BaseAddr)(lpFileOp);
9.    Hook[1].Hook;
10.    end;
11.    procedure InitHook;     //安装 Hook
12.    begin
13.    Hook[1] := TNtHookClass.Create('Shell32.dll','SHFileOperationW',@NewSHFileOperationW);
14.    end;
第13行用于创建一个Hook对象,然后会挂钩到新的执行过程NewSHFileOperationW这里,
第5行表示如果是删除程序calc.exe的话,是无法删除的,如图2。

               图2
第7,8,9行是表示,如果是其它文件的话(如notepad.exe),先卸载钩子,执行删除操作,再安装钩子,这样是删不掉的,如图3。


                    图3
根据上面的测试,通过Hook SHFileOperationW函数,从而达到了文件防删除的效果。

下载:只允许会员下载 该文件只允许会员下载! 登录 | 注册

[本日志由 admin 于 2013-12-03 06:40 PM 编辑]
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags:
评论: 0 | 引用: 0 | 查看次数: 5031
发表评论
昵 称:
密 码: 游客发言不需要密码.
验证码: 验证码
内 容:
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.
字数限制 1000 字 | UBB代码 开启 | [img]标签 关闭