News:

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

the stack

Started by ecube, July 19, 2010, 01:16:02 AM

Previous topic - Next topic

ecube

I been playing around with the stack a lot lately yet i'm having troubles understanding something take for example


.data?
mybuff db 256 dup(?)
.code
start:
invoke func1,33,0,0
invoke ExitProcess,0

func1 proc p1,p2,p3
push esp
call func2
ret
func1 endp

func2 proc p1,p2,p3
invoke dwtoa,p1,addr mybuff             <-------------------gives some random number definitely not 33
invoke MessageBox,0,addr mybuff,NULL,MB_OK
ret
func2 endp

sinsi

'push esp' will push the value of esp, which points to the return address, not the parameter list for func1 (I assume that's what you want?).
Light travels faster than sound, that's why some people seem bright until you hear them.

ecube

thanks and yeah how I push the param list of the first function, without doing each 1 individually?

sinsi

Just use invoke as normal

func1 proc p1,p2,p3
  invoke func2,p1,p2,p3
  ret
func1 endp

Light travels faster than sound, that's why some people seem bright until you hear them.

ecube

that's not what i'm after :\ I want to push the whole param list without doing each one individually

sinsi


func1 proc p1,p2,p3
  jmp func2
func1 endp

Not sure what you are after...you want to reuse the params as they are on the stack without pushing them again?
Light travels faster than sound, that's why some people seem bright until you hear them.

MichaelW

If you need to replicate the parameters on the stack I can see multiple methods, but none better than pushing them individually.
eschew obfuscation

KeepingRealBusy

You can't depend on the stack parameters being the same on return as they were at the call.  People have been known to load a parameter and save a register on top of that parameter (see the laboratory). In other cases, the parameter is used as a work value (a count), so  always push them again.

ecube

what if you dont know the exact count for instance? just keep pushin? heh

KeepingRealBusy

I honestly don't understand your question. Could you rephrase it with an example?

Dave.

ecube

my question is very simple how can you pass on the entire stack to another function, without pushing individual parameters,  or is there a way to get the count of parameters from the stack? without knowing ahead of time it takes 5 params for instance.

dedndave

not without saving ESP in a variable ahead of time or something

you might try something like this

RetAddr dw ?

func1 proc p1,p2,p3
pop RetAddr
call func2
jmp dword ptr RetAddr
func1 endp

func2 proc p1,p2,p3
invoke dwtoa,p1,addr mybuff             <-------------------gives some random number definitely not 33
invoke MessageBox,0,addr mybuff,NULL,MB_OK
ret
func2 endp


another approach might be to make room on the stack before the call to func1
then, you could put the return address there and run func2 from func1

hutch--

Cube,

You can pass the address of the first and calculate the rest in the called proc but a simple set of pushes is usually more efficient.  coded up a test piece years ago to test this ands the MOV MEM and adjust ESP was a lot slower than the pushes. PUSH POP are generally optimised in the procressor.

You could rewrite the proc to take one pointer to a structure in EAX but its a different animal to what you are after.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

ecube


RetAddr dd ?

func1 proc p1,p2,p3
pop RetAddr
call func2
ret
func1 endp

func2 proc p1,p2,p3
invoke dwtoa,p1,addr mybuff             <-------------------gives some random number definitely not 33
invoke MessageBox,0,addr mybuff,NULL,MB_OK
ret
func2 endp


this works but what's weird is parameter p1 from func1 shows up as p2 in func2, and p2 in p3

also does this do any damage, even though it's calling a function with only 3 params?

push [ebp+56]
push [ebp+52]
push [ebp+48]
push [ebp+44]
push [ebp+40]
push [ebp+36]
push [ebp+32]
push [ebp+28]
push [ebp+24]
push [ebp+20]
push [ebp+16]
push [ebp+12]
push [ebp+8]
call func2

KeepingRealBusy

If one function called a second function with 3 parameters, and the second called the third function with the same 3 parameters, and the parameters were not needed anymore by the second function (maybe just the return value in eax), then the second function could pop the return address from the stack into a fixed memory DWORD, then call the third function (the parameters are still on the stack), then push the fixed memory DWORD to restore the return address. The second function would have to maintain the stack frame itself and do a ret 0 and not try to adjust the stack for the 3 parameters, or the third function would have to maintain the stack frame itself and not adjust the stack for the 3 parameters, or finally, the second function could adjust adjust the stack upon return from the third function with lea esp,[esp+12] to reinstate the 3 parameters that the third function removed before the second function pushed the fixed DWORD back on the stack.

Messy, fail prone, but doable. MASM lets you get into as much trouble as you want.

Dave.