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

Adapt basic block analysis for the Hexagon architecture. #2073

Merged
merged 4 commits into from
Jan 5, 2022

Conversation

Rot127
Copy link
Member

@Rot127 Rot127 commented Dec 6, 2021

Your checklist for this pull request

  • I've read the guidelines for contributing to this repository
  • I made sure to follow the project's coding style
  • I've documented or updated the documentation of every function and struct this PR changes. If not so I've explained why.
  • I've added tests that prove my fix is effective or that my feature works (if possible)
  • I've updated the rizin book with the relevant information (if needed)

Detailed description

The run_basic_block_analysis function does not continue analysis if it encounters an register jump and analysis.jmp.after=true. This is not correct, since analysis.jmp.after=true explicitly states that the analysis should continue after a jump instruction.

Now to the big problem.

All additions I made to the code are only executed if the analysis runs on the Hexagon architecture (see usage of is_hexagon flag). Because if it changes its analysis behavior for all architectures a lot (>60) tests fail.

Test plan

Tests were added.
Only the analysis.ijmp missing branch bug failed. Could someone, who is more familiar than me with the x86_64 arch, please take a look at this one? I can't really tell whether it is good that it failed or not.

Closing issues

kinda closes #2047 (Since for all other architectures than Hexagon the problem persists.)
closes #1796
closes rizinorg/rz-hexagon#36

Tiny additional feature added
Added analysis.trap.after=false config. Set to true, it will continue the analysis after a trap instruction.

@Rot127
Copy link
Member Author

Rot127 commented Dec 6, 2021

Just a random idea which came to my mind.
It would be possible to allow the user to fine grade when the analysis should be continue after jumps.
Something like that:

analysis.jmp.after.outofmap     // Continue analysis if jump leaves mapped memory region.
analysis.jmp.after.reg          // Continue analysis after a register jump.
analysis.jmp.after.cond         // Continue analysis after a conditional jump.
analysis.jmp.after.outfcn       // Continue analysis if jump leads out of function.

It would allow the user to configure the analysis style best fitting to the platform being analysed.
Do you like the idea?

@XVilka
Copy link
Member

XVilka commented Dec 7, 2021

Regarding:

analysis.jmp.after.outofmap     // Continue analysis if jump leaves mapped memory region.
analysis.jmp.after.reg          // Continue analysis after a register jump.
analysis.jmp.after.cond         // Continue analysis after a conditional jump.
analysis.jmp.after.outfcn       // Continue analysis if jump leads out of function.

The idea is good, but this should be thoroughly tested with various combinations for main architectures.

@Rot127 Rot127 changed the title Fix: Continue analysis after register jump if analysis.jmp.after is set. Hexagon: Continue analysis after register jump if analysis.jmp.after is set. Dec 7, 2021
@Rot127
Copy link
Member Author

Rot127 commented Dec 7, 2021

The idea is good, but this should be thoroughly tested with various combinations for main architectures.

After spending more time to adapt run_basic_block_analysis() for Hexagon, I think it is better to write a function for each architecture.
run_basic_block_analysis() is already really complex and adding exceptions everywhere will make it only worse.
Besides, shouldn't there only one way to correctly analyze assembly of an architecture? Or are there exceptions?

@Rot127 Rot127 changed the title Hexagon: Continue analysis after register jump if analysis.jmp.after is set. Hexagon: Add separate basic block analysis function. Dec 7, 2021
librz/analysis/fcn.c Outdated Show resolved Hide resolved
librz/analysis/fcn.c Show resolved Hide resolved
librz/include/rz_analysis.h Show resolved Hide resolved
librz/include/rz_analysis.h Show resolved Hide resolved
@Rot127 Rot127 changed the title Hexagon: Add separate basic block analysis function. Adapt basic block analysis for the Hexagon architecture. Dec 8, 2021
@Rot127
Copy link
Member Author

Rot127 commented Dec 8, 2021

Please wait with merging. It needs more testing.
Recognized a few mistakes and meanwhile am confused at which point it is right to treat an instruction as branch and when to continue analysis etc. Need to draw it out on paper again.

@Rot127
Copy link
Member Author

Rot127 commented Jan 4, 2022

After doing some reversing with the current state of this PR I think it should be ready to merge. The result is fairly decent.
Sorry for not marking it as draft in the first place.

Comment on lines 586 to +589
bool is_x86 = is_arm ? false : analysis->cur->arch && !strncmp(analysis->cur->arch, "x86", 3);
bool is_amd64 = is_x86 ? fcn->cc && !strcmp(fcn->cc, "amd64") : false;
bool is_dalvik = is_x86 ? false : analysis->cur->arch && !strncmp(analysis->cur->arch, "dalvik", 6);
bool is_hexagon = is_x86 ? false : analysis->cur->arch && !strncmp(analysis->cur->arch, "hexagon", 7);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these checks are kinda weird, i'm not sure about this, but maybe i would change this to a if-else-if-else statement.

@wargio wargio enabled auto-merge (squash) January 5, 2022 16:27
@wargio wargio merged commit 1409025 into rizinorg:dev Jan 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants