News:

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

Main Menu

RegQueryValueEx

Started by jj2007, August 27, 2013, 02:16:53 AM

Previous topic - Next topic

jj2007

Simple idea:
  ; edi is dest buffer, esp is addr SizeValBuffer
  push -1         ; no limit
  invoke RegQueryValueEx, hKey, pValue, 0, addr rkType, edi, esp
  pop edx         ; balance stack

It works - sometimes. MSDN:

RegQueryValueEx(
  _In_         HKEY hKey,
  _In_opt_     LPCTSTR lpValueName,
  _Reserved_   LPDWORD lpReserved,
  _Out_opt_    LPDWORD lpType,
  _Out_opt_    LPBYTE lpData,
  _Inout_opt_  LPDWORD lpcbData

lpcbData [in, out, optional]

    A pointer to a variable that specifies the size of the buffer pointed to by the lpData parameter, in bytes. When the function returns, this variable contains the size of the data copied to lpData.


Only the boyz in Redmond know why it chokes with "unlimited" size. With 65k it works, apparently...

Zen

JOCHEN,
Why not call RegQueryValueEx twice ???
Discussion at Raymond Chen's Blog that doesn't even remotely relate to your problem:  Beware of Non-Null-Terminated Registry Strings, Aug 2004

jj2007

Quote from: Zen on August 27, 2013, 06:01:51 AM
JOCHEN,
Why not call RegQueryValueEx twice ???

Why should I??? ::)

GoneFishing

Hi Jochen,
WinDbg has very nice event filter . I could try to find out what an exception occurs there if I had some more lines of your code ( + data definitions )

jj2007

Hi vertograd,
Nice offer :t

An exe with int 3 before the call to RegQueryValueEx is attached.

If you want to build it yourself, you need the latest version of MB; afterwards, replace \Masm32\MasmBasic\MasmBasic.lib with the attached "special" edition.

include \masm32\MasmBasic\MasmBasic.inc        ; download
        Init
        mov f2sOlly, 123        ; flag for special edition of MasmBasic.lib
        void GetRegVal("HKCR\Applications\qeditor.exe\shell\open\command", 0, "No luck in HKCR/App...")
        deb 4, "Registry HKCR", $eax, $Err$()
        Inkey
        Exit
end start

Expected outcome:

Registry HKCR
$eax            "C:\masm32\qeditor.exe" "%1"
$Err$()         Operation successfully completed.

UnderWin7-32, it happened to me several times that it returned nothing, although the behaviour was not predictable. Everything is fine, though, since I replaced the push -1 for sizeofdata with 65k....

qWord

Quote from: jj2007 on August 27, 2013, 02:16:53 AMpush -1         ; no limit
[...]
A pointer to a variable that specifies the size of the buffer pointed to by the lpData parameter, in bytes.
[...]
Only the boyz in Redmond know why it chokes with "unlimited" size.
you may try it with a valid buffer.
MREAL macros - when you need floating point arithmetic while assembling!

MichaelW

It works for me, Windows XP SP3.

;==============================================================================
include \masm32\include\masm32rt.inc
include \masm32\include\Advapi32.inc
includelib \masm32\lib\Advapi32.lib
;==============================================================================
.data
    hKey    HKEY 0
    cbData  dd -1
