pending constraints in symbolic execution for better
play

Pending Constraints in Symbolic Execution for Better Exploration and - PowerPoint PPT Presentation

Pending Constraints in Symbolic Execution for Better Exploration and Seeding Timotej Kapus Frank Busse Cristian Cadar Imperial College London 1 Symbolic Execution Program analysis technique Active research area Used in


  1. Pending Constraints in Symbolic Execution for Better Exploration and Seeding Timotej Kapus Frank Busse Cristian Cadar Imperial College London 1

  2. Symbolic Execution ● Program analysis technique ● Active research area ● Used in industry ○ IntelliTest, SAGE Angr ○ KLOVER 2

  3. Why symbolic execution? ● No false positives! ○ Every bug found has a concrete input triggering it ● Can interact with the environment ○ I/O, unmodeled libraries ● Only relevant code executed “symbolically”, the rest is fast “native” execution 3

  4. Why (not) symbolic execution? ● Scalability, scalability, scalability ○ Constraint solving is hard ○ Path explosion 4

  5. This talk Introduce pending constraints which enhance the scalability of symbolic execution via aggressively tackling paths that are known to be feasible. 5

  6. “known to be feasible” Caching Seeding ● Cache assignments from ● External, usually valid previous solver queries concrete inputs ● Already widely adopted ● Used to bootstrap symbolic execution ● From test-suites, examples, production data 6

  7. Symbolic execution example: get_sign int get_sign( int x) { int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; return r; } 7

  8. get_sign( x ); int get_sign( int x) { int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; return r; } Known assignments ∅ 8

  9. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; return r; } Known assignments ∅ 9

  10. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } Known assignments ∅ 10

  11. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x < 1 Known assignments Known assignments x = -2 x = -2 11

  12. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 Known assignments Known assignments x = -2 x = -2 x = 7 12

  13. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 Known assignments x == 0 x = -2 x = 7 13

  14. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 Known assignments x == 0 x ≠ 0 x = -2 x = 7 14

  15. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 Known assignments x == 0 x ≠ 0 x = -2 x = 0 x = 0 x = 7 x = 0 15

  16. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 Known assignments x == 0 x ≠ 0 x = -2 x = 0 x = 0 x = 7 x = 0 r = 0; 16

  17. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 Known assignments x == 0 x ≠ 0 x = -2 x = 0 x = 7 x = 0 r = 0; return r; 17

  18. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 Known assignments x == 0 x ≠ 0 x = -2 x = 0 x = 7 x = 0 r = 0; return r; return r; 18

  19. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 r = 1; Known assignments x == 0 x ≠ 0 x = -2 x = 0 x = 7 x = 0 r = 0; return r; return r; 19

  20. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 r = 1; Known assignments x == 0 x ≠ 0 x = -2 x = 0 x == 0 x = 7 x = 0 r = 0; return r; return r; 20

  21. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 r = 1; Known assignments x == 0 x ≠ 0 x = -2 x = 0 x == 0 x = 7 x = 0 x = 0 r = 0; return r; return r; 21

  22. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 r = 1; Known assignments x == 0 x ≠ 0 x = -2 x = 0 x == 0 x = 7 x ≠ 0 x = 0 x = 0 r = 0; return r; return r; 22

  23. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 r = 1; Known assignments x == 0 x ≠ 0 x = -2 x = 0 x == 0 x = 7 x ≠ 0 x = 0 x = 0 r = 0; return r; return r; return r; 23

  24. Symbolic execution with pending constraints int get_sign( int x) { ● Explore paths that are known int r = -1; to be feasible if (x >= 1) r = 1; ● Solve constraints only when if (x == 0) r = 0; necessary to make progress return r; } 24

  25. get_sign( x ); int get_sign( int x) { int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; return r; } Known assignments ∅ 25

  26. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; return r; } Known assignments ∅ 26

  27. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 Known assignments ∅ 27

  28. get_sign( x ); int get_sign( int x) { Pending constraints r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; ● Not known to be feasible } x ≥ 1 x < 1 ● When only pending constraints left ○ Pick one and check Known assignments ∅ 28

  29. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 Known assignments x = -2 29

  30. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 Known assignments x == 0 x ≠ 0 x = -2 x = 0 30

  31. get_sign( x ); int get_sign( int x) { Pending constraints: still not known if feasible r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 Known assignments x == 0 x ≠ 0 x = -2 x = 0 31

  32. get_sign( x ); int get_sign( int x) { Pending constraints: known feasible path! r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 Known assignments x == 0 x ≠ 0 x = -2 x = 0 32

  33. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 Known assignments x == 0 x ≠ 0 x = -2 x = 0 return r; 33

  34. get_sign( x ); int get_sign( int x) { Only pending constraints: check one r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 Known assignments x == 0 x ≠ 0 x = -2 x = 0 return r; 34

  35. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 Known assignments x == 0 x ≠ 0 x = -2 x = 0 x = 0 r = 0; return r; return r; 35

  36. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 r = 1; Known assignments x == 0 x ≠ 0 x = -2 x = 0 x = 0 x = 7 r = 0; return r; return r; 36

  37. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 r = 1; Known assignments x == 0 x ≠ 0 x = -2 x = 0 x == 0 x = 0 x ≠ 0 x = 0 x = 7 r = 0; return r; return r; 37

  38. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 r = 1; Known assignments x == 0 x ≠ 0 x = -2 x = 0 x == 0 x = 0 x ≠ 0 x = 0 x = 7 r = 0; return r; return r; return r; 38

  39. get_sign( x ); int get_sign( int x) { r = -1; int r = -1; if (x >= 1) r = 1; if (x == 0) r = 0; x >= 1 return r; } x ≥ 1 x < 1 r = 1; Known assignments x == 0 x ≠ 0 x = -2 x = 0 x == 0 x = 0 x ≠ 0 x = 0 x = 7 r = 0; return r; return r; return r; 39

  40. Pending constraints: why would they be useful? ● Reversing md5 hash char msg[8] = symbolic; ○ Very hard for SMT solvers uint32_t *hash = md5(msg, 8); ● assert(hash[0] == 1471037522) 1471037522 = md5("ase2020")[0] ○ Use as seed 40

  41. Suppose this exploration tree for md5 41

  42. Suppose this path md5("ase2020") 42

  43. Solver queries: 0 Pending Vanilla 43

  44. Solver queries: 0 Pending Vanilla ase20 20 44

  45. Solver queries: 0 Pending Vanilla ase20 20 45

  46. Solver queries: 0 Pending Vanilla ase20 20 46

  47. Solver queries: 1 Pending Vanilla ase20 20 47

  48. Solver queries: 2 Pending Vanilla ase20 20 48

  49. Solver queries: 3 Pending Vanilla ase20 20 49

  50. Solver queries: 4 Pending Vanilla ase20 20 50

  51. Solver queries: 5 Pending Vanilla ase20 20 51

  52. Solver queries: 6 Pending Vanilla ase20 20 52

  53. Solver queries: 7 Pending Vanilla ase20 20 53

  54. Solver queries: 8 Pending Vanilla ase20 ase20 20 20 54

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend