怎样实现对注册表的实时监控

时间:2022-09-04 22:41:38
将所有对注册表的改动全部都记录下来,怎样实现?——我的一贯原则:欢迎代码。

21 个解决方案

#1


MARK

#2


使用RegNotifyChangeKeyValue函数,具体使用说明看一看msdn吧。

#3


waiting for other answers……

#4


读写注册表时应该有相应消息的,截获一下

#5


RegNotifyChangeKeyValue?查找……………………

#6


学习学习……

#7


关注

#8


提前一下

#9


关于“RegNotifyChangeKeyValue”到底是什麽?
和如何用???

#10


监视程序的编制 

  

(哈尔滨 赵晓辉) 

  

  

  监视程序,这个名字听起来似乎很陌生。它的用途主要是在后台监视系统中 

关键信息的改变,比如注册表 

的改变及硬盘上由于文件操作引起的改变等等。也许有人会问了,编制这样的程 

序有什么价值呢?硬盘上文件 

改变了,我只要在资源管理器里点一点不就全都清楚了吗?问题当然不会这样简 

单,如今大家的硬盘都已经用 

G来做单位了,一块4.3G的硬盘中,大大小小的文件全都加起来也会有若干万( 

相信新购机的朋友会考虑IBM10 

.1G的大硬盘,那文件数量将更加不可想象),更何况那些看不见的系统文件和 

隐藏文件了。再加上注册表,那 

其中的条条款款,数量也丝毫不逊于硬盘上的文件。要想随时知道自己机器是否 

有所变动,绝对不是一件很轻 

松的事。而监视程序就可以随时检测到这些变化,帮助我们了解这些情况。 

  当然这只是监视程序的一部分作用,它最大的作用就是可以记录下某个软件 

安装前后系统的改变,从而为 

卸载这个软件提供重要的依据。虽然Windows自带了一个Uninstall Shield,但 

是它似乎并不能很干净地把原来的软件卸掉,每次卸载总会留下一些讨厌的残渣 

,致使系统中的垃圾信息不断增长,我们的硬盘空间也总是莫名其妙地越用越少 

。因此,一些号称能够完全卸载软件的专用卸载工具应运而生。在这其中,有一 

些就运用了监视系统的技术,比如Uninstaller Manager和RegMonitor。 

  下面我们开始讨论如何编程实现这一监视功能。首先介绍几个重要的api函 

数: 

  FindFirstChangeNotification( ); 

  FindNextChangeNotification( ); 

  WaitForSingleObject( ); 

  其中FindFirstChangeNotification(lpzpath,fwatchsubtree, 

fdwfilter)中的lpzpath表示要监视的路径名,fwatchsubtree判断是否查看子 

目录,fdwfilter为要监视的事件,函数执行成功后返回一个句柄。 

  参数fdwfilter取值及其含义如下: 

  FILE_NOTIFY_CHANGE_FILE_NAME 

  查看指定目录下任何文件名的改变 

  FILE_NOTIFY_CHANGE_DIR_NAME 

  查看指定目录下任何目录名的改变 

  FILE_NOTIFY_CHANGE_SIZE 

  查看指定目录下文件大小的改变 

  FILE_NOTIFY_CHANGE_ATTRIBUTES 

  查看指定目录下文件属性的改变 

  FindNextChangeNotification(hchange),hchan 

  ge为FindFirstChangenNotification返回的句柄,其作用是请求系统在下次 

检测到相应改变时发出改变通 

知消息句柄。当函数成功返回后,应用程序可通过WaitForMultipleObjects或 

WaitfForSingleObject来等待发 

生改变的通知。WaitForSingleObject(hchange,dwmilliseconds)中hchange 

为FindFirstChangeNotificati 

on 返回的句柄,dwmilliseconds为等待时间值,指定等待完成需要的时间,单 

位为毫秒。该值为-1时表示时间无限长。最好在结束监视程序之前先用 

FindCloseChangeNotification(hchange) 