.code
;==============================================================================
start:
;==============================================================================
    mov ebx, alloc(1024*1024*100)

    invoke RegOpenKeyEx, HKEY_LOCAL_MACHINE,
                         chr$("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
                         0,
                         KEY_QUERY_VALUE,
                         ADDR hKey
    .IF eax != ERROR_SUCCESS
        printf("RegOpenKeyEx %s\n\n", LastError$())
    .ENDIF

    invoke RegQueryValueEx, hKey,
                            chr$("Identifier"),
                            NULL,
                            NULL,
                            ebx,
                            ADDR cbData

    .IF eax != ERROR_SUCCESS
        printf("RegQueryValueEx %s\n\n", LastError$())
    .ENDIF

    printf("\n%s\n%d\n\n", ebx, cbData)

    invoke RegCloseKey, hKey
    free ebx
    inkey
    exit
;==============================================================================
end start


x86 Family 6 Model 7 Stepping 3
32


There is some related information here:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms724872(v=vs.85).aspx/html

But so far I have not been able to determine what "latest format" and "standard format" mean. Perhaps your system is using the standard format.
Well Microsoft, here's another nice mess you've gotten us into.

Antariy

Jochen, your code passes the buffer that's smaller than the it claimed to be - sometimes system functions check if the targed buffer doesn't satisfy claimed size, and probably if the buffer belongs specific memory location (stack or executable image). For me your code works, it may depend on SP2 vs SP3. Try your code with allocation of a buffer from a heap, not in exe .data? - probably it would work.

Quote from: jj2007 on August 27, 2013, 06:38:46 AM
Quote from: Zen on August 27, 2013, 06:01:51 AM
JOCHEN,
Why not call RegQueryValueEx twice ???

Why should I??? ::)


push 0
invoke RegQueryValueEx,hkey,offset valuename,0,0,0,esp ; lpData is set to zero - function will return the size of the data in variable pointed by lpcbData
; [esp] now is the exact size of the data
call crt_malloc ; the size is already in the stack, and this function doesn't pops it (cdecl).
xchg eax,ebx
invoke RegQueryValueEx,hkey,offset valuename,0,0,ebx,esp
pop edx

EBX now points the buffer with exact data
EDX - the size of the data


sinsi

You know what they say jj, "garbage in, garbage out". If you pass 4GB as a size you should have a 4GB buffer :P
🍺🍺🍺

jj2007

Quote from: MichaelW on August 27, 2013, 09:52:49 AM
It works for me, Windows XP SP3.

For me, too - even with mov ebx, alloc(1024). But not always... it's the kind of un-chaseable bug that you find only by sheer coincidence, such as sending myself to google for Visual Basic ;)

@Alex & Zen: Thanks, now I got it. I didn't check for required buffer size simply because the string goes into MB's rotating buffer, and 160k is more than enough.

The whole point is about logic: From a "legal" viewpoint, qWord & sinsi are right - pass a valid buffer size. From a practical viewpoint, passing -1 should signal "don't worry", and the response of the OS should be either "I trust you" or "invalid parameter". As I see it here, Win7-32 responds sometimes with "no problem", and sometimes with "ERROR_NOT_ENOUGH_MEMORY" - which is nonsense when you are waiting for a 20-character string.

sinsi

So it sometimes crashes with the exact same registry value? Or different ones?
Registry access has changed, admin rights affects things, so does a 32/64 bit OS.

For example, I don't think 32-bit vista/7 have a HKLM\Software\Wow6432Node (btw, can someone confirm this?) and that can be a silent redirect to HKLM\Software.
🍺🍺🍺

jj2007

Quote from: sinsi on August 27, 2013, 05:36:46 PM
So it sometimes crashes with the exact same registry value?

With the same value, but in a slightly different context:
a) launched from my Masm32 folders: OK
b) launched from a temp folder: fails with error 8 (but succeeds if 65k are passed as buffer size)

GoneFishing

Jochen,

I and WinDbg didn't found hard-coded breakpoint. Your app runs and terminates correctly here .
There's no exception reports in the debugger.

sinsi

Might be a permission problem. Add a manifest to run as admin then try from both places.
🍺🍺🍺

jj2007

Quote from: vertograd on August 27, 2013, 06:21:10 PM
Jochen,

I and WinDbg didn't found hard-coded breakpoint. Your app runs and terminates correctly here .
There's no exception reports in the debugger.

Thanxalot to everybody. New version 27b uses a valid 65k buffer and reports error codes better (MbGuide.rtf, GetRegVal):
- error codes for RegOpenKeyEx are in rvRegKey, those for RegQueryValueEx are in rvRegQuery