用Delphi5.0實現注冊表監視
隨著Internet的不斷普及,網絡安全越來越受到人們的重視。除了計算機病毒以外,網上不斷出現的的各類黑客軟件、遠程控制軟件等,更讓人們對自己的機器越來越不放心。而這類軟件的多樣性及不斷更新等,使得單靠一些防病毒軟件已不能完全保護自己的機器。 |
| 有沒有什么好的方法防止來歷不明的軟件安裝在自己的機器上呢?答案就是密切注意系統關鍵文件的變化。大家都知道,一個程序如果要在Windows啟動時自動運行,一般有三種方法: |
| 1.在開始菜單的[啟動]組中加入快捷方式 |
| 2.在Win.ini中加入相關項目 |
| 3.在注冊表的 HKEY_Local_Machine/SoftWare/Microsoft/Windows/CurrentVersion/Run主鍵下加入指向自己的鍵值。 |
| 而第一種方法太明顯,很容易發現。所以一般的黑客程序使用后兩種方法啟動自己。筆者在此介紹一個自己編寫的簡單的注冊表監視器,用于實時監視注冊表中鍵值的變化,以發現不明來歷的程序。讀者有興趣的可以在此基礎上進一步完善。 |
| 程序設計思路 |
| 本程序用Delphi5.0開發。Delphi是Borland公司出品的快速可視化Windows程序開發工具,功能強大,易于使用。程序中通過一個定時器來實現每隔一定時間對注冊表比較一次。程序在啟動時保留一份原始的注冊表相關鍵值的數據備份,然后定時和當前的鍵值進行比較,如果發現變化,則提示用戶查看。 |
| 程序實現 |
| 1、在Delphi中建立一個新的PRoject,將Form1改名為FormMain |
| 2、在FormMain上放置一個定時器控件TTimer,將Project保存為PiRegWatch.Dpr |
| 3、修改PiRegWatch.Dpr中的代碼: |
| application.Initialize; |
| Application.CreateForm(TFormMain, FormMain); |
| //使主窗口啟動時不顯示 |
| Application.ShowMainForm:=False; |
| Application.Run; |
| 在FormMain中增加幾個對象。 |
| 對象類型說明 |
| RegTregistry用于注冊表的訪問 |
| IniFileTiniFile用于保存原始注冊表數據 |
| LogTstringList用于記錄變化的日志 |
| RegKeysTstringList用于存放Run分支下的主鍵名 |
| 4、在FormMain:OnCreate事件中保留原始注冊表數據,主要代碼如下: |
| …… |
| self.Reg:=TRegistry.Create; |
| with self.Reg do |
| begin |
| RootKey:=HKEY_Local_Machine; |
| If OpenKey('Software/Microsoft/Windows/CurrentVersion/Run',false) |
| then |
| begin |
| RegKeys:=TStringList.Create; |
| GetValueNames(RegKeys); //取得Run下面的所有主鍵名 |
| 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; |
| end; |
| end; |
| end; |
| …… |
| 5、在TTimer1.OnTmer事件中加入比較注冊表的代碼。主要代碼如下: |
| 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 //檢查新加的和已修改了的鍵值 |
| 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 //檢查已被刪除的鍵值 |
| 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; |
| 6、在FormMain:OnClose事件中進行對象釋放及必要的清理工作 |
| 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; |
| 經過實際運行,該程序在發現來歷不明的程序方面確實能起到一定的作用。當然,它的功能也很單一,如果要進一步完善,增加監視系統其他關鍵文件的變化,則效果會更好。希望能與有興趣的讀者交流。 |
新聞熱點
疑難解答
圖片精選