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
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
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 (http://msdn.microsoft.com/en-us/library/windows/desktop/aa366714(v=vs.85).aspx) 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.
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
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?
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.
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