JonathanSalwan / Triton

Triton is a dynamic binary analysis library. Build your own program analysis tools, automate your reverse engineering, perform software verification or just emulate code.
https://triton-library.github.io
Apache License 2.0
3.53k stars 538 forks source link

Why do children of a node with type 'triton::ast::ast_e::REFERENCE_NODE' not exist? #1356

Open sudmit0802 opened 2 months ago

sudmit0802 commented 2 months ago

Hey!

image

I emulated the code above. Then I got a correct AST in graphviz and I tried to find a child (ZX) of a REF node (REF 366):

image It obviously exists on AST graph below REF 366, but it doesn't exists in vector with children, so it looks like incorrect work of API for interacting with ASTs:

image

image

Am I thinking right?

jordan9001 commented 2 months ago

Reference nodes don't have children, just the reference to a symbolic expression. You need to follow references with se = astnode.getSymbolicExpression() and can do a se.getAst() to get the referenced ast node.

This helps with things like backslicing because symbolic expressions have extra info like the associated disassembly.

sudmit0802 commented 2 months ago

Anyway, it's too complicated. I expect to get children immediatly when I call .getChildren() method. But as you say I always have to cast SharedAbstractNode to ReferenceNode then getSymbolicExpresssion from it and then getAst from it again to finally get a real node with children. It sounds like choosing Jungles road instead of Highway.

JonathanSalwan commented 2 months ago

lol if you want to ride the highway, go use highway_ast = AstContext::unroll(jungle_ast)

sudmit0802 commented 2 months ago

Thanks!

sudmit0802 commented 2 months ago

But still one question. Is it a big deal to add Children to Refs? Why is it not implemented?

JonathanSalwan commented 2 months ago

To avoid duplicating nodes/sub-trees in memory and to keep an SSA form.

psi-func commented 2 months ago

Is there a problem in adding another shared_ptr? the lifetime of a real node will not change from this, and the API will become consistent and convenient without unnecessary static_cast How does this preserve the SSA representation? ast::unroll is a cannon for sparrows for this task

JonathanSalwan commented 2 months ago

Is there a problem in adding another shared_ptr?

Probably some. I do not remember exactly why I did this years ago. But for example, the first one that comes in mind is when do you stop printing an ast representation (print(ast))?

However, if you think this feature could improve the library for X or Y reason, feel free to provide an MR :). I will be happy to review and merge it :).