来关闭句柄。 

  下面给出一个简单的实例,其功能就是监视c:\pwin98目录下是否有文件发 

生变化。一旦有重命名、创建 

或删除情况发生时,通过Edit控件给出提示。 

  // 

  ---------------- 

  。nclude 

  。ragma hdrstop 

   

  。nclude “Unit1.h” 

  FILE_NOTIFY_CHANGE_ATTRIBUTES 

  查看指定目录下文件属性的改变 

  FindNextChangeNotification(hchange),hchan 

  ge为FindFirstChangenNotification返回的句柄,其作用是请求系统在下次 

检测到相应改变时发出改变通 

知消息句柄。当函数成功返回后,应用程序可通过WaitForMultipleObjects或 

WaitfForSingleObject来等待发 

生改变的通知。WaitForSingleObject(hchange,dwmilliseconds)中hchange 

为FindFirstChangeNotificati 

on 返回的句柄,dwmilliseconds为等待时间值,指定等待完成需要的时间,单 

位为毫秒。该值为-1时表示时间无限长。最好在结束监视程序之前先用 

FindCloseChangeNotification(hchange) 

来关闭句柄。 

  下面给出一个简单的实例,其功能就是监视c:\pwin98目录下是否有文件发 

生变化。一旦有重命名、创建 

或删除情况发生时,通过Edit控件给出提示。 

  // 

  ---------------- 

  。nclude 

  。ragma hdrstop 

   

  。nclude “Unit1.h” 

  //---------------- 

  。ragma package(smart_init) 

  。ragma resource “*.dfm” 

  TForm1 *Form1; 

  //----------------- 

  __fastcall TForm1::TForm1(TComponent* Owner) 

   : TForm(Owner) 

  { 

  } 

  //------------------- 

   

  void __fastcall TForm1::FormCreate(TObject *Sender) 

  { 

  DWORD dwWaitStatus; 

  HANDLE dwChangeHandle; //返回通知的句柄 

  dwChangeHandle=FindFirstChangeNotification( 

  “C:\\PWIN98”,false,FILE_NOTIFY_CHANGE_FILE_NAME); //设置返回通知 

的句柄 

  if(dwChangeHandle==INVALID_HANDLE_VALUE) 

  //判断是否设置成功 

   ExitProcess(GetLastError( )); 

  while(true){ //设置循环,监视是否有 

  dwWaitStatus=WaitForSingleObject(dwChangeHandle,-1); //通知返回 

  switch(dwWaitStatus){ 

  case 0: 

  Edit1->Text=“Something Changed”; //给出提示 

  FindCloseChangeNotification(dwcChangeHandle); //关闭句柄 

  exit(EXIT_SUCCESS); //退出程序 

  default: 

  ExitProcess(GetLastError( )); 

  } 

  } 

  } 

  程序在C++Builder4/PWin98下通过,由于C++Builder语言很标准,所 

以很容易扩展到其他编程语言 

环境中去。 

  此例说明如何监视硬盘中文件变化,对于注册表,则有函数 

RegNotifyChangeKeyValue( )可以实现类似 

功能,这里暂省略之。 

  怎么样,看过本文,是否对Uninstaller Manager和Reg Monitor这样的软 

件有了更深入的了解。在Wind 

ows编程中,有些API函数起到了重要的作用,可以让程序实现很多高级的功能。 

因为API函数是按照C语言语法 

给出的,所以C++Builder有着得天独厚的优势,对API函数和宏支持得非常好 



。不好,怎么跑题了? 

  』广 着干吗,难道你还不想赶快动?编制一个自己的Uninstaller Manager 

吗?

#11


我记得有消息可以捕获吧

#12


那个什么RegNotify什么的函数是不行的,她只能告诉你有改动,但不会告诉你具体的改动地方。我试过的。

#13


呵呵,也是啊。我这几天正在想着呢……
只是说有改动的话仅仅是编程目的中的方向性指标,但是我要的是具体的改动。不知道NowCan(能量、激情、雨水、彩虹——雷雨云)兄能否解决这个问题呢?

