News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Reversing Stack Values

Started by RotateRight, August 06, 2006, 05:57:25 AM

Previous topic - Next topic

RotateRight

In the process of determining the arguments to
a function call, I am not able to use an invoke
statement to call a particular stdcall function.

What I would like to do is push all my arguments
on the stack and have "something" reverse all these
arguments.  Then make my call to the function.
I do know the total number of arguments pushed. 
And I also realize that I would have to
initially push a "double" in the wrong order to
have a reverse work correctly.   

Anyone every done this sort of thing?
And making it into a function?

Maybe something like

while (num args >=0)

  swap(dword at register, dword at register + (num args * 4))

  dec num args


Somebody point me at a path,

Mark

Ratch

RotateRight,

    Sure, let's assume you have 10 parameters.  First, assign 10 DWORDS in the .DATA? segment.  Then write your parameters in the normal order in that area.  When finished, do 10 PUSH's of all the parameters in the .DATA? area starting from the first paramter.  Your parameters will then be on the stack in reverse order for your function call.  Ratch

Mark Jones

Quote from: RotateRight on August 06, 2006, 05:57:25 AM
What I would like to do is push all my arguments on the stack and have "something" reverse all these arguments, then make my call to the function. I do know the total number of arguments pushed.

Hi Mark, can you just push the values in reverse from the calling code? :)

There's a macro in MACROS.ASM which I think will do this:


; ------------------------------------------------------------------
; macro for making STDCALL procedure and API calls.
; ------------------------------------------------------------------

    Scall MACRO name:REQ,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12, \
                     p13,p14,p15,p16,p17,p18,p19,p20,p21,p22

    ;; ---------------------------------------
    ;; loop through arguments backwards, push
    ;; NON blank ones and call the function.
    ;; ---------------------------------------

      FOR arg,<p22,p21,p20,p19,p18,p17,p16,p15,p14,p13,\
               p12,p11,p10,p9,p8,p7,p6,p5,p4,p3,p2,p1>
        IFNB <arg>    ;; If not blank
          push arg    ;; push parameter
        ENDIF
      ENDM

      call name       ;; call the procedure

    ENDM


Short of this, if you really need to modify the stack from inside the called procedure, how about copying all the dwords into a lower stack position (say like ESP-128), then copy those values back in reverse order. The data coped to ESP-128 may or may not ever get overwritten later, and is cleaned up automatically by ExitProcess.
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

RotateRight

Mark,

Thanks for your time on this.
Still in the works on my part.

I considered Ratch's suggestion,
but at a more general level.
I would allocate dwNumBytes * 4,
on the heap, populate them in one
direction, push them in the opposite
and then free the memory.  Thanks Ratch.

I still think I could generalize
something like this.

Some code does this:

push 5    ;this goes to ESP=12FFC0
push 4    ;this goes to ESP=12FFBC
push 3    ;this goes to ESP=12FFB8
push 2    ;this goes to ESP=12FFB4
push 1    ;this goes to ESP=12FFB0


The called function really wants the
reverse of above.

At this point I know that dwNumBytes is 20.

I am thinking about something along the lines of:

divide dwNumBytes by 4 (gives total number of pushes)
divide that by 2 (number of swaps needed, dwSwaps)
set dwIndex to zero

then

move value at ESP+dwNumBytes+4 to a register
move value at ESP+dwIndex+4 to ESP+dwNumBytes+4
move value at register to ESP+dwIndex+4

increment dwIndex by 4
decrement dwNumBytes by 4
decrement dwSwaps by 1

and loop until dwSwaps = 0


Thinks something like this would work?

Is this similar to what you mentioned in
copying the lower part of the stack?

I would still need to consider making it into
a function (it may happen dozens of times).

Mark