News:

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

Main Menu

Having problems with .while Cnt < 32

Started by hfheatherfox07, January 18, 2013, 12:34:14 PM

Previous topic - Next topic

hfheatherfox07

Hello,
I need to change  .while Cnt < 32
To  .while Cnt < Buffervaluesize
How do I do that?
Thank you !

Here is what I am working on :
Read REG_BINARY Key Value:
; Read a REG_BINARY Key Value in Hex
.386
.model flat, stdcall
option casemap: none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\advapi32.inc  ; Needed to support the registry API's
include \masm32\include\masm32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\advapi32.lib ; Needed to support the registry API's
includelib \masm32\lib\masm32.lib

ReadRegistry PROTO

.data
sPIdKey     db "SOFTWARE\RandomTestKey\Test key", 0 ; // handle of key adress
keyread db "REG_BINARY Key Read...",0 ;  MessageBox Caption
sPIdValue   db "TestValue", 0 ; // address of name of value to query
szSpace     db " ",0
format      db "%X",0; Cpital X Is Captital Letters, Small x is small Letters

; Read Key Error
szError     db "Could Not read Key!",0
szErrorCapt db "Sorry",0

.data?
hkKey      HKEY ? ; // handle of key to query
;dwKeySize DWORD ? ; // address of data buffer size
szBuff   dd  1024 dup(?) ; // address of Hexadecimal Value buffer
szBuff1  dd  1024 dup(?) ; // address of Decimal Value buffer
szBuff2  dd  1024 dup(?)
dwValueType   dd  ? ; // address of buffer for value type
dwKeySize dd ?
Cnt dd ?
;---------------------------------------------------------------------------
.code
start:

INVOKE ReadRegistry

ReadRegistry proc

;LOCAL    Cnt:DWORD
;open or create a new key
; Gets the PId
    INVOKE RegOpenKeyEx, HKEY_CURRENT_USER,  addr sPIdKey, 0, KEY_WRITE or KEY_READ,  addr hkKey
    mov dwKeySize, sizeof szBuff; Or mov dwKeySize, sizeof szFinalBuffer
    INVOKE RegQueryValueEx, hkKey,  addr sPIdValue, NULL,  addr dwValueType,  addr szBuff ,  addr dwKeySize
    ; If Key exsists
  .IF eax == ERROR_SUCCESS ; Same as  .IF eax !=1

   mov     byte ptr szBuff2, 0
            and     Cnt, 0
         .while Cnt < 32
               xor     edx, edx
               mov     eax, Cnt
               mov     dl, byte ptr szBuff[eax]
            INVOKE     wsprintf, addr szBuff1, addr format, edx
            INVOKE     lstrcat, addr szBuff2, addr szBuff1
            .if al!=0 ; We look if the last
               INVOKE     lstrcat, addr szBuff2, addr szSpace
            .endif
               inc     Cnt
 
         .endw

             INVOKE MessageBox, 0,  addr szBuff2 , addr keyread, MB_OK ; Display the value   
   
     
    INVOKE RegCloseKey, hkKey ; Close the registry key
   
   jmp exit
   ret
  .ELSE
  INVOKE MessageBox, NULL, addr szError, addr szErrorCapt, MB_ICONEXCLAMATION ;call our Messagbox
jmp exit
.ENDIF
exit:
  INVOKE ExitProcess,0
  xor eax,eax
ret

ReadRegistry endp

end start


If you want to test the above , You can write that registry Key With this:

; Create NEW registry key + REG_BINARY Value
.386
.model flat, stdcall
option casemap: none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\advapi32.inc  ; Needed to support the registry API's

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\advapi32.lib ; Needed to support the registry API's

SaveRegistry PROTO

.data
szRegInfo       db "SOFTWARE\RandomTestKey\Test key", 0
szRegValue      db "TestValue",0
szRegValueData  db 48h,65h,6Ch,6Ch,6Fh,20h,57h,6Fh,72h,6Ch,64h
; You can write the value as a string and It will be converted any ways! szRegValueData  db "Hello World",0
; But it adds 2 extra zeros at the end and a "." !!!
;Hello World = 48 65 6C 6C 6F 20 57 6F 72 6C 64
; ***NOTE:***
;  dd 48h,65h,6Ch,6Ch,6Fh,20h,57h,6Fh,72h,6Ch,64h  Will Write 6 extra zeros-So: 48 00 00 00 65 00 00 00 ETC...
;  dw 48h,65h,6Ch,6Ch,6Fh,20h,57h,6Fh,72h,6Ch,64h  Will Write 2 extra zeros-So: 48 00 65 00 ETC...

szSuccess    db "REG Key Was Created",0 ;  MessageBox Message
szSuccessCpt db "Reg key...",0     ;  MessageBox Title
; Writr Key Error
szError     db "Could Not Write Key!",0
szErrorCapt db "Sorry",0
.data?
hkKey    HKEY  ?
szlpData  dd ?
;---------------------------------------------------------------------------
.code
start:
INVOKE SaveRegistry

SaveRegistry proc


;open or create a new key
   INVOKE RegCreateKey, HKEY_CURRENT_USER, ADDR szRegInfo,  ADDR hkKey
; Add an entry into the registry to remember that the file has already been created

   mov    szlpData,sizeof szRegValueData
; you can have REG_SZ ,REG_DWORD, REG_BINARY ,REG_NONE , REG_EXPAND_SZ,REG_LINK,REG_RESOURCE_LIST,REG_DWORD_LITTLE_ENDIAN,REG_DWORD_BIG_ENDIAN,REG_MULTI_SZ
   INVOKE RegSetValueEx, hkKey,ADDR szRegValue,NULL, REG_BINARY , ADDR szRegValueData,szlpData
   INVOKE RegCloseKey, hkKey ; Close the key
    ; If Key Created
  .IF eax == ERROR_SUCCESS ; Same as  .IF eax !=1
    INVOKE MessageBox, NULL, ADDR szSuccess, addr szSuccessCpt, MB_ICONINFORMATION ; Display a success Message
  jmp exit
   ret
  .ELSE
  INVOKE MessageBox, NULL, addr szError, addr szErrorCapt, MB_ICONEXCLAMATION ;call our Messagbox
jmp exit
.ENDIF
exit:
  INVOKE ExitProcess,NULL
  xor eax,eax
ret

SaveRegistry endp

end start
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.

dedndave

you can't compare one memory operand to another memory operand that way
put one of the values in a register
in this case, it's nice to have Cnt in a register because it's used inside the loop
EBX needs to be preserved across calls
and - it is preserved across API calls - no need to push/pop inside the loop
        push    ebx
        xor     ebx,ebx
        .while ebx < Buffervaluesize
            movzx   edx, byte ptr szBuff[ebx]
            INVOKE  wsprintf, addr szBuff1, addr format, edx
            INVOKE  lstrcat, addr szBuff2, addr szBuff1
            .if al!=0                                         ; We look if the last
                INVOKE  lstrcat, addr szBuff2, addr szSpace
            .endif
            inc     ebx
        .endw
        pop     ebx

qWord

an ugly trick for two memory operands:
mov eax,mem1
.while mem2 < eax
    ;...
    mov eax,mem1
.endw
MREAL macros - when you need floating point arithmetic while assembling!

hfheatherfox07

Thank you all   :biggrin:
@qWord that's going to come in handy!
I like that trick  :t
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.

hfheatherfox07

Quote from: qWord on January 18, 2013, 12:55:47 PM
an ugly trick for two memory operands:
mov eax,mem1
.while mem2 < eax
    ;...
    mov eax,mem1
.endw


@ qWord
How did you intend this to work in this situation?
; Read a REG_BINARY Key Value in Hex
.386
.model flat, stdcall
option casemap: none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\advapi32.inc  ; Needed to support the registry API's
include \masm32\include\masm32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\advapi32.lib ; Needed to support the registry API's
includelib \masm32\lib\masm32.lib

ReadRegistry PROTO

.data
sPIdKey     db "SOFTWARE\RandomTestKey\Test key", 0 ; // handle of key adress
keyread db "REG_BINARY Key Read...",0 ;  MessageBox Caption
sPIdValue   db "TestValue", 0 ; // address of name of value to query
szSpace     db " ",0
format      db "%X",0; Cpital X Is Captital Letters, Small x is small Letters

; Read Key Error
szError     db "Could Not read Key!",0
szErrorCapt db "Sorry",0

.data?
hkKey      HKEY ? ; // handle of key to query
;dwKeySize DWORD ? ; // address of data buffer size
szBuff   dd  256 dup(?) ; // address of Hexadecimal Value buffer
szBuff1  dd  256 dup(?) ; // address of Decimal Value buffer
szBuff2  dd  256 dup(?)
szTempBuffer dd  1024 dup(?)
dwValueType   dd  ? ; // address of buffer for value type
dwKeySize dd ?
Cnt dd ?
;---------------------------------------------------------------------------
.code
start:

INVOKE ReadRegistry

ReadRegistry proc


;open or create a new key
; Gets the PId
    INVOKE RegOpenKeyEx, HKEY_CURRENT_USER,  addr sPIdKey, 0, KEY_WRITE or KEY_READ,  addr hkKey
    mov dwKeySize, sizeof szBuff
    INVOKE RegQueryValueEx, hkKey,  addr sPIdValue, NULL,  addr dwValueType,  addr szBuff ,  addr dwKeySize
    ; If Key exsists
  .IF eax == ERROR_SUCCESS ; Same as  .IF eax !=1
 
       mov eax,szBuff ; Moves our value into eax

        .while szTempBuffer < eax
               xor     edx, edx
               mov     eax, Cnt
               mov     dl, byte ptr szBuff[eax]
       
            INVOKE     wsprintf, addr szBuff1, addr format, edx
            INVOKE     lstrcat, addr szBuff2, addr szBuff1
             .if al!=0 
               INVOKE    lstrcat, addr szBuff2, addr szSpace
            .endif
               inc     Cnt
 
         .endw


             INVOKE MessageBox, 0,  addr szBuff2 , addr keyread, MB_OK ; Display the value   
   
     
    INVOKE RegCloseKey, hkKey ; Close the registry key
   
   jmp exit
   ret
  .ELSE
  INVOKE MessageBox, NULL, addr szError, addr szErrorCapt, MB_ICONEXCLAMATION ;call our Messagbox
jmp exit
.ENDIF
exit:
  INVOKE ExitProcess,0
  xor eax,eax
ret

ReadRegistry endp

end start
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.

hfheatherfox07

Here is another working version :t
In Case some one needs to read REG_BINARY Registry Key
; Read a REG_BINARY Key Value in Hex
.386
.model flat, stdcall
option casemap: none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\advapi32.inc  ; Needed to support the registry API's
include \masm32\include\masm32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\advapi32.lib ; Needed to support the registry API's
includelib \masm32\lib\masm32.lib

ReadRegistry PROTO

.data
sPIdKey     db "SOFTWARE\RandomTestKey\Test key", 0 ; // handle of key adress
keyread db "REG_BINARY Key Read...",0 ;  MessageBox Caption
sPIdValue   db "TestValue", 0 ; // address of name of value to query
szSpace     db " ",0
format      db "%X",0; Cpital X Is Captital Letters, Small x is small Letters

; Read Key Error
szError     db "Could Not read Key!",0
szErrorCapt db "Sorry",0

.data?
hkKey      HKEY ? ; // handle of key to query
;dwKeySize DWORD ? ; // address of data buffer size
szBuff   dd  1024 dup(?) ; // address of Hexadecimal Value buffer
szBuff1  dd  1024 dup(?) ; // address of Decimal Value buffer
szBuff2  dd  1024 dup(?)
dwValueType   dd  ? ; // address of buffer for value type
dwKeySize dd ?

;---------------------------------------------------------------------------
.code
start:

INVOKE ReadRegistry

ReadRegistry proc


;open or create a new key
; Gets the PId
    INVOKE RegOpenKeyEx, HKEY_CURRENT_USER,  addr sPIdKey, 0, KEY_WRITE or KEY_READ,  addr hkKey
    mov dwKeySize, sizeof szBuff; Or mov dwKeySize, sizeof szFinalBuffer
    INVOKE RegQueryValueEx, hkKey,  addr sPIdValue, NULL,  addr dwValueType,  addr szBuff ,  addr dwKeySize
    ; If Key exsists
  .IF eax == ERROR_SUCCESS ; Same as  .IF eax !=1

       push    ebx     ; push ebx, this register needs to be saved
        xor     ebx,ebx ; clear ebx register
        .while ebx < dwKeySize ; compare count (ebx) to sizeof szBuff We moved (mov dwKeySize, sizeof szBuff) So we can read the Key
            movzx   edx, byte ptr szBuff[ebx]
            INVOKE  wsprintf, addr szBuff1, addr format, edx  ; Format Result in edx
            INVOKE  lstrcat, addr szBuff2, addr szBuff1       ; Copy szBuff1 to szBuff2
            .if al!=0                                         ; We look if the last Value, If we did
                INVOKE  lstrcat, addr szBuff2, addr szSpace   ; add space To it in szBuff2
            .endif
            inc     ebx ; Increase counter
        .endw
        pop     ebx ; pop ebx off the stack again

             INVOKE MessageBox, 0,  addr szBuff2 , addr keyread, MB_OK ; Display the value   
   
     
    INVOKE RegCloseKey, hkKey ; Close the registry key
   
   jmp exit
   ret
  .ELSE
  INVOKE MessageBox, NULL, addr szError, addr szErrorCapt, MB_ICONEXCLAMATION ;call our Messagbox
