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

Dedupe Traits #60

Closed
c3rb3ru5d3d53c opened this issue Apr 28, 2022 · 11 comments · Fixed by #124
Closed

Dedupe Traits #60

c3rb3ru5d3d53c opened this issue Apr 28, 2022 · 11 comments · Fixed by #124
Assignees
Labels
bug Something isn't working

Comments

@c3rb3ru5d3d53c
Copy link
Owner

Fix trait duplication

@c3rb3ru5d3d53c c3rb3ru5d3d53c added the bug Something isn't working label Apr 28, 2022
@c3rb3ru5d3d53c c3rb3ru5d3d53c added this to the v1.1.1 milestone Apr 28, 2022
@jbx81-1337
Copy link
Collaborator

If someone can link an executable that generate duplicates I will investigate about that

@c3rb3ru5d3d53c
Copy link
Owner Author

binlex/src/decompiler.cpp

Lines 518 to 527 in 0f84757

if (sections[index].discovered.empty()){
uint64_t tmp_addr = MaxAddress(sections[index].coverage);
if (tmp_addr < sections[index].data_size){
sections[index].discovered.push(tmp_addr);
sections[index].addresses[tmp_addr] = DECOMPILER_OPERAND_TYPE_FUNCTION;
sections[index].visited[tmp_addr] = DECOMPILER_VISITED_QUEUED;
continue;
}
break;
}

Looks like no check if addr is visited here, maybe why we getting dupes

@jbx81-1337
Copy link
Collaborator

This check seems dont fix the issue, trying to put a 'guard' check after the element is get from the queue by the DecompilerWorker and check if is visited (this should not be visited) if we dont have an issue on address scheduling this bug is on TraitWorker

@c3rb3ru5d3d53c
Copy link
Owner Author

@jbx81-1337 you may want to try checking out the branch staging as we keep all our bleeding edge changes there to see if there is any difference.

@c3rb3ru5d3d53c
Copy link
Owner Author

@herrcore did we address this, this issue ongoing?

@c3rb3ru5d3d53c c3rb3ru5d3d53c removed this from the v1.1.1 milestone May 7, 2022
@c3rb3ru5d3d53c
Copy link
Owner Author

binlex/src/decompiler.cpp

Lines 229 to 257 in dd107c1

if (block == true && IsConditionalInsn(insn) > 0){
b_trait.tmp_trait = TrimRight(b_trait.tmp_trait);
b_trait.tmp_bytes = TrimRight(b_trait.tmp_bytes);
b_trait.size = GetByteSize(b_trait.tmp_bytes);
b_trait.offset = sections[index].offset + myself.pc - b_trait.size;
AppendTrait(&b_trait, sections, index);
ClearTrait(&b_trait);
if (function == false){
ClearTrait(&f_trait);
break;
}
}
if (block == true && IsEndInsn(insn) == true){
b_trait.tmp_trait = TrimRight(b_trait.tmp_trait);
b_trait.tmp_bytes = TrimRight(b_trait.tmp_bytes);
b_trait.size = GetByteSize(b_trait.tmp_bytes);
b_trait.offset = sections[index].offset + myself.pc - b_trait.size;
AppendTrait(&b_trait, sections, index);
ClearTrait(&b_trait);
}
if (function == true && IsEndInsn(insn) == true){
f_trait.tmp_trait = TrimRight(f_trait.tmp_trait);
f_trait.tmp_bytes = TrimRight(f_trait.tmp_bytes);
f_trait.size = GetByteSize(f_trait.tmp_bytes);
f_trait.offset = sections[index].offset + myself.pc - f_trait.size;
AppendTrait(&f_trait, sections, index);
ClearTrait(&f_trait);
break;

@jbx81-1337
Copy link
Collaborator

Seems AppendTrait is called multiple times for the same trait, i dont understand if is possible to trigger multiple conditional path in the section code provided by @c3rb3ru5d3d53c . I have tried to switch from 'if' to 'else if' but seems equal, my suggestion is to keep track of processed trait with AppendTrait in 'visited' map, set address as DECOMPILER_VISITED_APPENDED and remove the duplicated trait.

@c3rb3ru5d3d53c
Copy link
Owner Author

Investigating this one now 😄

@c3rb3ru5d3d53c
Copy link
Owner Author

c3rb3ru5d3d53c commented May 19, 2022

Seems AppendTrait is called multiple times for the same trait, i dont understand if is possible to trigger multiple conditional path in the section code provided by @c3rb3ru5d3d53c . I have tried to switch from 'if' to 'else if' but seems equal, my suggestion is to keep track of processed trait with AppendTrait in 'visited' map, set address as DECOMPILER_VISITED_APPENDED and remove the duplicated trait.

So I thought about this a decent amount, there are times where a jump instruction can be referenced multiple times, and I also notice that functions are not duplicated. As such, I think that this issue does stem from what you are saying. Now the hard part is to determine where to best implement code to solve that. We could implement an additional check perhaps to the method CollectOperands under each switch case perhaps by checking sections[index].addresses and their associated types. I think this would be much more ideal than adding it to the method AppendTrait as I think this would be inefficient.

@c3rb3ru5d3d53c
Copy link
Owner Author

So believe I found the issue, we need to split sections[index].addresses into two sets, this would be easier to maintain, I could be incorrect, however it would appear we cannot store 2 different values for the same key in a map. This is needed because Functions will start with a block at the same address.

image

@jbx81-1337
Copy link
Collaborator

Ok, I don't really understand where the issue is because I noticed that the duplicated traits are type=block, and in any case the actual code doesn't push the addr on the Worker queue if Is already visited, I also made some checks for older version of binlex and seems has the same bug

@c3rb3ru5d3d53c c3rb3ru5d3d53c linked a pull request May 22, 2022 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants