The code below shows what I am trying to achieve. This code works (single stepping in OllyDbg) but only because the arguments used for the Type and SizeOf statements are those of the actual variables. For a generalised solution I need to obtain these values dynamically for the real variables via the DWORD pointers passed by the INVOKE statement. I have searched extensively and tried all the variations I can generate without success. I assume that the solution needs to be something like "mov ah,Type [esi]", whilst this statement compiles OK it returns a value of 0 rather than 1 at runtime. All the other variations that I have tried return the error "A2166 Structure Field expected"
It would be appreciated if somebody could help me with this and provide a sample of the instructions that I need to use.
CODE
~~~~
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
testpro proto :DWORD,:DWORD
.data
Msg1 db "This is my first message string",0
Msg2 db " ",0
Wrd1 dw 25,26
DWd1 dd 100,200
DQw1 dq 1000,2000
DTw1 dt 12345,67890
.code
start:
invoke testpro, addr Msg1, addr Msg1
invoke ExitProcess,NULL
testpro proc Sstr:DWORD, Dstr:DWORD
mov esi,Sstr
mov edi,Dstr
;Check both parameters are of type(byte)
mov ah,Type Msg1
mov al,Type Msg2
cmp ah,al
jz testpro1
mov eax,1
jmp testpro5
testpro1:
;Check Sizes are equal, if unequal use shortest for Count
mov ah,SizeOf Msg1
mov al,SizeOf Msg2
cmp al,ah
jg testpro2
jmp testpro3
testpro2:
xchg al,ah
testpro3:
and eax,000000FFh
dec eax
mov ecx,eax
testpro4:
lodsb
stosb
loop testpro4
testpro5:
ret
testpro endp
end start
Cheers and Thanks
Tarka
Unfortunately this isn't possible using native types. I assume you're familiar with languages like Java that have type information as an intrinsic part of the classes, and this is where you're getting the idea from...
As I said, this is not the case - languages like java have a whole lot of hidden code and information in order to do this.
Programming is like working under a contract - you cannot expect a given result unless you abide by the rules of the contract. For example, you can't use the strlen function with a number, and expect a reasonable result (the decimal length of the number?) - the contract states you pass in a pointer to a string, if you pass a pointer to anything else the contract is void.
Mirno
Thanks Mirno
If type checking as I was trying to implement it is not available, how do you prevent someone passing the wrong arguments and causing a mal function. i.e. a buffer overrun. I had considered calculating the string length by scanning for the "0" terminator. However if the routine were passed two quadbytes instead of strings, or even a byte string without a terminator, there would not be any terminators and the first zero that would be found would be a random event and belong to something else. In my case that would cause me to incorrectly overwrite an area of memory with a potentially nasty result.
How are arguments validated in say a .dll. I assume there must be a way otherwise it would be a simple to crash any program . Or do we assume that all users of shared code will only use it in the correct manner?
Comments Please
Cheers & Thanks
Tarka
You might use a macro and check the opattr directive. This allows to call the proc based on the info available at assembly time. See here (http://www.masm32.com/board/index.php?topic=9457.msg74857#msg74857) for an example.
tarka,
Here is where you can find information about the OPATTR expression :
http://webster.cs.ucr.edu/Page_TechDocs/MASMDoc/ProgrammersGuide/Chap_09.htm
Thanks jj2007 & Vortex
I have read the info about OPATTR and found it helpful. Unfortunately, it does not provide exactly what I want but it has given me some more ideas. I now think its a case of back to the drawing board and design it again!
Thanks for your help.
Cheers & Thanks
Tarka