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

identifyParameterCandidates only looks for stores #14

Open
Trass3r opened this issue Feb 27, 2016 · 5 comments
Open

identifyParameterCandidates only looks for stores #14

Trass3r opened this issue Feb 27, 2016 · 5 comments

Comments

@Trass3r
Copy link
Contributor

Trass3r commented Feb 27, 2016

struct Base
{
    virtual ~Base() = default;
    virtual void foo() {}
    int a;
};
__attribute__((noinline))
void doSomething(Base* b)
{
    b->foo();
}
int main(int argc, const char* argv[])
{
    doSomething(new Base);
    return 0;
}
<doSomething(Base*)>:
;   b->foo();
  400680:   48 8b 07                mov    rax,QWORD PTR [rdi]
  400683:   ff 60 10                jmp    QWORD PTR [rax+0x10]

<main>:
  400690:   50                      push   rax
  400691:   bf 10 00 00 00          mov    edi,0x10
;   doSomething(new Base);
  400696:   e8 d5 fe ff ff          call   400570 <operator new(unsigned long)@plt>
  40069b:   48 c7 00 78 07 40 00    mov    QWORD PTR [rax],0x400778
  4006a2:   48 89 c7                mov    rdi,rax
  4006a5:   e8 d6 ff ff ff          call   400680 <doSomething(Base*)>
@Trass3r
Copy link
Contributor Author

Trass3r commented Feb 27, 2016

The call void x86_jump_intrin in doSomething is inferred as call void() as rdi is never written to.
Could use some input on this with respect to MemorySSA etc.

@fay59
Copy link
Owner

fay59 commented Feb 27, 2016

I'm not sure how to solve that. In its current state, I expect that fcd will get the parameter right for doSomething, but beyond that, I can't think of a lot to do for indirect calls. Since we can't guess the jump destination, we can't rely on the function code to infer parameters and we have to base our information off what we see at the call site.

Fcd detects call-site parameters by looking at which registers are set without being used before a function call, and this causes false negatives. If we check for registers read as well, we'll get false positives instead. (Plus, merely reading from a register really isn't an indication that callees will do it too.)

@Trass3r
Copy link
Contributor Author

Trass3r commented Mar 8, 2016

The confusing thing is that the code is split into a callsite (https://github.com/zneak/fcd/blob/776872d/fcd/callconv/x86_64_systemv.cpp#L110) and a function analysis (https://github.com/zneak/fcd/blob/776872d/fcd/callconv/x86_64_systemv.cpp#L292) for parameters and return values.
And it seems like callsite analysis is not performed for normal functions with a body which leads to missed parameters if the function just forwards its arguments to another function.

@fay59
Copy link
Owner

fay59 commented Mar 8, 2016

Yes, I see what you're saying. That's true, it leads to problems when a function with a body calls a function with a body which forwards parameters to a function without a body.

@Trass3r
Copy link
Contributor Author

Trass3r commented Mar 8, 2016

Yes indeed. I tested a non-virtual interface, public non-virtual method calling a same-signature protected virtual one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants