有没有办法监视某一类文件的打开与关闭(50分)

  • 主题发起人 主题发起人 poy
  • 开始时间 开始时间
P

poy

Unregistered / Unconfirmed
GUEST, unregistred user!
比如,我想监视所有word文档的打开与关闭.<br>在打开之前,先截获消息,作一些处理...<br>在word关闭文件之后,再作一些处理.....<br>要用什么API....
 
有没有人会啊,,,,请高手出山
 
这个问题一般用Hook的方式来解决:<br>1。启动程序<br>2。Hook系统OpenFile的API<br>3。判断文件名的后缀,如果是你要处理的文件,则记录下来。<br><br>至于如何Hook Windows API的方式,各个网上特别多!<br><br>Good Luck!
 
关于DELPHI中的API HOOK(1)<br><br>创建时间:2002-05-17<br>文章属性:原创<br>文章来源:angliu<br>文章提交:angliu (aixihuan_at_21cn.com)<br><br>关于API HOOK,我相信大家比我知道的多,大家应该记得在DOS中编程,经常都要用截取中断向量的技术,这样我们可以设置新的中断服务程序,因此当一个新的程序调用这个中断向量的时候,它就会先调用我们自己设置的中断程序,然后调用原来的中断程序,这样我们就能够非凡的控制权,许多的病毒程序都是这样的。在WINDOWS中,也可以采用类似的技术,当系统调用某个API函数时,就会先进入我们设置的函数,其工作原理和DOS的中断差不多,这种技术也有很多的名称,像&quot;陷阱技术&quot;,&quot;重入技术&quot;。可我认为API HOOK好一些吧!这些技术再很多的软件中也有应用的,像&quot;金山词霸&quot;就是的了。呵呵~~~不是故意拿金山公司的产品说的啊!这个软件就运用了这个技术,像当你把鼠标指向一个单词,这时就会弹出一个窗口翻译单词了。这也就是用了钩子的原理。说了这么多废话,说正题了,要使自己的代码正确运行,函数必须和要改写的API函数有相同形式的参数。我在程序中,拦截了MessageBoxA和MessageBoxW这两个函数。如:<br>fuction MyBoxA(hwn:hwnd;Iptext:pcter;Ipcapion:pchar;utype:cardinal):interger;stdcall;<br>fuction MyBoxW(hwn:hwnd;Iptext:pchter;Ipcapiom:pchar;utype:cardinal):interger;stdcall;<br>这里我使用了stdcall关键字,这个我上面已经说了,函数的形参的进出栈顺序要和拦截的函数一样,在WIN32中并不允许直接修改内存中的代码,但可以调用一个函数来运用:WriteProcessMemory。当然有的人问这个不能改写,可我用着很好!也许用它会有些bug,可我不知道,知道的人请给我来信。<br>在PE文件中,当你呼叫另一模块中的函数列如:USER32.DLL中的GetMessage),编译出来的CALL指令并不会吧控制权直接传给DLL里的函数,而是传给了JMP DWORD PTR [XXXXXXXXX]指令,[XXXXXXXXXX]里有该函数的真正地址(进入点),要得到API函数,可以这样写:Address:=@MessageBoxA。像上面说的那样,这里只得到了一个跳转的指令,后面的MessageBoxA才是代码开始的地方。下面的程序我自己定义了一个结构(使用了packed关键字)<br>TlmportCode =packed record<br> &nbsp; &nbsp;Jumplnstruction: Word; //是$25FF,JUMP指令<br>AddressOfPointer ToFunction: PPointer;//真正开始的地址<br>end;<br>PlmportCode = ^TlportCode;<br>这里,Ppointer =^pointer ;用下面函数返回函数的真正地址:<br>function TrueFunctionAddress(func: Pointer): Pointer;<br>var<br> &nbsp;Code: PlmportCode;<br>Begin<br> &nbsp;Result:= func;<br> &nbsp;if func = nil then exit;<br> &nbsp;try<br> &nbsp; Code := func;<br> &nbsp; if (Code.jumplnstruction = $25FF) then begin<br> &nbsp; &nbsp; Result := Code.AddressOfPointer ToFunction^;<br> &nbsp; end;<br> &nbsp; except<br> &nbsp; &nbsp; Result :=nil;<br> &nbsp;end;<br>end;<br>这样,只要用自己的函数的地址代替它就可以了。替换函数:<br>Procedure PermuteFunction(OldFunc:Ppointer; NewFunc:Poiner);<br>var<br> &nbsp;written: DWORD;<br>begin<br> &nbsp;WriteProcessMemory(GetCurrentProcess,OldFunc,@NewFunc,4,written);<br>end;<br>新建一个API HOOK,把上面的保存就可以了。<br>新建一个Application Try1,主FORM的单元名称就用TRYUNIT1。把上面的HOOK加进来,再新建一个UNIT MESS,添加下面的代码:<br>unit mess<br><br>interface<br>uses<br> &nbsp; Windows,Message,SysUtils,Classes,APIHook;<br><br>procedure API_Hookup;<br>procedure Un_API_Hook;<br><br>var<br> &nbsp; FuncMessageboxA,FuncMessagew;PlmportCode;<br><br>implementation<br><br>type <br> &nbsp; TmessageA = function(hwn: hwnd; Iptext: pchar; Ipcapion:pchar; utype: cardinal): interger;stdcall;<br> &nbsp; TmessageW = function(hwn: hwnd; Iptext: pchar; Ipcapion:pchar; utype: cardinal): interger;stdcall;<br><br>var<br> &nbsp; OldMessageBoxA: TmessageA;<br> &nbsp; OldMessageBoxW: TmessageW;<br><br><br>functionj MyBoxA (hwn: hwnd; Iptext: pchar; Ipcapion:pchar; utype: cardinal): interger;stdcall;<br>begin<br>result :=OldMessageBoxA(hwn,'Succes Hook A!', Ipcapion,utype);<br>end;<br><br>functionj MyBoxW (hwn: hwnd; Iptext: pchar; Ipcapion:pchar; utype: cardinal): interger;stdcall;<br>result :=OldMessageBoxW(hwn,'成功挂上W!'Ipcapion,utype);<br>end;<br><br>procedure API_Hookup;<br>begin<br> &nbsp; if @OldMessageBoxA = nil then<br>@OleMessageBoxA = TrueFunctionAddress(@messageboxA);<br> &nbsp; if @OldMessageBoxW = nil then<br>@OleMessageBoxW = TrueFunctionAddress(@messageboxW);<br><br>PermuteFunction(FuncMessageboxA,AddressOfPointerToFunction,@MyBoxA);<br>PermuteFunction(FuncMessageboxW,AddressOfPointerToFunction,@MyBoxW);<br>end;<br><br>procedure Un_API_Hook;<br>begin<br> &nbsp;if @OldMessageBoxA &lt;&gt; nil then begin<br> &nbsp; &nbsp; &nbsp; &nbsp; PermuteFunction(FuncMessageboxA,AddressOfPointer ToFunction,@OldMessageboxA);<br> &nbsp; &nbsp; &nbsp; &nbsp; PermuteFunction(FuncMessageboxW,AddressOfPointer ToFunction,@OldMessageboxW);<br> &nbsp;end;<br>end;<br><br>initialization<br> &nbsp; FundMessageboxA := @MeesageboxA;<br> &nbsp; FundMessageboxW := @MeesageboxW;<br>end;<br>在主窗体中添加三按钮,添加Onclick事件的代码,如下:<br>procedure TForm1.Button1Click( Sender: TObject);<br>begin<br> &nbsp; API_Hook;<br>end;<br><br>procedure TForm1.Button3Click( Sender: TObject);<br> &nbsp; Un_API_Hook;<br>end;<br><br>procedure TForm1.Button2Click( Sender: TObject);<br>begin<br> &nbsp;MessageBoxA(Form1.Handle,'NO HOOK UP A','MessageBoxA',MB_OK);<br> &nbsp;MessageBoxW(Form1.Handle,'NO HOOK UP W','MessageBoxW',MB_OK);<br> &nbsp;MessageBox (Form1.Handle,'NO HOOK UP BOX','MessageBox',MB_OK);<br>end;<br>先运行TRY1,再运行TestTry。看看结果,APIHook仅仅再TRY1中挂上了,并没有在所以的系统进程中挂上,这个时想想鼠标钩子的时候做法,用SetWindowsHookEx挂上鼠标钩子,当其它的进程发出鼠标消息的时候,我们的程序就会拦截到并做出响应,还可以用UpHooklWindowsHookEx解除鼠标钩子,这样,我们就知道了,应该为我们的函数挂上钩子,当然你要知道鼠标钩子有各种的消息响应其它进程。有两种方法,一种是模仿SetWindowsHookEx,编制自己的MySetWindowsHookEx。还有一种也是WINDOWS所提供的另一个函数:GetMsgProc。这个函数在DELPHI帮助里说的很清楚得了。我们的目的也就是在动态链接库中挂上WH_GETMESSAGE消息钩子。当其它进程发出这个函数的时候,就会加载我们的动态链接库,如果我们的DLL加载时自动运行API_Hook,就可以让其它进程挂上我们的API Hook了。<br>第二个程序我会在下次写出来。以上的程序可能有些不足,大家可以来信指点。(angliu@hackermail.com)
 
楼上的兄弟,我要怎么 才能 hook到系统的OpenFile呢,<br>在PermuteFunction里,我该把GetCurentProcess改成什么 ?是Explorer的进程Handle吗?<br>Procedure PermuteFunction(OldFunc:Ppointer; NewFunc:Poiner);<br>var<br> &nbsp;written: DWORD;<br>begin<br> &nbsp;//WriteProcessMemory(GetCurrentProcess,OldFunc,@NewFunc,4,written);<br> &nbsp;WriteProcessMemory(??,OldFunc,@NewFunc,4,written);<br>end;
 
没有人会继续回答问题吗,有点急啊
 
以前也想实现类似功能,所以拿CIH原代码看了一下,不懂。太难了。CIH病毒才有这种功能。若真要实现,用心研究CIH吧。HOOK API的复杂度与CIH不相上下。
 

Similar threads

回复
0
查看
798
不得闲
D
回复
0
查看
2K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部