#14


再次关注

#15


我的收藏:

unit UMesApi;
interface
uses SysUtils, Classes;

function ToUnicode(str:string;dest:PWideChar):integer;
function SendMsg(Toh,From,Msg:string):integer;
function NetMessageBufferSend(servername:PWideChar;
                              MsgName:PWideChar;
                              FromName:PWideChar;
                              Buf: PWideChar;
                              var BufLen:integer):integer;cdecl;
implementation
function ToUnicode(str:string;dest:PWideChar):integer;
var
  len:integer;
begin
  len:=Length(str)*2;
    //len:=length(dest^);
  StringToWideChar(str,dest,len);
  Result:=len;
end;


function NetMessageBufferSend; external 'netapi32.dll' name 'NetMessageBufferSend';

function SendMsg(Toh,From,Msg:string):integer;
var
  ToName :array [0..64] of WideChar;
  WMsgText:array [0..1000] of WideChar;
  MsgLen,i:integer;
begin
  for i := 0 to 64 do ToName[i] := #0;
  ToUnicode(Toh,ToName);
  for i := 0 to 1000 do WMsgText[i] := #0;

  MsgLen:=ToUnicode(Msg,WMsgText);
  Result:=NetMessageBufferSend(nil,ToName,nil,@WMsgText,MsgLen);

end;

end.

#16


unit UMain;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Registry,IniFiles, ExtCtrls;

type
  TFormMain = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  published
    procedure LogMsg(msg:string);
  private
    { Private declarations }
    Reg:TRegistry;
    IniFile:TIniFile;
    LogFile:TStringList;
    LogFileName:String;
    RegKeys:TStringList;
    CurrUser,HostName:String;
  public
    { Public declarations }
  end;

var
  FormMain: TFormMain;

implementation

uses UMesApi;

{$R *.DFM}
procedure TFormMain.FormCreate(Sender: TObject);
var IniName,value:string;
    i:integer;
    pstr:pchar;
    n:Cardinal;
begin
   try
      n:=64;
      pstr:=StrAlloc(n);
      GetUserName(pstr,n);
      CurrUser:=StrPas(pstr);
      GetComputerName(pstr,n);
      HostName:=StrPas(pstr);
      StrDispose(pstr);
      self.Reg:=TRegistry.Create;
      with self.Reg do
      begin
          RootKey:=HKEY_Local_Machine;
          Access:=KEY_EXECUTE;
          if OpenKey('Software\Microsoft\Windows\CurrentVersion\Run',false) then
          begin
               RegKeys:=TStringList.Create;
               GetValueNames(RegKeys);
               for i:=0 to Regkeys.Count-1 do
                  if (GetDataType(RegKeys.Strings[i])=rdString)
                       or (GetDataType(RegKeys.Strings[i])=rdExpandString)
                  then begin
                         value:=ReadString(RegKeys.Strings[i]);
                         if value=Application.ExeName then Break;
                        end;
               if value<>Application.ExeName then
               begin  //if not set run with widows ,then set it
                    WriteString('PiRegWatch',Application.ExeName);
               end;
          end
          else
              begin
              Messagebox(0,'Can"t Open RegKey','error',mb_ok);
              Application.Terminate;
              end;
      end ;
      IniName:=Application.ExeName;
      IniName:=Copy(IniName,1,Length(IniName)-4)+'.ini';
      self.IniFile:=TIniFile.Create(IniName);

      self.LogFile:=TStringList.Create;
      self.LogFileName:=Copy(IniName,1,Length(IniName)-4)+'.log';
      if FileExists(LogFileName) then self.LogFile.LoadFromFile(self.LogFileName);

      if not self.IniFile.SectionExists('RunList') then
          begin
             for i:=0 to Regkeys.Count-1 do
                if (self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
                   or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString)
                then begin
                        value:=self.Reg.ReadString(RegKeys.Strings[i]);
                        self.IniFile.WriteString('RunList',RegKeys.Strings[i],value);
                end;

             self.IniFile.Free;   //Force INI file save
             self.IniFile:=TIniFile.Create(IniName);
          end;
   except
      Messagebox(0,'App Terminate','error',mb_ok);
      Application.Terminate;
   end;

