Denny577 Posted January 19, 2009 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
wolf9228 Posted January 19, 2009 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 صرح السماء كان هنا
Denny577 Posted January 19, 2009 Author 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.
wolf9228 Posted January 19, 2009 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. صرح السماء كان هنا
SkinnyWhiteGuy Posted January 20, 2009 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.
Denny577 Posted January 20, 2009 Author 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
wolf9228 Posted January 21, 2009 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 صرح السماء كان هنا
Denny577 Posted January 21, 2009 Author 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
LoWang Posted October 27, 2010 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
LoWang Posted November 1, 2010 Posted November 1, 2010 Forums were down recently so I hope now somebody has a clue when it's back again
LoWang Posted November 13, 2010 Posted November 13, 2010 too bad It seems I am destined to ask questions nobody knows the answer for :-] Biatu 1
VAN0 Posted December 7, 2018 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
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