Vector35 / binaryninja-api

Public API, examples, documentation and issues for Binary Ninja
https://binary.ninja/
MIT License
907 stars 207 forks source link

Optimize virtual calls with "this" parameter when global variable is used in HLIL #5679

Open mostobriv opened 3 months ago

mostobriv commented 3 months ago

What is the feature you'd like to have? In virtual calls with global variable as "this" param HLIL creates new local variable instead of using global variable, thus instead of:

// gSomeObj - global variable of type "struct SomeClass"
gSomeObj->vtable->SomeFunc(gSomeObj, ...);

HLIL looks like:

struct SomeClass* gSomeObj_1 = gSomeObj
gSomeObj_1->vtable->SomeFunc(gSomeObj_1, ...)

Are any alternative solutions acceptable? Idk actually, mb it can be solved with workflow (?).

Additional Information: As i've said it only happens (at least i've checked against it) only when "this" parameter is passed to the function, so if function signature not using it, then BN generates compact code, for example, if SomeFunc signature is void(*)() or void(*)(int32_t @ rdx) then code would be gSomeObj->vtable->SomeFunc() and gSomeObj->vtable->SomeFunc(1337) accordingly.

emesare commented 3 months ago

Right now for folding to occur here we would need to special case for this exact expression, if there was a compelling argument other than just removing a single assignment, and that this is actually impacting our analysis further down the function, then we could see about making this fold.

The reason you are seeing the fold when it's not in the parameter is because then there is only one use. Any other folding must occur where no side effects are observed, in your case this is not an issue but nonetheless it should be mentioned.