Sign in to follow this  
Idov

Walking a FPO stack

Recommended Posts

Hi!


I'm trying to walk a callstack which has FPO enabled.
MSDN says about the FPO_Data structure:
"Represents the stack frame layout for a function on an x86 computer when frame pointer omission (FPO) optimization is used. The structure is used to locate the base of the call frame."
My question is: HOW? I don't see there any information related to the base address...

[url="http://msdn.microsoft.com/en-us/library/windows/desktop/ms679352%28v=vs.85%29.aspx"]http://msdn.microsoft.com/en-us/library/windows/desktop/ms679352(v=vs.85).aspx[/url]

I searched the web for days but I couldn't find a shred of information about this.

Can anyone help me?

thanks :)

Share this post


Link to post
Share on other sites
The compiler must make sure that every instruction within a frame-omitted function has a constant stack offset relative to the function's entry instruction. Since it can't use the rBP register to quickly restore rSP, it must make sure that all code paths consistently return rSP to its original value. It must also make sure that every code path that merges into another code path (such as at the end of an if/else block) consistently returns to the same stack offset (you'll see "ADD rSP, imm" instructions used for this purpose when the two branched paths differ in their stack operations - say, if an 'if/else' calls a function in the 'if' block but doesn't in the else block).

If the compiler stores this information for use by the debugger, the debugger can look up the frame position for the current function given the address of the executing instruction and the current stack position (and nothing else). To walk the stack using this technique, you also need to know what kind of 'ret' instruction the current function uses (near or far, pops parameters or not). Find the frame, get the contents of the stack to get the CS:rIP, repeat.

If the compiler didn't store this info, or just stored minimal info such as the start/end addresses of each function, the debugger can reconstruct it on the fly by disassembling the function and reconstructing the info on the fly by counting each "PUSH", "POP", "SUB rSP, imm", "ADD rSP, imm", and CALL instruction (if the call uses the stdcall convention which pops arguments with a 'RET imm' instruction).

I don't know how the FPO_Data structure works, but it seems like it's got enough information to perform one of the methods above.

Share this post


Link to post
Share on other sites
Ok, So if I have the ESP register and in the FPO_Data structure I have the size of the function ("cbProcSize"),
then the end of the function is at ESP + cbProcSize?
and its return values is 4 bytes earlier?

And then for the next call in the stack, i'll use the end of the prvious method end address as the new ESP?


isn't "NEAR" or "FAR" something that belong to 16-bit system? does anyobdy use it nowadays or I can ignore it completely?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this