Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

local variable's ebp offset doesn't match #223

Closed
y0ny0ns0n opened this issue Mar 19, 2019 · 2 comments
Closed

local variable's ebp offset doesn't match #223

y0ny0ns0n opened this issue Mar 19, 2019 · 2 comments
Labels
Type: Bug Something isn't working

Comments

@y0ny0ns0n
Copy link

y0ny0ns0n commented Mar 19, 2019

Describe the bug
I try to analyze some pwn challenge with ghidra. And it looks nice at first.

image

But If I try to disassemble that last cmp instruction's opcode with another disassembler... it looks like this.

image

My GDB and IDA and Intel Manual also agree with above result. I don't know the reason but there are some problem in local stack variable recognition.

To Reproduce
Just Open antipesto binary with ghidra and check function.

Environment (please complete the following information):

  • OS: Microsoft Windows 10 Pro 10.0.17763
  • Java Version: 11.0.2
  • Ghidra Version: 9.0
@y0ny0ns0n y0ny0ns0n added the Type: Bug Something isn't working label Mar 19, 2019
@ahroach
Copy link
Contributor

ahroach commented Mar 19, 2019

I think that if you look at the raw disassembled instruction in Ghidra without inferred stack variable markup, you will find that your instruction is being correctly disassembled. To verify this, either select the instruction and look in the far bottom right corner of the CodeBrowser Window, or navigate to Edit->Tool Options..., then go to Listing Fields, then Operands Field, and then deselect Markup Stack Variable References.

The next question is why does Ghidra assign a local variable name of local_14 when the offset from EBP is -0x10? If you look in the "Function Signature, Attributes and Variables" section of Ghidra's Help and read the "Variables" subsection, you'll see that "Any references to the stack ... are relative to the stack pointer when the function is entered." In the example that you provided, EBP is PUSHed onto the stack after function entry, before ESP is MOVed to EBP. This creates a difference of 0x4 between the local variable offset relative to EBP, and the local variable offset relative to ESP at function entry.

This is also why your function parameters are listed as having offsets of +0x4 and +0x8 even though they are stored at ESP and ESP+0x4 before the function call. The CALL implicitly pushes on the return address, which places them at ESP+0x4 and ESP+0x8 at function entry.

I hope this helps clarify some of what you're seeing. The naming of stack variables and parameters can definitely be confusing if you don't know exactly how they're being defined.

@emteere
Copy link
Contributor

emteere commented Mar 19, 2019

The choice of stack variable offsets based on the frame variable versus stack variables based on the stack pointer can cause some confusion. @ahroach describes it well. What it allows is ignoring the stack frame variable and just creating references to the stack wherever they occur however they occur. There are many examples of the stack pointer loaded into alternate registers without a frame, so a universal base of the stack at entry seemed like a good choice and less confusing when there is and isn't a frame pointer in two different functions.

When debug information is loaded the conversion to SP at entry needs to be done. In addition, many compilers have gotten rid of the use of a stack frame register all together.

There has been some discussion of adding the frame based / debugger based offsets as a view option when a frame variable is actually in use. The calculation wouldn't be too difficult.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants