News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Is this ugly coding?

Started by minor28, November 06, 2014, 03:01:21 AM

Previous topic - Next topic

minor28

To find out if param2 is used


MyFunction proc c param1:dword,param2:vararg

mov eax,ebp
add eax,4
mov eax,dword ptr [eax]
mov eax,dword ptr [eax]
and eax,0FFFFFFh
shr eax,16
.if eax==8
mov eax,param2
.endif
endp


jj2007

A bit clumsy, and not foolproof, as many things can be found on the stack. Often, you would use param1 to pass the number of arguments. If you don't want that, you might try to find the return address, i.e. something between GetModuleHandle(0) and some label towards the end of your program, plus code from libraries that eventually got included. And yet, this would work only if the "true" parameters can't be in that range.

What do you want to achieve here?

minor28

It is an existing dll function that I use in some of my programs. Now I update this function and I need an additional parameter without having to modify the applications that already use it.

jj2007

You could pass it in eax, ecx, edx, maybe with a simple xor check:

include \masm32\include\masm32rt.inc

.code
MyFunction proc c param1:dword ; ,param2:vararg
xor edx, eax
.if edx==12345678h
print str$(eax), 9, "valid p2", 13, 10
.else
print str$(eax), 9, "INVALID p2", 13, 10
.endif
print str$(param1), 9, "p1", 13, 10, 10
ret
MyFunction endp

start:
mov eax, 111
mov edx, eax
xor edx, 12345678h
invoke MyFunction, 777

mov eax, 222
mov edx, eax
xor edx, 12345678h
inc edx ; invalidate
invoke MyFunction, 777

exit

end start

qWord

Quote from: minor28 on November 06, 2014, 04:22:24 AMNow I update this function and I need an additional parameter without having to modify the applications that already use it.
Do not "update" the function - create a new function.
MREAL macros - when you need floating point arithmetic while assembling!

Gunther

Quote from: qWord on November 06, 2014, 04:48:21 AM
Do not "update" the function - create a new function.

That's a good advice.  :t

Gunther
You have to know the facts before you can distort them.

minor28

OK, as I understand it from your answers, it's not a solution that I should use.

GoneFishing

What if to use a simple macro?
Something like this:

MyInvoke MACRO myprocname, firstarg, secondarg:=<0>
         .if secondarg
             invoke myprocname, firstarg, secondarg
         .else
             invoke myprocname, firstarg
         .endif
         ENDM

dedndave

this is the "inkey" macro from masm32
maybe you can get some ideas   :t
    inkey MACRO user_text:VARARG
      IFDIF <user_text>,<NULL>                  ;; if user text not "NULL"
        IFNB <user_text>                        ;; if user text not blank
          print user_text                       ;; print user defined text
        ELSE                                    ;; else
          print "Press any key to continue ..." ;; print default text
        ENDIF
      ENDIF
      call wait_key
      print chr$(13,10)
    ENDM

Vortex

Determining parameters during runtime :

include     CheckParam.inc

CheckParam  PROTO C arg1:DWORD,arglist:VARARG

SECOND_PARAM    equ 2*4
RET_ADDR        equ 4

.data

msg1        db 'There is no second parameter.',13,10,0
msg2        db 'The second parameter is = %u',13,10,0

.data?     

buffer      db 256 dup(?)

.code

start:

    invoke  CheckParam,9,7,3,5,1

    invoke  CheckParam,1,5

    invoke  CheckParam,10

    invoke  ExitProcess,0

CheckParam  PROC C arg1:DWORD,arglist:VARARG

    mov     edx,DWORD PTR [ebp+4]       ; ebp -> Return address
                                        ; The ADD command is following
                                        ; the invoke instruction
                                        ; Encoding of ADD esp,x                                       
                                        ; 0x83 , 0xC4 , 4*x
    movzx   eax,BYTE PTR [edx+2]
    cmp     eax,SECOND_PARAM            ; check for the second parameter
    jae     @f

    invoke  StdOut,ADDR msg1
    ret
@@:
    mov     ecx,arg1
   
    invoke  wsprintf,ADDR buffer,\
            ADDR msg2,\
            DWORD PTR [ebp + RET_ADDR + SECOND_PARAM]

    invoke  StdOut,ADDR buffer
    ret

CheckParam ENDP

END start

jj2007

Very neat trick, Erol - thanks for sharing this :t

CheckParam  PROC C arg1:DWORD,arglist:VARARG
Local v1, v2, rc:RECT      ; works with locals, too
    mov     edx,DWORD PTR [ebp+4]       ; ebp -> Return address
                                        ; The ADD command is following
                                        ; the invoke instruction
                                        ; Encoding of ADD esp,x                                       
                                        ; 0x83 , 0xC4 , 4*x
    cmp BYTE PTR [edx+2], SECOND_PARAM  ; check for the second parameter
    jae     @f

Vortex

Hi Jochen,

Thanks for the line cmp BYTE PTR [edx+2], SECOND_PARAM
That's quicker and easier.

minor28

Vortex,

What you suggest is the same as I wrote in my question. I also compare what is written in the return address "add esp,8" (0x83C408) but perhaps in a bit clumsy way.

My question remains. Is this ugly coding?

hutch--

 :biggrin:

I have a simple view on the beauty of coding , if it works, it works. If it works it ain't ugly.  :P

TouEnMasm


Not uggly,but can be more readable



.const
Ctest PROTO C :DWORD,:VARARG
.code
invoke Ctest,0,1,2,3,4,addr recta

Ctest PROC C fixed:DWORD,item:VARARG
Local  varargsize:DWORD
Local  varargadr:DWORD
         mov edx,[ebp+4] ;point return adress ,"ADD esp,x"
         movzx   eax,BYTE PTR [edx+2] ;get x
         sub eax,sizeof fixed
         mov varargsize,eax ;VARARG size
         lea edx,fixed
         add edx,sizeof fixed
         mov varargadr,edx ;VARARG adress
         

FindeCtest:
         ret
Ctest endp
Fa is a musical note to play with CL