The MASM Forum Archive 2004 to 2012

General Forums => The Laboratory => Topic started by: Vortex on December 21, 2004, 07:18:21 PM

Title: Macro simulating invoke
Post by: Vortex on December 21, 2004, 07:18:21 PM
Hi friends,

Here is a macro example simulating invoke, the attachment contains an example.
_invoke MACRO funcname:REQ,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20
local pos,counter
counter=0

    FOR arg,<p20,p19,p18,p17,p16,p15,p14,p13,p12,p11,p10,p9,p8,p7,p6,p5,p4,p3,p2,p1>

        IFNB <arg>
             
             counter=counter+1
             pos=@InStr(1,arg,<ADDR>) OR @InStr(1,arg,<addr>) OR @InStr(1,arg,<Addr>)

             IF pos

                IF (OPATTR(@SubStr(arg,%pos+5))) EQ 98
                        lea eax,@SubStr(<arg>,%pos+5)
                        push eax
                ELSE
                        push OFFSET @SubStr(<arg>,%pos+5)
                ENDIF

             ELSE
                        push arg
             ENDIF
        ENDIF
    ENDM
call funcname
ENDM

The variable counter holds the number of passed parameters.

[attachment deleted by admin]
Title: Re: Macro simulating invoke
Post by: Tedd on December 22, 2004, 04:37:30 PM
Very nice.

Just to be annoying - how about a warning if eax gets over-written upon the lea? :bdg
Title: Re: Macro simulating invoke
Post by: Vortex on December 22, 2004, 06:30:06 PM
Quote from: Tedd on December 22, 2004, 04:37:30 PM
Very nice.

Just to be annoying - how about a warning if eax gets over-written upon the lea? :bdg


Yes, you can insert the directive echo to output warnings.
Title: Re: Macro simulating invoke
Post by: raymond on December 23, 2004, 01:32:52 AM
Just curious. What would be the advantage of using such a macro instead of the invoke statement?

Raymond
Title: Re: Macro simulating invoke
Post by: Mark_Larson on December 23, 2004, 01:34:13 AM
Quote from: raymond on December 23, 2004, 01:32:52 AM
Just curious. What would be the advantage of using such a macro instead of the invoke statement?

Raymond


  The current invoke macro does not support calling a pointer to an address.  If you have your own macro, you can modify it to support that.

Title: Re: Macro simulating invoke
Post by: raymond on December 23, 2004, 01:37:56 AM
Thanks

Raymond
Title: Re: Macro simulating invoke
Post by: rea on December 23, 2004, 04:38:52 AM
If you overwrite completely, even you can automatically do the way how goasm (as I know) pass the addresses of locals :).
Title: Re: Macro simulating invoke
Post by: Ratch on December 23, 2004, 04:44:51 AM
Here is my version of a INVOKE macro.  Ratch



;*******************************************************************************
; @ArgRev :  MACRO FUNCTION                                                    *
;                                                                              *
; Called by: @ArgRev(P1,P2:VARARG)                                             *
;                                                                              *
; Returns :  VARARG list in reverse order                                      *
;-------------------------------------------------------------------------------
@ArgRev MACRO P1,P2:VARARG
LOCAL TXT
TXT TEXTEQU <P1>

FOR ARG,<P2>
 TXT CATSTR <ARG>,<!,>,TXT
ENDM

EXITM <TXT>
ENDM
;*******************************************************************************
PUSHIT MACRO P1:VARARG
FOR arg,<P1>
 PUSH arg
ENDM
ENDM
;*******************************************************************************
RPUSHIT MACRO P1:VARARG
%PUSHIT @ArgRev(P1)
ENDM
;-------------------------------------------------------------------------------
INVOKIT MACRO P1:REQ,P2:VARARG
IFNB <P2>
 RPUSHIT P2
ENDIF
CALL P1
ENDM
;-
Title: Re: Macro simulating invoke
Post by: Robert Collins on December 23, 2004, 05:59:42 AM
Quote from: Ratch on December 23, 2004, 04:44:51 AM
Here is my version of a INVOKE macro.  Ratch



;*******************************************************************************
; @ArgRev :  MACRO FUNCTION                                                    *
;                                                                              *
; Called by: @ArgRev(P1,P2:VARARG)                                             *
;                                                                              *
; Returns :  VARARG list in reverse order                                      *
;-------------------------------------------------------------------------------
@ArgRev MACRO P1,P2:VARARG
LOCAL TXT
TXT TEXTEQU <P1>

FOR ARG,<P2>
 TXT CATSTR <ARG>,<!,>,TXT
ENDM

EXITM <TXT>
ENDM
;*******************************************************************************
PUSHIT MACRO P1:VARARG
FOR arg,<P1>
 PUSH arg
ENDM
ENDM
;*******************************************************************************
RPUSHIT MACRO P1:VARARG
%PUSHIT @ArgRev(P1)
ENDM
;-------------------------------------------------------------------------------
INVOKIT MACRO P1:REQ,P2:VARARG
IFNB <P2>
 RPUSHIT P2
ENDIF
CALL P1
ENDM
;-


I'm not trying to be sarcastic but I don't like the macro name PUSHIT because it looks like.........well you can see what I mean.
Title: Re: Macro simulating invoke
Post by: Ratch on December 23, 2004, 06:09:47 AM
To Robert Collins,
     The MACRO's name is easily changed if it offends you.  The complement to PUSHIT is POPIT.  What do you think about the conciseness of the INVOKIT MACRO?  Ratch
Title: Re: Macro simulating invoke
Post by: Robert Collins on December 23, 2004, 06:35:16 AM
Quote from: Ratch on December 23, 2004, 06:09:47 AM
To Robert Collins,
     The MACRO's name is easily changed if it offends you.  The complement to PUSHIT is POPIT.  What do you think about the conciseness of the INVOKIT MACRO?  Ratch

The name is OK. I was just kidding about saying I dont like it. Its just that when I looked at it the last four letters stood out more profoundly. I have seen many names used in programming that just happen to fall into this category. I only said that because I know how some of the programmers where I work would use that name in their normal daily activities. Anyway, it's perfectly fine with me.
Title: Re: Macro simulating invoke
Post by: Vortex on December 23, 2004, 11:09:34 AM
Hi Raymond,

With a macro simulating invoke, you don't need define function prototypes. A simple extrern directive is enough to declare an external function.
Title: Re: Macro simulating invoke
Post by: hutch-- on December 23, 2004, 11:53:11 AM


Quote
The current invoke macro does not support calling a pointer to an address.  If you have your own macro, you can modify it to support that

This is not exactly the case, it all in the prototype. Quoting directly from the "macros.asm" file in MASM32,

comment * -----------------------------------------------------------------

   NOTES on DDPROTO macro

   This macro is for producing prototypes for functions where the start
   address is known and the parameter count is known. It requires a named
   DWORD sized entry in the .DATA or .DATA? section which has the start
   address written to it before the function is called.

        EXAMPLE:
        .data?
          user32_msgbox dd ?            ; << The named variable

        msgbox DDPROTO(user32_msgbox,4) ; create prototype

        This is expanded to the following. The TYPEDEF refers to
        the macro "pr4" in the WINDOWS.INC file.

        pt4 TYPEDEF PTR pr4
        msgbox equ <(TYPE pt4) PTR user32_msgbox>

        The address must be written to the DWORD variable before it can
        be called. This can be LoadLibrary/GetProcAddress or it can be
        an address recovered from a virtual table in a DLL or any other
        viable means of obtaining the start address of a function to call.

        invoke msgbox,hWnd,ADDR message_text, ADDR title_text,MB_OK

        ----------------------------------------------------------------- *

If you have the start address you want to use and know the number of parameters, you create a prototype for it using this or a similar macro then use INVOKE like normal.
Title: Re: Macro simulating invoke
Post by: Vortex on December 23, 2004, 08:19:38 PM
Here is a situation where an alternate invoke macro can be used

Tricks to use Masm with import libraries created directly from DLLs. These are:
i) Creating import libraries containing function names with no decoration
ii) Using the syscall convention
iii) Using an alternate invoke macro to call API functions

.386
.model flat, syscall ; SYSCALL convention
option casemap:none
include \masm32\include\windows.inc
include invoke.inc

extern ExitProcess:proc
extern MessageBoxA:proc
MessageBox equ <MessageBoxA>

includelib kernel32.lib
includelib user32.lib

.data
MsgCaption      db "Iczelion's tutorial no.2",0
MsgBoxText      db "Win32 Assembly is Great!",0

.code
_start:
_invoke MessageBox, NULL,addr MsgBoxText, addr MsgCaption, MB_OK
_invoke ExitProcess,NULL

END _start

[attachment deleted by admin]