hello all

lets say i have this :

call @_Proc1 ; 1st caller
...

@_Proc1 proc
      call @_Proc2 ; 2nd caller
@_Proc1 endp

@_Proc2 proc
?????  ; how to return to the 1st???
@_Proc2 endp




how do i return to the 1st caller from @_Proc2 ?

i tried and but without success....

thanks



Posted on 2006-06-10 13:07:26 by GR33d
add esp, 4
retn

assuming that the functions have no parameters, or local variables on the stack.
Posted on 2006-06-10 13:47:30 by ti_mo_n
The usual way would be, of course:


call @_Proc1 ; 1st caller
...

@_Proc1 proc
      call @_Proc2 ; 2nd caller
RET ; this bugger
@_Proc1 endp

@_Proc2 proc
RET ; this bugger, too
@_Proc2 endp


Otherwise, follow timon's suggestion. Search for a recent topic "...about the stack..", for a explanation
Posted on 2006-06-10 13:49:03 by Ultrano
Also note that its possible to 'return to somewhere else' :)

In a recent project, I had some code that was executing from a chunk of memory allocated at runtime.
When it had completed its task,it needed to call GlobalFree to free its OWN memory, but NOT return to the caller, since that memory would no longer be valid.. I needed to 'return to somewhere else' after the api function freed my code's memory..

look at this !!

push pMemoryToFree
push pWhereToReturn
jmp GlobalFree

What I'm doing is manually pushing the Return Address which would usually be silently done by the CALL opcode.. and rather than using CALL, I JMP to the api function.. which contains a RET somewhere within it.
When that RET is encountered, the Return Address is popped into EIP, and so, execution resumes at pWhereToReturn - tricky huh?
Posted on 2006-06-10 23:16:42 by Homer
Hm, executing from memory allocated with anything but VirtualAlloc is a pretty bad idea, homer - NX bit in recent CPUs and all :)
Posted on 2006-06-11 07:14:58 by f0dder
Also, I think it is possible to go this way, if the procedure uses stack frames:

mov esp,
add esp, 0x4
ret

This code is indepent on parameters and local variables. But idea, suggested by Homer is really cool!
Posted on 2006-06-11 07:23:37 by Mika0x65
mov esp,
add esp, 0x4
ret

This will work ONLY if the first proc (the 'less nested' one) does _NOT_ use "stack frames"/variables/etc.
Posted on 2006-06-11 07:56:24 by ti_mo_n
it did the trick

cause what i needed was a "WAIT" function in a loop but without using the Sleep API
so i was seting a timer and had get out the : WAIT proc and the MAIN loop.

so i had to return 2 calls

add esp,8
ret

did the trick
Posted on 2006-06-11 08:39:09 by GR33d
GR33D, why not Sleep()?

It also sounds like there might be a cleaner way to solve your problem... but oh well, if it works for you :)
Posted on 2006-06-11 08:45:05 by f0dder
Thanks for the heads-up , f0dder.
Actually, I was referring to the 'stubcode' for my little 'exe self-decompression' project mentioned elsewhere on the board.
I'll switch to using VirtualAlloc as you suggested  8)
Posted on 2006-06-11 08:51:30 by Homer
Sleep() will freeze the proggy :(

so i set a quick timer so that the user still can use the proggy while it waits.
Posted on 2006-06-11 08:55:09 by GR33d

Sleep() will freeze the proggy :(

so i set a quick timer so that the user still can use the proggy while it waits.

Ah yes, indeed it will if used in the same thread as your MessageLoop.

What kind of operation are you doing?
Posted on 2006-06-11 08:58:47 by f0dder
its just a interpreter of commands (a lot of them)
a compiler or something like that...
that will do a lot of diferent things
calcs, draw result, add, sub ...
so i have the WAIT function
but i hate Sleep() :)
Posted on 2006-06-11 09:13:12 by GR33d
Hehe - well, Sleep is good for a lot of things, because you use 0% CPU time while Sleeping. But if you need to keep a GUI updated while something is waiting, you either need multiple threads or some other way of wait than sleep...
Posted on 2006-06-11 09:20:42 by f0dder
i did a trick style with the SetTimer heh

WAIT:
SetTimer
ret 2 calls

WM_TIMER message:
get back to the main loop
were we waiting? yes
jump to last position


or something like it :)
Posted on 2006-06-11 09:23:25 by GR33d
What about the following to return two calls?

mov esp, ebp ; resolve 1st stack frame
pop ebp ; pop the one from call before?
mov esp, ebp ;resolve that stack frame
ret


Now this would return the proc were in and skip the proc before that as if it was ret'd at the same time.

I believe this would only work if every proc had a stack frame. Masm doesn't attribute stack frames to proc unless locals are defined. (iirc)
Posted on 2006-06-11 11:22:54 by JimmyClif
Actually, I was under the impression that masm ALWAYS creates a stackframe, and that was the reason why we have the directives:
PROLOGUE:NONE and EPILOGUE:NONE
which disable stackframes until we use:
PROLOGUE:DEFAULT and EPILOGUE:DEFAULT

right guys?
Posted on 2006-06-11 11:29:09 by Homer

mov esp,
add esp, 0x4
ret

This will work ONLY if the first proc (the 'less nested' one) does _NOT_ use "stack frames"/variables/etc.


Why? As I understand stack will look like this:

100: old_ebp
96: loc_var1
92: loc_var2
88: data
84: data
80: arg1
76: arg2
72: retaddr
68: old_ebp (100)
64: loc_var1
60: loc_var2
56: data
52: arg1
48: retaddr
44: old_ebp (68)
40: loc_var1
36: data

ebp now contains 44. So, command 'mov esp, ebp' will bring us to previous stack frame (ebp will contain 68), after that we will point esp to ret addr 'add esp, 4' and then execute 'ret' command.

So, as I understand, we can jump through stack frames untill the frame we need and use its ret addr.

What is wrong?..
Posted on 2006-06-11 12:32:11 by Mika0x65
Homer,

Try it out.


test1 proc
nop
ret
test1 endp


in a project gives me:

.text:0040102E sub_40102E      proc near              ; CODE XREF: DialogFunc+Dp
.text:0040102E                nop
.text:0040102F                retn
.text:0040102F sub_40102E      endp


Posted on 2006-06-11 13:02:35 by JimmyClif
Mika0x65: Play with Ollydbg ;) Your method will (1) return the first function CALLED, not to the caller, and (2) it'll not restore the ebp, which can cause serious problems.

Posted on 2006-06-11 16:10:33 by ti_mo_n