draperlaboratory / cbat_tools

Program analysis tools developed at Draper on the CBAT project.
MIT License
102 stars 14 forks source link

--pointer-reg-list: no longer error on registers that do not exist #242

Closed DieracDelta closed 4 years ago

DieracDelta commented 4 years ago

230 introduced a bug where including a register not in the analyzed sub would result in an error. For example, when invoking cbat with --pointer-reg-list=ASDF on any binary, we would like to continue with analysis and ignore these extraneous registers that are not used. Additionally, the error was a string error, which should occur at the start/frontend instead of in the middle of analysis. (note: I'm mostly paraphrasing things @codyroux mentioned in slack)

construct_pointer_constraint now takes in lists of Constr.z3_exprs instead of strings. The string -> z3_expr occurs much earlier on.

To continue with analysis and not throw an error, we do two things:

This should allow us to add in constraints for all registers provided (even if they do not exist or are unused in the sub).

The tests seem to pass. I'm not 100% sure that I'm adding in the registers correctly. On the other hand, perhaps I'm being too careful. When adding in registers I:

1) Add all registers seen in the sub. 2) Call init_vars on those registers to update their init maps 3) Add in all registers listed in pointer-reg-list that don't already exist in the corresponding init map. 4) Call init_vars on the registers introduced in (3).

I'm not sure if this is overcomplicating things. Perhaps I should just Var.create on all the strings provided by pointer-reg-list and then union them with the set of variables found by Pre.get_vars?

fortunac commented 4 years ago

When adding in registers I:

  1. Add all registers seen in the sub.
  2. Call init_vars on those registers to update their init maps
  3. Add in all registers listed in pointer-reg-list that don't already exist in the corresponding init map.
  4. Call init_vars on the registers introduced in (3).

What was your reasoning for calling init_vars twice? Does creating a set that contains all the registers found in the sub and all the registers listed in pointer-reg-list, and then passing that to init_vars not work?

DieracDelta commented 4 years ago

You're right--I don't think there is a good reason to have two sequential invocations to init_vars. I was mostly using this as a convenience to generate errors. I've refactored to only have one invocation over a union of the two sets and this seems to work well!