News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

RegEnumValue

Started by Don57, January 09, 2013, 06:29:38 AM

Previous topic - Next topic

Don57

I am using the code example from dedndave to enumerate the registry for installed apps. It works fine listing one app at a time,  whose name or GUID I then save to a buffer sequentially.

          invoke RegOpenKeyEx, HKEY_LOCAL_MACHINE, offset sz_SubKey, NULL, KEY_ALL_ACCESS, offset hKeyKey         
          or eax,eax
          jnz Exit_RegOpen                                                      ; exit if error on open

          INVOKE  RegQueryInfoKey,hKeyKey,eax,eax,eax,offset dw_Count,offset dw_BufSize,eax,eax,eax,eax,eax,eax
          cmp     dw_BufSize,sizeof sz_Buffer-1
          ja  Exit_RegEnum                                                    ;exit if our buffer is too small

          mov ecx,dw_Count                                                    ; number of entries
          xor edx,edx

          Next_Entry:
             push ecx
             mov  dw_BufSize, sizeof sz_Buffer-1
             push edx
             xor  ecx,ecx
             invoke  RegEnumKeyEx,hKeyKey,edx,offset sz_Buffer,offset dw_BufSize,ecx,ecx,ecx,ecx
             pop  edx
             pop  ecx
             inc  edx
             dec  ecx

             CALL Save_Entry                                                  ; dump single entry to buffer

             cmp  ecx,0
             jnz  Next_Entry
             
          Exit_RegOpen:

             invoke RegCloseKey, hKeyKey

          Exit_RegEnum:

Now I wish to enumerate the subkeys in each entry usin RegEnumValue. When I place the call after CALL Save_Entry, according to OLLY the call succeeds, but no data is being dumped to the assigned buffers.

invoke RegEnumValue, hKeyKey, edx, offset lp_RegDataName, offset lp_RegDataNameLen, NULL, offset lp_RegDataType, offset lp_RegData, offset lp_RegDataLen


Does the RegEnumValue call replace the RegEnumKeyEx call.  edx uses the same counter as the RegEnumKeyEX call. I've been reading the microsoft data sheets for 2 days and it looks like I've got it right but it doesn't work.

qWord

you may attach the full source that fails?
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

for each subkey that is enumerated by RegEnumKeyEx,
you must open a handle to the subkey
you can then enumerate the subkeys and/or values under that
then, you want to close that subkey handle

what you may want to do is to make a PROC out of it
then, use LOCALS for the handles, subkeys, and values

that way, you can call the routine, recursively
with each level of recursion, prepend 2 spaces to the keys and values
that will make it a little easier to read   :P

hfheatherfox07

Quote from: qWord on January 09, 2013, 07:10:03 AM
you may attach the full source that fails?

It is Top Secret  LOL

@ Don57

gunner made such an example already  :biggrin:

Download:
http://www.dreamincode.net/forums/index.php?app=core&module=attach&section=attach&attach_id=29746&s=34a925358ed7c821f7d2db53161e6a70



I hope I am not stepping on any toes posting this  :(
Sorry If I am Gunner
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

Don57

Not top secret, I just enjoy writting the code myself. I try to understand the paradigm, then work the code out from there. Thanks for the help.

hfheatherfox07

You are welcome, Gunners help really

Part of the charm of this place is that people take their time to help one another , if you noticed most topics have a solution ....we come up on searches for years to come.  So lets suppose 5 years from now some has the  same question and Google it (or even members using the search) , when they get to see this thread it is nice to have a working solution!
I make it a habit to post a source with my posts .... You can always post a little window with just the part that you need help with .... Like a bare bones example. That way you can still enjoy working on your own code, and other can reference this topic ..... Can you imagine no masm sources on the net ? And only snippets that you know the answers too?
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

Greenhorn

If I look at the code from post #1 I think you're enumerating just the first value of the Subkey.
That value is almost the "Default" key which is empty. Could that be the case ? ;o)
Kole Feut un Nordenwind gift en krusen Büdel un en lütten Pint.

Gunner

Quote from: hfheatherfox07 on January 09, 2013, 08:07:04 PM
I hope I am not stepping on any toes posting this  :(
Sorry If I am Gunner

Not at all!  It was written to help all!
~Rob

Don57

Still having trouble reading the subkey. Everything works fine except the Read_SubKey Proc.

dedndave

right off, i see this problem...
QuoteRead_SubKey PROC

     
      CALL ParsePath                                                          ; path for sub key enumeration

invoke MessageBox,0,offset sz_Buffer2,0,0

      INVOKE RegOpenKeyEx, HKEY_LOCAL_MACHINE, offset sz_Buffer2, NULL, KEY_ALL_ACCESS, offset hSubKey

push eax
invoke GetLastError
invoke MessageBox,0,uhex$(eax),0,0
pop  eax
 
      or eax,eax
      jnz Exit_RegSubOpen                                                     ; exit if error on open

      xor edx,edx                                                             ; zero index

      Next_SubEntry:

         push edx
         xor  ecx,ecx
         INVOKE  RegEnumKeyEx,hSubKey,edx,offset lp_BufferEntry,offset dw_BufSize,ecx,ecx,ecx,ecx

         pop  edx
         inc  edx
         cmp  eax,ERROR_NO_MORE_ITEMS
         jne  Next_SubEntry
             

      Exit_RegSubEnum:

         INVOKE RegCloseKey, hKeyKey

      Exit_RegSubOpen:

      ret

Read_SubKey ENDP

oops   :biggrin:

that may not be the only issue.....

Don57

Thanks. Too much copy and paste.

dedndave

one thing you can do.....
when you open the key "HKLM\level1\level2", you can pass that handle to the next OpenKey call...
and use "level3" as the key string to open "HKLM\level1\level2\level3"

qWord

you use push/pop to save (counter/index-) registers across calls - it is maybe more efficient and readable to use local variables instead.
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

ok
when you make the "original" RegEnumKeyEx call....
         mov  dw_BufSize, sizeof sz_Buffer-1
         push edx
         xor  ecx,ecx
         INVOKE  RegEnumKeyEx,hKeyKey,edx,offset sz_Buffer,offset dw_BufSize,ecx,ecx,ecx,ecx

you initialize the buffer size variable to the size of the buffer
when the function returns, it fills that variable with the length of the returned string (if successful)

now, when you call Read_SubKey, it thinks the buffer is that big   :P
the normal practice would be to re-initialize that variable each time you call RegEnumKeyEx
that way, the function uses the buffer size, not the size of the last returned string

so - you want to add a line of code in the Read_SubKey proc just before each call to RegEnumKeyEx
      Next_SubEntry:

         push edx
         xor  ecx,ecx
         mov  dw_BufSize, sizeof sz_Buffer-1
         INVOKE  RegEnumKeyEx,hSubKey,edx,offset lp_BufferEntry,offset dw_BufSize,ecx,ecx,ecx,ecx

         pop  edx
         inc  edx
         cmp  eax,ERROR_NO_MORE_ITEMS
         jne  Next_SubEntry

dedndave

another thing to mention....

      Next_SubEntry:

         push edx
         xor  ecx,ecx
         mov  dw_BufSize, sizeof sz_Buffer-1
         INVOKE  RegEnumKeyEx,hSubKey,edx,offset lp_BufferEntry,offset dw_BufSize,ecx,ecx,ecx,ecx

         pop  edx
         inc  edx
         cmp  eax,ERROR_NO_MORE_ITEMS
         jne  Next_SubEntry


notice that the function may fail for reasons other than ERROR_NO_MORE_ITEMS
it's ok - your loop will continue to run until the last item
but other errors may be returned that you should handle, like the buffer is too small
if EAX is anything other than 0, you may not want to not try to delete the key or something   :biggrin: