News:

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

Main Menu

string

Started by mabdelouahab, February 02, 2014, 11:49:58 AM

Previous topic - Next topic

mabdelouahab

Hello all
How do I know that the passer Parameter  with function is the text or value
fx:

.data
  MyStr    db "string",0
  MyVal    dd   ?

MyProc proc Any:dword
   ;<---------- check (Any) is string or int <<<
   ret
MyProc endp

   invoke MyProc,Addr MyStr    ;<------- str
   invoke MyProc,MyVal   
   invoke MyProc,10
   invoke MyProc,chr$("String") ;<------- str


dedndave

    INCLUDE     \masm32\include\masm32rt.inc

;------------------------

MyFunction PROTO :DWORD,:LPSTR

;------------------------

    .DATA

szString db 'sdfsfd',0

;------------------------

    .CODE

main    PROC

    INVOKE  MyFunction,sizeof szString-1,offset szString

;;;

    INVOKE  ExitProcess,0

main    ENDP

;------------------------

MyFunction PROC dwLength:DWORD,lpszString:LPSTR

    mov     edx,lpszString
    mov     ecx,dwLength

;;;

   ret

MyFunction ENDP

;------------------------

    END     main

MichaelW

#2
If the question is how to determine if the passed DWORD is a pointer to a string or some integer value, AFAIK there is no way to determine this with certainty for the full range of DWORD values. Under conditions where you can ignore the potentially bad side effects of the function, you can use the IsBadStringPtr function to test the value. If the function returns zero then you can assume that the value probably is a pointer to a string, but you cannot be certain because the value, used as an address, could point to an area of memory that the function can read, from the address up to a null byte or to the size specified in the ucchMax parameter, see the function documentation. If you can limit your integers to 16-bit values then you can eliminate the uncertainty because in a Win32 app there are no valid addresses in this range.

Well Microsoft, here's another nice mess you've gotten us into.

jj2007

You can achieve that with a macro, as shown below.

include \masm32\include\masm32rt.inc

printstring MACRO arg
  tmp$ CATSTR <TheArg=>, <arg>, < with size=>, %(TYPE arg)
  % echo tmp$
  if TYPE arg eq DWORD
   print arg, 13, 10
  elseif TYPE arg eq BYTE
   print offset arg, 13, 10
  else
   .err <illegal argument>
  endif
ENDM

.code
  MyStr    db "string",0
  MyVal    dd MyStr
start:
   printstring MyStr
   printstring MyVal
   exit
end start

mabdelouahab

hi dedndave, MichaelW, jj2007
I thank you for your help
so
In the case of the use of value  Or variable
   invoke MyProc,MyVal   
   invoke MyProc,10
We can use invoke IsBadReadPtr,Any,4
They are return 0 in the case of Any is ptr
I keep the difference between ptr to String and ptr to STRUCT
the Function MultiByteToWideChar Returne the size of "Any " , But it does not differentiate between String and STRUCT

IsString proc Any:dword
LOCAL E
    invoke IsBadReadPtr,Any,4
    .if eax == 0 ; <------ Any is string or STRUCT
invoke MultiByteToWideChar,CP_MACCP,0,Any,-1,NULL,0
mov E,eax ; <------ size of Any
.if E == 0 ; ERROR_INVALID_PARAMETER
mov eax,FALSE
.else
mov eax,TRUE
.endif
    .else ; <------ Any is Value or Variable
mov eax,FALSE
    .endif
   ret
IsString endp


      invoke IsString,addr MyStr               ;<------- TRUE   
      invoke IsString,MyVar                  ;<------- FALSE   
      invoke IsString,MySTRUCT                  ;<------- TRUE   
      invoke IsString,chr$("String an copy")       ;<------- TRUE   
      invoke IsString,10                        ;<------- FALSE   
   

Is there a way to differentiate between String and struct?

ragdog

QuoteIsBadReadPtr function

Verifies that the calling process has read access to the specified range of memory.

Important  This function is obsolete and should not be used. Despite its name, it does not guarantee that the pointer is valid or that the memory pointed to is safe to use. For more information, see Remarks on this page.

jj2007

Hi mabdelouahab,

Your routine can be shortened a little bit, see below.

But apart from that, note that:
- MultiByteToWideChar writes to Any, so you should use IsBadWritePtr
- and both IsBadWritePtr and IsBadReadPtr fail miserably with an internal exception for the example line below that is commented out, i.e. these functions are indeed unreliable.

What is the purpose of your exercise?

include \masm32\include\masm32rt.inc

.data
MyVar dd 123
MyRect RECT <12, 34, 56, 78>
MyString db "This is a string", 0


.code
IsString proc Any:dword
    invoke IsBadWritePtr, Any, 100
    .if !eax ; <------ Any is string or STRUCT
invoke MultiByteToWideChar,CP_MACCP,0,Any,-1,NULL,0
; mov E,eax ; <------ size of Any
; .if E == 0 ; ERROR_INVALID_PARAMETER
; mov eax,FALSE
; .else
; mov eax,TRUE
.endif
    .else ; <------ Any is Value or Variable
mov eax,FALSE
    .endif
   ret
IsString endp

start:
print str$(rv(IsString, MyVar)), 9, "MyVar", 13, 10
print str$(rv(IsString, addr MyVar)), 9, "addr MyVar", 13, 10
print str$(rv(IsString, MyRect.left)), 9, "MyRect.left", 13, 10
print str$(rv(IsString, addr MyRect)), 9, "addr MyRect", 13, 10
; print str$(rv(IsString, MyString)), 9, "MyString", 13, 10
print str$(rv(IsString, addr MyString)), 9, "addr MyString", 13, 10
print "ok"
exit

end start