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

windows 16bit and 8 bit registers not simplified #1255

Open
NaC-L opened this issue Jun 16, 2023 · 2 comments
Open

windows 16bit and 8 bit registers not simplified #1255

NaC-L opened this issue Jun 16, 2023 · 2 comments

Comments

@NaC-L
Copy link

NaC-L commented Jun 16, 2023

code

from triton import *

ctx = TritonContext(ARCH.X86_64)
block = BasicBlock([
    Instruction(b"\x66\xBE\x00\x00"),                    # mov si, 0
    Instruction(b"\x66\xBE\x01\x00"),                    # mov si, 1
])


print('[Original basic block] ----------------------------------------------- ')
ctx.disassembly(block, 0x140004149)
print(block)
print('[End of original basic block] ---------------------------------------- ')

print()

print('[Simplified basic block] --------------------------------------------- ')
sblock = ctx.simplify(block)
ctx.disassembly(sblock, 0x140004149)
print(sblock)
print('[End of simplified basic block] -------------------------------------- ')

output:

[Original basic block] ----------------------------------------------- 
0x140004149: mov si, 0
0x14000414d: mov si, 1
[End of original basic block] ---------------------------------------- 

[Simplified basic block] --------------------------------------------- 
0x140004149: mov si, 0
0x14000414d: mov si, 1
[End of simplified basic block] -------------------------------------- 

expected output:

[Original basic block] ----------------------------------------------- 
0x140004149: mov si, 0
0x14000414d: mov si, 1
[End of original basic block] ---------------------------------------- 

[Simplified basic block] --------------------------------------------- 
0x14000414d: mov si, 1
[End of simplified basic block] -------------------------------------- 
@NaC-L
Copy link
Author

NaC-L commented Jun 20, 2023

I traced the issue back to

auto worklist = triton::ast::childrenExtraction(expr->getAst(), true /* unroll */, false /* revert */);

         auto worklist = triton::ast::childrenExtraction(expr->getAst(), true /* unroll */, false /* revert */);
        
        for (auto&& n : worklist) {
          if (n->getType() == triton::ast::REFERENCE_NODE) {
            auto expr  = reinterpret_cast<triton::ast::ReferenceNode*>(n.get())->getSymbolicExpression();
            auto eid   = expr->getId();

            exprs[eid] = expr;
          }
        }
        

Tried to comment those lines and see it helped, it was a big no-no. it would turn

add rax,1
add rax,1

to

add rax,1

instead of keeping it same

add rax,1
add rax,1

I tried to set unroll to false by
triton::ast::childrenExtraction(expr->getAst(), false/* unroll */, false /* revert */);

that would only keep last two instructions

input:

add rax,1
add rax,1
add rax,1
add rax,1
mov si, 1
mov si, 2
mov si, 3

to

add rax,1
add rax,1
mov si, 2
mov si, 3

So it appears like the problem is with

static std::vector<SharedAbstractNode> nodesExtraction(const SharedAbstractNode& node, bool unroll, bool revert, bool descend) {

@JonathanSalwan
Copy link
Owner

JonathanSalwan commented Jun 20, 2023

Yeah the problem is that regs like si, ah, al, are sub registers that do not clear the upper bits of the register. So basically we can't easily determine if we should remove the last assignment. For example:

mov esi, 0x11220000
mov si, 0x3344

We have an optimization that fixes your issue : AST_OPTIMIZATIONS, however it kills other unit tests.

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

No branches or pull requests

2 participants