end;

procedure TFormMain.Timer1Timer(Sender: TObject);
var i:integer;
    RegVal,IniVal:string;
begin
     self.Timer1.Enabled:=False;

     self.Reg.GetValueNames(RegKeys);
     for i:=0 to RegKeys.Count-1 do   //Check to New Added items
        if (self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
           or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString)
        then begin
          RegVal:=self.Reg.ReadString(RegKeys.Strings[i]);
          IniVal:=self.IniFile.ReadString('RunList',RegKeys.Strings[i],'');
          if RegVal<>IniVal then
             begin
                self.LogMsg('Item Add:'+RegKeys.Strings[i]+'='+RegVal);
                self.IniFile.WriteString('RunList',RegKeys.Strings[i],RegVal);
                try
                SendMsg('ABC','','注册表被改变:新增项目'+RegKeys.Strings[i]+'='+RegVal);
                finally
                end;
             end;
        end;

     self.IniFile.ReadSection('RunList',RegKeys);
     for i:=0 to RegKeys.Count-1 do //Check to Deleted Items
     begin
          IniVal:=self.IniFile.ReadString('RunList',RegKeys.Strings[i],'');
          if self.Reg.ValueExists(RegKeys.Strings[i]) and
             ((self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
               or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString) )
          then
             RegVal:=self.Reg.ReadString(RegKeys.Strings[i])
          else
             RegVal:='';
          if (IniVal<>'') and (RegVal='') then
             begin
                self.LogMsg('Item Del:'+RegKeys.Strings[i]+'='+IniVal);
                self.IniFile.DeleteKey('RunList',RegKeys.Strings[i]);
                try
                SendMsg('ABC','','注册表被改变:项目删除'+RegKeys.Strings[i]+'='+IniVal);
                finally
                end;
             end;
     end;
     self.IniFile.UpdateFile;
     self.Timer1.Enabled:=True;
end;

procedure TFormMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
     if Assigned(self.Reg) then self.Reg.Free;
     if Assigned(self.IniFile) then self.IniFile.Free;
     if Assigned(self.LogFile) then self.LogFile.Free;
     if Assigned(self.RegKeys) then self.RegKeys.Free;
end;

procedure TFormMain.LogMsg(msg:string);
var str:string;
    y,m,d:word;
begin
     str:=Format('[%s] %s on %s ,%s',[DatetimeToStr(Now),self.CurrUser,self.HostName,msg]);
     self.LogFile.Add(str);
     if self.LogFile.Count<=100 then
        self.LogFile.SaveToFile(self.LogFileName)
     else begin
               DecodeDate(Now,y,m,d);
               str:=ExtractFilePath(self.LogFileName)+Format('%2d%2d%2d',[y,m,d])+'.log';
               self.LogFile.SaveToFile(str);
               self.LogFile.Clear;
               self.LogFile.SaveToFile(self.LogFileName);
          end;
end;

end.


有谁把他改成BCB,我看见Begin End就麻.


我下大家满足了吧!

#17


这个问题?

禁止注册表的改动,就可以!

#18


感谢Bird1945(老唬是女人!),呵呵。去试试看先……
To dycdyc123(重出江湖),我没有说要禁止他阿,我只要看他改动哪里就可以了。哦,还有,恕我肤浅,怎样禁止注册表的改动?我不知道阿。

#19


就是让在local maching的什么里面加一个disabled
你可以去查一下
一般的黑客网站都有

#20


Bird1945的代码好像有点问题
因为在formcreate时候一直监测文件夹]的变动
是不是会造成form显示不出来阿
我只是猜测阿

#21


没错,Bird1945的代码大有问题!
不知他自己有无调试过?
直接从网上拷过来的吧?

#1


MARK

#2


使用RegNotifyChangeKeyValue函数,具体使用说明看一看msdn吧。

#3


waiting for other answers……

#4


读写注册表时应该有相应消息的,截获一下

#5


RegNotifyChangeKeyValue?查找……………………

#6


学习学习……

#7


关注

#8


提前一下

#9


关于“RegNotifyChangeKeyValue”到底是什麽?
和如何用???

#10


监视程序的编制 

  

(哈尔滨 赵晓辉) 

  

  

  监视程序,这个名字听起来似乎很陌生。它的用途主要是在后台监视系统中 

关键信息的改变,比如注册表 

的改变及硬盘上由于文件操作引起的改变等等。也许有人会问了,编制这样的程 

序有什么价值呢?硬盘上文件 

改变了,我只要在资源管理器里点一点不就全都清楚了吗?问题当然不会这样简 

单,如今大家的硬盘都已经用 

G来做单位了,一块4.3G的硬盘中,大大小小的文件全都加起来也会有若干万( 

相信新购机的朋友会考虑IBM10 

.1G的大硬盘,那文件数量将更加不可想象),更何况那些看不见的系统文件和 

隐藏文件了。再加上注册表,那 

其中的条条款款,数量也丝毫不逊于硬盘上的文件。要想随时知道自己机器是否 

有所变动,绝对不是一件很轻 

松的事。而监视程序就可以随时检测到这些变化,帮助我们了解这些情况。 

  当然这只是监视程序的一部分作用,它最大的作用就是可以记录下某个软件 

安装前后系统的改变,从而为 

卸载这个软件提供重要的依据。虽然Windows自带了一个Uninstall Shield,但 

是它似乎并不能很干净地把原来的软件卸掉,每次卸载总会留下一些讨厌的残渣 

,致使系统中的垃圾信息不断增长,我们的硬盘空间也总是莫名其妙地越用越少 

。因此,一些号称能够完全卸载软件的专用卸载工具应运而生。在这其中,有一 

些就运用了监视系统的技术,比如Uninstaller Manager和RegMonitor。 

  下面我们开始讨论如何编程实现这一监视功能。首先介绍几个重要的api函 

数: 

  FindFirstChangeNotification( ); 

  FindNextChangeNotification( ); 

  WaitForSingleObject( ); 

  其中FindFirstChangeNotification(lpzpath,fwatchsubtree, 

fdwfilter)中的lpzpath表示要监视的路径名,fwatchsubtree判断是否查看子 

目录,fdwfilter为要监视的事件,函数执行成功后返回一个句柄。 

  参数fdwfilter取值及其含义如下: 

  FILE_NOTIFY_CHANGE_FILE_NAME 

  查看指定目录下任何文件名的改变 

  FILE_NOTIFY_CHANGE_DIR_NAME 

  查看指定目录下任何目录名的改变 

  FILE_NOTIFY_CHANGE_SIZE 

  查看指定目录下文件大小的改变 

  FILE_NOTIFY_CHANGE_ATTRIBUTES 

  查看指定目录下文件属性的改变 

  FindNextChangeNotification(hchange),hchan 

  ge为FindFirstChangenNotification返回的句柄,其作用是请求系统在下次 

检测到相应改变时发出改变通 

知消息句柄。当函数成功返回后,应用程序可通过WaitForMultipleObjects或 

WaitfForSingleObject来等待发 

生改变的通知。WaitForSingleObject(hchange,dwmilliseconds)中hchange 

为FindFirstChangeNotificati 

on 返回的句柄,dwmilliseconds为等待时间值,指定等待完成需要的时间,单 

位为毫秒。该值为-1时表示时间无限长。最好在结束监视程序之前先用 

FindCloseChangeNotification(hchange) 

来关闭句柄。 

  下面给出一个简单的实例,其功能就是监视c:\pwin98目录下是否有文件发 

生变化。一旦有重命名、创建 

