Page 1 of 1

ASM Question (Caller's Address?)

Posted: Tue Sep 07, 2004 8:59 am
by PolyVector
I have a function that needs to know where it's going to return to when it's finished... I have read up on this (and it's been discussed before here) but I simply can't get it to work!
As far as I know, the return address of a function is stored in [ebp+4] but every time I try to put it into a variable I get a big fat NULL value...

I've tried this:

Code: Select all

MOV MyVariable,[ebp+4]
But I get an error... So I try this:

Code: Select all

MOV EAX,[ebp+4]
MOV MyVariable,EAX
and I get NULL....

So I obviously don't know assembly!... Does anybody have working code to retrieve the return address of a function? I'm stumped!

I remember somebody on the forums saying it's in [ESP+20+(4*NumOfParams)] but that doesn't work either :(

Posted: Tue Sep 07, 2004 10:07 am
by filperj
Why not simply:

Code: Select all

Procedure.l myfunc(Returnaddress,arg1,arg2)
   Debug Returnaddress
EndProcedure



myfunc(?returnplace,arg1,arg2)
Returnplace:

Sorry if it's a stupid idea :roll:

Posted: Tue Sep 07, 2004 10:34 am
by PolyVector
Well, the reason is that it will be used in many different places, and this is more-or-less a thing of convenience for the developer using my lib...
My lib will already have a list of all functions they could be calling from...

It would be simple to decypher where they are and return the info they want based on that if I had this pointer... It is by no means necessary, but it would keep their code much cleaner this way...


example of my lib in use...

Code: Select all

Procedure HookedProcedure(X.l,Y.l,Z.l)
Debug "OriginalProcedure(" + Str(X) + "," + Str(Y) + "," + Str(Z) + ")"
Trampoline=GetTrampolineFunction(@OriginalProcedure())
ProcedureReturn CallFunctionFast(Trampoline,X,Y,Z)
EndProcedure

Procedure OriginalProcedure(X.l,Y.l,Z.l)
EndProcedure

OriginalProcedure(1,2,3) ;/This calls OriginalProcedure()

ReplaceFunction(@OriginalProcedure(),@HookedProcedure())

OriginalProcedure(1,2,3) ;/This calls HookedProcedure()!!!

RestoreFunction(@OriginalProcedure())

OriginalProcedure(1,2,3) ;/This calls OriginalProcedure()
Here's what it would look like if I could decypher where the caller is:

Code: Select all

Procedure HookedProcedure(X.l,Y.l,Z.l)
Debug "OriginalProcedure(" + Str(X) + "," + Str(Y) + "," + Str(Z) + ")"
ProcedureReturn CallFunctionFast(Trampoline(),X,Y,Z) ;/CHANGED
EndProcedure

Procedure OriginalProcedure(X.l,Y.l,Z.l)
EndProcedure

OriginalProcedure(1,2,3) ;/This calls OriginalProcedure()

ReplaceFunction(@OriginalProcedure(),@HookedProcedure())

OriginalProcedure(1,2,3) ;/This calls HookedProcedure()!!!

RestoreFunction(@OriginalProcedure())

OriginalProcedure(1,2,3) ;/This calls OriginalProcedure()
Not a big difference, but you can see how that's a nicer syntax...
It makes a much bigger deal when the replaced function is in a dll...... that can get annoying!

Posted: Tue Sep 07, 2004 10:39 am
by GedB
This seems to work for me:

Code: Select all

Procedure p()
  x = 0
  
  MOV eax, ebp
  MOV x, eax
  
  Debug x
  
EndProcedure

Debug ?After

p()
After:

Posted: Tue Sep 07, 2004 10:47 am
by PolyVector
Hehe, I was actually using that method for a while... Until I discovered this!

This breaks it...
I think ebp is just storing whatever Debug last uses.... GRRR

Code: Select all

Procedure p() 
  x = 0 
  
  MOV eax, ebp 
  MOV x, eax 
  
  Debug x 
  
EndProcedure 

Debug ?After 
Debug ?Before

Before:
p() 
After: 


EDIT
This seems to work!

Code: Select all

MOV ebp,[esp+20]  ;esp+20+(4*ParamCount)
MOV x, ebp

Posted: Tue Sep 07, 2004 10:52 am
by wilbert
As far is I know, when a call is made to a procedure, the return address is pushed on the stack. If it's a procedure created in PB, 5 registers are pushed before your first instruction is executed.

Code: Select all

Global RetAddr.l

Procedure test()
! mov eax,[esp+20]
! mov [v_RetAddr],eax
  Debug Hex(RetAddr)
EndProcedure

test()
This should work, but only when there are five registers pushed.

Posted: Tue Sep 07, 2004 11:05 am
by PolyVector
Your code seems to work until I impliment it into my own procedure.... I can't see the difference...

Posted: Tue Sep 07, 2004 4:23 pm
by Pupil
Here's something to play with :)

Code: Select all

Procedure.l hello(a.s, b.s)
	MessageRequester(a, b)
	ProcedureReturn -1
EndProcedure

Procedure.l wrap(a.l, b.l, proc.l)
	!MOV eax, dword [esp+8] ; proc
	!ADD esp, 32
	!jmp eax
	Debug 1234 ; This will not be executed
EndProcedure

a.s = "hello"
b.s = "hmm!"

Debug wrap(@a, @b, @hello())

Posted: Tue Sep 07, 2004 10:19 pm
by PolyVector
:D
I guess I'm going to have to leave this extra feature out... I can't get it to work... Ah well!
Thanks for helping out everyone... It's been educational :)