Jump to content

Hooking registry changes?


Recommended Posts

Is there a way I can have autoit monitor the registry or a set of keys for realtime changes and writes(I believe that a hook of some kind is the only way but I may be wrong). I have tried a loop to do before and after comparisons of keys but it is not catching temporary writes to the registry.

Edited by billym
Link to comment
Share on other sites

Is there a way I can have autoit monitor the registry or a set of keys for realtime changes and writes(I believe that a hook of some kind is the only way but I may be wrong). I have tried a loop to do before and after comparisons of keys but it is not catching temporary writes to the registry.

<{POST_SNAPBACK}>

maybe you should check this out "RegMon"

RegMon

hope it helps

8)

NEWHeader1.png

Link to comment
Share on other sites

maybe you should check this out "RegMon"

RegMon

hope it helps

8)

<{POST_SNAPBACK}>

This is a small but important piece of a project I am working on. I really need all of the functionality self contained in this case, although that is the kinda hooking I am looking for. Just need to do it somehow in autoit.
Link to comment
Share on other sites

Is there a way I can have autoit monitor the registry or a set of keys for realtime changes and writes(I believe that a hook of some kind is the only way but I may be wrong). I have tried a loop to do before and after comparisons of keys but it is not catching temporary writes to the registry.

<{POST_SNAPBACK}>

I used to have a VB6 program that did this through DLL calls. I'll see if I can find it and you can translate it to AutoIt.
Link to comment
Share on other sites

OK, here's the routine to set the watch hook:

CODE

Declare Function OSRegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long

Declare Function OSRegNotifyChangeKeyValue Lib "advapi32.dll" Alias "RegNotifyChangeKeyValue" (ByVal hKey As Long, ByVal bWatchSubTree As Long, ByVal dwNotifyFilter As Long, ByVal hEvent As Long, ByVal fAsynchronus As Long) As Long

Declare Function OSRegCloseKey Lib "advapi32.dll" Alias "RegCloseKey" (ByVal hKey As Long) As Long

Public Sub RegMonitor(hKey As Long, sRegKeyPath As String, bWatchSubTree As Boolean, dwFilters As Long)

Dim lKeyHandle As Long, lRet As Long

lRet = OSRegOpenKey(hKey, sRegKeyPath, lKeyHandle)

OSRegNotifyChangeKeyValue lKeyHandle, bWatchSubTree, dwFilters, 0&, False

lRet = OSRegCloseKey(lKeyHandle)

End Sub

I don't remember how to check if the key(s) have been changed or not.

Here's the constants to help you out:

CODE

' Reg Return Error Constants

Public Const ERROR_SUCCESS = 0& ' Operation Successfull

Public Const ERROR_NONE = 0 ' No Errors

Public Const ERROR_BADDB = 1 ' Corrupt Registry Database

Public Const ERROR_BADKEY = 2 ' Key Name Is Bad

Public Const ERROR_CANTOPEN = 3 ' Unable To Open Key

Public Const ERROR_CANTREAD = 4 ' Unable To Read Key

Public Const ERROR_CANTWRITE = 5 ' Unable To Write Key

Public Const ERROR_OUTOFMEMORY = 6 ' Out Of Memory

Public Const ERROR_ARENA_TRASHED = 7 ' Unknown Error

Public Const ERROR_ACCESS_DENIED = 8 ' Registry Access Denied

Public Const ERROR_INVALID_PARAMETERS = 87 ' Invalid Parameter

Public Const ERROR_MORE_DATA = 234

Public Const ERROR_NO_MORE_ITEMS = 259 ' No More Items

' Reg Key ROOT Locations

Public Const HKEY_CLASSES_ROOT = &H80000000

Public Const HKEY_CURRENT_CONFIG = &H80000005

Public Const HKEY_CURRENT_USER = &H80000001

Public Const HKEY_DYN_DATA = &H80000006

Public Const HKEY_LOCAL_MACHINE = &H80000002

Public Const HKEY_PERFORMANCE_DATA = &H80000004

Public Const HKEY_USERS = &H80000003

' I Thought You Would Like This

Public Const HKCR = HKEY_CLASSES_ROOT

Public Const HKCC = HKEY_CURRENT_CONFIG

Public Const HKCU = HKEY_CURRENT_USER

Public Const HKDD = HKEY_DYN_DATA

Public Const HKLM = HKEY_LOCAL_MACHINE

Public Const HKPD = HKEY_PERFORMANCE_DATA

Public Const HKUS = HKEY_USERS

' Reg Value Data Types

Public Const REG_NONE = 0 ' No value type

Public Const REG_SZ = 1 ' Unicode nul terminated string

Public Const REG_EXPAND_SZ = 2 ' Unicode nul terminated string

Public Const REG_BINARY = 3 ' Free form binary

Public Const REG_DWORD = 4 ' 32-bit number

Public Const REG_DWORD_LITTLE_ENDIAN = 4 ' 32-bit number (same as REG_DWORD)

Public Const REG_DWORD_BIG_ENDIAN = 5 ' 32-bit number

Public Const REG_LINK = 6 ' Symbolic Link (unicode)

Public Const REG_MULTI_SZ = 7 ' Multiple Unicode strings

Public Const REG_RESOURCE_LIST = 8 ' Resource list in the resource map

Public Const REG_FULL_RESOURCE_DESCRIPTOR = 9 ' Resource list in the hardware description

Public Const REG_RESOURCE_REQUIREMENTS_LIST = 10 '

Public Const REG_CREATED_NEW_KEY = &H1 ' New Registry Key created

Public Const REG_OPENED_EXISTING_KEY = &H2 ' Existing Key opened

Public Const REG_WHOLE_HIVE_VOLATILE = &H1 ' Restore whole hive volatile