或删除情况发生时,通过Edit控件给出提示。 

  // 

  ---------------- 

  。nclude 

  。ragma hdrstop 

   

  。nclude “Unit1.h” 

  FILE_NOTIFY_CHANGE_ATTRIBUTES 

  查看指定目录下文件属性的改变 

  FindNextChangeNotification(hchange),hchan 

  ge为FindFirstChangenNotification返回的句柄,其作用是请求系统在下次 

检测到相应改变时发出改变通 

知消息句柄。当函数成功返回后,应用程序可通过WaitForMultipleObjects或 

WaitfForSingleObject来等待发 

生改变的通知。WaitForSingleObject(hchange,dwmilliseconds)中hchange 

为FindFirstChangeNotificati 

on 返回的句柄,dwmilliseconds为等待时间值,指定等待完成需要的时间,单 

位为毫秒。该值为-1时表示时间无限长。最好在结束监视程序之前先用 

FindCloseChangeNotification(hchange) 

来关闭句柄。 

  下面给出一个简单的实例,其功能就是监视c:\pwin98目录下是否有文件发 

生变化。一旦有重命名、创建 

或删除情况发生时,通过Edit控件给出提示。 

  // 

  ---------------- 

  。nclude 

  。ragma hdrstop 

   

  。nclude “Unit1.h” 

  //---------------- 

  。ragma package(smart_init) 

  。ragma resource “*.dfm” 

  TForm1 *Form1; 

  //----------------- 

  __fastcall TForm1::TForm1(TComponent* Owner) 

   : TForm(Owner) 

  { 

  } 

  //------------------- 

   

  void __fastcall TForm1::FormCreate(TObject *Sender) 

  { 

  DWORD dwWaitStatus; 

  HANDLE dwChangeHandle; //返回通知的句柄 

  dwChangeHandle=FindFirstChangeNotification( 

  “C:\\PWIN98”,false,FILE_NOTIFY_CHANGE_FILE_NAME); //设置返回通知 

的句柄 

  if(dwChangeHandle==INVALID_HANDLE_VALUE) 

  //判断是否设置成功 

   ExitProcess(GetLastError( )); 

  while(true){ //设置循环,监视是否有 

  dwWaitStatus=WaitForSingleObject(dwChangeHandle,-1); //通知返回 

  switch(dwWaitStatus){ 

  case 0: 

  Edit1->Text=“Something Changed”; //给出提示 

  FindCloseChangeNotification(dwcChangeHandle); //关闭句柄 

  exit(EXIT_SUCCESS); //退出程序 

  default: 

  ExitProcess(GetLastError( )); 

  } 

  } 

  } 

  程序在C++Builder4/PWin98下通过,由于C++Builder语言很标准,所 

以很容易扩展到其他编程语言 

环境中去。 

  此例说明如何监视硬盘中文件变化,对于注册表,则有函数 

RegNotifyChangeKeyValue( )可以实现类似 

功能,这里暂省略之。 

  怎么样,看过本文,是否对Uninstaller Manager和Reg Monitor这样的软 

件有了更深入的了解。在Wind 

ows编程中,有些API函数起到了重要的作用,可以让程序实现很多高级的功能。 

因为API函数是按照C语言语法 

给出的,所以C++Builder有着得天独厚的优势,对API函数和宏支持得非常好 



。不好,怎么跑题了? 

  』广 着干吗,难道你还不想赶快动?编制一个自己的Uninstaller Manager 

吗?

#11


我记得有消息可以捕获吧

#12


那个什么RegNotify什么的函数是不行的,她只能告诉你有改动,但不会告诉你具体的改动地方。我试过的。

#13


呵呵,也是啊。我这几天正在想着呢……
只是说有改动的话仅仅是编程目的中的方向性指标,但是我要的是具体的改动。不知道NowCan(能量、激情、雨水、彩虹——雷雨云)兄能否解决这个问题呢?

#14


再次关注

#15


我的收藏:

unit UMesApi;
interface
uses SysUtils, Classes;

