Denny577 Posted January 19, 2009 Share Posted January 19, 2009 (edited) First post =)I found out how to monitor the registry with RegistryKeyChangeEvent with the help of MSDN and XxXFaNtA's example script, only problem is, this class doesn't support HKEY_CURRENT_USER. I found an article about defining a registry class (here) and I was wondering whether this is possible with AutoIt (to create a class for the HKEY_CURRENT_USER hive).Example:;~ Credits must go to XxXFaNtA =) Global $o_WMI, $o_Sink, $s_Query $o_Sink = ObjCreate("WbemScripting.SWbemSink") ObjEvent($o_Sink , "SINK_") $s_Query = 'Select * FROM RegistryKeyChangeEvent WHERE Hive="HKEY_CURRENT_USER" AND KeyPath="Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"' $o_WMI = ObjGet('winmgmts:\\' & @ComputerName & '\root\default') If Not @error Then $o_WMI.ExecNotificationQueryAsync($o_Sink, $s_Query, Default, Default, Default) ConsoleWrite("Ready and waiting for changes") EndIf While 1 Sleep(100) WEnd Func SINK_OnObjectReady($objLatestEvent, $objAsyncContext) ConsoleWrite($objLatestEvent.GetObjectText_()) EndFunc ;==>SINK_OnObjectReadyIf you run this, it produces:C:\Documents and Settings\Dennis\Mijn documenten\AutoIt\Test2.au3 (10) : ==> The requested action with this object has failed.: $o_WMI.ExecNotificationQueryAsync($o_Sink, $s_Query, Default, Default, Default) $o_WMI.ExecNotificationQueryAsync($o_Sink, $s_Query, Default, Default, Default)^ ERRORIf all this is just not possible, is there a way to monitor HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall and HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall without WMI in a not too resource-wasting manner?Regards, Dennis =) Edited January 20, 2009 by Denny577 Link to comment Share on other sites More sharing options...
wolf9228 Posted January 19, 2009 Share Posted January 19, 2009 (edited) $strComputer = "." $objWMIServices = ObjGet( _ "winmgmts:{impersonationLevel=impersonate}!\\" & _ $strComputer & "\root\default") $objSink = ObjCreate( _ "WbemScripting.SWbemSink") $oMyEvent = ObjEvent($objSink,"SINK") if IsObj($oMyEvent) Then MsgBox(0,"","OK") $objWMIServices.ExecNotificationQueryAsync ($objSink, _ "SELECT * FROM RegistryKeyChangeEvent " _ & "WHERE Hive='HKEY_LOCAL_MACHINE' AND " _ & "KeyPath='Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall'" ) While(True) Sleep(1000) Wend Func SINK_OnObjectReady($wmiObject, $wmiAsyncContext) MsgBox(0,"", "Received Registry Change Event" _ & @CRLF & $wmiObject.GetObjectText_()) EndFunc Edited January 19, 2009 by wolf9228 صرح السماء كان هنا Link to comment Share on other sites More sharing options...
Denny577 Posted January 19, 2009 Author Share Posted January 19, 2009 I already use the example I posted, only with Hive="HKEY_LOCAL_MACHINE". The HKEY_CURRENT_USER part was the problem. Link to comment Share on other sites More sharing options...
wolf9228 Posted January 19, 2009 Share Posted January 19, 2009 I already use the example I posted, only with Hive="HKEY_LOCAL_MACHINE". The HKEY_CURRENT_USER part was the problem. http://msdn.microsoft.com/en-us/library/aa393040(VS.85).aspxName of the hive (subtree) that contains the key (or keys) that is changed. For example, HKEY_LOCAL_MACHINE. Changes to the HKEY_CLASSES_ROOT and HKEY_CURRENT_USER hives are not supported by RegistryEvent or classes derived from it, such as RegistryKeyChangeEvent. صرح السماء كان هنا Link to comment Share on other sites More sharing options...
SkinnyWhiteGuy Posted January 20, 2009 Share Posted January 20, 2009 HKEY_CURRENT_USER is actually just a mapped location under HKEY_LOCAL_MACHINE\System\ControlSet00X, where the ControlSet00X is whichever it is mapped to. Read the value from HKEY_LOCAL_MACHINE\System\Select\Current to get which control set to look in. It is possible to do what you want, just in a round about way. Link to comment Share on other sites More sharing options...
Denny577 Posted January 20, 2009 Author Share Posted January 20, 2009 (edited) http://msdn.microsoft.com/en-us/library/aa393040(VS.85).aspx Name of the hive (subtree) that contains the key (or keys) that is changed. For example, HKEY_LOCAL_MACHINE. Changes to the HKEY_CLASSES_ROOT and HKEY_CURRENT_USER hives are not supported by RegistryEvent or classes derived from it, such as RegistryKeyChangeEvent. I believe I clearly stated the fact that I found out that HKEY_CURRENT_USER wasn't supported, and was asking whether there might be an other way to do the same? I found out how to monitor the registry with RegistryKeyChangeEvent with the help of MSDN and XxXFaNtA's example script, only problem is, this class doesn't support HKEY_CURRENT_USER. Ring any bells? @SkinnyWhiteGuy, Thank you very much, I will try it right now. EDIT: I just tried, but... HKEY_LOCAL_MACHINE\System\Select\Current = 1 HKEY_LOCAL_MACHINE\System\ControlSet001 doesn't quite look like HKEY_CURRENT_USER. I did find that HKEY_LOCAL_MACHINE\System\ControlSet001\HardwareProfiles\Current and HKEY_LOCAL_MACHINE\System\CurrentControlSet\HardwareProfiles\Current both look like HKEY_CURRENT_CONFIG But nothing seems to look like HKEY_CURRENT_USER. Am I on the right track? EDIT: I found that HKEY_USERS\S-1-5-21-1935655697-1960408961-1547161642-1004 is HKEY_CURRENT_USER and HKEY_USERS\S-1-5-21-1935655697-1960408961-1547161642-1004_Classes is HKEY_CLASSES_ROOT. I found this snippet on the Hey, Scripting Guy page: strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") Set objAccount = objWMIService.Get _ ("Win32_UserAccount.Name='kenmyer',Domain='atl-ws-01'") Wscript.Echo objAccount.SID</span> From which I managed to create this function: Func _GetSID($s_User = @UserName, $s_Domain = @LogonDomain) Local $o_WMI = ObjGet("winmgmts:\\.\root\cimv2") If Not IsObj($o_WMI) Then Return SetError(1, 0, -1) Local $s_SID = $o_WMI.Get("Win32_UserAccount.Name='" & $s_User & "',Domain='" & $s_Domain & "'") Return $s_SID.SID EndFuncoÝ÷ Ù*&Èr`%DCSQ!²Úâ(¹^Â+aEè"²Úò)ì©àxKÞÜ(ºW[y«¢+ØÌäí!-e}UMILÀäÈìÌäìµÀì}ÑM% ¤µÀìÌäìÀäÈíM½ÑÝÉÀäÈí5¥É½Í½ÐÀäÈí]¥¹½ÝÌÀäÈí ÕÉɹÑYÉÍ¥½¸ÀäÈíU¹¥¹Íѱ°Ìäì Problem solved. @SkinnyWhiteGuy, Thanks again Regards =) Edited January 20, 2009 by Denny577 Link to comment Share on other sites More sharing options...
wolf9228 Posted January 21, 2009 Share Posted January 21, 2009 expandcollapse popup#Include <EventLog.au3> #Include <WinAPI.au3> #Include <Array.au3> Const $HKEY_CLASSES_ROOT = 0x80000000 Const $HKEY_CURRENT_USER = 0x80000001 Const $HKEY_LOCAL_MACHINE = 0x80000002 Const $HKEY_USERS = 0x80000003 Const $HKEY_CURRENT_CONFIG = 0x80000005 Const $READ_CONTROL = 0x20000 Const $STANDARD_RIGHTS_READ = ($READ_CONTROL) Const $KEY_QUERY_VALUE = 0x1 Const $KEY_ENUMERATE_SUB_KEYS = 0x8 Const $KEY_NOTIFY = 0x10 Const $REG_NOTIFY_CHANGE_NAME = 0x1 Const $REG_NOTIFY_CHANGE_ATTRIBUTES = 0x2 Const $REG_NOTIFY_CHANGE_LAST_SET = 0x4 Const $REG_NOTIFY_CHANGE_SECURITY = 0x8 Const $KEY_READ = BitOR($STANDARD_RIGHTS_READ, $KEY_QUERY_VALUE, $KEY_ENUMERATE_SUB_KEYS, $KEY_NOTIFY) Dim $dwFilter = BitOR($REG_NOTIFY_CHANGE_NAME, $REG_NOTIFY_CHANGE_ATTRIBUTES, $REG_NOTIFY_CHANGE_LAST_SET, $REG_NOTIFY_CHANGE_SECURITY) Global $Func ,$hEvent,$hEventLog ;RegNotifyChangeKeyValue Function ;http://msdn.microsoft.com/en-us/library/ms724892.aspx ;RegOpenKeyEx Function ;http://msdn.microsoft.com/en-us/library/ms724897.aspx RegistryChange() While 1 WEnd Func RegistryChange($STR_KEY = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Wbem", _ $REG_NOTIFY_CHANGE = $dwFilter , $bWatchSubtree = True , $ReturnFunc = "myFunc") $Func = $ReturnFunc Local $lpSubKey ,$phkResult , $ulOptions = 0 , $samDesired = $KEY_READ _ ,$dwNotifyFilter = $REG_NOTIFY_CHANGE , $fAsynchronous = True $hEventLog = _EventLog__Open ("", "RegistryChange") $hEvent = _WinAPI_CreateEvent (0, False, False, "") _EventLog__Notify ($hEventLog, $hEvent) $StringSplit = StringSplit($STR_KEY, "\") $CaseStr = StringUpper($StringSplit[1]) Select Case $CaseStr = "HKLM" Or $CaseStr = "HKEY_LOCAL_MACHINE" $Long_KEY = $HKEY_LOCAL_MACHINE Case $CaseStr = "HKCU" Or $CaseStr = "HKEY_CURRENT_USER" $Long_KEY = $HKEY_CURRENT_USER Case $CaseStr = "HKCR" Or $CaseStr = "HKEY_CLASSES_ROOT" $Long_KEY = $HKEY_CLASSES_ROOT Case $CaseStr = "HKU" Or $CaseStr = "HKEY_USERS" $Long_KEY = $HKEY_USERS Case $CaseStr = "HKCC" Or $CaseStr = "HKEY_CURRENT_CONFIG" $Long_KEY = $HKEY_CURRENT_CONFIG EndSelect $STR_KEY2 = $STR_KEY Do $STR_KEY2 = StringTrimLeft($STR_KEY2,1) Until StringLeft($STR_KEY2 , 1) = "\" or $STR_KEY2 = "" $lpSubKey = StringTrimLeft($STR_KEY2 , 1) $Structhar = DllStructCreate("char[" & StringLen($lpSubKey) + 1 & "]") DllStructSetData($Structhar, 1, $lpSubKey) $phkResult = DllStructCreate("int") $DllCall = DllCall("Advapi32.dll","long","RegOpenKeyEx","int",$Long_KEY,"ptr", _ DllStructGetPtr($Structhar),"int",$ulOptions,"long",$samDesired,"ptr",DllStructGetPtr($phkResult)) If @error Then Return 0 $hKey = DllStructGetData($phkResult, 1) $DllCall = DllCall("Advapi32.dll","long","RegNotifyChangeKeyValue","int",$hKey,"int", _ $bWatchSubtree,"int",$dwNotifyFilter,"int",$hEvent,"int",$fAsynchronous) If @error Then Return 0 AdlibEnable("ChkeRegistryChange") Return 1 EndFunc Func ChkeRegistryChange() $iResult = _WinAPI_WaitForSingleObject ($hEvent,0) if $iResult = 0 Then AdlibDisable ( ) $aEvent = _EventLog__Read($hEventLog) Call ($Func,$aEvent) EndIf EndFunc Func myFunc($DATA) _ArrayDisplay($DATA, "EventLog__Read") EndFunc صرح السماء كان هنا Link to comment Share on other sites More sharing options...
Denny577 Posted January 21, 2009 Author Share Posted January 21, 2009 That might actually work, but it's constantly checking for changes. I prefer it being event-driven (which works now ) Regards Link to comment Share on other sites More sharing options...
LoWang Posted October 27, 2010 Share Posted October 27, 2010 (edited) Great, it works. But please do you have an idea how to get more info then just GetObjectText_() from it? For example which process did that registry change. Of course I am talking about malware hunting ;-) But probably this information is just not available this way. Although sysinternals Process Monitor somehow does it...technet scripting guy - read the last paragraphso it seems it really is not possible by this method. So I wonder how does the process monitor do it? Edited October 27, 2010 by LoWang Link to comment Share on other sites More sharing options...
LoWang Posted November 1, 2010 Share Posted November 1, 2010 Forums were down recently so I hope now somebody has a clue when it's back again Link to comment Share on other sites More sharing options...
LoWang Posted November 2, 2010 Share Posted November 2, 2010 bump Link to comment Share on other sites More sharing options...
LoWang Posted November 13, 2010 Share Posted November 13, 2010 too bad It seems I am destined to ask questions nobody knows the answer for :-] Biatu 1 Link to comment Share on other sites More sharing options...
VAN0 Posted December 7, 2018 Share Posted December 7, 2018 (edited) @Denny577 your example with _GetSID works wonderfully! Thank you. Is there a way get information what exactly was changed? (added/deleted/modified, name of the value, etc) Edited December 7, 2018 by VAN0 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now