jmp exit
.ENDIF
exit:
  INVOKE ExitProcess,0
  xor eax,eax
ret

ReadRegistry endp

end start

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.

dedndave

  .IF eax == ERROR_SUCCESS ; Same as  .IF eax !=1

   mov     byte ptr szBuff2, 0


did you forget this line - or not need it ?

hfheatherfox07

Not needed ? I get the same result with or with out
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.

dedndave

yah - it doesn't look like it's needed if ERROR_SUCCESS

but - it might be nice to set it to null if there is an error
  .IF eax == ERROR_SUCCESS ; Same as  .IF eax !=1

;do stuff

  .ELSE
  mov byte ptr szBuff2,0
  INVOKE MessageBox, NULL, addr szError, addr szErrorCapt, MB_ICONEXCLAMATION ;call our Messagbox
.ENDIF


i just noticed - the "jmp exit" lines
neither of those are needed because execution continues at "exit" after the if/else/endif
also - the word "exit" is the name of a macro
you will get error messages if you try to include macros.asm

jj2007

.While 1
  mov eax, mem1
  .Break .if mem2>eax  ; or whatever
  ...
.Endw

.Repeat
  ...
    mov eax, mem1
.Until mem2>eax  ; or whatever


Note that .Repeat ... .Until is a bit faster and shorter than .While - if you are sure that the loop must be taken at least once, use .Repeat.

dedndave

i think registry value data can have null length

hfheatherfox07