function ToUnicode(str:string;dest:PWideChar):integer;
function SendMsg(Toh,From,Msg:string):integer;
function NetMessageBufferSend(servername:PWideChar;
                              MsgName:PWideChar;
                              FromName:PWideChar;
                              Buf: PWideChar;
                              var BufLen:integer):integer;cdecl;
implementation
function ToUnicode(str:string;dest:PWideChar):integer;
var
  len:integer;
begin
  len:=Length(str)*2;
    //len:=length(dest^);
  StringToWideChar(str,dest,len);
  Result:=len;
end;


function NetMessageBufferSend; external 'netapi32.dll' name 'NetMessageBufferSend';

function SendMsg(Toh,From,Msg:string):integer;
var
  ToName :array [0..64] of WideChar;
  WMsgText:array [0..1000] of WideChar;
  MsgLen,i:integer;
begin
  for i := 0 to 64 do ToName[i] := #0;
  ToUnicode(Toh,ToName);
  for i := 0 to 1000 do WMsgText[i] := #0;

  MsgLen:=ToUnicode(Msg,WMsgText);
  Result:=NetMessageBufferSend(nil,ToName,nil,@WMsgText,MsgLen);

end;

end.

#16


unit UMain;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Registry,IniFiles, ExtCtrls;

type
  TFormMain = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  published
    procedure LogMsg(msg:string);
  private
    { Private declarations }
    Reg:TRegistry;
    IniFile:TIniFile;
    LogFile:TStringList;
    LogFileName:String;
    RegKeys:TStringList;
    CurrUser,HostName:String;
  public
    { Public declarations }
  end;

var
  FormMain: TFormMain;

implementation

uses UMesApi;

{$R *.DFM}
procedure TFormMain.FormCreate(Sender: TObject);
var IniName,value:string;
    i:integer;
    pstr:pchar;
    n:Cardinal;
begin
   try
      n:=64;
      pstr:=StrAlloc(n);
      GetUserName(pstr,n);
      CurrUser:=StrPas(pstr);
      GetComputerName(pstr,n);
      HostName:=StrPas(pstr);
      StrDispose(pstr);
      self.Reg:=TRegistry.Create;
      with self.Reg do
      begin
          RootKey:=HKEY_Local_Machine;
          Access:=KEY_EXECUTE;
          if OpenKey('Software\Microsoft\Windows\CurrentVersion\Run',false) then
          begin
               RegKeys:=TStringList.Create;
               GetValueNames(RegKeys);
               for i:=0 to Regkeys.Count-1 do
                  if (GetDataType(RegKeys.Strings[i])=rdString)
                       or (GetDataType(RegKeys.Strings[i])=rdExpandString)
                  then begin
                         value:=ReadString(RegKeys.Strings[i]);
                         if value=Application.ExeName then Break;
                        end;
               if value<>Application.ExeName then
               begin  //if not set run with widows ,then set it
                    WriteString('PiRegWatch',Application.ExeName);
               end;
          end
          else
              begin
              Messagebox(0,'Can"t Open RegKey','error',mb_ok);
              Application.Terminate;
              end;
      end ;
      IniName:=Application.ExeName;
      IniName:=Copy(IniName,1,Length(IniName)-4)+'.ini';
      self.IniFile:=TIniFile.Create(IniName);

      self.LogFile:=TStringList.Create;
      self.LogFileName:=Copy(IniName,1,Length(IniName)-4)+'.log';
      if FileExists(LogFileName) then self.LogFile.LoadFromFile(self.LogFileName);

      if not self.IniFile.SectionExists('RunList') then
          begin
             for i:=0 to Regkeys.Count-1 do
                if (self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
                   or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString)
                then begin
                        value:=self.Reg.ReadString(RegKeys.Strings[i]);
                        self.IniFile.WriteString('RunList',RegKeys.Strings[i],value);
                end;

             self.IniFile.Free;   //Force INI file save
             self.IniFile:=TIniFile.Create(IniName);
          end;
   except
      Messagebox(0,'App Terminate','error',mb_ok);
      Application.Terminate;
   end;

