ASM Question (Caller's Address?)

Everything else that doesn't fall into one of the other PB categories.
PolyVector
Enthusiast
Enthusiast
Posts: 499
Joined: Wed Sep 17, 2003 9:17 pm
Location: Southern California
Contact:

ASM Question (Caller's Address?)

Post 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 :(
filperj
User
User
Posts: 77
Joined: Tue Sep 16, 2003 8:53 pm
Location: Nevers(France)

Post 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:
PolyVector
Enthusiast
Enthusiast
Posts: 499
Joined: Wed Sep 17, 2003 9:17 pm
Location: Southern California
Contact:

Post 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!
Last edited by PolyVector on Tue Sep 07, 2004 10:40 am, edited 1 time in total.
User avatar
GedB
Addict
Addict
Posts: 1313
Joined: Fri May 16, 2003 3:47 pm
Location: England
Contact:

Post 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:
PolyVector
Enthusiast
Enthusiast
Posts: 499
Joined: Wed Sep 17, 2003 9:17 pm
Location: Southern California
Contact:

Post 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
Last edited by PolyVector on Tue Sep 07, 2004 10:53 am, edited 1 time in total.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3943
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Post 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.
PolyVector
Enthusiast
Enthusiast
Posts: 499
Joined: Wed Sep 17, 2003 9:17 pm
Location: Southern California
Contact:

Post by PolyVector »

Your code seems to work until I impliment it into my own procedure.... I can't see the difference...
Pupil
Enthusiast
Enthusiast
Posts: 715
Joined: Fri Apr 25, 2003 3:56 pm

Post 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())
PolyVector
Enthusiast
Enthusiast
Posts: 499
Joined: Wed Sep 17, 2003 9:17 pm
Location: Southern California
Contact:

Post 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 :)
Post Reply