I am getting the same result either way ... same as the other one ...too many extra zeros  :(
May be the ugly trick does not work in this case  :(
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.

hfheatherfox07

@ qWord
I Got It  :t
I forgot to take into account that I moved  the size of result of key read , with  "mov dwKeySize, sizeof szBuff"
So we have to compare Cnt to eax after we move that into eax  "mov eax,dwKeySize"

Here is another working example : :greenclp:

; Read a REG_BINARY Key Value in Hex
.386
.model flat, stdcall
option casemap: none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\advapi32.inc  ; Needed to support the registry API's
include \masm32\include\masm32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\advapi32.lib ; Needed to support the registry API's
includelib \masm32\lib\masm32.lib

ReadRegistry PROTO

.data
sPIdKey     db "SOFTWARE\RandomTestKey\Test key", 0 ; // handle of key adress
keyread db "REG_BINARY Key Read...",0 ;  MessageBox Caption
sPIdValue   db "TestValue", 0 ; // address of name of value to query
szSpace     db " ",0
format      db "%X",0; Cpital X Is Captital Letters, Small x is small Letters

; Read Key Error
szError     db "Could Not read Key!",0
szErrorCapt db "Sorry",0

.data?
hkKey      HKEY ? ; // handle of key to query
;dwKeySize DWORD ? ; // address of data buffer size
szBuff   dd  256 dup(?) ; // address of Hexadecimal Value buffer
szBuff1  dd  256 dup(?) ; // address of Decimal Value buffer
szBuff2  dd  256 dup(?)
szTempBuffer dd  1024 dup(?)
dwValueType   dd  ? ; // address of buffer for value type
dwKeySize dd ?
Cnt dd ?
;---------------------------------------------------------------------------
.code
start:

INVOKE ReadRegistry

ReadRegistry proc


;open or create a new key
; Gets the PId
    INVOKE RegOpenKeyEx, HKEY_CURRENT_USER,  addr sPIdKey, 0, KEY_WRITE or KEY_READ,  addr hkKey
    mov dwKeySize, sizeof szBuff
    INVOKE RegQueryValueEx, hkKey,  addr sPIdValue, NULL,  addr dwValueType,  addr szBuff ,  addr dwKeySize
    ; If Key exsists
  .IF eax == ERROR_SUCCESS ; Same as  .IF eax !=1
 
       mov eax,dwKeySize ; We moves our dwKeySize value into eax To compare count  Since  We moved (mov dwKeySize, sizeof szBuff) So we can read the Key

        .while Cnt < eax
               xor     edx, edx
               mov     eax, Cnt
               mov     dl, byte ptr szBuff[eax]
       
            INVOKE     wsprintf, addr szBuff1, addr format, edx
            INVOKE     lstrcat, addr szBuff2, addr szBuff1
             .if al!=0 
               INVOKE    lstrcat, addr szBuff2, addr szSpace
            .endif
               inc     Cnt
   mov eax,dwKeySize
         .endw


             INVOKE MessageBox, 0,  addr szBuff2 , addr keyread, MB_OK ; Display the value   
   
     
    INVOKE RegCloseKey, hkKey ; Close the registry key
   
   jmp exit
   ret
  .ELSE
  INVOKE MessageBox, NULL, addr szError, addr szErrorCapt, MB_ICONEXCLAMATION ;call our Messagbox
jmp exit
.ENDIF
exit:
  INVOKE ExitProcess,0
  xor eax,eax
ret

ReadRegistry endp

end start
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.

hfheatherfox07

Quote from: jj2007 on January 18, 2013, 05:16:18 PM
.While 1
  mov eax, mem1
  .Break .if mem2>eax  ; or whatever
  ...
.Endw

.Repeat
  ...
    mov eax, mem1
.Until mem2>eax  ; or whatever


Note that .Repeat ... .Until is a bit faster and shorter than .While - if you are sure that the loop must be taken at least once, use .Repeat.

:t

Here is an example using .Repeat and .Until  :biggrin:

; Read a REG_BINARY Key Value in Hex
.386
.model flat, stdcall
option casemap: none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\advapi32.inc  ; Needed to support the registry API's
include \masm32\include\masm32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\advapi32.lib ; Needed to support the registry API's
includelib \masm32\lib\masm32.lib

ReadRegistry PROTO

.data
sPIdKey     db "SOFTWARE\RandomTestKey\Test key", 0 ; // handle of key adress
keyread db "REG_BINARY Key Read...",0 ;  MessageBox Caption
sPIdValue   db "TestValue", 0 ; // address of name of value to query
szSpace     db " ",0
format      db "%X",0; Cpital X Is Captital Letters, Small x is small Letters

; Read Key Error
szError     db "Could Not read Key!",0
szErrorCapt db "Sorry",0

.data?
hkKey      HKEY ? ; // handle of key to query
;dwKeySize DWORD ? ; // address of data buffer size
szBuff   dd  256 dup(?) ; // address of Hexadecimal Value buffer
szBuff1  dd  256 dup(?) ; // address of Decimal Value buffer
szBuff2  dd  256 dup(?)
szTempBuffer dd  1024 dup(?)
dwValueType   dd  ? ; // address of buffer for value type
dwKeySize dd ?
Cnt dd ?
;---------------------------------------------------------------------------
.code
start:

INVOKE ReadRegistry

ReadRegistry proc


;open or create a new key
; Gets the PId
    INVOKE RegOpenKeyEx, HKEY_CURRENT_USER,  addr sPIdKey, 0, KEY_WRITE or KEY_READ,  addr hkKey
    mov dwKeySize, sizeof szBuff
    INVOKE RegQueryValueEx, hkKey,  addr sPIdValue, NULL,  addr dwValueType,  addr szBuff ,  addr dwKeySize
    ; If Key exsists
  .IF eax == ERROR_SUCCESS ; Same as  .IF eax !=1
 
   
.Repeat
               xor     edx, edx ; clear rd register
               mov     eax, Cnt ; move Count to eax
               mov     dl, byte ptr szBuff[eax]
       
            INVOKE     wsprintf, addr szBuff1, addr format, edx ; Format result in szBuff1
            INVOKE     lstrcat, addr szBuff2, addr szBuff1      ; Copy szBuff1 to szBuff2
             .if al!=0  ; If We look if the last character
               INVOKE    lstrcat, addr szBuff2, addr szSpace    ; Add a space
            .endif
               inc     Cnt  ; Increase counter
   mov eax,dwKeySize  ;  mov eax,dwKeySize ; We moves our dwKeySize value into eax To compare count  Since  We moved (mov dwKeySize, sizeof szBuff) So we can read the Key
.Until Cnt==eax


             INVOKE MessageBox, 0,  addr szBuff2 , addr keyread, MB_OK ; Display the value   
   
     
    INVOKE RegCloseKey, hkKey ; Close the registry key
   
   jmp exit
   ret
  .ELSE
  INVOKE MessageBox, NULL, addr szError, addr szErrorCapt, MB_ICONEXCLAMATION ;call our Messagbox
jmp exit
.ENDIF
exit:
  INVOKE ExitProcess,0
  xor eax,eax
ret

ReadRegistry endp

end start
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.

jj2007

               xor     edx, edx ; clear rd register
               mov     eax, Cnt ; move Count to eax
               mov     dl, byte ptr szBuff[eax]


better:
               mov     eax, Cnt ; move Count to eax
               movzx     edx, byte ptr szBuff[eax]

in case you want signed values:
               xor     edx, edx ; clear rd register
               mov     eax, Cnt ; move Count to eax
               movsx     edx, byte ptr szBuff[eax]