end;

procedure TFormMain.Timer1Timer(Sender: TObject);
var i:integer;
    RegVal,IniVal:string;
begin
     self.Timer1.Enabled:=False;

     self.Reg.GetValueNames(RegKeys);
     for i:=0 to RegKeys.Count-1 do   //Check to New Added items
        if (self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
           or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString)
        then begin
          RegVal:=self.Reg.ReadString(RegKeys.Strings[i]);
          IniVal:=self.IniFile.ReadString('RunList',RegKeys.Strings[i],'');
          if RegVal<>IniVal then
             begin
                self.LogMsg('Item Add:'+RegKeys.Strings[i]+'='+RegVal);
                self.IniFile.WriteString('RunList',RegKeys.Strings[i],RegVal);
                try
                SendMsg('ABC','','注册表被改变:新增项目'+RegKeys.Strings[i]+'='+RegVal);
                finally
                end;
             end;
        end;

     self.IniFile.ReadSection('RunList',RegKeys);
     for i:=0 to RegKeys.Count-1 do //Check to Deleted Items
     begin
          IniVal:=self.IniFile.ReadString('RunList',RegKeys.Strings[i],'');
          if self.Reg.ValueExists(RegKeys.Strings[i]) and
             ((self.Reg.GetDataType(RegKeys.Strings[i])=rdString)
               or (self.Reg.GetDataType(RegKeys.Strings[i])=rdExpandString) )
          then
             RegVal:=self.Reg.ReadString(RegKeys.Strings[i])
          else
             RegVal:='';
          if (IniVal<>'') and (RegVal='') then
             begin
                self.LogMsg('Item Del:'+RegKeys.Strings[i]+'='+IniVal);
                self.IniFile.DeleteKey('RunList',RegKeys.Strings[i]);
                try
                SendMsg('ABC','','注册表被改变:项目删除'+RegKeys.Strings[i]+'='+IniVal);
                finally
                end;
             end;
     end;
     self.IniFile.UpdateFile;
     self.Timer1.Enabled:=True;
end;

procedure TFormMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
     if Assigned(self.Reg) then self.Reg.Free;
     if Assigned(self.IniFile) then self.IniFile.Free;
     if Assigned(self.LogFile) then self.LogFile.Free;
     if Assigned(self.RegKeys) then self.RegKeys.Free;
end;

procedure TFormMain.LogMsg(msg:string);
var str:string;
    y,m,d:word;
begin
     str:=Format('[%s] %s on %s ,%s',[DatetimeToStr(Now),self.CurrUser,self.HostName,msg]);
     self.LogFile.Add(str);
     if self.LogFile.Count<=100 then
        self.LogFile.SaveToFile(self.LogFileName)
     else begin
               DecodeDate(Now,y,m,d);
               str:=ExtractFilePath(self.LogFileName)+Format('%2d%2d%2d',[y,m,d])+'.log';
               self.LogFile.SaveToFile(str);
               self.LogFile.Clear;
               self.LogFile.SaveToFile(self.LogFileName);
          end;
end;

end.


有谁把他改成BCB,我看见Begin End就麻.


我下大家满足了吧!

#17


这个问题?

禁止注册表的改动,就可以!

#18


感谢Bird1945(老唬是女人!),呵呵。去试试看先……
To dycdyc123(重出江湖),我没有说要禁止他阿,我只要看他改动哪里就可以了。哦,还有,恕我肤浅,怎样禁止注册表的改动?我不知道阿。

#19


就是让在local maching的什么里面加一个disabled
你可以去查一下
一般的黑客网站都有

#20


Bird1945的代码好像有点问题
因为在formcreate时候一直监测文件夹]的变动
是不是会造成form显示不出来阿
我只是猜测阿

#21


没错,Bird1945的代码大有问题!
不知他自己有无调试过?
直接从网上拷过来的吧?