Public Const REG_REFRESH_HIVE = &H2 ' Unwind changes to last flush

Public Const REG_NOTIFY_CHANGE_NAME = &H1 ' Create or delete (child)

Public Const REG_NOTIFY_CHANGE_ATTRIBUTES = &H2 '

Public Const REG_NOTIFY_CHANGE_LAST_SET = &H4 ' Time stamp

Public Const REG_NOTIFY_CHANGE_SECURITY = &H8 '

These snippets were taken from a code library by Randy Mcdowell

Edited by blindwig
Link to comment
Share on other sites

err, nevermind. I just found my source for that project (about 2 years ago) and it looks like I never got the hook thing working so I just wrote a service to check the values every so many milliseconds and throw a flag for my program to do it's thing.

Link to comment
Share on other sites

  • 8 months later...

I kinda got this to work....

I looked up RegNotifyChangeKeyValue here

http://www.mentalis.org/apilist/RegNotifyC...eKeyValue.shtml

I found this thread involving the windows API and the registry

http://www.autoitscript.com/forum/index.ph...c=11441&hl=

EDIT

After reading this

http://msdn.microsoft.com/library/en-us/sy...ngekeyvalue.asp

and looking over the code from the above post i got this to work now!

You have to change something in the registry in order for this to exit correctly. I change a service display name when testing.

MsgBox(0, "Count:", _RegKeyMon("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services") & @CRLF & @error)

Func _RegKeyMon($s_key)
    Local $advapi32 = DllOpen("advapi32.dll")
    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        ;Create or delete (child)
    Const $REG_NOTIFY_CHANGE_ATTRIBUTES = 0x2
    Const $REG_NOTIFY_CHANGE_LAST_SET = 0x4    ;time stamp
    Const $REG_NOTIFY_CHANGE_SECURITY = 0x8
    Const $REG_NOTIFY_ALL = BitOR($REG_NOTIFY_CHANGE_NAME, $REG_NOTIFY_CHANGE_ATTRIBUTES, $REG_NOTIFY_CHANGE_LAST_SET, $REG_NOTIFY_CHANGE_SECURITY)
    
    Local $p, $a_key = StringSplit($s_key, "\"), $key, $subkey, $i
    
    Switch StringUpper($a_key[1])
        Case "HKLM" Or "HKEY_LOCAL_MACHINE"
            $key = $HKEY_LOCAL_MACHINE
        Case "HKU" Or "HKEY_USERS"
            $key = $HKEY_USERS
        Case "HKCU" Or "HKEY_CURRENT_USER"
            $key = $HKEY_CURRENT_USER
        Case "HKCR" Or "HKEY_CLASSES_ROOT"
            $key = $HKEY_CLASSES_ROOT
        Case "HKCC" Or "HKEY_CURRENT_CONFIG"
            $key = $HKEY_CURRENT_CONFIG
    EndSwitch
    
    For $i = 2 To $a_key[0]
        $subkey = $subkey & $a_key[$i] & "\"
    Next
    $subkey = StringTrimRight($subkey, 1)
    Local $str = DllStructCreate("char[" & StringLen($subkey) + 1 & "]")
    DllStructSetData($str, 1, $subkey)
    Local $handle = DllStructCreate("int")
    
    DllCall($advapi32, "long", "RegOpenKeyEx", _
            "int", $key, _
            "ptr", DllStructGetPtr($str), _
            "int", 0, _
            "long", BitOR($STANDARD_RIGHTS_READ, $KEY_QUERY_VALUE, $KEY_ENUMERATE_SUB_KEYS, $KEY_NOTIFY), _
            "ptr", DllStructGetPtr($handle))
    If @error Then
        $str = 0
        $handle = 0
        SetError(1)
        Return 0
    EndIf
    Local $i_handle = DllStructGetData($handle, 1)
    
    MsgBox(0, $i_handle, "WARNING You have to change/add a key to the registry at this location" & @CRLF & @CRLF & $s_key & @CRLF & @CRLF & "othewise this program will not exit")
    
    $x = DllCall($advapi32, _
            "long", "RegNotifyChangeKeyValue", _;Long
            "long", $i_handle, _;hKey Long: Identifies a currently open key
            "long", True, _;bWatchSubtree Long: bWatchSubtree Specifies a flag that indicates whether to report changes in the specified key and all of its subkeys or only in the specified key
            "long", $REG_NOTIFY_ALL, _;dwNotifyFilter Long: Specifies a set of flags that control which changes should be reported
            "long", "", _;hEvent Long: Identifies an event. Changes are reported by signaling this event
            "long", False);fAsynchronus Long: Specifies a flag that indicates how the function reports changes

    DllCall($advapi32, "long", "RegCloseKey", "int", DllStructGetData($handle, 1))
    DllClose($advapi32)
    $str = 0
    $handle = 0
    Return $x
EndFunc  ;==>_RegKeyMon
Edited by mikeytown2
Link to comment
Share on other sites

  • 4 months later...

I just find this old project. The registry change is catched but the Count message box is empty. Shouldn't it show something? And second question, is there any chance to show what exactly was done in registry and which key/value has been changed/deleted?

Thanks in advance for any help!

Edited by odklizec
Link to comment
Share on other sites

  • 4 months later...

lol yeah i've been MIA. Finals are done!

Anyway this program calls this DLL advapi32.dll which has this function inside of it RegNotifyChangeKeyValue. This function has 2 return values...

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in Winerror.h. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

In short this returns nothing when it succeeds. Thus having the Count message box empty is no problem. As for why i called it Count, your guess is as good as mine; i think i might have been playing with hEvent and fAsynchronous flags as that would make this multi threaded. Doing something like that is beyond me because you need the CreateEvent() function out of the windows.h C++ Library.
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...