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

undocumented/unintended ZYDIS_FORMATTER_FUNC_POST_OPERAND behavior #497

Open
440bx opened this issue Mar 15, 2024 · 6 comments · May be fixed by #543
Open

undocumented/unintended ZYDIS_FORMATTER_FUNC_POST_OPERAND behavior #497

440bx opened this issue Mar 15, 2024 · 6 comments · May be fixed by #543
Labels
A-formatter Area: Formatter C-bug Category: This is a bug (or a fix for a bug, when applied to PRs)

Comments

@440bx
Copy link

440bx commented Mar 15, 2024

Hello,

Hooking the function for ZYDIS_FORMATTER_FUNC_POST_OPERAND does not seem to behave as documented. if the function returns ZYAN_STATUS_SUCCESS then the source operand is dropped from the instruction (not output/printed). if the function returns ZYAN_STATUS_FAILED then the source operand is printed.

The above behavior does not seem consistent with the behavior documented for ZydisFormatterFunc.

The above behavior can be obtained by making the following modifications to the "Formatter01" example.

(1.)

// add the following in the "data" array (as the first line)

0x48, 0x8D, 0x65, 0x00,   // lea rsp, [rbp]  // the ", [rbp]" will be dropped depending on return value

(2.)

// in DisassembleBuffer add the following statements

    default_post_op = (ZydisFormatterFunc) &ZydisFormatterPostOperand;
    ZydisFormatterSetHook(&formatter, ZYDIS_FORMATTER_FUNC_POST_OPERAND, (const void**) &default_post_op);

(3.) add the following hook function

static ZyanStatus ZydisFormatterPostOperand(const ZydisFormatter* formatter,
  ZydisFormatterBuffer* buffer,
  ZydisFormatterContext* context)
{   // breakpoint here - for tracing

    // there is no default function, therefore nothing to execute (nil pointer)

  // uncomment the statement below and the source operand will be printed 
   
  //return ZYAN_STATUS_FAILED;  // source operand is printed/output - the formatting process did
                              // not fail (contrary to what the documentation states)

  return ZYAN_STATUS_SUCCESS; // causes the source operand to be omitted
                              // this behavior is not documented (unintended ??)
}

(4.) declare the variable to pass to the set hook function

ZydisFormatterFunc default_post_op;

@flobernd flobernd added C-enhancement Category: Enhancement of existing features A-formatter Area: Formatter labels Mar 16, 2024
@flobernd
Copy link
Member

Yes, we should clarify that in the documentation.

The proper way of omitting an operand here is to return ZYDIS_STATUS_SKIP_TOKEN.

A failure status code immediately stops the complete formatting and causes that code to be propagated to the exported ZydisFormatter* APIs.

@440bx
Copy link
Author

440bx commented Mar 16, 2024

What I find particularly disconcerting is that returning ZYAN_STATUS_SUCCESS causes the source operand to be dropped resulting in an invalid instruction being printed (missing the source operand.) When a function returns ZYAN_STATUS_SUCCESS, I expect a complete, valid, instruction not a mutilated one.

Basically, ZYAN_STATUS_SUCCESS is behaving sort of as ZYDIS_STATUS_SKIP_TOKEN. I say "sort of" because I didn't test returning ZYDIS_STATUS_SKIP_TOKEN and comparing the results but, after tracing the execution, I believe it might be the same.

@flobernd
Copy link
Member

Right. There is a ! missing for the post-operand condition check.

@flobernd flobernd added C-bug Category: This is a bug (or a fix for a bug, when applied to PRs) and removed C-enhancement Category: Enhancement of existing features labels Mar 16, 2024
@440bx
Copy link
Author

440bx commented Mar 16, 2024

The following question is strictly curiousity... I don't want it to be interpreted as being "unreasonable" or "pushy".

I see this bug as a fairly simple bug with a fairly simple fix, though I could be wrong about that but, presuming it is a simple fix, what's the reasonable time frame to expect a bug of this kind to be fixed ?

@flobernd
Copy link
Member

If you create a PR, we can fix it as soon as you are ready 🙂

Should be fixed by adding the missing "not" in front of the ZYAN_SUCCESS() call after the post-operand callback in ZydisFormatterIntel.c and ZydisFormatterATT.c

Not sure if I have time to work on it myself over the weekend..

@440bx
Copy link
Author

440bx commented Mar 16, 2024

I'm not well versed in Zydis (but learning) nor github,

If I were, I would gladly make the necessary changes and test them but, at this time, I am too afraid I'll mess something up due to general "lack of knowledge" (read: ignorance.)

@widberg widberg linked a pull request Dec 7, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-formatter Area: Formatter C-bug Category: This is a bug (or a fix for a bug, when applied to PRs)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants