时间: 2021-07-31 作者:daque
在win32下用delphi侦测目次变革,可用win32供给的文献变换报告api来实行。findfirstchangenotification, findnextchangenotification,findclosechangenotification。 在运用步调中挪用那些因变量时,爆发一个监察和控制这个变革的句柄,可用wait因变量集来等候这个变革。如许,当监察和控制步调运转时,不妨到达监察和控制文献变革的举措。更进一步,可把此步调做出一个状况区图标(tray)来实行监察和控制。 windows在简略、复制、挪动、考察文献时并不发送动静,固然截获不到。要截取那些操纵进程的独一方法即是截获api,这又须要你编写vxd步调了,杀毒软硬件都是如许作的。你提防一下杀毒软硬件普遍都带有一个vxd步调。光有vxd还不行,还需截获文献api。再有其余一个方法,即是cih宏病毒沿用的方法,径直跳到体例零层去操纵。简直方法如次: 一、sidt训令( 将阻碍刻画符表存放器idtr--64位宽,16~47bit存有阻碍刻画符表idt基地方--的实质惠存指定地方单位)不是特权训令,即是说咱们不妨在ring3下实行该训令,赢得idt的基地方,进而窜改idt,减少一个阻碍门安排咱们的阻碍效劳,一旦ring3步调中爆发此阻碍,vmm就会挪用此阻碍效劳步调,而此阻碍效劳步调就运转在ring0下了。这一点与在dos下特殊一致。 二、要实行对体例中一切文献i/o操纵的及时监督,还要用到另一种要害技-filehooking,经过挂接一个处置因变量,截获一切与文献i/o操纵相关的系 统挪用。windows9x运用32位养护形式可安置文献体例(ifs),由可安置文献体例处置器(ifsmanager)融合对文献体例和摆设的考察,它接受以win32api因变量挪用情势向体例发出的文献i/o乞求,再将乞求转轨文献体例启动步调fsd,由它挪用初级其余ios体例实行最后考察。每个文献i/oapi挪用都有一个一定的fsd因变量与之对应,ifsmanager控制实行由api到fsd的参数安装处事,在实行文献i/oapi因变量参数的安装之后转相映fsd实行之前,它会挪用一个称为filesystemapihookfunction的hooker因变量。经过安置本人的hooker因变量,就不妨截获体例内一切对文献i/o的api挪用,进而实行及时监察和控制。 ========================================= procedure tform1.button2click(sender: tobject); begin {establish a notification for file name changes on the selected directory} notificationhandle := findfirstchangenotification(pchar(directorylistbox1.directory), false,file_notify_change_file_name); {if the notification was set up correctly, modify some ui elements...} if (notificationhandle <> invalid_handle_value) then begin button1.enabled := true; button2.enabled := false; end else begin {...otherwise indicate that there was an error} showmessage('there was an error setting the notification'); exit; end; end; procedure tform1.button1click(sender: tobject); var dwresult: dword; // holds the result of waiting on the notification waiting: boolean; // loop control variable begin {setup the loop control for a continuous loop} waiting := true; {indicate that the application is waiting for the change notification to fire} button1.enabled := false; statusbar1.simpletext := 'now waiting for a filename change'; application.processmessages; {enter the loop} while waiting do begin {at this point, the application is suspended until the notification object is signaled that a filename change has occured in the selected directory (this includes file deletions)} dwresult := waitforsingleobject(notificationhandle,infinite); if (dwresult = wait_object_0) then begin {indicate that the notification object was signaled} showmessage('the selected directory signaled a filename change'); {query the user to see if they wish to continue monitoring this directory} if application.messagebox('do you wish to continue monitoring this directory?', 'continue?', mb_iconquestion or mb_yesno) = idyes then {if the user wishes to continue monitoring the directory, reset the notification object and continue the loop...} findnextchangenotification(notificationhandle) else {...otherwise break out of the loop} waiting := false; end; end; {close the notification object} findclosechangenotification(notificationhandle); {reset ui elements} button1.enabled := false; button2.enabled := true; statusbar1.simpletext := ''; filelistbox1.update; end; =========================================== 底下是一个监督的控件: unit dirnotify; interface uses windows, messages, sysutils, classes, graphics, controls, forms, dialogs; type edirnotificationerror = class(exception); tdirnotify = class; tnotifyfilter = (nffilename, nfdirname, nfattributes, nfsize, nflastwrite, nfsecurity); tnotifyfilters = set of tnotifyfilter; tnotificationthread = class(tthread) owner: tdirnotify; procedure execute; override; procedure dochange; end; tdirnotify = class(tcomponent) private fenabled: boolean; fonchange: tnotifyevent; fnotificationthread: tnotificationthread; fpath: string; fwatchsubtree: boolean; ffilter: tnotifyfilters; procedure setenabled( value: boolean ); procedure setonchange( value: tnotifyevent ); procedure setpath( value: string ); procedure setwatchsubtree( value: boolean ); procedure setfilter( value: tnotifyfilters ); procedure recreatethread; protected procedure change; procedure loaded; override; public constructor create(aowner: tcomponent); override; destructor destroy; override; published property enabled: boolean read fenabled write setenabled default true; property onchange: tnotifyevent read fonchange write setonchange; property path: string read fpath write setpath; property watchsubtree: boolean read fwatchsubtree write setwatchsubtree; property filter: tnotifyfilters read ffilter write setfilter default [nffilename, nfdirname, nfattributes, nflastwrite, nfsecurity]; end; procedure register; implementation const lasterrortextlength = 500; var lasterrortext: array [0..lasterrortextlength] of char; function getlasterrortext: pchar; begin formatmessage( format_message_from_system, nil, getlasterror, 0, lasterrortext, lasterrortextlength, nil ); result := lasterrortext; end; procedure tnotificationthread.execute; var h: thandle; nf: longint; wst: longbool; begin nf := 0; if (nffilename in owner.filter) then nf := file_notify_change_file_name; if (nfdirname in owner.filter) then nf := nf or file_notify_change_dir_name; if (nfattributes in owner.filter) then nf := nf or file_notify_change_attributes; if (nfsize in owner.filter) then nf := nf or file_notify_change_size; if (nflastwrite in owner.filter) then nf := nf or file_notify_change_last_write; if (nfsecurity in owner.filter) then nf := nf or file_notify_change_security; // yeahh, this one is stupid but win98 malfunctions in any other value than 0 or 1 if owner.fwatchsubtree then wst := longbool(1) else wst := longbool(0); h := findfirstchangenotification( pointer(owner.path), wst, nf ); if (h = invalid_handle_value) then raise edirnotificationerror.create( getlasterrortext ); repeat if (waitforsingleobject( h, 1000 ) = wait_object_0) then begin synchronize(dochange); if not findnextchangenotification( h ) then raise edirnotificationerror.create( getlasterrortext ); end; until terminated; end; procedure tnotificationthread.dochange; begin owner.change; end; constructor tdirnotify.create(aowner: tcomponent); begin inherited create(aowner); fenabled := true; ffilter := [nffilename]; end; destructor tdirnotify.destroy; begin fnotificationthread.free; inherited destroy; end; procedure tdirnotify.loaded; begin inherited; recreatethread; end; procedure tdirnotify.setenabled(value: boolean); begin if value <> fenabled then begin fenabled := value; recreatethread; end; end; procedure tdirnotify.setpath( value: string ); begin if value <> fpath then begin fpath := value; recreatethread; end; end; procedure tdirnotify.setwatchsubtree( value: boolean ); begin if value <> fwatchsubtree then begin fwatchsubtree := value; recreatethread; end; end; procedure tdirnotify.setfilter( value: tnotifyfilters ); begin if value <> ffilter then begin ffilter := value; recreatethread; end; end; procedure tdirnotify.setonchange(value: tnotifyevent); begin fonchange := value; end; procedure tdirnotify.change; begin if assigned(fonchange) then fonchange(self); end; procedure tdirnotify.recreatethread; begin // destroy thread fnotificationthread.free; fnotificationthread := nil; if fenabled and not(csdesigning in componentstate) and not(csloading in componentstate) and (fpath <> '') then begin // create thread fnotificationthread := tnotificationthread.create(true); fnotificationthread.owner := self; fnotificationthread.resume; end; end; procedure register; begin registercomponents('system', [tdirnotify]); end; end.