{"id":17963897,"url":"https://github.com/jonathansalwan/ttexplore","last_synced_at":"2025-03-25T05:32:23.442Z","repository":{"id":62154172,"uuid":"555275162","full_name":"JonathanSalwan/ttexplore","owner":"JonathanSalwan","description":"TTexplore is a library that performs path exploration on binary code using symbolic execution","archived":false,"fork":false,"pushed_at":"2022-11-14T16:48:30.000Z","size":565,"stargazers_count":78,"open_issues_count":0,"forks_count":7,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-03-19T09:14:23.991Z","etag":null,"topics":["fuzzing","symbolic-execution"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JonathanSalwan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-10-21T09:05:57.000Z","updated_at":"2025-02-14T20:55:23.000Z","dependencies_parsed_at":"2023-01-23T02:15:57.717Z","dependency_job_id":null,"html_url":"https://github.com/JonathanSalwan/ttexplore","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JonathanSalwan%2Fttexplore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JonathanSalwan%2Fttexplore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JonathanSalwan%2Fttexplore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JonathanSalwan%2Fttexplore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JonathanSalwan","download_url":"https://codeload.github.com/JonathanSalwan/ttexplore/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245407667,"owners_count":20610231,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fuzzing","symbolic-execution"],"created_at":"2024-10-29T11:45:48.370Z","updated_at":"2025-03-25T05:32:22.989Z","avatar_url":"https://github.com/JonathanSalwan.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Summary\n\n* [Bootstrapping code coverage on top of Triton](#bootstrapping-code-coverage-on-top-of-triton)\n* [Harness your target](#harness-your-target)\n* [The output](#output)\n* [The corpus](#the-corpus)\n* [Sharing corpus between libfuzzer and TTexplore](#sharing-corpus-between-libfuzzer-and-TTexplore)\n* [The TTexplore config structure](#the-TTexplore-config-structure)\n\n# Bootstrapping code coverage on top of Triton\n\n[Triton](https://github.com/jonathansalwan/Triton) is a dynamic binary analysis library that aims to provide components\nsuch as dynamic symbolic execution, but lets the user define its own strategy in order to cover code. This repository\naims to provide a bootstrap code for doing path exploration on top of the Triton library. The [TTexplore](./lib/ttexplore.cpp) library exposes\na `SymbolicExplorator` class that takes as input a `triton::Context`. This context is used as the initial point for the path\nexploration. Then, it does a classical snapshot-based code coverage process. The logic is the following:\n\n1. Save the initial context as backup\n2. Continue the execution from the given `triton::Context`\n3. When execution is done, generate inputs that discover new paths\n4. Restore the backup\n5. Go to point 2\n\nNote that TTexplore is not an advanced library. It's just a bootstrap code that provides a simple coverage logic. Consider this project as a base example about how to cover code with Triton. You will probably adapt it according to your targets and goals. That's why the code of the library aims to be as small as possible.\n\n## Harness your target\n\nLet's consider the following sample that comes from [AFL++ fuzzer challenges](https://github.com/AFLplusplus/fuzzer-challenges).\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cunistd.h\u003e\n#include \u003cstring.h\u003e\n#include \u003cstrings.h\u003e\n#include \u003cstdlib.h\u003e\n#include \u003cstdint.h\u003e\n#include \u003csys/types.h\u003e\n#include \u003csys/stat.h\u003e\n#include \u003cfcntl.h\u003e\n\n#define bail(msg, pos)                                         \\\n  while (1) {                                                  \\\n    return 0;                                                  \\\n  }\n\nint LLVMFuzzerTestOneInput(uint8_t *buf, size_t len) {\n  uint8_t *p8;\n\n  if (len \u003c 28) bail(\"too short\", 0);\n  if (strncasecmp((char *)buf, \"0123\", 4)) bail(\"wrong string\", 0);\n  if (strncasecmp((char *)buf + 4, \"87654321\", 8)) bail(\"wrong string\", 4);\n  if (strncasecmp((char *)buf + 12, \"ABCDEFHIKLMNOPQR\", 16))\n    bail(\"wrong string\", 12);\n  if (len \u003c 54) bail(\"too short\", 0);\n  if (strncasecmp((char *)buf + 28, \"ZYXWVUTSRQPONMLKJIHGFEDCBA\", 26))\n    bail(\"wrong string\", 28);\n\n  return 1;\n}\n```\n\nOur harness is the following:\n\n```cpp\n#include \u003cmap\u003e\n#include \u003ciostream\u003e\n#include \u003cvector\u003e\n\n#include \u003cLIEF/ELF.hpp\u003e\n#include \u003ctriton/context.hpp\u003e\n#include \u003ctriton/cpuSize.hpp\u003e\n#include \u003ctriton/stubs.hpp\u003e\n\n#include \u003cttexplore.hpp\u003e\n\n/* We will map the libc stub at this address */\nconst triton::uint64 base_libc = 0x66600000;\n\nint main(int ac, const char *av[]) {\n  /* Init the triton context */\n  triton::Context ctx(triton::arch::ARCH_X86_64);\n\n  if (ac != 2) {\n    std::cerr \u003c\u003c \"Usage: \" \u003c\u003c av[0] \u003c\u003c \" \u003cbinary\u003e\" \u003c\u003c std::endl;\n    return -1;\n  }\n\n  /* We use LIEF to map segments of the target into the Triton context */\n  std::unique_ptr\u003cconst LIEF::ELF::Binary\u003e binary{LIEF::ELF::Parser::parse(av[1])};\n  for (const LIEF::ELF::Segment\u0026 s : binary-\u003esegments()) {\n    std::vector\u003ctriton::uint8\u003e data;\n    data.insert(data.begin(), s.content().begin(), s.content().end());\n    ctx.setConcreteMemoryAreaValue(s.virtual_address(), data);\n  }\n\n  /* Map the stub of libc at 0x66600000 */\n  ctx.setConcreteMemoryAreaValue(base_libc, triton::stubs::x8664::systemv::libc::code);\n\n  /* Do the relocation of the strcmp@target.plt to my strcmp@libc_stub */\n  ctx.setConcreteMemoryValue(\n    triton::arch::MemoryAccess(0x4018, triton::size::qword),\n    base_libc + triton::stubs::x8664::systemv::libc::symbols.at(\"strncasecmp\")\n  );\n\n  /* Setup some Triton optimizations */\n  ctx.setMode(triton::modes::ALIGNED_MEMORY, true);\n  ctx.setMode(triton::modes::AST_OPTIMIZATIONS, true);\n  ctx.setMode(triton::modes::CONSTANT_FOLDING, true);\n\n  /* Setup the program counter and arguments */\n  ctx.setConcreteRegisterValue(ctx.registers.x86_rip, 0x1135);     /* we directly call the target function (LLVMFuzzerTestOneInput) */\n  ctx.setConcreteRegisterValue(ctx.registers.x86_rdi, 0xdead);     /* First argument of the LLVMFuzzerTestOneInput function (buf) */\n  ctx.setConcreteRegisterValue(ctx.registers.x86_rsi, 100);        /* Second argument of the LLVMFuzzerTestOneInput function (len) */\n  ctx.setConcreteRegisterValue(ctx.registers.x86_rsp, 0x7ffffff0); /* init stack */\n  ctx.setConcreteRegisterValue(ctx.registers.x86_rbp, 0x7ffffff0); /* init stack */\n\n  /* Setup symbolic variable. 0xdead is the first arg of LLVMFuzzerTestOneInput (see above) */\n  ctx.symbolizeMemory(0xdead, 100);\n  \n  /* Setup exploration */\n  triton::engines::exploration::SymbolicExplorator explorator;\n  \n  explorator.initContext(\u0026ctx); /* define an initial context */\n  explorator.explore();         /* do the exploration */\n  explorator.dumpCoverage();    /* dump the code coverage */\n\n  return 0;\n  ```\n\nHarnessing your target with TTexplore only consist to craft the `triton::Context` with the appropriate state. It can be initialized from a memory dump, a raw binary or by hand. It can be user or kernel code. The main point is that TTexplore will not emulate nor execute external calls, so your `triton::Context` must handle them before starting the exploration. For example, see how `strncasecmp` is handled in the above harness.\n\n## Output\n\nAfter compiling the harness with the TTexplore library. The output is the following:\n\n```raw\n$ ./build/harness4 ./harness/4/target/test-strcmp\n[TT] exec: 0,  icov: 0,  sat: 1,  unsat: 0,  timeout: 0,  worklist: 1\n[TT] exec: 1,  icov: 70,  sat: 4,  unsat: 1,  timeout: 0,  worklist: 3\n[TT] exec: 2,  icov: 70,  sat: 4,  unsat: 1,  timeout: 0,  worklist: 2\n[TT] exec: 3,  icov: 77,  sat: 7,  unsat: 3,  timeout: 0,  worklist: 4\n[TT] exec: 4,  icov: 77,  sat: 7,  unsat: 3,  timeout: 0,  worklist: 3\n[TT] exec: 5,  icov: 77,  sat: 10,  unsat: 5,  timeout: 0,  worklist: 5\n[TT] exec: 6,  icov: 77,  sat: 10,  unsat: 5,  timeout: 0,  worklist: 4\n[TT] exec: 7,  icov: 77,  sat: 13,  unsat: 7,  timeout: 0,  worklist: 6\n[TT] exec: 8,  icov: 77,  sat: 13,  unsat: 7,  timeout: 0,  worklist: 5\n[TT] exec: 9,  icov: 88,  sat: 16,  unsat: 10,  timeout: 0,  worklist: 7\n[TT] exec: 10,  icov: 88,  sat: 16,  unsat: 10,  timeout: 0,  worklist: 6\n[TT] exec: 11,  icov: 88,  sat: 19,  unsat: 12,  timeout: 0,  worklist: 8\n[TT] exec: 12,  icov: 88,  sat: 19,  unsat: 12,  timeout: 0,  worklist: 7\n[TT] exec: 13,  icov: 88,  sat: 22,  unsat: 14,  timeout: 0,  worklist: 9\n[TT] exec: 14,  icov: 88,  sat: 22,  unsat: 14,  timeout: 0,  worklist: 8\n[TT] exec: 15,  icov: 88,  sat: 25,  unsat: 16,  timeout: 0,  worklist: 10\n[TT] exec: 16,  icov: 88,  sat: 25,  unsat: 16,  timeout: 0,  worklist: 9\n[TT] exec: 17,  icov: 88,  sat: 28,  unsat: 18,  timeout: 0,  worklist: 11\n[TT] exec: 18,  icov: 88,  sat: 28,  unsat: 18,  timeout: 0,  worklist: 10\n[TT] exec: 19,  icov: 88,  sat: 31,  unsat: 20,  timeout: 0,  worklist: 12\n[TT] exec: 20,  icov: 88,  sat: 31,  unsat: 20,  timeout: 0,  worklist: 11\n[TT] exec: 21,  icov: 88,  sat: 34,  unsat: 22,  timeout: 0,  worklist: 13\n[TT] exec: 22,  icov: 88,  sat: 34,  unsat: 22,  timeout: 0,  worklist: 12\n[TT] exec: 23,  icov: 88,  sat: 37,  unsat: 24,  timeout: 0,  worklist: 14\n[TT] exec: 24,  icov: 88,  sat: 37,  unsat: 24,  timeout: 0,  worklist: 13\n[TT] exec: 25,  icov: 100,  sat: 40,  unsat: 27,  timeout: 0,  worklist: 15\n[TT] exec: 26,  icov: 100,  sat: 40,  unsat: 27,  timeout: 0,  worklist: 14\n[TT] exec: 27,  icov: 100,  sat: 43,  unsat: 29,  timeout: 0,  worklist: 16\n[TT] exec: 28,  icov: 100,  sat: 43,  unsat: 29,  timeout: 0,  worklist: 15\n[TT] exec: 29,  icov: 100,  sat: 46,  unsat: 31,  timeout: 0,  worklist: 17\n[TT] exec: 30,  icov: 100,  sat: 46,  unsat: 31,  timeout: 0,  worklist: 16\n[TT] exec: 31,  icov: 100,  sat: 49,  unsat: 33,  timeout: 0,  worklist: 18\n[TT] exec: 32,  icov: 100,  sat: 49,  unsat: 33,  timeout: 0,  worklist: 17\n[TT] exec: 33,  icov: 100,  sat: 52,  unsat: 35,  timeout: 0,  worklist: 19\n[TT] exec: 34,  icov: 100,  sat: 52,  unsat: 35,  timeout: 0,  worklist: 18\n[TT] exec: 35,  icov: 100,  sat: 55,  unsat: 37,  timeout: 0,  worklist: 20\n[TT] exec: 36,  icov: 100,  sat: 55,  unsat: 37,  timeout: 0,  worklist: 19\n[TT] exec: 37,  icov: 100,  sat: 58,  unsat: 39,  timeout: 0,  worklist: 21\n[TT] exec: 38,  icov: 100,  sat: 58,  unsat: 39,  timeout: 0,  worklist: 20\n[TT] exec: 39,  icov: 100,  sat: 61,  unsat: 41,  timeout: 0,  worklist: 22\n[TT] exec: 40,  icov: 100,  sat: 61,  unsat: 41,  timeout: 0,  worklist: 21\n[TT] exec: 41,  icov: 100,  sat: 64,  unsat: 43,  timeout: 0,  worklist: 23\n[TT] exec: 42,  icov: 100,  sat: 64,  unsat: 43,  timeout: 0,  worklist: 22\n[TT] exec: 43,  icov: 100,  sat: 67,  unsat: 45,  timeout: 0,  worklist: 24\n[TT] exec: 44,  icov: 100,  sat: 67,  unsat: 45,  timeout: 0,  worklist: 23\n[TT] exec: 45,  icov: 100,  sat: 70,  unsat: 47,  timeout: 0,  worklist: 25\n[TT] exec: 46,  icov: 100,  sat: 70,  unsat: 47,  timeout: 0,  worklist: 24\n[TT] exec: 47,  icov: 100,  sat: 73,  unsat: 49,  timeout: 0,  worklist: 26\n[TT] exec: 48,  icov: 100,  sat: 73,  unsat: 49,  timeout: 0,  worklist: 25\n[TT] exec: 49,  icov: 100,  sat: 76,  unsat: 51,  timeout: 0,  worklist: 27\n[TT] exec: 50,  icov: 100,  sat: 76,  unsat: 51,  timeout: 0,  worklist: 26\n[TT] exec: 51,  icov: 100,  sat: 79,  unsat: 53,  timeout: 0,  worklist: 28\n[TT] exec: 52,  icov: 100,  sat: 79,  unsat: 53,  timeout: 0,  worklist: 27\n[TT] exec: 53,  icov: 100,  sat: 82,  unsat: 55,  timeout: 0,  worklist: 29\n[TT] exec: 54,  icov: 100,  sat: 82,  unsat: 55,  timeout: 0,  worklist: 28\n[TT] exec: 55,  icov: 100,  sat: 85,  unsat: 57,  timeout: 0,  worklist: 30\n[TT] exec: 56,  icov: 100,  sat: 85,  unsat: 57,  timeout: 0,  worklist: 29\n[TT] exec: 57,  icov: 113,  sat: 88,  unsat: 60,  timeout: 0,  worklist: 31\n[TT] exec: 58,  icov: 113,  sat: 88,  unsat: 60,  timeout: 0,  worklist: 30\n[TT] exec: 59,  icov: 113,  sat: 91,  unsat: 62,  timeout: 0,  worklist: 32\n[TT] exec: 60,  icov: 113,  sat: 91,  unsat: 62,  timeout: 0,  worklist: 31\n[TT] exec: 61,  icov: 113,  sat: 94,  unsat: 64,  timeout: 0,  worklist: 33\n[TT] exec: 62,  icov: 113,  sat: 94,  unsat: 64,  timeout: 0,  worklist: 32\n[TT] exec: 63,  icov: 113,  sat: 97,  unsat: 66,  timeout: 0,  worklist: 34\n[TT] exec: 64,  icov: 113,  sat: 97,  unsat: 66,  timeout: 0,  worklist: 33\n[TT] exec: 65,  icov: 113,  sat: 100,  unsat: 68,  timeout: 0,  worklist: 35\n[TT] exec: 66,  icov: 113,  sat: 100,  unsat: 68,  timeout: 0,  worklist: 34\n[TT] exec: 67,  icov: 113,  sat: 103,  unsat: 70,  timeout: 0,  worklist: 36\n[TT] exec: 68,  icov: 113,  sat: 103,  unsat: 70,  timeout: 0,  worklist: 35\n[TT] exec: 69,  icov: 113,  sat: 106,  unsat: 72,  timeout: 0,  worklist: 37\n[TT] exec: 70,  icov: 113,  sat: 106,  unsat: 72,  timeout: 0,  worklist: 36\n[TT] exec: 71,  icov: 113,  sat: 109,  unsat: 74,  timeout: 0,  worklist: 38\n[TT] exec: 72,  icov: 113,  sat: 109,  unsat: 74,  timeout: 0,  worklist: 37\n[TT] exec: 73,  icov: 113,  sat: 112,  unsat: 76,  timeout: 0,  worklist: 39\n[TT] exec: 74,  icov: 113,  sat: 112,  unsat: 76,  timeout: 0,  worklist: 38\n[TT] exec: 75,  icov: 113,  sat: 115,  unsat: 78,  timeout: 0,  worklist: 40\n[TT] exec: 76,  icov: 113,  sat: 115,  unsat: 78,  timeout: 0,  worklist: 39\n[TT] exec: 77,  icov: 113,  sat: 118,  unsat: 80,  timeout: 0,  worklist: 41\n[TT] exec: 78,  icov: 113,  sat: 118,  unsat: 80,  timeout: 0,  worklist: 40\n[TT] exec: 79,  icov: 113,  sat: 121,  unsat: 82,  timeout: 0,  worklist: 42\n[TT] exec: 80,  icov: 113,  sat: 121,  unsat: 82,  timeout: 0,  worklist: 41\n[TT] exec: 81,  icov: 113,  sat: 124,  unsat: 84,  timeout: 0,  worklist: 43\n[TT] exec: 82,  icov: 113,  sat: 124,  unsat: 84,  timeout: 0,  worklist: 42\n[TT] exec: 83,  icov: 113,  sat: 127,  unsat: 86,  timeout: 0,  worklist: 44\n[TT] exec: 84,  icov: 113,  sat: 127,  unsat: 86,  timeout: 0,  worklist: 43\n[TT] exec: 85,  icov: 113,  sat: 130,  unsat: 88,  timeout: 0,  worklist: 45\n[TT] exec: 86,  icov: 113,  sat: 130,  unsat: 88,  timeout: 0,  worklist: 44\n[TT] exec: 87,  icov: 113,  sat: 133,  unsat: 90,  timeout: 0,  worklist: 46\n[TT] exec: 88,  icov: 113,  sat: 133,  unsat: 90,  timeout: 0,  worklist: 45\n[TT] exec: 89,  icov: 113,  sat: 136,  unsat: 92,  timeout: 0,  worklist: 47\n[TT] exec: 90,  icov: 113,  sat: 136,  unsat: 92,  timeout: 0,  worklist: 46\n[TT] exec: 91,  icov: 113,  sat: 139,  unsat: 94,  timeout: 0,  worklist: 48\n[TT] exec: 92,  icov: 113,  sat: 139,  unsat: 94,  timeout: 0,  worklist: 47\n[TT] exec: 93,  icov: 113,  sat: 142,  unsat: 96,  timeout: 0,  worklist: 49\n[TT] exec: 94,  icov: 113,  sat: 142,  unsat: 96,  timeout: 0,  worklist: 48\n[TT] exec: 95,  icov: 113,  sat: 145,  unsat: 98,  timeout: 0,  worklist: 50\n[TT] exec: 96,  icov: 113,  sat: 145,  unsat: 98,  timeout: 0,  worklist: 49\n[TT] exec: 97,  icov: 113,  sat: 148,  unsat: 100,  timeout: 0,  worklist: 51\n[TT] exec: 98,  icov: 113,  sat: 148,  unsat: 100,  timeout: 0,  worklist: 50\n[TT] exec: 99,  icov: 113,  sat: 151,  unsat: 102,  timeout: 0,  worklist: 52\n[TT] exec: 100,  icov: 113,  sat: 151,  unsat: 102,  timeout: 0,  worklist: 51\n[TT] exec: 101,  icov: 113,  sat: 154,  unsat: 104,  timeout: 0,  worklist: 53\n[TT] exec: 102,  icov: 113,  sat: 154,  unsat: 104,  timeout: 0,  worklist: 52\n[TT] exec: 103,  icov: 113,  sat: 157,  unsat: 106,  timeout: 0,  worklist: 54\n[TT] exec: 104,  icov: 113,  sat: 157,  unsat: 106,  timeout: 0,  worklist: 53\n[TT] exec: 105,  icov: 113,  sat: 160,  unsat: 108,  timeout: 0,  worklist: 55\n[TT] exec: 106,  icov: 113,  sat: 160,  unsat: 108,  timeout: 0,  worklist: 54\n[TT] exec: 107,  icov: 113,  sat: 163,  unsat: 110,  timeout: 0,  worklist: 56\n[TT] exec: 108,  icov: 113,  sat: 163,  unsat: 110,  timeout: 0,  worklist: 55\n[TT] exec: 109,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 54\n[TT] exec: 110,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 53\n[TT] exec: 111,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 52\n[TT] exec: 112,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 51\n[TT] exec: 113,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 50\n[TT] exec: 114,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 49\n[TT] exec: 115,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 48\n[TT] exec: 116,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 47\n[TT] exec: 117,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 46\n[TT] exec: 118,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 45\n[TT] exec: 119,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 44\n[TT] exec: 120,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 43\n[TT] exec: 121,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 42\n[TT] exec: 122,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 41\n[TT] exec: 123,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 40\n[TT] exec: 124,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 39\n[TT] exec: 125,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 38\n[TT] exec: 126,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 37\n[TT] exec: 127,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 36\n[TT] exec: 128,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 35\n[TT] exec: 129,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 34\n[TT] exec: 130,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 33\n[TT] exec: 131,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 32\n[TT] exec: 132,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 31\n[TT] exec: 133,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 30\n[TT] exec: 134,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 29\n[TT] exec: 135,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 28\n[TT] exec: 136,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 27\n[TT] exec: 137,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 26\n[TT] exec: 138,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 25\n[TT] exec: 139,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 24\n[TT] exec: 140,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 23\n[TT] exec: 141,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 22\n[TT] exec: 142,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 21\n[TT] exec: 143,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 20\n[TT] exec: 144,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 19\n[TT] exec: 145,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 18\n[TT] exec: 146,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 17\n[TT] exec: 147,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 16\n[TT] exec: 148,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 15\n[TT] exec: 149,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 14\n[TT] exec: 150,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 13\n[TT] exec: 151,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 12\n[TT] exec: 152,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 11\n[TT] exec: 153,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 10\n[TT] exec: 154,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 9\n[TT] exec: 155,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 8\n[TT] exec: 156,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 7\n[TT] exec: 157,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 6\n[TT] exec: 158,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 5\n[TT] exec: 159,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 4\n[TT] exec: 160,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 3\n[TT] exec: 161,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 2\n[TT] exec: 162,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 1\n[TT] exec: 163,  icov: 114,  sat: 163,  unsat: 113,  timeout: 0,  worklist: 0\n[TT] IDA coverage file has been written in workspace/coverage/ida_cov.py\n```\n\nThe output format is the following:\n\n* `[TT]`: verbose from TTexplore\n* `exec`: number of executions\n* `icov`: number of unique instructions covered\n* `sat`: number of queries that are sat\n* `unsat`: number of queries that are unsat\n* `timeout`: number of queries that raise a timeout\n* `worklist`: number of seeds that are waiting to be injected into the program\n\nNote that a `workspace/coverage/ida_cov.py` file has been generated. It's an IDA plugin that colors all instructions covered.\n\n## The corpus\n\nAll the corpus is stored on the disk into a `workspace` directory. There is one file per execution.\n\n```console\n$ ls workspace/corpus\n1    102  106  11   113  117  120  124  128  131  135  139  142  146  15   153  157  160  17  20  24  28  31  35  39  42  46  5   53  57  60  64  68  71  75  79  82  86  9   93  97\n10   103  107  110  114  118  121  125  129  132  136  14   143  147  150  154  158  161  18  21  25  29  32  36  4   43  47  50  54  58  61  65  69  72  76  8   83  87  90  94  98\n100  104  108  111  115  119  122  126  13   133  137  140  144  148  151  155  159  162  19  22  26  3   33  37  40  44  48  51  55  59  62  66  7   73  77  80  84  88  91  95  99\n101  105  109  112  116  12   123  127  130  134  138  141  145  149  152  156  16   163  2   23  27  30  34  38  41  45  49  52  56  6   63  67  70  74  78  81  85  89  92  96\n```\n\nRegarding [our sample](#harness-your-target), if we print all the corpus once the coverage is done we got the following output:\n\n```console\n$ strings workspace/corpus/*\n0123@\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgf\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgfe\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgfe\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgfed\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgfed\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgfedc\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgfedc\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgfedcb\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgfedcb|\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgfedcba\n01238\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgfedcbP\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgfedcP\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgfedX\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgfeA\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgfH\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgA\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihZ\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjiX\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjH\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkP\n01238?\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlZ\n012387654321abcdefhiklmnopqrzyxwvutsrqponmH\n012387654321abcdefhiklmnopqrzyxwvutsrqponH\n012387654321abcdefhiklmnopqrzyxwvutsrqpoH\n012387654321abcdefhiklmnopqrzyxwvutsrqpA\n012387654321abcdefhiklmnopqrzyxwvutsrqP\n012387654321abcdefhiklmnopqrzyxwvutsrZ\n012387654321abcdefhiklmnopqrzyxwvutsX\n012387654321abcdefhiklmnopqrzyxwvutZ\n012387654321abcdefhiklmnopqrzyxwvuZ\n012387\n012387654321abcdefhiklmnopqrzyxwvH\n012387654321abcdefhiklmnopqrzyxwZ\n012387654321abcdefhiklmnopqrzyxA\n012387654321abcdefhiklmnopqrzyA\n012387654321abcdefhiklmnopqrzH\n012387654321abcdefhiklmnopqrA\n012387654321abcdefhiklmnopqX\n012387654321abcdefhiklmnopH\n012387654321abcdefhiklmnoA\n012387654321abcdefhiklmnH\n012387\u003e\n012387654321abcdefhiklmP\n012387654321abcdefhiklA\n012387654321abcdefhikZ\n012387654321abcdefhiH\n012387654321abcdefhA\n012387654321abcdefA\n012387654321abcdeH\n012387654321abcdH\n012387654321abcA\n012387654321abP\n0123876\n012387654321aZ\n012387654321X\n01238765432A\n0123876543P\n012387654Z\n01238765A\n0123876P\n012387H\n01238P\n0123H\n0123876^\n012X\n01238765\n01238765z\n012387654\n012387654@\n0123876543\n01238765438\n01238765432\n01238765432\n012387654321\n012387654321z\n012387654321a\n012387654321az\n012387654321ab\n012387654321abk\n012387654321abc\n012387654321abc\n012387654321abcd\n012387654321abcdf\n012387654321abcde\n012387654321abcdez\n012387654321abcdef\n012387654321abcdef\n012387654321abcdefh\n012387654321abcdefh\n012387654321abcdefhi\n012387654321abcdefhi\n012387654321abcdefhik\n012387654321abcdefhik\n012387654321abcdefhikl\n012387654321abcdefhikl\n012387654321abcdefhiklm\n012387654321abcdefhiklm~\n012387654321abcdefhiklmn\n012387654321abcdefhiklmnz\n012387654321abcdefhiklmno\n012387654321abcdefhiklmno|\n012387654321abcdefhiklmnop\n012387654321abcdefhiklmnop\n012387654321abcdefhiklmnopq\n012387654321abcdefhiklmnopq|\n012387654321abcdefhiklmnopqr\n012387654321abcdefhiklmnopqr\n012387654321abcdefhiklmnopqrz\n012387654321abcdefhiklmnopqrzz\n012387654321abcdefhiklmnopqrzy\n012387654321abcdefhiklmnopqrzy|\n012387654321abcdefhiklmnopqrzyx\n012387654321abcdefhiklmnopqrzyxz\n012387654321abcdefhiklmnopqrzyxw\n012387654321abcdefhiklmnopqrzyxw~\n012387654321abcdefhiklmnopqrzyxwv\n012387654321abcdefhiklmnopqrzyxwv\n012387654321abcdefhiklmnopqrzyxwvu\n012387654321abcdefhiklmnopqrzyxwvu|\n012387654321abcdefhiklmnopqrzyxwvut\n012387654321abcdefhiklmnopqrzyxwvut{\n012387654321abcdefhiklmnopqrzyxwvuts\n012387654321abcdefhiklmnopqrzyxwvutsz\n012387654321abcdefhiklmnopqrzyxwvutsr\n012387654321abcdefhiklmnopqrzyxwvutsrz\n012387654321abcdefhiklmnopqrzyxwvutsrq\n012387654321abcdefhiklmnopqrzyxwvutsrq|\n012387654321abcdefhiklmnopqrzyxwvutsrqp\n012;\n012387654321abcdefhiklmnopqrzyxwvutsrqp\n012387654321abcdefhiklmnopqrzyxwvutsrqpo\n012387654321abcdefhiklmnopqrzyxwvutsrqpo\n012387654321abcdefhiklmnopqrzyxwvutsrqpon\n012387654321abcdefhiklmnopqrzyxwvutsrqpon\n012387654321abcdefhiklmnopqrzyxwvutsrqponm\n012387654321abcdefhiklmnopqrzyxwvutsrqponm\n012387654321abcdefhiklmnopqrzyxwvutsrqponml\n012387654321abcdefhiklmnopqrzyxwvutsrqponml{\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlk\n0123\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlk\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkj\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkj|\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkji\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkji\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjih\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjih\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihg\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihg\n012387654321abcdefhiklmnopqrzyxwvutsrqponmlkjihgf\n```\n\n# Sharing corpus between libfuzzer and TTexplore\n\nNowadays combining multiple sources of fuzzer and sharing seeds is something relevant. This is something that can be quickly done here. Let's consider the following snippet:\n\n```c\n#include \u003cstdint.h\u003e\n#include \u003cstddef.h\u003e\n\nextern \"C\" int LLVMFuzzerTestOneInput(const char* data, size_t size) {\n  if (size \u003c 4)\n    return 0;\n  uint32_t r = ((uint32_t*)data)[0];\n  if ((r * 2) == 0xdeadbef0)\n    __builtin_trap();\n  return 0;\n}\n```\n\nIf we compile this snippet with libfuzzer without optimization (`clang++ -g -O0 -fsanitize=fuzzer,memory target.cpp`), libfuzzer will run for a while before finding `r * 2 == 0xdeadbef0`. In other hand, this kind of constraint is really easy to solve using symbolic execution. So, combining dynamic symbolic execution and runtime fuzzing is something very interesting.\n\nThe only thing we have to do is to run libfuzzer with 2 jobs and defining a corpus directory (here the TTexplore workspace). Note that we have to run at least 2 jobs, otherwise libfuzzer will not refresh its corpus, which is an issue as we need to share seeds from TTexplore and libfuzzer.\n\nSo, in a first console, let's run libfuzzer like this:\n\n```console\n$ ./harness/6/target/target-libfuzzer -jobs=2 ./workspace/corpus\n```\n\nAnd in another console, let's run our TTexplore harness like this:\n\n```console\n$ ./build/harness6\n```\n\nAs soon as TTexplore will find a model which solves `r * 2 == 0xdeadbef0`, it will write the seed into the `./workspace/corpus` directory and at the next libfuzzer refresh, libfuzzer will trigger the `__builtin_trap`. \n\n![tt-and-libfuzzer](https://user-images.githubusercontent.com/991046/197147618-fc09e934-7340-4ebb-aa34-6f77be4422d8.gif)\n\nThis is a very straightforward example, but it shows how combining multiple sources of fuzzer enhances our chances of finding new paths.\n\n# The TTexplore config structure\n\nYou can quickly configure the exploration. There is a structure for that.\n\n```cpp\nstruct config_s {\n  bool            stats;\n  std::string     workspace = \"workspace\";\n  triton::uint64  end_point;\n  triton::usize   ea_model;\n  triton::usize   jmp_model;\n  triton::usize   limit_inst;\n  triton::usize   timeout; /* seconds */\n};\n```\n\n* `stats`: `true` if you want `[TT]` verbosity\n* `workspace`: The default workspace name directory\n* `end_point`: The instruction address where to stop the execution\n* `ea_model`: Number of queries sent to the solver when a symbolic load or store is hit. E.g, `mov rax, [rsi + rdi]` where `rdi` is symbolic.\n* `jmp_model`: Number of queries sent to the solver when a symbolic jump is hit. E.g, `jmp rax` where `rax` is symbolic.\n* `limit_inst`: The limit of instructions executed per execution.\n* `timeout`: The timeout in seconds for solving queries.\n\nThere are only few possible configurations as it aims to be a bootstrap code.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonathansalwan%2Fttexplore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonathansalwan%2Fttexplore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonathansalwan%2Fttexplore/lists"}