[
  {
    "path": ".gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n\n# Test program builds\ncorpus/persist/deferred\ncorpus/persist/deferred_nohook\ncorpus/persist/nopersist\ncorpus/persist/persist\ncorpus/persist/persist_hang\ncorpus/libtest/libtest1.so\ncorpus/libtest/libtest2.so\ncorpus/libtest/test\ncorpus/libtest/pie\ncorpus/afl_test/test\ncorpus/afl_test/test32\ncorpus/afl_test/test-qemu\ncorpus/afl_test/test-fast\ncorpus/afl_test/test-fast-deferred\ncorpus/afl_test/test-fast-persist\ncorpus/afl_test/test-fast-persist-deferred\ncorpus/afl_test/test-fast-persist-hang\n\n# Visual Studio 2015 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# DNX\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# TODO: Comment the next line if you want to checkin your web deploy settings\n# but database connection strings (with potential passwords) will be unencrypted\n#*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n# NuGet v3's project.json files produces more ignoreable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\nnode_modules/\norleans.codegen.cs\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# JetBrains Rider\n.idea/\n*.sln.iml\n\n# CodeRush\n.cr/\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc\n\n# VIM files\n*.swp\n*.swo\n\n# LaTeX files\n*.toc\n*.aux\n*.pdf\n*.out\n\n# sqlite database files\n*.db\n\n# CMake directory\nbuild/\n\n# AFL program files\nafl_progs/afl-as\nafl_progs/afl-clang\nafl_progs/afl-clang++\nafl_progs/afl-g++\nafl_progs/afl-gcc\nafl_progs/afl-qemu-trace\nafl_progs/afl-showmap\nafl_progs/as\nafl_progs/qemu_mode/qemu-2.10.0.tar.xz\nafl_progs/qemu_mode/qemu-2.10.0/\nafl_progs/afl-clang-fast\nafl_progs/afl-clang-fast++\nafl_progs/afl-llvm-pass.so\nafl_progs/afl-llvm-rt-64.o\nafl_progs/afl-llvm-rt-32.o\nafl_progs/afl-llvm-rt.o\n\n"
  },
  {
    "path": ".gitlab-ci.yml",
    "content": "stages:\n  - test\n  - release\n\nbuild-windows-vs2017:\n  script:\n    - call tools\\release_vs2017.bat\n  variables:\n    GIT_STRATEGY: clone\n    GIT_SUBMODULE_STRATEGY: recursive\n  tags:\n    - windows\n    - vs2017\n  only:\n    - web\n  artifacts:\n    paths:\n      - release\\killerbeez-*.zip\n    expire_in: 1 week\n  stage: release\n\nbuild-windows-vs2019:\n  script:\n    - call tools\\release_vs2019.bat\n  variables:\n    GIT_STRATEGY: clone\n    GIT_SUBMODULE_STRATEGY: recursive\n  tags:\n    - windows\n    - vs2019\n  only:\n    - web\n  artifacts:\n    paths:\n      - release\\killerbeez-*.zip\n    expire_in: 1 week\n  stage: release\n\nrelease-linux:\n  script:\n    - mkdir build\n    - cd build\n    - cmake ..\n    - make release\n  image: killerbeez-builder:latest\n  variables:\n    GIT_STRATEGY: clone\n    GIT_SUBMODULE_STRATEGY: recursive\n  tags:\n    - ubuntu-16.04\n  only:\n    - web\n  artifacts:\n    paths:\n      - build/killerbeez-*.zip\n    expire_in: 1 week\n  stage: release\n\n# Smoke tests on all platforms\n.smoketest-linux: &smoketest-linux\n  script:\n    - cd ..\n    - killerbeez/tests/smoke_test.sh\n  variables:\n    GIT_STRATEGY: clone\n    GIT_SUBMODULE_STRATEGY: recursive\n  only:\n    - web\n  stage: test\n  # The build is broken on most of the platforms\n  allow_failure: true\n\nsmoketest-ubuntu-14.04:\n  <<: *smoketest-linux\n  tags:\n    - ubuntu-14.04\n\nsmoketest-ubuntu-16.04:\n  <<: *smoketest-linux\n  tags:\n    - ubuntu-16.04\n  # This platform is supposed to be working\n  allow_failure: false\n\nsmoketest-ubuntu-18.04:\n  <<: *smoketest-linux\n  tags:\n    - ubuntu-18.04\n\nsmoketest-ubuntu-19.04:\n  <<: *smoketest-linux\n  tags:\n    - ubuntu-19.04\n\nsmoketest-fedora-29:\n  <<: *smoketest-linux\n  tags:\n    - fedora-29\n\nsmoketest-fedora-30:\n  <<: *smoketest-linux\n  tags:\n    - fedora-30\n\nsmoketest-debian-8:\n  <<: *smoketest-linux\n  tags:\n    - debian-8\n\nsmoketest-debian-9:\n  <<: *smoketest-linux\n  tags:\n    - debian-9\n\nsmoketest-debian-10:\n  <<: *smoketest-linux\n  tags:\n    - debian-10\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"server/boinc\"]\n\tpath = server/boinc\n\turl = https://github.com/BOINC/boinc.git\n"
  },
  {
    "path": "APLv2",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (killerbeez)\ninclude(ExternalProject)\n\nset(CMAKE_C_FLAGS_DEBUG \"${CMAKE_C_FLAGS_DEBUG} -D_DEBUG\")\t# for _DEBUG ifdefs in utils.h\nset(CMAKE_POSITION_INDEPENDENT_CODE ON)\n\nif (UNIX)\n\tset(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -Wfatal-errors\") # quit after first error\nendif (UNIX)\n\nif (APPLE)\n\tset(CMAKE_MACOSX_RPATH 1) # https://github.com/liballeg/allegro5/issues/532#issuecomment-170338164\nendif (APPLE)\n\nif(NOT CMAKE_BUILD_TYPE)\n\tset(CMAKE_BUILD_TYPE Debug) \t# for gcc -g\n\tmessage(\"WARNING: Building with debug options; performance will be impacted. Try cmake -DCMAKE_BUILD_TYPE=Release ..\")\nendif()\n\n\nif (WIN32)\n\t# windows/visual studio build convention eg build/X86/Debug\n\tSET ( BUILD_DIRECTORY ${CMAKE_SOURCE_DIR}/build/${CMAKE_C_COMPILER_ARCHITECTURE_ID}/${CMAKE_BUILD_TYPE} )\n\tadd_definitions(-D_CRT_SECURE_NO_WARNINGS -D_DEPRECATION_DISABLE -D_CRT_NONSTDC_NO_DEPRECATE)\nelse (WIN32)\n\tSET ( BUILD_DIRECTORY ${CMAKE_BINARY_DIR} )\nendif (WIN32)\n\nSET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BUILD_DIRECTORY}/killerbeez/ )\nSET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${BUILD_DIRECTORY}/killerbeez/ )\nSET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${BUILD_DIRECTORY}/killerbeez/ )\n\n# Make linux builds relocatable\nSET(CMAKE_BUILD_WITH_INSTALL_RPATH 1)\nSET(CMAKE_INSTALL_RPATH \"$ORIGIN\")\n\n# add headers for utils from utils source folder/repo\ninclude_directories (jansson/)\ninclude_directories (utils/)\n\n# IWYU. Pass -DNO_IWYU=1 to disable, -DNO_IWYU= to re-enable (or regenerate cache)\nif (UNIX AND NOT NO_IWYU)\n\tfind_program(iwyu_path NAMES include-what-you-use iwyu)\n\tif(NOT iwyu_path)\n\t\t# can be installed with sudo apt install iwyu -y\n\t\tmessage(STATUS \"Could not find include-what-you-use, continuing without it\")\n\telse()\n\t\tmessage(STATUS \"Found include-what-you-use, displaying its suggestions\")\n\t\tset(CMAKE_C_INCLUDE_WHAT_YOU_USE ${iwyu_path})\n\t\tset(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${iwyu_path})\n\tendif()\nelse()\n\tmessage(STATUS \"include-what-you-use disabled\")\nendif()\n\nadd_subdirectory(jansson/)\n\n# The general mutator library with the common functionality\nadd_subdirectory(mutators)\n\nadd_subdirectory(corpus) # test programs\nadd_subdirectory(fuzzer) # instantiates & coordinates other parts\nadd_subdirectory(driver) # starts program, feeds input, determines when program is done\nadd_subdirectory(instrumentation) # inserts instructions to program to tell whether an input makes the binary take a new path\nadd_subdirectory(merger) # merges instrumentation data between fuzzer nodes\nadd_subdirectory(tracer) # runs through program and records basic block edges\n\nif (WIN32)\nadd_subdirectory(picker) # picks which libraries of a target program are being used, and worth fuzzing\nadd_subdirectory(winafl) # parts ripped from winafl for dynamorio\nendif (WIN32)\n\n### RELEASE ZIP CONFIG ###\n# Choose what to install into the release zip\ninstall(DIRECTORY ${BUILD_DIRECTORY}/killerbeez DESTINATION . USE_SOURCE_PERMISSIONS)\ninstall(DIRECTORY ${BUILD_DIRECTORY}/mutators DESTINATION . USE_SOURCE_PERMISSIONS)\n\n### BOINC wrapper ###\n# If on Windows, include prebuilt BOINC wrapper\nif (WIN32)\n  SET(BOINC_WRAPPER C:/killerbeez/wrapper_26014_windows_x86_64.exe)\nendif ()\n# If on Linux, we can build our own BOINC wrapper\nif (UNIX AND (NOT APPLE))\n  SET(BOINC_WRAPPER ${CMAKE_SOURCE_DIR}/server/boinc/samples/wrapper/wrapper)\n  ExternalProject_Add(boinc-wrapper\n    SOURCE_DIR ${CMAKE_SOURCE_DIR}/server/boinc\n    DOWNLOAD_COMMAND cd ${CMAKE_SOURCE_DIR} && git submodule update --init server/boinc\n    BUILD_IN_SOURCE true\n    CONFIGURE_COMMAND ./_autosetup\n    COMMAND ./configure --disable-server --disable-client --disable-manager --enable-boinczip\n    BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}\n    COMMAND ${CMAKE_MAKE_PROGRAM} -C samples/wrapper\n    INSTALL_COMMAND \"\"\n  )\nendif ()\ninstall(PROGRAMS ${BOINC_WRAPPER} DESTINATION server/skel)\n\n### radamsa ###\nset(RADAMSA_URL https://gitlab.com/akihe/radamsa.git)\nExternalProject_Add(radamsa\n  GIT_REPOSITORY ${RADAMSA_URL}\n  GIT_TAG develop\n  BUILD_IN_SOURCE true\n  CONFIGURE_COMMAND \"\"\n  BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}\n  INSTALL_COMMAND \"\"\n  EXCLUDE_FROM_ALL true\n)\nExternalProject_Get_Property(radamsa SOURCE_DIR)\ninstall(DIRECTORY ${SOURCE_DIR}/bin DESTINATION radamsa USE_SOURCE_PERMISSIONS)\ninstall(FILES ${SOURCE_DIR}/LICENCE DESTINATION radamsa)\n\n# Set up CPack to generate the release zip\nSET(CPACK_GENERATOR \"ZIP\")\n# TODO: might want some kind of versioning or architecture in this name\nSET(CPACK_PACKAGE_FILE_NAME \"killerbeez-${CMAKE_SYSTEM_NAME}\")\nSET(CPACK_SOURCE_GENERATOR \"ZIP\")\nSET(CPACK_SOURCE_IGNORE_FILES \"/build/;/server/boinc/\")\nSET(CPACK_SOURCE_INSTALLED_DIRECTORIES \"${CMAKE_SOURCE_DIR};killerbeez\")\ninclude (CPack)\n\n# Special `release` target to ensure boinc-wrapper is built before package\nadd_custom_target(release\n  ${CMAKE_MAKE_PROGRAM} package)\nif (UNIX)\n  if (APPLE)\n    # macOS can't build the boinc wrapper right now, maybe we can patch\n    # things up in the future to make this possible, but for now we're\n    # just not building it.\n    add_dependencies(release radamsa)\n  else ()\n    add_dependencies(release radamsa boinc-wrapper)\n  endif ()\nendif ()\n"
  },
  {
    "path": "LICENSE",
    "content": "Unless otherwise marked, this license applies to all code in this repository.\n\nUniversity of Illinois/NCSA Open Source License (UIUC license)\nCopyright (c) 2018 Grimm. All rights reserved.\n\n\nDeveloped by: Software Security Group\nGrimm\nhttps://grimm-co.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal with\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\n- Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimers.\n- Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimers in the documentation\n  and/or other materials provided with the distribution.\n- Neither the names of Grimm, nor the names of its contributors may be used to\n  endorse or promote products derived from this Software without specific prior\n  written permission.\n\n\nSOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\nPARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.\n"
  },
  {
    "path": "Makefile",
    "content": ".PHONY=all clean docs\n\nall: docs\n\ndocs:\n\t# Defer to the Makefile in the docs directory\n\tmake -C docs\n"
  },
  {
    "path": "README.md",
    "content": "# Killerbeez\n\nKillerbeez is a modular fuzzing framework that aims to bring awesome tools\ntogether into a standard format. \n\n## Table of Contents\n* [Motivation](#motivation)\n* [Getting Started](#getting-started)\n * [Windows](#windows)\n * [Linux and Mac](#linux-and-mac)\n* [Documentation](#documentation)\n* [Troubleshooting](#troubleshooting)\n\n## Motivation\n\nMany fuzzing tools are \"research-quality\" code, which means they're difficult to\nincorporate with each other or make changes to short of forking.  Killerbeez\nseeks to reduce the engineering effort required to bring these tools together.\nBy writing things to a common API, we hope to encourage clean interfaces, which\nshould discourage spaghetti code and make writing cross-platform tools easier.\n\n## Getting Started\n\nWe provide build instructions for Windows and Linux, and binaries for Windows.\nFor instructions building Killerbeez from source, see the [BUILD\ninstructions](docs/BUILD.md). Currently only the standalone client is available,\nserver coming soon!\n\n### Windows\n\n#### [Binary Releases](https://github.com/grimm-co/killerbeez/releases)\nIf you don't want to build the project from source, you can try the [binary\nreleases](https://github.com/grimm-co/killerbeez/releases) (though be\nwarned they are likely out of date).  They have been tested on the\nfollowing operating systems.\n\n| Windows Version|    64-Bit        |    32-Bit        | \n| -------------- | ------------     | ---------------  |\n| Windows 7      | Not Working [1]  | Not Working [1]  |\n| Windows 8      | Working          | Experimental [2] |\n| Windows 8.1    | Working          | Experimental [2] |\n| Windows 10     | Experimental [2] | Experimental [2] |\n\nYou will also need to install the 2017 Microsoft Visual C++\nRedistributable. Please note that if you are running Killerbeez on a 64-bit\nhost, you will need to install both the 64-bit and the 32-bit versions of\nthe redistributable.\n- [64-Bit Redistributable Download](https://aka.ms/vs/15/release/vc_redist.x64.exe)\n- [32-Bit Redistributable Download](https://aka.ms/vs/15/release/vc_redist.x86.exe)\n\n[1] This is due to a compatibility problem with Windows 7 and DynamoRIO see\n[this issue](https://github.com/DynamoRIO/dynamorio/issues/2658) for more\ninfo.  \n[2] Experimental status means that most of the features are working as\nexpected, and a few are not. \n\n#### Quickstart and Examples\n\n##### Fuzzing a simple test program:\n```\nREM Paste this into cmd.exe.\nREM Assuming you: set WORKDIR=C:/killerbeez\nREM Note: if using backslashes, they need to be escaped to be proper JSON.\n\ncd %WORKDIR%/killerbeez/build/x64/Debug/killerbeez\necho {\"path\":\"%WORKDIR%/killerbeez/corpus/test/test.exe\",\"arguments\":\"@@\"} > driver.json\nfuzzer.exe -n 9 -s \"%WORKDIR%/killerbeez/corpus/test/inputs/close.txt\" ^\n\t-d driver.json file debug bit_flip\n```\n\nSuccessful output should look like\n```\nWed Aug  8 18:27:08 2018 - INFO     - Logging Started\nWed Aug  8 18:27:09 2018 - CRITICAL - Found crashes\nWed Aug  8 18:27:09 2018 - INFO     - Ran 9 iterations in 1 seconds\n```\n\n##### Fuzzing Windows Media Player\nDownload a small video file you would like to use as a seed file (e.g.\n`youtube-dl --format mp4 --output test.mp4 your-favorite-video`).\nBe sure to replace the seed file argument `-s` with the path to the video file\nyou just downloaded. \n\nNote that because `wmplayer.exe` is a 32-bit executable you'll either need\nto use the 32-bit `fuzzer.exe`, or manually specify the path to the 32-bit\n`winafl.dll` with the instrumentation's `winafl_dir` option. Additionally,\nthe `-target_offset` argument that is passed to the instrumentation will\nneed to be updated depending on your Windows version. In this case we are\njust using the entry point of `wmplayer.exe`, below there is a table to use\nas reference but it is best to verify the entry point of your binary.\n\n|   WMP Version   | Offset |\n| --------------- | ------ |\n| 12.0.7601       | 0x176D |\n| 12.0.9200       | 0x1BAD |\n| 12.0.9600       | 0x1F00 |\n| 12.0.17134      | 0x1F20 |\n\n```\necho {\"timeout\":20} > driver.json\necho {\"timeout\":5000,\"coverage_modules\":[\"wmp.DLL\"],\"target_path\":\"C:\\\\Program Files (x86)\\\\Windows Media Player\\\\wmplayer.exe\"} > instrumentation.json\nfuzzer.exe -n 3 -s \"C:\\Users\\user\\Desktop\\test.mp4\" -d driver.json -i instrumentation.json wmp dynamorio nop\n```\nYou may need to modify these parameters to match your environment.  In\norder to speed up fuzzing, it may be useful to enable persistence mode.\nSee [PersistenceMode.md](docs/PersistenceMode.md) for instructions.\n\n### Linux and Mac\n\nOnce you've built Killerbeez following the [BUILD\ninstructions](docs/BUILD.md#linux-and-mac), you should be ready to change\ninto the right directory and run the fuzzer.  Here's an example of running\nit on a test program from our corpus.\n\n```\n# assuming that you're in $WORKDIR/build/killerbeez\ncd ../build/killerbeez/\necho '{\"path\":\"corpus/test-linux\",\"arguments\":\"@@\"}' > driver.json\n./fuzzer -n 20 -s /bin/bash -d driver.json file return_code honggfuzz\n```\n\nIf it ran correctly, you should see something like this:\n```\nThu Jul 19 09:40:46 2018 - INFO     - Logging Started\nThu Jul 19 09:40:46 2018 - INFO     - Ran 20 iterations in 0 seconds\n```\n\nIn the example above, we're using the **file** driver, the **return\\_code**\ninstrumentation, and the **honggfuzz** mutator module.  We are only going to do 20\nexecutions and our seed file is /bin/bash, because why not?\n\nThe -d option are for the driver.  We need to give it the path to our executable\nand the command line arguments, which in our case is just the filename,\nrepresented by \"@@\" here.\n\nWe don't need to specify any options for the mutator or the instrumentation, so\nwe'll rely on default values instead.  To see the options available, you can use\nthe `-h` help flag. Some examples:\n\n```\n./fuzzer -h\n./fuzzer -hd\n./fuzzer -hi\n```\n\nLooking at the results in the \"output\" directory, we see that it didn't find\nany crashes, hangs or new paths.  At first glance, it might seem like it didn't\nwork.  However, we were using the return\\_code instrumentation, which does not\nactually track code coverage, so it can not determine the execution path, thus\nit can't determine if a new path was hit.  Instead, it just looks at the return\ncode to determine if the process crashed or not.  It's very efficient, however\nthis is effectively dumb fuzzing.  In order to track coverage on Linux,\nKillerbeez has support for Intel Processor Trace.  See [IPT.md](docs/IPT.md) for\nmore details.\n\nTo see a crash, we can just change our seed file to be close to the file which\nwill cause a crash.  It's cheating, but it works well to demonstrate the\nimportance of seed files as well as illustrating what the output of finding a\ncrash looks like.  The following commands assume you are still in the directory\ncontaining ./fuzzer.\n\n```\n# assuming that you're in $WORKDIR/build/killerbeez\necho \"ABC@\" > test1  # ABC@ is one bit different than ABCD, the crashing input\necho '{\"path\":\"corpus/test-linux\",\"arguments\":\"@@\"}' > driver.json\n./fuzzer -n 2000 -s ./test1 -d driver.json file return_code honggfuzz\n```\n\nWhich should yield output similar to this:\n\n```\nThu Jul 19 12:03:11 2018 - INFO     - Logging Started\nThu Jul 19 12:03:13 2018 - CRITICAL - Found crashes\nThu Jul 19 12:03:13 2018 - CRITICAL - Found crashes\nThu Jul 19 12:03:19 2018 - CRITICAL - Found crashes\nThu Jul 19 12:03:22 2018 - CRITICAL - Found crashes\nThu Jul 19 12:03:22 2018 - INFO     - Ran 2000 iterations in 11 seconds\n```\n\nLooking in the output/crashes folder, we can see the inputs which were found to\ncrash this target and reproduce the crash manually.\n\n```\n$ ls output/crashes/\n2B81D0C867F76051FD33D8690AA2AC68  5220E572A6F9DAAF522EF5C5698EAF4C  59F885D0289BE9A83E711C5E7CFCBE4D  ED5D34C74E59D16BD6D5B3683DB655C3\n$ cat output/crashes/59F885D0289BE9A83E711C5E7CFCBE4D ; echo\nABCD\n$ corpus/test-linux output/crashes/59F885D0289BE9A83E711C5E7CFCBE4D\nSegmentation fault (core dumped)\n```\n\n## Documentation\nDocumentation of the API can be found in the [docs](docs) folder.  It's written in\nLaTeX which can be used to generate a PDF, HTML, or various other formats.\nPDFs are also included so the documentation is easy to read for those who\ndo not have a LaTeX typesetting environment set up.\n\n## Troubleshooting\nQ: The target program doesn't start   \nA: Windows Media Player won't automatically play media the first time is run.\n   There's a pop-up which requires you to configure some settings.  Just run it\n   manually once and you should be good to go after that.\n\nQ: I'm getting an error about a pipe timing out  \nA: This is related to the instrumentation and the target taking too long to\n   start up.  If running it again doesn't work, try increasing the \"timeout\" on\n   the -i argument and that should take care of it.\n\n## Still Having a Problem?\n\nPlease create an issue on GitHub and we will address it as soon as possible.\n\n## Have questions? Wanna chat?\n\nFeel free to join the mailing list! Send a request to join to\n`killerbeez-join@lists.grimm-co.com` then post your questions to\n`killerbeez@lists.grimm-co.com`! We've also got #killerbeez on freenode,\nbut it's pretty quiet.\n\n## License\n\nThis project is licensed under the UIUC License - see the\n[LICENSE](LICENSE) file for details.  Some parts of this project have been\nincluded from other software and will be under different licenses, where\nmarked.\n"
  },
  {
    "path": "afl_progs/Makefile",
    "content": "#\n# american fuzzy lop - makefile\n# -----------------------------\n#\n# Originally written and maintained by Michal Zalewski <lcamtuf@google.com>\n#\n# Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at:\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Modified by GRIMM\n\nCOMM_HDR    = alloc-inl.h config.h debug.h types.h\nPROGS       = afl-gcc\n\n\nPREFIX     ?= /usr/local\nBIN_PATH    = $(PREFIX)/bin\nHELPER_PATH = $(PREFIX)/lib/afl\nDOC_PATH    = $(PREFIX)/share/doc/afl\n\nCFLAGS     ?= -O3 -funroll-loops\nCFLAGS     += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \\\n              -DAFL_PATH=\\\"$(HELPER_PATH)\\\" -DDOC_PATH=\\\"$(DOC_PATH)\\\" \\\n              -DBIN_PATH=\\\"$(BIN_PATH)\\\"\n\nifeq \"$(findstring clang, $(shell $(CC) --version 2>/dev/null))\" \"\"\n  TEST_CC   = afl-gcc\nelse\n  TEST_CC   = afl-clang\nendif\n\nall: test_x86 $(PROGS) afl-as test_build all_done\n\nifndef AFL_NO_X86\ntest_x86:\n\t@echo \"[*] Checking for the ability to compile x86 code...\"\n\t@echo 'main() { __asm__(\"xorb %al, %al\"); }' | $(CC) -w -x c - -o .test || ( echo; echo \"Oops, looks like your compiler can't generate x86 code.\"; echo; echo \"Don't panic! You can use the LLVM or QEMU mode, but see docs/INSTALL first.\"; echo \"(To ignore this error, set AFL_NO_X86=1 and try again.)\"; echo; exit 1 )\n\t@rm -f .test\n\t@echo \"[+] Everything seems to be working, ready to compile.\"\nelse\ntest_x86:\n\t@echo \"[!] Note: skipping x86 compilation checks (AFL_NO_X86 set).\"\nendif\n\n\nafl-gcc: afl-gcc.c $(COMM_HDR) | test_x86\n\t$(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS)\n\tset -e; for i in afl-g++ afl-clang afl-clang++; do ln -sf afl-gcc $$i; done\n\tln -sf afl-gcc afl-clang\n\tln -sf afl-gcc afl-clang++\n\tln -sf afl-gcc afl-g++\n\nafl-as: afl-as.c afl-as.h $(COMM_HDR) | test_x86\n\t$(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS)\n\tln -sf afl-as as\n\nafl-showmap: afl-showmap.c hash.h $(COMM_HDR) | test_x86\n\t$(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS)\n\nifndef AFL_NO_X86\ntest_build: test-instr.c afl-gcc afl-as afl-showmap\n\t@echo \"[*] Testing the CC wrapper and instrumentation output...\"\n\tunset AFL_USE_ASAN AFL_USE_MSAN; AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. ./$(TEST_CC) $(CFLAGS) test-instr.c -o test-instr $(LDFLAGS)\n\techo 0 | ./afl-showmap -m none -q -o .test-instr0 ./test-instr\n\techo 1 | ./afl-showmap -m none -q -o .test-instr1 ./test-instr\n\t@rm -f test-instr\n\t@cmp -s .test-instr0 .test-instr1; DR=\"$$?\"; rm -f .test-instr0 .test-instr1; if [ \"$$DR\" = \"0\" ]; then echo; echo \"Oops, the instrumentation does not seem to be behaving correctly!\"; echo; echo \"Please ping <lcamtuf@google.com> to troubleshoot the issue.\"; echo; exit 1; fi\n\t@echo \"[+] All right, the instrumentation seems to be working!\"\nelse\ntest_build: afl-gcc afl-as afl-showmap\n\t@echo \"[!] Note: skipping build tests (you may need to use LLVM or QEMU mode).\"\nendif\n\nall_done: test_build\n\t@if [ ! \"`which clang 2>/dev/null`\" = \"\" ]; then echo \"[+] LLVM users: see llvm_mode/README.llvm for a faster alternative to afl-gcc.\"; fi\n\t@echo \"[+] All done! Be sure to review README - it's pretty short and useful.\"\n\t@if [ \"`uname`\" = \"Darwin\" ]; then printf \"\\nWARNING: Fuzzing on MacOS X is slow because of the unusually high overhead of\\nfork() on this OS. Consider using Linux or *BSD. You can also use VirtualBox\\n(virtualbox.org) to put AFL inside a Linux or *BSD VM.\\n\\n\"; fi\n\t@! tty <&1 >/dev/null || printf \"\\033[0;30mNOTE: If you can read this, your terminal probably uses white background.\\nThis will make the UI hard to read. See docs/status_screen.txt for advice.\\033[0m\\n\" 2>/dev/null\n\n"
  },
  {
    "path": "afl_progs/afl-as.c",
    "content": "/*\n   american fuzzy lop - wrapper for GNU as\n   ---------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   The sole purpose of this wrapper is to preprocess assembly files generated\n   by GCC / clang and inject the instrumentation bits included from afl-as.h. It\n   is automatically invoked by the toolchain when compiling programs using\n   afl-gcc / afl-clang.\n\n   Note that it's an explicit non-goal to instrument hand-written assembly,\n   be it in separate .s files or in __asm__ blocks. The only aspiration this\n   utility has right now is to be able to skip them gracefully and allow the\n   compilation process to continue.\n\n   That said, see experimental/clang_asm_normalize/ for a solution that may\n   allow clang users to make things work even with hand-crafted assembly. Just\n   note that there is no equivalent for GCC.\n\n */\n\n#define AFL_MAIN\n\n#include \"config.h\"\n#include \"types.h\"\n#include \"debug.h\"\n#include \"alloc-inl.h\"\n\n#include \"afl-as.h\"\n\n#include <stdio.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <ctype.h>\n#include <fcntl.h>\n\n#include <sys/wait.h>\n#include <sys/time.h>\n\nstatic u8** as_params;          /* Parameters passed to the real 'as'   */\n\nstatic u8*  input_file;         /* Originally specified input file      */\nstatic u8*  modified_file;      /* Instrumented file for the real 'as'  */\n\nstatic u8   be_quiet,           /* Quiet mode (no stderr output)        */\n            clang_mode,         /* Running in clang mode?               */\n            pass_thru,          /* Just pass data through?              */\n            just_version,       /* Just show version?                   */\n            sanitizer;          /* Using ASAN / MSAN                    */\n\nstatic u32  inst_ratio = 100,   /* Instrumentation probability (%)      */\n            as_par_cnt = 1;     /* Number of params to 'as'             */\n\n/* If we don't find --32 or --64 in the command line, default to \n   instrumentation for whichever mode we were compiled with. This is not\n   perfect, but should do the trick for almost all use cases. */\n\n#ifdef __x86_64__\n\nstatic u8   use_64bit = 1;\n\n#else\n\nstatic u8   use_64bit = 0;\n\n#ifdef __APPLE__\n#  error \"Sorry, 32-bit Apple platforms are not supported.\"\n#endif /* __APPLE__ */\n\n#endif /* ^__x86_64__ */\n\n\n/* Examine and modify parameters to pass to 'as'. Note that the file name\n   is always the last parameter passed by GCC, so we exploit this property\n   to keep the code simple. */\n\nstatic void edit_params(int argc, char** argv) {\n\n  u8 *tmp_dir = getenv(\"TMPDIR\"), *afl_as = getenv(\"AFL_AS\");\n  u32 i;\n\n#ifdef __APPLE__\n\n  u8 use_clang_as = 0;\n\n  /* On MacOS X, the Xcode cctool 'as' driver is a bit stale and does not work\n     with the code generated by newer versions of clang that are hand-built\n     by the user. See the thread here: http://goo.gl/HBWDtn.\n\n     To work around this, when using clang and running without AFL_AS\n     specified, we will actually call 'clang -c' instead of 'as -q' to\n     compile the assembly file.\n\n     The tools aren't cmdline-compatible, but at least for now, we can\n     seemingly get away with this by making only very minor tweaks. Thanks\n     to Nico Weber for the idea. */\n\n  if (clang_mode && !afl_as) {\n\n    use_clang_as = 1;\n\n    afl_as = getenv(\"AFL_CC\");\n    if (!afl_as) afl_as = getenv(\"AFL_CXX\");\n    if (!afl_as) afl_as = \"clang\";\n\n  }\n\n#endif /* __APPLE__ */\n\n  /* Although this is not documented, GCC also uses TEMP and TMP when TMPDIR\n     is not set. We need to check these non-standard variables to properly\n     handle the pass_thru logic later on. */\n\n  if (!tmp_dir) tmp_dir = getenv(\"TEMP\");\n  if (!tmp_dir) tmp_dir = getenv(\"TMP\");\n  if (!tmp_dir) tmp_dir = \"/tmp\";\n\n  as_params = ck_alloc((argc + 32) * sizeof(u8*));\n\n  as_params[0] = afl_as ? afl_as : (u8*)\"as\";\n\n  as_params[argc] = 0;\n\n  for (i = 1; i < argc - 1; i++) {\n\n    if (!strcmp(argv[i], \"--64\")) use_64bit = 1;\n    else if (!strcmp(argv[i], \"--32\")) use_64bit = 0;\n\n#ifdef __APPLE__\n\n    /* The Apple case is a bit different... */\n\n    if (!strcmp(argv[i], \"-arch\") && i + 1 < argc) {\n\n      if (!strcmp(argv[i + 1], \"x86_64\")) use_64bit = 1;\n      else if (!strcmp(argv[i + 1], \"i386\"))\n        FATAL(\"Sorry, 32-bit Apple platforms are not supported.\");\n\n    }\n\n    /* Strip options that set the preference for a particular upstream\n       assembler in Xcode. */\n\n    if (clang_mode && (!strcmp(argv[i], \"-q\") || !strcmp(argv[i], \"-Q\")))\n      continue;\n\n#endif /* __APPLE__ */\n\n    as_params[as_par_cnt++] = argv[i];\n\n  }\n\n#ifdef __APPLE__\n\n  /* When calling clang as the upstream assembler, append -c -x assembler\n     and hope for the best. */\n\n  if (use_clang_as) {\n\n    as_params[as_par_cnt++] = \"-c\";\n    as_params[as_par_cnt++] = \"-x\";\n    as_params[as_par_cnt++] = \"assembler\";\n\n  }\n\n#endif /* __APPLE__ */\n\n  input_file = argv[argc - 1];\n\n  if (input_file[0] == '-') {\n\n    if (!strcmp(input_file + 1, \"-version\")) {\n      just_version = 1;\n      modified_file = input_file;\n      goto wrap_things_up;\n    }\n\n    if (input_file[1]) FATAL(\"Incorrect use (not called through afl-gcc?)\");\n      else input_file = NULL;\n\n  } else {\n\n    /* Check if this looks like a standard invocation as a part of an attempt\n       to compile a program, rather than using gcc on an ad-hoc .s file in\n       a format we may not understand. This works around an issue compiling\n       NSS. */\n\n    if (strncmp(input_file, tmp_dir, strlen(tmp_dir)) &&\n        strncmp(input_file, \"/var/tmp/\", 9) &&\n        strncmp(input_file, \"/tmp/\", 5)) pass_thru = 1;\n\n  }\n\n  modified_file = alloc_printf(\"%s/.afl-%u-%u.s\", tmp_dir, getpid(),\n                               (u32)time(NULL));\n\nwrap_things_up:\n\n  as_params[as_par_cnt++] = modified_file;\n  as_params[as_par_cnt]   = NULL;\n\n}\n\n\n/* Process input file, generate modified_file. Insert instrumentation in all\n   the appropriate places. */\n\nstatic void add_instrumentation(void) {\n\n  static u8 line[MAX_LINE];\n\n  FILE* inf;\n  FILE* outf;\n  s32 outfd;\n  u32 ins_lines = 0;\n\n  u8  instr_ok = 0, skip_csect = 0, skip_next_label = 0,\n      skip_intel = 0, skip_app = 0, instrument_next = 0;\n\n#ifdef __APPLE__\n\n  u8* colon_pos;\n\n#endif /* __APPLE__ */\n\n  if (input_file) {\n\n    inf = fopen(input_file, \"r\");\n    if (!inf) PFATAL(\"Unable to read '%s'\", input_file);\n\n  } else inf = stdin;\n\n  outfd = open(modified_file, O_WRONLY | O_EXCL | O_CREAT, 0600);\n\n  if (outfd < 0) PFATAL(\"Unable to write to '%s'\", modified_file);\n\n  outf = fdopen(outfd, \"w\");\n\n  if (!outf) PFATAL(\"fdopen() failed\");  \n\n  while (fgets(line, MAX_LINE, inf)) {\n\n    /* In some cases, we want to defer writing the instrumentation trampoline\n       until after all the labels, macros, comments, etc. If we're in this\n       mode, and if the line starts with a tab followed by a character, dump\n       the trampoline now. */\n\n    if (!pass_thru && !skip_intel && !skip_app && !skip_csect && instr_ok &&\n        instrument_next && line[0] == '\\t' && isalpha(line[1])) {\n\n      fprintf(outf, use_64bit ? trampoline_fmt_64 : trampoline_fmt_32,\n              R(MAP_SIZE));\n\n      instrument_next = 0;\n      ins_lines++;\n\n    }\n\n    /* Output the actual line, call it a day in pass-thru mode. */\n\n    fputs(line, outf);\n\n    if (pass_thru) continue;\n\n    /* All right, this is where the actual fun begins. For one, we only want to\n       instrument the .text section. So, let's keep track of that in processed\n       files - and let's set instr_ok accordingly. */\n\n    if (line[0] == '\\t' && line[1] == '.') {\n\n      /* OpenBSD puts jump tables directly inline with the code, which is\n         a bit annoying. They use a specific format of p2align directives\n         around them, so we use that as a signal. */\n\n      if (!clang_mode && instr_ok && !strncmp(line + 2, \"p2align \", 8) &&\n          isdigit(line[10]) && line[11] == '\\n') skip_next_label = 1;\n\n      if (!strncmp(line + 2, \"text\\n\", 5) ||\n          !strncmp(line + 2, \"section\\t.text\", 13) ||\n          !strncmp(line + 2, \"section\\t__TEXT,__text\", 21) ||\n          !strncmp(line + 2, \"section __TEXT,__text\", 21)) {\n        instr_ok = 1;\n        continue; \n      }\n\n      if (!strncmp(line + 2, \"section\\t\", 8) ||\n          !strncmp(line + 2, \"section \", 8) ||\n          !strncmp(line + 2, \"bss\\n\", 4) ||\n          !strncmp(line + 2, \"data\\n\", 5)) {\n        instr_ok = 0;\n        continue;\n      }\n\n    }\n\n    /* Detect off-flavor assembly (rare, happens in gdb). When this is\n       encountered, we set skip_csect until the opposite directive is\n       seen, and we do not instrument. */\n\n    if (strstr(line, \".code\")) {\n\n      if (strstr(line, \".code32\")) skip_csect = use_64bit;\n      if (strstr(line, \".code64\")) skip_csect = !use_64bit;\n\n    }\n\n    /* Detect syntax changes, as could happen with hand-written assembly.\n       Skip Intel blocks, resume instrumentation when back to AT&T. */\n\n    if (strstr(line, \".intel_syntax\")) skip_intel = 1;\n    if (strstr(line, \".att_syntax\")) skip_intel = 0;\n\n    /* Detect and skip ad-hoc __asm__ blocks, likewise skipping them. */\n\n    if (line[0] == '#' || line[1] == '#') {\n\n      if (strstr(line, \"#APP\")) skip_app = 1;\n      if (strstr(line, \"#NO_APP\")) skip_app = 0;\n\n    }\n\n    /* If we're in the right mood for instrumenting, check for function\n       names or conditional labels. This is a bit messy, but in essence,\n       we want to catch:\n\n         ^main:      - function entry point (always instrumented)\n         ^.L0:       - GCC branch label\n         ^.LBB0_0:   - clang branch label (but only in clang mode)\n         ^\\tjnz foo  - conditional branches\n\n       ...but not:\n\n         ^# BB#0:    - clang comments\n         ^ # BB#0:   - ditto\n         ^.Ltmp0:    - clang non-branch labels\n         ^.LC0       - GCC non-branch labels\n         ^.LBB0_0:   - ditto (when in GCC mode)\n         ^\\tjmp foo  - non-conditional jumps\n\n       Additionally, clang and GCC on MacOS X follow a different convention\n       with no leading dots on labels, hence the weird maze of #ifdefs\n       later on.\n\n     */\n\n    if (skip_intel || skip_app || skip_csect || !instr_ok ||\n        line[0] == '#' || line[0] == ' ') continue;\n\n    /* Conditional branch instruction (jnz, etc). We append the instrumentation\n       right after the branch (to instrument the not-taken path) and at the\n       branch destination label (handled later on). */\n\n    if (line[0] == '\\t') {\n\n      if (line[1] == 'j' && line[2] != 'm' && R(100) < inst_ratio) {\n\n        fprintf(outf, use_64bit ? trampoline_fmt_64 : trampoline_fmt_32,\n                R(MAP_SIZE));\n\n        ins_lines++;\n\n      }\n\n      continue;\n\n    }\n\n    /* Label of some sort. This may be a branch destination, but we need to\n       tread carefully and account for several different formatting\n       conventions. */\n\n#ifdef __APPLE__\n\n    /* Apple: L<whatever><digit>: */\n\n    if ((colon_pos = strstr(line, \":\"))) {\n\n      if (line[0] == 'L' && isdigit(*(colon_pos - 1))) {\n\n#else\n\n    /* Everybody else: .L<whatever>: */\n\n    if (strstr(line, \":\")) {\n\n      if (line[0] == '.') {\n\n#endif /* __APPLE__ */\n\n        /* .L0: or LBB0_0: style jump destination */\n\n#ifdef __APPLE__\n\n        /* Apple: L<num> / LBB<num> */\n\n        if ((isdigit(line[1]) || (clang_mode && !strncmp(line, \"LBB\", 3)))\n            && R(100) < inst_ratio) {\n\n#else\n\n        /* Apple: .L<num> / .LBB<num> */\n\n        if ((isdigit(line[2]) || (clang_mode && !strncmp(line + 1, \"LBB\", 3)))\n            && R(100) < inst_ratio) {\n\n#endif /* __APPLE__ */\n\n          /* An optimization is possible here by adding the code only if the\n             label is mentioned in the code in contexts other than call / jmp.\n             That said, this complicates the code by requiring two-pass\n             processing (messy with stdin), and results in a speed gain\n             typically under 10%, because compilers are generally pretty good\n             about not generating spurious intra-function jumps.\n\n             We use deferred output chiefly to avoid disrupting\n             .Lfunc_begin0-style exception handling calculations (a problem on\n             MacOS X). */\n\n          if (!skip_next_label) instrument_next = 1; else skip_next_label = 0;\n\n        }\n\n      } else {\n\n        /* Function label (always instrumented, deferred mode). */\n\n        instrument_next = 1;\n    \n      }\n\n    }\n\n  }\n\n  if (ins_lines)\n    fputs(use_64bit ? main_payload_64 : main_payload_32, outf);\n\n  if (input_file) fclose(inf);\n  fclose(outf);\n\n  if (!be_quiet) {\n\n    if (!ins_lines) WARNF(\"No instrumentation targets found%s.\",\n                          pass_thru ? \" (pass-thru mode)\" : \"\");\n    else OKF(\"Instrumented %u locations (%s-bit, %s mode, ratio %u%%).\",\n             ins_lines, use_64bit ? \"64\" : \"32\",\n             getenv(\"AFL_HARDEN\") ? \"hardened\" : \n             (sanitizer ? \"ASAN/MSAN\" : \"non-hardened\"),\n             inst_ratio);\n \n  }\n\n}\n\n\n/* Main entry point */\n\nint main(int argc, char** argv) {\n\n  s32 pid;\n  u32 rand_seed;\n  int status;\n  u8* inst_ratio_str = getenv(\"AFL_INST_RATIO\");\n\n  struct timeval tv;\n  struct timezone tz;\n\n  clang_mode = !!getenv(CLANG_ENV_VAR);\n\n  if (isatty(2) && !getenv(\"AFL_QUIET\")) {\n\n    SAYF(cCYA \"afl-as \" cBRI VERSION cRST \" by <lcamtuf@google.com>\\n\");\n \n  } else be_quiet = 1;\n\n  if (argc < 2) {\n\n    SAYF(\"\\n\"\n         \"This is a helper application for afl-fuzz. It is a wrapper around GNU 'as',\\n\"\n         \"executed by the toolchain whenever using afl-gcc or afl-clang. You probably\\n\"\n         \"don't want to run this program directly.\\n\\n\"\n\n         \"Rarely, when dealing with extremely complex projects, it may be advisable to\\n\"\n         \"set AFL_INST_RATIO to a value less than 100 in order to reduce the odds of\\n\"\n         \"instrumenting every discovered branch.\\n\\n\");\n\n    exit(1);\n\n  }\n\n  gettimeofday(&tv, &tz);\n\n  rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();\n\n  srandom(rand_seed);\n\n  edit_params(argc, argv);\n\n  if (inst_ratio_str) {\n\n    if (sscanf(inst_ratio_str, \"%u\", &inst_ratio) != 1 || inst_ratio > 100) \n      FATAL(\"Bad value of AFL_INST_RATIO (must be between 0 and 100)\");\n\n  }\n\n  if (getenv(AS_LOOP_ENV_VAR))\n    FATAL(\"Endless loop when calling 'as' (remove '.' from your PATH)\");\n\n  setenv(AS_LOOP_ENV_VAR, \"1\", 1);\n\n  /* When compiling with ASAN, we don't have a particularly elegant way to skip\n     ASAN-specific branches. But we can probabilistically compensate for\n     that... */\n\n  if (getenv(\"AFL_USE_ASAN\") || getenv(\"AFL_USE_MSAN\")) {\n    sanitizer = 1;\n    inst_ratio /= 3;\n  }\n\n  if (!just_version) add_instrumentation();\n\n  if (!(pid = fork())) {\n\n    execvp(as_params[0], (char**)as_params);\n    FATAL(\"Oops, failed to execute '%s' - check your PATH\", as_params[0]);\n\n  }\n\n  if (pid < 0) PFATAL(\"fork() failed\");\n\n  if (waitpid(pid, &status, 0) <= 0) PFATAL(\"waitpid() failed\");\n\n  if (!getenv(\"AFL_KEEP_ASSEMBLY\")) unlink(modified_file);\n\n  exit(WEXITSTATUS(status));\n\n}\n\n"
  },
  {
    "path": "afl_progs/afl-as.h",
    "content": "/*\n   american fuzzy lop - injectable parts\n   -------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Forkserver design by Jann Horn <jannhorn@googlemail.com>\n\n   Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This file houses the assembly-level instrumentation injected into fuzzed\n   programs. The instrumentation stores XORed pairs of data: identifiers of the\n   currently executing branch and the one that executed immediately before.\n\n   TL;DR: the instrumentation does shm_trace_map[cur_loc ^ prev_loc]++\n\n   The code is designed for 32-bit and 64-bit x86 systems. Both modes should\n   work everywhere except for Apple systems. Apple does relocations differently\n   from everybody else, so since their OSes have been 64-bit for a longer while,\n   I didn't go through the mental effort of porting the 32-bit code.\n\n   In principle, similar code should be easy to inject into any well-behaved\n   binary-only code (e.g., using DynamoRIO). Conditional jumps offer natural\n   targets for instrumentation, and should offer comparable probe density.\n\n */\n\n/*\n\tThis file has been modified from the original AFL version to incorporate into\n\tKillerbeez.  Specifically, the injected fork server has been modified to match\n\tthe Killerbeez fork server protocol.\n */\n\n#ifndef _HAVE_AFL_AS_H\n#define _HAVE_AFL_AS_H\n\n#include \"config.h\"\n#include \"types.h\"\n#include \"../instrumentation/forkserver_internal.h\"\n\n/* \n   ------------------\n   Performances notes\n   ------------------\n\n   Contributions to make this code faster are appreciated! Here are some\n   rough notes that may help with the task:\n\n   - Only the trampoline_fmt and the non-setup __afl_maybe_log code paths are\n     really worth optimizing; the setup / fork server stuff matters a lot less\n     and should be mostly just kept readable.\n\n   - We're aiming for modern CPUs with out-of-order execution and large\n     pipelines; the code is mostly follows intuitive, human-readable\n     instruction ordering, because \"textbook\" manual reorderings make no\n     substantial difference.\n\n   - Interestingly, instrumented execution isn't a lot faster if we store a\n     variable pointer to the setup, log, or return routine and then do a reg\n     call from within trampoline_fmt. It does speed up non-instrumented\n     execution quite a bit, though, since that path just becomes\n     push-call-ret-pop.\n\n   - There is also not a whole lot to be gained by doing SHM attach at a\n     fixed address instead of retrieving __afl_area_ptr. Although it allows us\n     to have a shorter log routine inserted for conditional jumps and jump\n     labels (for a ~10% perf gain), there is a risk of bumping into other\n     allocations created by the program or by tools such as ASAN.\n\n   - popf is *awfully* slow, which is why we're doing the lahf / sahf +\n     overflow test trick. Unfortunately, this forces us to taint eax / rax, but\n     this dependency on a commonly-used register still beats the alternative of\n     using pushf / popf.\n\n     One possible optimization is to avoid touching flags by using a circular\n     buffer that stores just a sequence of current locations, with the XOR stuff\n     happening offline. Alas, this doesn't seem to have a huge impact:\n\n     https://groups.google.com/d/msg/afl-users/MsajVf4fRLo/2u6t88ntUBIJ\n\n   - Preforking one child a bit sooner, and then waiting for the \"go\" command\n     from within the child, doesn't offer major performance gains; fork() seems\n     to be relatively inexpensive these days. Preforking multiple children does\n     help, but badly breaks the \"~1 core per fuzzer\" design, making it harder to\n     scale up. Maybe there is some middle ground.\n\n   Perhaps of note: in the 64-bit version for all platforms except for Apple,\n   the instrumentation is done slightly differently than on 32-bit, with\n   __afl_prev_loc and __afl_area_ptr being local to the object file (.lcomm),\n   rather than global (.comm). This is to avoid GOTRELPC lookups in the critical\n   code path, which AFAICT, are otherwise unavoidable if we want gcc -shared to\n   work; simple relocations between .bss and .text won't work on most 64-bit\n   platforms in such a case.\n\n   (Fun fact: on Apple systems, .lcomm can segfault the linker.)\n\n   The side effect is that state transitions are measured in a somewhat\n   different way, with previous tuple being recorded separately within the scope\n   of every .c file. This should have no impact in any practical sense.\n\n   Another side effect of this design is that getenv() will be called once per\n   every .o file when running in non-instrumented mode; and since getenv() tends\n   to be optimized in funny ways, we need to be very careful to save every\n   oddball register it may touch.\n\n */\n\nstatic const u8* trampoline_fmt_32 =\n\n  \"\\n\"\n  \"/* --- AFL TRAMPOLINE (32-BIT) --- */\\n\"\n  \"\\n\"\n  \".align 4\\n\"\n  \"\\n\"\n  \"leal -16(%%esp), %%esp\\n\"\n  \"movl %%edi,  0(%%esp)\\n\"\n  \"movl %%edx,  4(%%esp)\\n\"\n  \"movl %%ecx,  8(%%esp)\\n\"\n  \"movl %%eax, 12(%%esp)\\n\"\n  \"movl $0x%08x, %%ecx\\n\"\n  \"call __afl_maybe_log\\n\"\n  \"movl 12(%%esp), %%eax\\n\"\n  \"movl  8(%%esp), %%ecx\\n\"\n  \"movl  4(%%esp), %%edx\\n\"\n  \"movl  0(%%esp), %%edi\\n\"\n  \"leal 16(%%esp), %%esp\\n\"\n  \"\\n\"\n  \"/* --- END --- */\\n\"\n  \"\\n\";\n\nstatic const u8* trampoline_fmt_64 =\n\n  \"\\n\"\n  \"/* --- AFL TRAMPOLINE (64-BIT) --- */\\n\"\n  \"\\n\"\n  \".align 4\\n\"\n  \"\\n\"\n  \"leaq -(128+24)(%%rsp), %%rsp\\n\"\n  \"movq %%rdx,  0(%%rsp)\\n\"\n  \"movq %%rcx,  8(%%rsp)\\n\"\n  \"movq %%rax, 16(%%rsp)\\n\"\n  \"movq $0x%08x, %%rcx\\n\"\n  \"call __afl_maybe_log\\n\"\n  \"movq 16(%%rsp), %%rax\\n\"\n  \"movq  8(%%rsp), %%rcx\\n\"\n  \"movq  0(%%rsp), %%rdx\\n\"\n  \"leaq (128+24)(%%rsp), %%rsp\\n\"\n  \"\\n\"\n  \"/* --- END --- */\\n\"\n  \"\\n\";\n\nstatic const u8* main_payload_32 = \n\n  \"\\n\"\n  \"/* --- AFL MAIN PAYLOAD (32-BIT) --- */\\n\"\n  \"\\n\"\n  \".text\\n\"\n  \".att_syntax\\n\"\n  \".code32\\n\"\n  \".align 8\\n\"\n  \"\\n\"\n\n  \"__afl_maybe_log:\\n\"\n  \"\\n\"\n  \"  lahf\\n\"\n  \"  seto %al\\n\"\n  \"\\n\"\n  \"  /* Check if SHM region is already mapped. */\\n\"\n  \"\\n\"\n  \"  movl  __afl_area_ptr, %edx\\n\"\n  \"  testl %edx, %edx\\n\"\n  \"  je    __afl_setup\\n\"\n  \"\\n\"\n  \"__afl_store:\\n\"\n  \"\\n\"\n  \"  /* Calculate and store hit for the code location specified in ecx. There\\n\"\n  \"     is a double-XOR way of doing this without tainting another register,\\n\"\n  \"     and we use it on 64-bit systems; but it's slower for 32-bit ones. */\\n\"\n  \"\\n\"\n#ifndef COVERAGE_ONLY\n  \"  movl __afl_prev_loc, %edi\\n\"\n  \"  xorl %ecx, %edi\\n\"\n  \"  shrl $1, %ecx\\n\"\n  \"  movl %ecx, __afl_prev_loc\\n\"\n#else\n  \"  movl %ecx, %edi\\n\"\n#endif /* ^!COVERAGE_ONLY */\n  \"\\n\"\n#ifdef SKIP_COUNTS\n  \"  orb  $1, (%edx, %edi, 1)\\n\"\n#else\n  \"  incb (%edx, %edi, 1)\\n\"\n#endif /* ^SKIP_COUNTS */\n  \"\\n\"\n  \"__afl_return:\\n\"\n  \"\\n\"\n  \"  addb $127, %al\\n\"\n  \"  sahf\\n\"\n  \"  ret\\n\"\n  \"\\n\"\n  \".align 8\\n\"\n  \"\\n\"\n  \"__afl_setup:\\n\"\n  \"\\n\"\n  \"  /* Do not retry setup if we had previous failures. */\\n\"\n  \"\\n\"\n  \"  cmpb $0, __afl_setup_failure\\n\"\n  \"  jne  __afl_return\\n\"\n  \"\\n\"\n  \"  /* Map SHM, jumping to __afl_setup_abort if something goes wrong.\\n\"\n  \"     We do not save FPU/MMX/SSE registers here, but hopefully, nobody\\n\"\n  \"     will notice this early in the game. */\\n\"\n  \"\\n\"\n  \"  pushl %eax\\n\"\n  \"  pushl %ecx\\n\"\n  \"\\n\"\n  \"  pushl $.AFL_SHM_ENV\\n\"\n  \"  call  getenv\\n\"\n  \"  addl  $4, %esp\\n\"\n  \"\\n\"\n  \"  testl %eax, %eax\\n\"\n  \"  je    __afl_setup_abort\\n\"\n  \"\\n\"\n  \"  pushl %eax\\n\"\n  \"  call  atoi\\n\"\n  \"  addl  $4, %esp\\n\"\n  \"\\n\"\n  \"  pushl $0          /* shmat flags    */\\n\"\n  \"  pushl $0          /* requested addr */\\n\"\n  \"  pushl %eax        /* SHM ID         */\\n\"\n  \"  call  shmat\\n\"\n  \"  addl  $12, %esp\\n\"\n  \"\\n\"\n  \"  cmpl $-1, %eax\\n\"\n  \"  je   __afl_setup_abort\\n\"\n  \"\\n\"\n  \"  /* Store the address of the SHM region. */\\n\"\n  \"\\n\"\n  \"  movl %eax, __afl_area_ptr\\n\"\n  \"  movl %eax, %edx\\n\"\n  \"\\n\"\n  \"  popl %ecx\\n\"\n  \"  popl %eax\\n\"\n  \"\\n\"\n  \"__afl_forkserver:\\n\"\n  \"\\n\"\n  \"  /* Enter the fork server mode to avoid the overhead of execve() calls. */\\n\"\n  \"\\n\"\n  \"  pushl %eax\\n\"\n  \"  pushl %ecx\\n\"\n  \"  pushl %edx\\n\"\n  \"\\n\"\n  \"  /* Phone home and tell the parent that we're OK. (Note that signals with\\n\"\n  \"     no SA_RESTART will mess it up). If this fails, assume that the fd is\\n\"\n  \"     closed because we were execve()d from an instrumented binary, or because\\n\" \n  \"     the parent doesn't want to use the fork server. */\\n\"\n  \"\\n\"\n  \"  pushl $4          /* length    */\\n\"\n  \"  pushl $__afl_temp /* data      */\\n\"\n  \"  pushl $\" STRINGIFY(FORKSRV_TO_FUZZER) \"  /* file desc */\\n\"\n  \"  call  write\\n\"\n  \"  addl  $12, %esp\\n\"\n  \"\\n\"\n  \"  cmpl  $4, %eax\\n\"\n  \"  jne   __afl_fork_resume\\n\"\n  \"\\n\"\n  \"__afl_fork_wait_loop:\\n\"\n  \"\\n\"\n  \"  /* Wait for parent FORK_RUN command by reading from the pipe. Abort if read fails. */\\n\"\n  \"\\n\"\n  \"  pushl $1          /* length    */\\n\"\n  \"  pushl $__afl_temp /* data      */\\n\"\n  \"  pushl $\" STRINGIFY(FUZZER_TO_FORKSRV) \"  /* file desc */\\n\"\n  \"  call  read\\n\"\n  \"  addl  $12, %esp\\n\"\n  \"\\n\"\n  \"  cmpl  $1, %eax\\n\"\n  \"  jne   __afl_die\\n\"\n  \"  movb  __afl_temp, %al\\n\"\n  \"  cmpb  $\" STRINGIFY(FORK_RUN) \", %al\\n\"\n  \"  jne   __afl_die\\n\"\n  \"\\n\"\n  \"  /* Once woken up, create a clone of our process. This is an excellent use\\n\"\n  \"     case for syscall(__NR_clone, 0, CLONE_PARENT), but glibc boneheadedly\\n\"\n  \"     caches getpid() results and offers no way to update the value, breaking\\n\"\n  \"     abort(), raise(), and a bunch of other things :-( */\\n\"\n  \"\\n\"\n  \"  call fork\\n\"\n  \"\\n\"\n  \"  cmpl $0, %eax\\n\"\n  \"  jl   __afl_die\\n\"\n  \"  je   __afl_fork_resume\\n\"\n  \"\\n\"\n  \"  /* In parent process: write PID to pipe, then wait for child. */\\n\"\n  \"\\n\"\n  \"  movl  %eax, __afl_fork_pid\\n\"\n  \"\\n\"\n  \"  pushl $4              /* length    */\\n\"\n  \"  pushl $__afl_fork_pid /* data      */\\n\"\n  \"  pushl $\" STRINGIFY(FORKSRV_TO_FUZZER) \"      /* file desc */\\n\"\n  \"  call  write\\n\"\n  \"  addl  $12, %esp\\n\"\n  \"\\n\"\n  \"  /* Wait for the GET_STATUS command by reading from the pipe. Abort if read fails. */\\n\"\n  \"\\n\"\n  \"  pushl $1          /* length    */\\n\"\n  \"  pushl $__afl_temp /* data      */\\n\"\n  \"  pushl $\" STRINGIFY(FUZZER_TO_FORKSRV) \"  /* file desc */\\n\"\n  \"  call  read\\n\"\n  \"  addl  $12, %esp\\n\"\n  \"\\n\"\n  \"  cmpl  $1, %eax\\n\"\n  \"  jne   __afl_die\\n\"\n  \"  movb  __afl_temp, %al\\n\"\n  \"  cmpb  $\" STRINGIFY(GET_STATUS) \", %al\\n\"\n  \"  jne   __afl_die\\n\"\n  \"\\n\"\n  \"  pushl $0             /* no flags  */\\n\"\n  \"  pushl $__afl_temp    /* status    */\\n\"\n  \"  pushl __afl_fork_pid /* PID       */\\n\"\n  \"  call  waitpid\\n\"\n  \"  addl  $12, %esp\\n\"\n  \"\\n\"\n  \"  cmpl  $0, %eax\\n\"\n  \"  jle   __afl_die\\n\"\n  \"\\n\"\n  \"  /* Relay wait status to pipe, then loop back. */\\n\"\n  \"\\n\"\n  \"  pushl $4          /* length    */\\n\"\n  \"  pushl $__afl_temp /* data      */\\n\"\n  \"  pushl $\" STRINGIFY(FORKSRV_TO_FUZZER) \"  /* file desc */\\n\"\n  \"  call  write\\n\"\n  \"  addl  $12, %esp\\n\"\n  \"\\n\"\n  \"  jmp __afl_fork_wait_loop\\n\"\n  \"\\n\"\n  \"__afl_fork_resume:\\n\"\n  \"\\n\"\n  \"  /* In child process: close fds, resume execution. */\\n\"\n  \"\\n\"\n  \"  pushl $\" STRINGIFY(FUZZER_TO_FORKSRV) \"\\n\"\n  \"  call  close\\n\"\n  \"\\n\"\n  \"  pushl $\" STRINGIFY(FORKSRV_TO_FUZZER) \"\\n\"\n  \"  call  close\\n\"\n  \"\\n\"\n  \"  addl  $8, %esp\\n\"\n  \"\\n\"\n  \"  popl %edx\\n\"\n  \"  popl %ecx\\n\"\n  \"  popl %eax\\n\"\n  \"  jmp  __afl_store\\n\"\n  \"\\n\"\n  \"__afl_die:\\n\"\n  \"\\n\"\n  \"  xorl %eax, %eax\\n\"\n  \"  call _exit\\n\"\n  \"\\n\"\n  \"__afl_setup_abort:\\n\"\n  \"\\n\"\n  \"  /* Record setup failure so that we don't keep calling\\n\"\n  \"     shmget() / shmat() over and over again. */\\n\"\n  \"\\n\"\n  \"  incb __afl_setup_failure\\n\"\n  \"  popl %ecx\\n\"\n  \"  popl %eax\\n\"\n  \"  jmp __afl_return\\n\"\n  \"\\n\"\n  \".AFL_VARS:\\n\"\n  \"\\n\"\n  \"  .comm   __afl_area_ptr, 4, 32\\n\"\n  \"  .comm   __afl_setup_failure, 1, 32\\n\"\n#ifndef COVERAGE_ONLY\n  \"  .comm   __afl_prev_loc, 4, 32\\n\"\n#endif /* !COVERAGE_ONLY */\n  \"  .comm   __afl_fork_pid, 4, 32\\n\"\n  \"  .comm   __afl_temp, 4, 32\\n\"\n  \"\\n\"\n  \".AFL_SHM_ENV:\\n\"\n  \"  .asciz \\\"\" SHM_ENV_VAR \"\\\"\\n\"\n  \"\\n\"\n  \"/* --- END --- */\\n\"\n  \"\\n\";\n\n/* The OpenBSD hack is due to lahf and sahf not being recognized by some\n   versions of binutils: http://marc.info/?l=openbsd-cvs&m=141636589924400\n\n   The Apple code is a bit different when calling libc functions because\n   they are doing relocations differently from everybody else. We also need\n   to work around the crash issue with .lcomm and the fact that they don't\n   recognize .string. */\n\n#ifdef __APPLE__\n#  define CALL_L64(str)\t\t\"call _\" str \"\\n\"\n#else\n#  define CALL_L64(str)\t\t\"call \" str \"@PLT\\n\"\n#endif /* ^__APPLE__ */\n\nstatic const u8* main_payload_64 = \n\n  \"\\n\"\n  \"/* --- AFL MAIN PAYLOAD (64-BIT) --- */\\n\"\n  \"\\n\"\n  \".text\\n\"\n  \".att_syntax\\n\"\n  \".code64\\n\"\n  \".align 8\\n\"\n  \"\\n\"\n  \"__afl_maybe_log:\\n\"\n  \"\\n\"\n#if defined(__OpenBSD__)  || (defined(__FreeBSD__) && (__FreeBSD__ < 9))\n  \"  .byte 0x9f /* lahf */\\n\"\n#else\n  \"  lahf\\n\"\n#endif /* ^__OpenBSD__, etc */\n  \"  seto  %al\\n\"\n  \"\\n\"\n  \"  /* Check if SHM region is already mapped. */\\n\"\n  \"\\n\"\n  \"  movq  __afl_area_ptr(%rip), %rdx\\n\"\n  \"  testq %rdx, %rdx\\n\"\n  \"  je    __afl_setup\\n\"\n  \"\\n\"\n  \"__afl_store:\\n\"\n  \"\\n\"\n  \"  /* Calculate and store hit for the code location specified in rcx. */\\n\"\n  \"\\n\"\n#ifndef COVERAGE_ONLY\n  \"  xorq __afl_prev_loc(%rip), %rcx\\n\"\n  \"  xorq %rcx, __afl_prev_loc(%rip)\\n\"\n  \"  shrq $1, __afl_prev_loc(%rip)\\n\"\n#endif /* ^!COVERAGE_ONLY */\n  \"\\n\"\n#ifdef SKIP_COUNTS\n  \"  orb  $1, (%rdx, %rcx, 1)\\n\"\n#else\n  \"  incb (%rdx, %rcx, 1)\\n\"\n#endif /* ^SKIP_COUNTS */\n  \"\\n\"\n  \"__afl_return:\\n\"\n  \"\\n\"\n  \"  addb $127, %al\\n\"\n#if defined(__OpenBSD__)  || (defined(__FreeBSD__) && (__FreeBSD__ < 9))\n  \"  .byte 0x9e /* sahf */\\n\"\n#else\n  \"  sahf\\n\"\n#endif /* ^__OpenBSD__, etc */\n  \"  ret\\n\"\n  \"\\n\"\n  \".align 8\\n\"\n  \"\\n\"\n  \"__afl_setup:\\n\"\n  \"\\n\"\n  \"  /* Do not retry setup if we had previous failures. */\\n\"\n  \"\\n\"\n  \"  cmpb $0, __afl_setup_failure(%rip)\\n\"\n  \"  jne __afl_return\\n\"\n  \"\\n\"\n  \"  /* Check out if we have a global pointer on file. */\\n\"\n  \"\\n\"\n#ifndef __APPLE__\n  \"  movq  __afl_global_area_ptr@GOTPCREL(%rip), %rdx\\n\"\n  \"  movq  (%rdx), %rdx\\n\"\n#else\n  \"  movq  __afl_global_area_ptr(%rip), %rdx\\n\"\n#endif /* !^__APPLE__ */\n  \"  testq %rdx, %rdx\\n\"\n  \"  je    __afl_setup_first\\n\"\n  \"\\n\"\n  \"  movq %rdx, __afl_area_ptr(%rip)\\n\"\n  \"  jmp  __afl_store\\n\" \n  \"\\n\"\n  \"__afl_setup_first:\\n\"\n  \"\\n\"\n  \"  /* Save everything that is not yet saved and that may be touched by\\n\"\n  \"     getenv() and several other libcalls we'll be relying on. */\\n\"\n  \"\\n\"\n  \"  leaq -352(%rsp), %rsp\\n\"\n  \"\\n\"\n  \"  movq %rax,   0(%rsp)\\n\"\n  \"  movq %rcx,   8(%rsp)\\n\"\n  \"  movq %rdi,  16(%rsp)\\n\"\n  \"  movq %rsi,  32(%rsp)\\n\"\n  \"  movq %r8,   40(%rsp)\\n\"\n  \"  movq %r9,   48(%rsp)\\n\"\n  \"  movq %r10,  56(%rsp)\\n\"\n  \"  movq %r11,  64(%rsp)\\n\"\n  \"\\n\"\n  \"  movq %xmm0,  96(%rsp)\\n\"\n  \"  movq %xmm1,  112(%rsp)\\n\"\n  \"  movq %xmm2,  128(%rsp)\\n\"\n  \"  movq %xmm3,  144(%rsp)\\n\"\n  \"  movq %xmm4,  160(%rsp)\\n\"\n  \"  movq %xmm5,  176(%rsp)\\n\"\n  \"  movq %xmm6,  192(%rsp)\\n\"\n  \"  movq %xmm7,  208(%rsp)\\n\"\n  \"  movq %xmm8,  224(%rsp)\\n\"\n  \"  movq %xmm9,  240(%rsp)\\n\"\n  \"  movq %xmm10, 256(%rsp)\\n\"\n  \"  movq %xmm11, 272(%rsp)\\n\"\n  \"  movq %xmm12, 288(%rsp)\\n\"\n  \"  movq %xmm13, 304(%rsp)\\n\"\n  \"  movq %xmm14, 320(%rsp)\\n\"\n  \"  movq %xmm15, 336(%rsp)\\n\"\n  \"\\n\"\n  \"  /* Map SHM, jumping to __afl_setup_abort if something goes wrong. */\\n\"\n  \"\\n\"\n  \"  /* The 64-bit ABI requires 16-byte stack alignment. We'll keep the\\n\"\n  \"     original stack ptr in the callee-saved r12. */\\n\"\n  \"\\n\"\n  \"  pushq %r12\\n\"\n  \"  movq  %rsp, %r12\\n\"\n  \"  subq  $16, %rsp\\n\"\n  \"  andq  $0xfffffffffffffff0, %rsp\\n\"\n  \"\\n\"\n  \"  leaq .AFL_SHM_ENV(%rip), %rdi\\n\"\n  CALL_L64(\"getenv\")\n  \"\\n\"\n  \"  testq %rax, %rax\\n\"\n  \"  je    __afl_setup_abort\\n\"\n  \"\\n\"\n  \"  movq  %rax, %rdi\\n\"\n  CALL_L64(\"atoi\")\n  \"\\n\"\n  \"  xorq %rdx, %rdx   /* shmat flags    */\\n\"\n  \"  xorq %rsi, %rsi   /* requested addr */\\n\"\n  \"  movq %rax, %rdi   /* SHM ID         */\\n\"\n  CALL_L64(\"shmat\")\n  \"\\n\"\n  \"  cmpq $-1, %rax\\n\"\n  \"  je   __afl_setup_abort\\n\"\n  \"\\n\"\n  \"  /* Store the address of the SHM region. */\\n\"\n  \"\\n\"\n  \"  movq %rax, %rdx\\n\"\n  \"  movq %rax, __afl_area_ptr(%rip)\\n\"\n  \"\\n\"\n#ifdef __APPLE__\n  \"  movq %rax, __afl_global_area_ptr(%rip)\\n\"\n#else\n  \"  movq __afl_global_area_ptr@GOTPCREL(%rip), %rdx\\n\"\n  \"  movq %rax, (%rdx)\\n\"\n#endif /* ^__APPLE__ */\n  \"  movq %rax, %rdx\\n\"\n  \"\\n\"\n  \"__afl_forkserver:\\n\"\n  \"\\n\"\n  \"  /* Enter the fork server mode to avoid the overhead of execve() calls. We\\n\"\n  \"     push rdx (area ptr) twice to keep stack alignment neat. */\\n\"\n  \"\\n\"\n  \"  pushq %rdx\\n\"\n  \"  pushq %rdx\\n\"\n  \"\\n\"\n  \"  /* Phone home and tell the parent that we're OK. (Note that signals with\\n\"\n  \"     no SA_RESTART will mess it up). If this fails, assume that the fd is\\n\"\n  \"     closed because we were execve()d from an instrumented binary, or because\\n\"\n  \"     the parent doesn't want to use the fork server. */\\n\"\n  \"\\n\"\n  \"  movq $4, %rdx               /* length    */\\n\"\n  \"  leaq __afl_temp(%rip), %rsi /* data      */\\n\"\n  \"  movq $\" STRINGIFY(FORKSRV_TO_FUZZER) \", %rdi       /* file desc */\\n\"\n  CALL_L64(\"write\")\n  \"\\n\"\n  \"  cmpq $4, %rax\\n\"\n  \"  jne  __afl_fork_resume\\n\"\n  \"\\n\"\n  \"__afl_fork_wait_loop:\\n\"\n  \"\\n\"\n  \"  /* Wait for parent FORK_RUN command by reading from the pipe. Abort if read fails. */\\n\"\n  \"\\n\"\n  \"  movq $1, %rdx               /* length    */\\n\"\n  \"  leaq __afl_temp(%rip), %rsi /* data      */\\n\"\n  \"  movq $\" STRINGIFY(FUZZER_TO_FORKSRV) \", %rdi             /* file desc */\\n\"\n  CALL_L64(\"read\")\n  \"  cmpq $1, %rax\\n\"\n  \"  jne  __afl_die\\n\"\n  \"  movb __afl_temp(%rip), %al\\n\"\n  \"  cmpb $\" STRINGIFY(FORK_RUN) \", %al\\n\"\n  \"  jne  __afl_die\\n\"\n  \"\\n\"\n  \"  /* Once woken up, create a clone of our process. This is an excellent use\\n\"\n  \"     case for syscall(__NR_clone, 0, CLONE_PARENT), but glibc boneheadedly\\n\"\n  \"     caches getpid() results and offers no way to update the value, breaking\\n\"\n  \"     abort(), raise(), and a bunch of other things :-( */\\n\"\n  \"\\n\"\n  CALL_L64(\"fork\")\n  \"  cmpq $0, %rax\\n\"\n  \"  jl   __afl_die\\n\"\n  \"  je   __afl_fork_resume\\n\"\n  \"\\n\"\n  \"  /* In parent process: write PID to pipe, then wait for child. */\\n\"\n  \"\\n\"\n  \"  movl %eax, __afl_fork_pid(%rip)\\n\"\n  \"\\n\"\n  \"  movq $4, %rdx                   /* length    */\\n\"\n  \"  leaq __afl_fork_pid(%rip), %rsi /* data      */\\n\"\n  \"  movq $\" STRINGIFY(FORKSRV_TO_FUZZER) \", %rdi             /* file desc */\\n\"\n  CALL_L64(\"write\")\n  \"\\n\"\n  \"  /* Wait for the GET_STATUS command by reading from the pipe. Abort if read fails. */\\n\"\n  \"\\n\"\n  \"  movq $1, %rdx               /* length    */\\n\"\n  \"  leaq __afl_temp(%rip), %rsi /* data      */\\n\"\n  \"  movq $\" STRINGIFY(FUZZER_TO_FORKSRV) \", %rdi             /* file desc */\\n\"\n  CALL_L64(\"read\")\n  \"  cmpq $1, %rax\\n\"\n  \"  jne  __afl_die\\n\"\n  \"  movb __afl_temp(%rip), %al\\n\"\n  \"  cmpb $\" STRINGIFY(GET_STATUS) \", %al\\n\"\n  \"  jne  __afl_die\\n\"\n  \"\\n\"\n  \"  movq $0, %rdx                   /* no flags  */\\n\"\n  \"  leaq __afl_temp(%rip), %rsi     /* status    */\\n\"\n  \"  movq __afl_fork_pid(%rip), %rdi /* PID       */\\n\"\n  CALL_L64(\"waitpid\")\n  \"  cmpq $0, %rax\\n\"\n  \"  jle  __afl_die\\n\"\n  \"\\n\"\n  \"  /* Relay wait status to pipe, then loop back. */\\n\"\n  \"\\n\"\n  \"  movq $4, %rdx               /* length    */\\n\"\n  \"  leaq __afl_temp(%rip), %rsi /* data      */\\n\"\n  \"  movq $\" STRINGIFY(FORKSRV_TO_FUZZER) \", %rdi         /* file desc */\\n\"\n  CALL_L64(\"write\")\n  \"\\n\"\n  \"  jmp  __afl_fork_wait_loop\\n\"\n  \"\\n\"\n  \"__afl_fork_resume:\\n\"\n  \"\\n\"\n  \"  /* In child process: close fds, resume execution. */\\n\"\n  \"\\n\"\n  \"  movq $\" STRINGIFY(FUZZER_TO_FORKSRV) \", %rdi\\n\"\n  CALL_L64(\"close\")\n  \"\\n\"\n  \"  movq $\" STRINGIFY(FORKSRV_TO_FUZZER) \", %rdi\\n\"\n  CALL_L64(\"close\")\n  \"\\n\"\n  \"  popq %rdx\\n\"\n  \"  popq %rdx\\n\"\n  \"\\n\"\n  \"  movq %r12, %rsp\\n\"\n  \"  popq %r12\\n\"\n  \"\\n\"\n  \"  movq  0(%rsp), %rax\\n\"\n  \"  movq  8(%rsp), %rcx\\n\"\n  \"  movq 16(%rsp), %rdi\\n\"\n  \"  movq 32(%rsp), %rsi\\n\"\n  \"  movq 40(%rsp), %r8\\n\"\n  \"  movq 48(%rsp), %r9\\n\"\n  \"  movq 56(%rsp), %r10\\n\"\n  \"  movq 64(%rsp), %r11\\n\"\n  \"\\n\"\n  \"  movq  96(%rsp), %xmm0\\n\"\n  \"  movq 112(%rsp), %xmm1\\n\"\n  \"  movq 128(%rsp), %xmm2\\n\"\n  \"  movq 144(%rsp), %xmm3\\n\"\n  \"  movq 160(%rsp), %xmm4\\n\"\n  \"  movq 176(%rsp), %xmm5\\n\"\n  \"  movq 192(%rsp), %xmm6\\n\"\n  \"  movq 208(%rsp), %xmm7\\n\"\n  \"  movq 224(%rsp), %xmm8\\n\"\n  \"  movq 240(%rsp), %xmm9\\n\"\n  \"  movq 256(%rsp), %xmm10\\n\"\n  \"  movq 272(%rsp), %xmm11\\n\"\n  \"  movq 288(%rsp), %xmm12\\n\"\n  \"  movq 304(%rsp), %xmm13\\n\"\n  \"  movq 320(%rsp), %xmm14\\n\"\n  \"  movq 336(%rsp), %xmm15\\n\"\n  \"\\n\"\n  \"  leaq 352(%rsp), %rsp\\n\"\n  \"\\n\"\n  \"  jmp  __afl_store\\n\"\n  \"\\n\"\n  \"__afl_die:\\n\"\n  \"\\n\"\n  \"  xorq %rax, %rax\\n\"\n  CALL_L64(\"_exit\")\n  \"\\n\"\n  \"__afl_setup_abort:\\n\"\n  \"\\n\"\n  \"  /* Record setup failure so that we don't keep calling\\n\"\n  \"     shmget() / shmat() over and over again. */\\n\"\n  \"\\n\"\n  \"  incb __afl_setup_failure(%rip)\\n\"\n  \"\\n\"\n  \"  movq %r12, %rsp\\n\"\n  \"  popq %r12\\n\"\n  \"\\n\"\n  \"  movq  0(%rsp), %rax\\n\"\n  \"  movq  8(%rsp), %rcx\\n\"\n  \"  movq 16(%rsp), %rdi\\n\"\n  \"  movq 32(%rsp), %rsi\\n\"\n  \"  movq 40(%rsp), %r8\\n\"\n  \"  movq 48(%rsp), %r9\\n\"\n  \"  movq 56(%rsp), %r10\\n\"\n  \"  movq 64(%rsp), %r11\\n\"\n  \"\\n\"\n  \"  movq  96(%rsp), %xmm0\\n\"\n  \"  movq 112(%rsp), %xmm1\\n\"\n  \"  movq 128(%rsp), %xmm2\\n\"\n  \"  movq 144(%rsp), %xmm3\\n\"\n  \"  movq 160(%rsp), %xmm4\\n\"\n  \"  movq 176(%rsp), %xmm5\\n\"\n  \"  movq 192(%rsp), %xmm6\\n\"\n  \"  movq 208(%rsp), %xmm7\\n\"\n  \"  movq 224(%rsp), %xmm8\\n\"\n  \"  movq 240(%rsp), %xmm9\\n\"\n  \"  movq 256(%rsp), %xmm10\\n\"\n  \"  movq 272(%rsp), %xmm11\\n\"\n  \"  movq 288(%rsp), %xmm12\\n\"\n  \"  movq 304(%rsp), %xmm13\\n\"\n  \"  movq 320(%rsp), %xmm14\\n\"\n  \"  movq 336(%rsp), %xmm15\\n\"\n  \"\\n\"\n  \"  leaq 352(%rsp), %rsp\\n\"\n  \"\\n\"\n  \"  jmp __afl_return\\n\"\n  \"\\n\"\n  \".AFL_VARS:\\n\"\n  \"\\n\"\n\n#ifdef __APPLE__\n\n  \"  .comm   __afl_area_ptr, 8\\n\"\n#ifndef COVERAGE_ONLY\n  \"  .comm   __afl_prev_loc, 8\\n\"\n#endif /* !COVERAGE_ONLY */\n  \"  .comm   __afl_fork_pid, 4\\n\"\n  \"  .comm   __afl_temp, 4\\n\"\n  \"  .comm   __afl_setup_failure, 1\\n\"\n\n#else\n\n  \"  .lcomm   __afl_area_ptr, 8\\n\"\n#ifndef COVERAGE_ONLY\n  \"  .lcomm   __afl_prev_loc, 8\\n\"\n#endif /* !COVERAGE_ONLY */\n  \"  .lcomm   __afl_fork_pid, 4\\n\"\n  \"  .lcomm   __afl_temp, 4\\n\"\n  \"  .lcomm   __afl_setup_failure, 1\\n\"\n\n#endif /* ^__APPLE__ */\n\n  \"  .comm    __afl_global_area_ptr, 8, 8\\n\"\n  \"\\n\"\n  \".AFL_SHM_ENV:\\n\"\n  \"  .asciz \\\"\" SHM_ENV_VAR \"\\\"\\n\"\n  \"\\n\"\n  \"/* --- END --- */\\n\"\n  \"\\n\";\n\n#endif /* !_HAVE_AFL_AS_H */\n"
  },
  {
    "path": "afl_progs/afl-gcc.c",
    "content": "/*\n   american fuzzy lop - wrapper for GCC and clang\n   ----------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This program is a drop-in replacement for GCC or clang. The most common way\n   of using it is to pass the path to afl-gcc or afl-clang via CC when invoking\n   ./configure.\n\n   (Of course, use CXX and point it to afl-g++ / afl-clang++ for C++ code.)\n\n   The wrapper needs to know the path to afl-as (renamed to 'as'). The default\n   is /usr/local/lib/afl/. A convenient way to specify alternative directories\n   would be to set AFL_PATH.\n\n   If AFL_HARDEN is set, the wrapper will compile the target app with various\n   hardening options that may help detect memory management issues more\n   reliably. You can also specify AFL_USE_ASAN to enable ASAN.\n\n   If you want to call a non-default compiler as a next step of the chain,\n   specify its location via AFL_CC or AFL_CXX.\n\n */\n\n#define AFL_MAIN\n\n#include \"config.h\"\n#include \"types.h\"\n#include \"debug.h\"\n#include \"alloc-inl.h\"\n\n#include <stdio.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <string.h>\n\nstatic u8*  as_path;                /* Path to the AFL 'as' wrapper      */\nstatic u8** cc_params;              /* Parameters passed to the real CC  */\nstatic u32  cc_par_cnt = 1;         /* Param count, including argv0      */\nstatic u8   be_quiet,               /* Quiet mode                        */\n            clang_mode;             /* Invoked as afl-clang*?            */\n\n\n/* Try to find our \"fake\" GNU assembler in AFL_PATH or at the location derived\n   from argv[0]. If that fails, abort. */\n\nstatic void find_as(u8* argv0) {\n\n  u8 *afl_path = getenv(\"AFL_PATH\");\n  u8 *slash, *tmp;\n\n  if (afl_path) {\n\n    tmp = alloc_printf(\"%s/as\", afl_path);\n\n    if (!access(tmp, X_OK)) {\n      as_path = afl_path;\n      ck_free(tmp);\n      return;\n    }\n\n    ck_free(tmp);\n\n  }\n\n  slash = strrchr(argv0, '/');\n\n  if (slash) {\n\n    u8 *dir;\n\n    *slash = 0;\n    dir = ck_strdup(argv0);\n    *slash = '/';\n\n    tmp = alloc_printf(\"%s/afl-as\", dir);\n\n    if (!access(tmp, X_OK)) {\n      as_path = dir;\n      ck_free(tmp);\n      return;\n    }\n\n    ck_free(tmp);\n    ck_free(dir);\n\n  }\n\n  if (!access(AFL_PATH \"/as\", X_OK)) {\n    as_path = AFL_PATH;\n    return;\n  }\n\n  FATAL(\"Unable to find AFL wrapper binary for 'as'. Please set AFL_PATH\");\n \n}\n\n\n/* Copy argv to cc_params, making the necessary edits. */\n\nstatic void edit_params(u32 argc, char** argv) {\n\n  u8 fortify_set = 0, asan_set = 0;\n  u8 *name;\n\n#if defined(__FreeBSD__) && defined(__x86_64__)\n  u8 m32_set = 0;\n#endif\n\n  cc_params = ck_alloc((argc + 128) * sizeof(u8*));\n\n  name = strrchr(argv[0], '/');\n  if (!name) name = argv[0]; else name++;\n\n  if (!strncmp(name, \"afl-clang\", 9)) {\n\n    clang_mode = 1;\n\n    setenv(CLANG_ENV_VAR, \"1\", 1);\n\n    if (!strcmp(name, \"afl-clang++\")) {\n      u8* alt_cxx = getenv(\"AFL_CXX\");\n      cc_params[0] = alt_cxx ? alt_cxx : (u8*)\"clang++\";\n    } else {\n      u8* alt_cc = getenv(\"AFL_CC\");\n      cc_params[0] = alt_cc ? alt_cc : (u8*)\"clang\";\n    }\n\n  } else {\n\n    /* With GCJ and Eclipse installed, you can actually compile Java! The\n       instrumentation will work (amazingly). Alas, unhandled exceptions do\n       not call abort(), so afl-fuzz would need to be modified to equate\n       non-zero exit codes with crash conditions when working with Java\n       binaries. Meh. */\n\n#ifdef __APPLE__\n\n    if (!strcmp(name, \"afl-g++\")) cc_params[0] = getenv(\"AFL_CXX\");\n    else if (!strcmp(name, \"afl-gcj\")) cc_params[0] = getenv(\"AFL_GCJ\");\n    else cc_params[0] = getenv(\"AFL_CC\");\n\n    if (!cc_params[0]) {\n\n      SAYF(\"\\n\" cLRD \"[-] \" cRST\n           \"On Apple systems, 'gcc' is usually just a wrapper for clang. Please use the\\n\"\n           \"    'afl-clang' utility instead of 'afl-gcc'. If you really have GCC installed,\\n\"\n           \"    set AFL_CC or AFL_CXX to specify the correct path to that compiler.\\n\");\n\n      FATAL(\"AFL_CC or AFL_CXX required on MacOS X\");\n\n    }\n\n#else\n\n    if (!strcmp(name, \"afl-g++\")) {\n      u8* alt_cxx = getenv(\"AFL_CXX\");\n      cc_params[0] = alt_cxx ? alt_cxx : (u8*)\"g++\";\n    } else if (!strcmp(name, \"afl-gcj\")) {\n      u8* alt_cc = getenv(\"AFL_GCJ\");\n      cc_params[0] = alt_cc ? alt_cc : (u8*)\"gcj\";\n    } else {\n      u8* alt_cc = getenv(\"AFL_CC\");\n      cc_params[0] = alt_cc ? alt_cc : (u8*)\"gcc\";\n    }\n\n#endif /* __APPLE__ */\n\n  }\n\n  while (--argc) {\n    u8* cur = *(++argv);\n\n    if (!strncmp(cur, \"-B\", 2)) {\n\n      if (!be_quiet) WARNF(\"-B is already set, overriding\");\n\n      if (!cur[2] && argc > 1) { argc--; argv++; }\n      continue;\n\n    }\n\n    if (!strcmp(cur, \"-integrated-as\")) continue;\n\n    if (!strcmp(cur, \"-pipe\")) continue;\n\n#if defined(__FreeBSD__) && defined(__x86_64__)\n    if (!strcmp(cur, \"-m32\")) m32_set = 1;\n#endif\n\n    if (!strcmp(cur, \"-fsanitize=address\") ||\n        !strcmp(cur, \"-fsanitize=memory\")) asan_set = 1;\n\n    if (strstr(cur, \"FORTIFY_SOURCE\")) fortify_set = 1;\n\n    cc_params[cc_par_cnt++] = cur;\n\n  }\n\n  cc_params[cc_par_cnt++] = \"-B\";\n  cc_params[cc_par_cnt++] = as_path;\n\n  if (clang_mode)\n    cc_params[cc_par_cnt++] = \"-no-integrated-as\";\n\n  if (getenv(\"AFL_HARDEN\")) {\n\n    cc_params[cc_par_cnt++] = \"-fstack-protector-all\";\n\n    if (!fortify_set)\n      cc_params[cc_par_cnt++] = \"-D_FORTIFY_SOURCE=2\";\n\n  }\n\n  if (asan_set) {\n\n    /* Pass this on to afl-as to adjust map density. */\n\n    setenv(\"AFL_USE_ASAN\", \"1\", 1);\n\n  } else if (getenv(\"AFL_USE_ASAN\")) {\n\n    if (getenv(\"AFL_USE_MSAN\"))\n      FATAL(\"ASAN and MSAN are mutually exclusive\");\n\n    if (getenv(\"AFL_HARDEN\"))\n      FATAL(\"ASAN and AFL_HARDEN are mutually exclusive\");\n\n    cc_params[cc_par_cnt++] = \"-U_FORTIFY_SOURCE\";\n    cc_params[cc_par_cnt++] = \"-fsanitize=address\";\n\n  } else if (getenv(\"AFL_USE_MSAN\")) {\n\n    if (getenv(\"AFL_USE_ASAN\"))\n      FATAL(\"ASAN and MSAN are mutually exclusive\");\n\n    if (getenv(\"AFL_HARDEN\"))\n      FATAL(\"MSAN and AFL_HARDEN are mutually exclusive\");\n\n    cc_params[cc_par_cnt++] = \"-U_FORTIFY_SOURCE\";\n    cc_params[cc_par_cnt++] = \"-fsanitize=memory\";\n\n\n  }\n\n  if (!getenv(\"AFL_DONT_OPTIMIZE\")) {\n\n#if defined(__FreeBSD__) && defined(__x86_64__)\n\n    /* On 64-bit FreeBSD systems, clang -g -m32 is broken, but -m32 itself\n       works OK. This has nothing to do with us, but let's avoid triggering\n       that bug. */\n\n    if (!clang_mode || !m32_set)\n      cc_params[cc_par_cnt++] = \"-g\";\n\n#else\n\n      cc_params[cc_par_cnt++] = \"-g\";\n\n#endif\n\n    cc_params[cc_par_cnt++] = \"-O3\";\n    cc_params[cc_par_cnt++] = \"-funroll-loops\";\n\n    /* Two indicators that you're building for fuzzing; one of them is\n       AFL-specific, the other is shared with libfuzzer. */\n\n    cc_params[cc_par_cnt++] = \"-D__AFL_COMPILER=1\";\n    cc_params[cc_par_cnt++] = \"-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1\";\n\n  }\n\n  if (getenv(\"AFL_NO_BUILTIN\")) {\n\n    cc_params[cc_par_cnt++] = \"-fno-builtin-strcmp\";\n    cc_params[cc_par_cnt++] = \"-fno-builtin-strncmp\";\n    cc_params[cc_par_cnt++] = \"-fno-builtin-strcasecmp\";\n    cc_params[cc_par_cnt++] = \"-fno-builtin-strncasecmp\";\n    cc_params[cc_par_cnt++] = \"-fno-builtin-memcmp\";\n    cc_params[cc_par_cnt++] = \"-fno-builtin-strstr\";\n    cc_params[cc_par_cnt++] = \"-fno-builtin-strcasestr\";\n\n  }\n\n  cc_params[cc_par_cnt] = NULL;\n\n}\n\n\n/* Main entry point */\n\nint main(int argc, char** argv) {\n\n  if (isatty(2) && !getenv(\"AFL_QUIET\")) {\n\n    SAYF(cCYA \"afl-cc \" cBRI VERSION cRST \" by <lcamtuf@google.com>\\n\");\n\n  } else be_quiet = 1;\n\n  if (argc < 2) {\n\n    SAYF(\"\\n\"\n         \"This is a helper application for afl-fuzz. It serves as a drop-in replacement\\n\"\n         \"for gcc or clang, letting you recompile third-party code with the required\\n\"\n         \"runtime instrumentation. A common use pattern would be one of the following:\\n\\n\"\n\n         \"  CC=%s/afl-gcc ./configure\\n\"\n         \"  CXX=%s/afl-g++ ./configure\\n\\n\"\n\n         \"You can specify custom next-stage toolchain via AFL_CC, AFL_CXX, and AFL_AS.\\n\"\n         \"Setting AFL_HARDEN enables hardening optimizations in the compiled code.\\n\\n\",\n         BIN_PATH, BIN_PATH);\n\n    exit(1);\n\n  }\n\n  find_as(argv[0]);\n\n  edit_params(argc, argv);\n\n  execvp(cc_params[0], (char**)cc_params);\n\n  FATAL(\"Oops, failed to execute '%s' - check your PATH\", cc_params[0]);\n\n  return 0;\n\n}\n"
  },
  {
    "path": "afl_progs/afl-showmap.c",
    "content": "/*\n   american fuzzy lop - map display utility\n   ----------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   A very simple tool that runs the targeted binary and displays\n   the contents of the trace bitmap in a human-readable form. Useful in\n   scripts to eliminate redundant inputs and perform other checks.\n\n   Exit code is 2 if the target program crashes; 1 if it times out or\n   there is a problem executing it; or 0 if execution is successful.\n\n */\n\n#define AFL_MAIN\n\n#include \"config.h\"\n#include \"types.h\"\n#include \"debug.h\"\n#include \"alloc-inl.h\"\n#include \"hash.h\"\n\n#include <stdio.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <errno.h>\n#include <signal.h>\n#include <dirent.h>\n#include <fcntl.h>\n\n#include <sys/wait.h>\n#include <sys/time.h>\n#include <sys/shm.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <sys/resource.h>\n\nstatic s32 child_pid;                 /* PID of the tested program         */\n\nstatic u8* trace_bits;                /* SHM with instrumentation bitmap   */\n\nstatic u8 *out_file,                  /* Trace output file                 */\n          *doc_path,                  /* Path to docs                      */\n          *target_path,               /* Path to target binary             */\n          *at_file;                   /* Substitution string for @@        */\n\nstatic u32 exec_tmout;                /* Exec timeout (ms)                 */\n\nstatic u64 mem_limit = MEM_LIMIT;     /* Memory limit (MB)                 */\n\nstatic s32 shm_id;                    /* ID of the SHM region              */\n\nstatic u8  quiet_mode,                /* Hide non-essential messages?      */\n           edges_only,                /* Ignore hit counts?                */\n           cmin_mode,                 /* Generate output in afl-cmin mode? */\n           binary_mode,               /* Write output as a binary map      */\n           keep_cores;                /* Allow coredumps?                  */\n\nstatic volatile u8\n           stop_soon,                 /* Ctrl-C pressed?                   */\n           child_timed_out,           /* Child timed out?                  */\n           child_crashed;             /* Child crashed?                    */\n\n/* Classify tuple counts. Instead of mapping to individual bits, as in\n   afl-fuzz.c, we map to more user-friendly numbers between 1 and 8. */\n\nstatic const u8 count_class_human[256] = {\n\n  [0]           = 0,\n  [1]           = 1,\n  [2]           = 2,\n  [3]           = 3,\n  [4 ... 7]     = 4,\n  [8 ... 15]    = 5,\n  [16 ... 31]   = 6,\n  [32 ... 127]  = 7,\n  [128 ... 255] = 8\n\n};\n\nstatic const u8 count_class_binary[256] = {\n\n  [0]           = 0,\n  [1]           = 1,\n  [2]           = 2,\n  [3]           = 4,\n  [4 ... 7]     = 8,\n  [8 ... 15]    = 16,\n  [16 ... 31]   = 32,\n  [32 ... 127]  = 64,\n  [128 ... 255] = 128\n\n};\n\nstatic void classify_counts(u8* mem, const u8* map) {\n\n  u32 i = MAP_SIZE;\n\n  if (edges_only) {\n\n    while (i--) {\n      if (*mem) *mem = 1;\n      mem++;\n    }\n\n  } else {\n\n    while (i--) {\n      *mem = map[*mem];\n      mem++;\n    }\n\n  }\n\n}\n\n\n/* Get rid of shared memory (atexit handler). */\n\nstatic void remove_shm(void) {\n\n  shmctl(shm_id, IPC_RMID, NULL);\n\n}\n\n\n/* Configure shared memory. */\n\nstatic void setup_shm(void) {\n\n  u8* shm_str;\n\n  shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600);\n\n  if (shm_id < 0) PFATAL(\"shmget() failed\");\n\n  atexit(remove_shm);\n\n  shm_str = alloc_printf(\"%d\", shm_id);\n\n  setenv(SHM_ENV_VAR, shm_str, 1);\n\n  ck_free(shm_str);\n\n  trace_bits = shmat(shm_id, NULL, 0);\n  \n  if (!trace_bits) PFATAL(\"shmat() failed\");\n\n}\n\n/* Write results. */\n\nstatic u32 write_results(void) {\n\n  s32 fd;\n  u32 i, ret = 0;\n\n  u8  cco = !!getenv(\"AFL_CMIN_CRASHES_ONLY\"),\n      caa = !!getenv(\"AFL_CMIN_ALLOW_ANY\");\n\n  if (!strncmp(out_file, \"/dev/\", 5)) {\n\n    fd = open(out_file, O_WRONLY, 0600);\n    if (fd < 0) PFATAL(\"Unable to open '%s'\", out_file);\n\n  } else if (!strcmp(out_file, \"-\")) {\n\n    fd = dup(1);\n    if (fd < 0) PFATAL(\"Unable to open stdout\");\n\n  } else {\n\n    unlink(out_file); /* Ignore errors */\n    fd = open(out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);\n    if (fd < 0) PFATAL(\"Unable to create '%s'\", out_file);\n\n  }\n\n\n  if (binary_mode) {\n\n    for (i = 0; i < MAP_SIZE; i++)\n      if (trace_bits[i]) ret++;\n    \n    ck_write(fd, trace_bits, MAP_SIZE, out_file);\n    close(fd);\n\n  } else {\n\n    FILE* f = fdopen(fd, \"w\");\n\n    if (!f) PFATAL(\"fdopen() failed\");\n\n    for (i = 0; i < MAP_SIZE; i++) {\n\n      if (!trace_bits[i]) continue;\n      ret++;\n\n      if (cmin_mode) {\n\n        if (child_timed_out) break;\n        if (!caa && child_crashed != cco) break;\n\n        fprintf(f, \"%u%u\\n\", trace_bits[i], i);\n\n      } else fprintf(f, \"%06u:%u\\n\", i, trace_bits[i]);\n\n    }\n  \n    fclose(f);\n\n  }\n\n  return ret;\n\n}\n\n\n/* Handle timeout signal. */\n\nstatic void handle_timeout(int sig) {\n\n  child_timed_out = 1;\n  if (child_pid > 0) kill(child_pid, SIGKILL);\n\n}\n\n\n/* Execute target application. */\n\nstatic void run_target(char** argv) {\n\n  static struct itimerval it;\n  int status = 0;\n\n  if (!quiet_mode)\n    SAYF(\"-- Program output begins --\\n\" cRST);\n\n  MEM_BARRIER();\n\n  child_pid = fork();\n\n  if (child_pid < 0) PFATAL(\"fork() failed\");\n\n  if (!child_pid) {\n\n    struct rlimit r;\n\n    if (quiet_mode) {\n\n      s32 fd = open(\"/dev/null\", O_RDWR);\n\n      if (fd < 0 || dup2(fd, 1) < 0 || dup2(fd, 2) < 0) {\n        *(u32*)trace_bits = EXEC_FAIL_SIG;\n        PFATAL(\"Descriptor initialization failed\");\n      }\n\n      close(fd);\n\n    }\n\n    if (mem_limit) {\n\n      r.rlim_max = r.rlim_cur = ((rlim_t)mem_limit) << 20;\n\n#ifdef RLIMIT_AS\n\n      setrlimit(RLIMIT_AS, &r); /* Ignore errors */\n\n#else\n\n      setrlimit(RLIMIT_DATA, &r); /* Ignore errors */\n\n#endif /* ^RLIMIT_AS */\n\n    }\n\n    if (!keep_cores) r.rlim_max = r.rlim_cur = 0;\n    else r.rlim_max = r.rlim_cur = RLIM_INFINITY;\n\n    setrlimit(RLIMIT_CORE, &r); /* Ignore errors */\n\n    if (!getenv(\"LD_BIND_LAZY\")) setenv(\"LD_BIND_NOW\", \"1\", 0);\n\n    setsid();\n\n    execv(target_path, argv);\n\n    *(u32*)trace_bits = EXEC_FAIL_SIG;\n    exit(0);\n\n  }\n\n  /* Configure timeout, wait for child, cancel timeout. */\n\n  if (exec_tmout) {\n\n    child_timed_out = 0;\n    it.it_value.tv_sec = (exec_tmout / 1000);\n    it.it_value.tv_usec = (exec_tmout % 1000) * 1000;\n\n  }\n\n  setitimer(ITIMER_REAL, &it, NULL);\n\n  if (waitpid(child_pid, &status, 0) <= 0) FATAL(\"waitpid() failed\");\n\n  child_pid = 0;\n  it.it_value.tv_sec = 0;\n  it.it_value.tv_usec = 0;\n  setitimer(ITIMER_REAL, &it, NULL);\n\n  MEM_BARRIER();\n\n  /* Clean up bitmap, analyze exit condition, etc. */\n\n  if (*(u32*)trace_bits == EXEC_FAIL_SIG)\n    FATAL(\"Unable to execute '%s'\", argv[0]);\n\n  classify_counts(trace_bits, binary_mode ?\n                  count_class_binary : count_class_human);\n\n  if (!quiet_mode)\n    SAYF(cRST \"-- Program output ends --\\n\");\n\n  if (!child_timed_out && !stop_soon && WIFSIGNALED(status))\n    child_crashed = 1;\n\n  if (!quiet_mode) {\n\n    if (child_timed_out)\n      SAYF(cLRD \"\\n+++ Program timed off +++\\n\" cRST);\n    else if (stop_soon)\n      SAYF(cLRD \"\\n+++ Program aborted by user +++\\n\" cRST);\n    else if (child_crashed)\n      SAYF(cLRD \"\\n+++ Program killed by signal %u +++\\n\" cRST, WTERMSIG(status));\n\n  }\n\n\n}\n\n\n/* Handle Ctrl-C and the like. */\n\nstatic void handle_stop_sig(int sig) {\n\n  stop_soon = 1;\n\n  if (child_pid > 0) kill(child_pid, SIGKILL);\n\n}\n\n\n/* Do basic preparations - persistent fds, filenames, etc. */\n\nstatic void set_up_environment(void) {\n\n  setenv(\"ASAN_OPTIONS\", \"abort_on_error=1:\"\n                         \"detect_leaks=0:\"\n                         \"symbolize=0:\"\n                         \"allocator_may_return_null=1\", 0);\n\n  setenv(\"MSAN_OPTIONS\", \"exit_code=\" STRINGIFY(MSAN_ERROR) \":\"\n                         \"symbolize=0:\"\n                         \"abort_on_error=1:\"\n                         \"allocator_may_return_null=1:\"\n                         \"msan_track_origins=0\", 0);\n\n  if (getenv(\"AFL_PRELOAD\")) {\n    setenv(\"LD_PRELOAD\", getenv(\"AFL_PRELOAD\"), 1);\n    setenv(\"DYLD_INSERT_LIBRARIES\", getenv(\"AFL_PRELOAD\"), 1);\n  }\n\n}\n\n\n/* Setup signal handlers, duh. */\n\nstatic void setup_signal_handlers(void) {\n\n  struct sigaction sa;\n\n  sa.sa_handler   = NULL;\n  sa.sa_flags     = SA_RESTART;\n  sa.sa_sigaction = NULL;\n\n  sigemptyset(&sa.sa_mask);\n\n  /* Various ways of saying \"stop\". */\n\n  sa.sa_handler = handle_stop_sig;\n  sigaction(SIGHUP, &sa, NULL);\n  sigaction(SIGINT, &sa, NULL);\n  sigaction(SIGTERM, &sa, NULL);\n\n  /* Exec timeout notifications. */\n\n  sa.sa_handler = handle_timeout;\n  sigaction(SIGALRM, &sa, NULL);\n\n}\n\n\n/* Detect @@ in args. */\n\nstatic void detect_file_args(char** argv) {\n\n  u32 i = 0;\n  u8* cwd = getcwd(NULL, 0);\n\n  if (!cwd) PFATAL(\"getcwd() failed\");\n\n  while (argv[i]) {\n\n    u8* aa_loc = strstr(argv[i], \"@@\");\n\n    if (aa_loc) {\n\n      u8 *aa_subst, *n_arg;\n\n      if (!at_file) FATAL(\"@@ syntax is not supported by this tool.\");\n\n      /* Be sure that we're always using fully-qualified paths. */\n\n      if (at_file[0] == '/') aa_subst = at_file;\n      else aa_subst = alloc_printf(\"%s/%s\", cwd, at_file);\n\n      /* Construct a replacement argv value. */\n\n      *aa_loc = 0;\n      n_arg = alloc_printf(\"%s%s%s\", argv[i], aa_subst, aa_loc + 2);\n      argv[i] = n_arg;\n      *aa_loc = '@';\n\n      if (at_file[0] != '/') ck_free(aa_subst);\n\n    }\n\n    i++;\n\n  }\n\n  free(cwd); /* not tracked */\n\n}\n\n\n/* Show banner. */\n\nstatic void show_banner(void) {\n\n  SAYF(cCYA \"afl-showmap \" cBRI VERSION cRST \" by <lcamtuf@google.com>\\n\");\n\n}\n\n/* Display usage hints. */\n\nstatic void usage(u8* argv0) {\n\n  show_banner();\n\n  SAYF(\"\\n%s [ options ] -- /path/to/target_app [ ... ]\\n\\n\"\n\n       \"Required parameters:\\n\\n\"\n\n       \"  -o file       - file to write the trace data to\\n\\n\"\n\n       \"Execution control settings:\\n\\n\"\n\n       \"  -t msec       - timeout for each run (none)\\n\"\n       \"  -m megs       - memory limit for child process (%u MB)\\n\"\n       \"  -Q            - use binary-only instrumentation (QEMU mode)\\n\\n\"\n\n       \"Other settings:\\n\\n\"\n\n       \"  -q            - sink program's output and don't show messages\\n\"\n       \"  -e            - show edge coverage only, ignore hit counts\\n\"\n       \"  -c            - allow core dumps\\n\\n\"\n\n       \"This tool displays raw tuple data captured by AFL instrumentation.\\n\"\n       \"For additional help, consult %s/README.\\n\\n\" cRST,\n\n       argv0, MEM_LIMIT, doc_path);\n\n  exit(1);\n\n}\n\n\n/* Find binary. */\n\nstatic void find_binary(u8* fname) {\n\n  u8* env_path = 0;\n  struct stat st;\n\n  if (strchr(fname, '/') || !(env_path = getenv(\"PATH\"))) {\n\n    target_path = ck_strdup(fname);\n\n    if (stat(target_path, &st) || !S_ISREG(st.st_mode) ||\n        !(st.st_mode & 0111) || st.st_size < 4)\n      FATAL(\"Program '%s' not found or not executable\", fname);\n\n  } else {\n\n    while (env_path) {\n\n      u8 *cur_elem, *delim = strchr(env_path, ':');\n\n      if (delim) {\n\n        cur_elem = ck_alloc(delim - env_path + 1);\n        memcpy(cur_elem, env_path, delim - env_path);\n        delim++;\n\n      } else cur_elem = ck_strdup(env_path);\n\n      env_path = delim;\n\n      if (cur_elem[0])\n        target_path = alloc_printf(\"%s/%s\", cur_elem, fname);\n      else\n        target_path = ck_strdup(fname);\n\n      ck_free(cur_elem);\n\n      if (!stat(target_path, &st) && S_ISREG(st.st_mode) &&\n          (st.st_mode & 0111) && st.st_size >= 4) break;\n\n      ck_free(target_path);\n      target_path = 0;\n\n    }\n\n    if (!target_path) FATAL(\"Program '%s' not found or not executable\", fname);\n\n  }\n\n}\n\n\n/* Fix up argv for QEMU. */\n\nstatic char** get_qemu_argv(u8* own_loc, char** argv, int argc) {\n\n  char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));\n  u8 *tmp, *cp, *rsl, *own_copy;\n\n  /* Workaround for a QEMU stability glitch. */\n\n  setenv(\"QEMU_LOG\", \"nochain\", 1);\n\n  memcpy(new_argv + 3, argv + 1, sizeof(char*) * argc);\n\n  new_argv[2] = target_path;\n  new_argv[1] = \"--\";\n\n  /* Now we need to actually find qemu for argv[0]. */\n\n  tmp = getenv(\"AFL_PATH\");\n\n  if (tmp) {\n\n    cp = alloc_printf(\"%s/afl-qemu-trace\", tmp);\n\n    if (access(cp, X_OK))\n      FATAL(\"Unable to find '%s'\", tmp);\n\n    target_path = new_argv[0] = cp;\n    return new_argv;\n\n  }\n\n  own_copy = ck_strdup(own_loc);\n  rsl = strrchr(own_copy, '/');\n\n  if (rsl) {\n\n    *rsl = 0;\n\n    cp = alloc_printf(\"%s/afl-qemu-trace\", own_copy);\n    ck_free(own_copy);\n\n    if (!access(cp, X_OK)) {\n\n      target_path = new_argv[0] = cp;\n      return new_argv;\n\n    }\n\n  } else ck_free(own_copy);\n\n  if (!access(BIN_PATH \"/afl-qemu-trace\", X_OK)) {\n\n    target_path = new_argv[0] = BIN_PATH \"/afl-qemu-trace\";\n    return new_argv;\n\n  }\n\n  FATAL(\"Unable to find 'afl-qemu-trace'.\");\n\n}\n\n\n/* Main entry point */\n\nint main(int argc, char** argv) {\n\n  s32 opt;\n  u8  mem_limit_given = 0, timeout_given = 0, qemu_mode = 0;\n  u32 tcnt;\n  char** use_argv;\n\n  doc_path = access(DOC_PATH, F_OK) ? \"docs\" : DOC_PATH;\n\n  while ((opt = getopt(argc,argv,\"+o:m:t:A:eqZQbc\")) > 0)\n\n    switch (opt) {\n\n      case 'o':\n\n        if (out_file) FATAL(\"Multiple -o options not supported\");\n        out_file = optarg;\n        break;\n\n      case 'm': {\n\n          u8 suffix = 'M';\n\n          if (mem_limit_given) FATAL(\"Multiple -m options not supported\");\n          mem_limit_given = 1;\n\n          if (!strcmp(optarg, \"none\")) {\n\n            mem_limit = 0;\n            break;\n\n          }\n\n          if (sscanf(optarg, \"%llu%c\", &mem_limit, &suffix) < 1 ||\n              optarg[0] == '-') FATAL(\"Bad syntax used for -m\");\n\n          switch (suffix) {\n\n            case 'T': mem_limit *= 1024 * 1024; break;\n            case 'G': mem_limit *= 1024; break;\n            case 'k': mem_limit /= 1024; break;\n            case 'M': break;\n\n            default:  FATAL(\"Unsupported suffix or bad syntax for -m\");\n\n          }\n\n          if (mem_limit < 5) FATAL(\"Dangerously low value of -m\");\n\n          if (sizeof(rlim_t) == 4 && mem_limit > 2000)\n            FATAL(\"Value of -m out of range on 32-bit systems\");\n\n        }\n\n        break;\n\n      case 't':\n\n        if (timeout_given) FATAL(\"Multiple -t options not supported\");\n        timeout_given = 1;\n\n        if (strcmp(optarg, \"none\")) {\n          exec_tmout = atoi(optarg);\n\n          if (exec_tmout < 20 || optarg[0] == '-')\n            FATAL(\"Dangerously low value of -t\");\n\n        }\n\n        break;\n\n      case 'e':\n\n        if (edges_only) FATAL(\"Multiple -e options not supported\");\n        edges_only = 1;\n        break;\n\n      case 'q':\n\n        if (quiet_mode) FATAL(\"Multiple -q options not supported\");\n        quiet_mode = 1;\n        break;\n\n      case 'Z':\n\n        /* This is an undocumented option to write data in the syntax expected\n           by afl-cmin. Nobody else should have any use for this. */\n\n        cmin_mode  = 1;\n        quiet_mode = 1;\n        break;\n\n      case 'A':\n\n        /* Another afl-cmin specific feature. */\n        at_file = optarg;\n        break;\n\n      case 'Q':\n\n        if (qemu_mode) FATAL(\"Multiple -Q options not supported\");\n        if (!mem_limit_given) mem_limit = MEM_LIMIT_QEMU;\n\n        qemu_mode = 1;\n        break;\n\n      case 'b':\n\n        /* Secret undocumented mode. Writes output in raw binary format\n           similar to that dumped by afl-fuzz in <out_dir/queue/fuzz_bitmap. */\n\n        binary_mode = 1;\n        break;\n\n      case 'c':\n\n        if (keep_cores) FATAL(\"Multiple -c options not supported\");\n        keep_cores = 1;\n        break;\n\n      default:\n\n        usage(argv[0]);\n\n    }\n\n  if (optind == argc || !out_file) usage(argv[0]);\n\n  setup_shm();\n  setup_signal_handlers();\n\n  set_up_environment();\n\n  find_binary(argv[optind]);\n\n  if (!quiet_mode) {\n    show_banner();\n    ACTF(\"Executing '%s'...\\n\", target_path);\n  }\n\n  detect_file_args(argv + optind);\n\n  if (qemu_mode)\n    use_argv = get_qemu_argv(argv[0], argv + optind, argc - optind);\n  else\n    use_argv = argv + optind;\n\n  run_target(use_argv);\n\n  tcnt = write_results();\n\n  if (!quiet_mode) {\n\n    if (!tcnt) FATAL(\"No instrumentation detected\" cRST);\n    OKF(\"Captured %u tuples in '%s'.\" cRST, tcnt, out_file);\n\n  }\n\n  exit(child_crashed * 2 + child_timed_out);\n\n}\n\n"
  },
  {
    "path": "afl_progs/alloc-inl.h",
    "content": "/*\n   american fuzzy lop - error-checking, memory-zeroing alloc routines\n   ------------------------------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This allocator is not designed to resist malicious attackers (the canaries\n   are small and predictable), but provides a robust and portable way to detect\n   use-after-free, off-by-one writes, stale pointers, and so on.\n\n */\n\n#ifndef _HAVE_ALLOC_INL_H\n#define _HAVE_ALLOC_INL_H\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"config.h\"\n#include \"types.h\"\n#include \"debug.h\"\n\n/* User-facing macro to sprintf() to a dynamically allocated buffer. */\n\n#define alloc_printf(_str...) ({ \\\n    u8* _tmp; \\\n    s32 _len = snprintf(NULL, 0, _str); \\\n    if (_len < 0) FATAL(\"Whoa, snprintf() fails?!\"); \\\n    _tmp = ck_alloc(_len + 1); \\\n    snprintf((char*)_tmp, _len + 1, _str); \\\n    _tmp; \\\n  })\n\n/* Macro to enforce allocation limits as a last-resort defense against\n   integer overflows. */\n\n#define ALLOC_CHECK_SIZE(_s) do { \\\n    if ((_s) > MAX_ALLOC) \\\n      ABORT(\"Bad alloc request: %u bytes\", (_s)); \\\n  } while (0)\n\n/* Macro to check malloc() failures and the like. */\n\n#define ALLOC_CHECK_RESULT(_r, _s) do { \\\n    if (!(_r)) \\\n      ABORT(\"Out of memory: can't allocate %u bytes\", (_s)); \\\n  } while (0)\n\n/* Magic tokens used to mark used / freed chunks. */\n\n#define ALLOC_MAGIC_C1  0xFF00FF00 /* Used head (dword)  */\n#define ALLOC_MAGIC_F   0xFE00FE00 /* Freed head (dword) */\n#define ALLOC_MAGIC_C2  0xF0       /* Used tail (byte)   */\n\n/* Positions of guard tokens in relation to the user-visible pointer. */\n\n#define ALLOC_C1(_ptr)  (((u32*)(_ptr))[-2])\n#define ALLOC_S(_ptr)   (((u32*)(_ptr))[-1])\n#define ALLOC_C2(_ptr)  (((u8*)(_ptr))[ALLOC_S(_ptr)])\n\n#define ALLOC_OFF_HEAD  8\n#define ALLOC_OFF_TOTAL (ALLOC_OFF_HEAD + 1)\n\n/* Allocator increments for ck_realloc_block(). */\n\n#define ALLOC_BLK_INC    256\n\n/* Sanity-checking macros for pointers. */\n\n#define CHECK_PTR(_p) do { \\\n    if (_p) { \\\n      if (ALLOC_C1(_p) ^ ALLOC_MAGIC_C1) {\\\n        if (ALLOC_C1(_p) == ALLOC_MAGIC_F) \\\n          ABORT(\"Use after free.\"); \\\n        else ABORT(\"Corrupted head alloc canary.\"); \\\n      } \\\n      if (ALLOC_C2(_p) ^ ALLOC_MAGIC_C2) \\\n        ABORT(\"Corrupted tail alloc canary.\"); \\\n    } \\\n  } while (0)\n\n#define CHECK_PTR_EXPR(_p) ({ \\\n    typeof (_p) _tmp = (_p); \\\n    CHECK_PTR(_tmp); \\\n    _tmp; \\\n  })\n\n\n/* Allocate a buffer, explicitly not zeroing it. Returns NULL for zero-sized\n   requests. */\n\nstatic inline void* DFL_ck_alloc_nozero(u32 size) {\n\n  void* ret;\n\n  if (!size) return NULL;\n\n  ALLOC_CHECK_SIZE(size);\n  ret = malloc(size + ALLOC_OFF_TOTAL);\n  ALLOC_CHECK_RESULT(ret, size);\n\n  ret += ALLOC_OFF_HEAD;\n\n  ALLOC_C1(ret) = ALLOC_MAGIC_C1;\n  ALLOC_S(ret)  = size;\n  ALLOC_C2(ret) = ALLOC_MAGIC_C2;\n\n  return ret;\n\n}\n\n\n/* Allocate a buffer, returning zeroed memory. */\n\nstatic inline void* DFL_ck_alloc(u32 size) {\n\n  void* mem;\n\n  if (!size) return NULL;\n  mem = DFL_ck_alloc_nozero(size);\n\n  return memset(mem, 0, size);\n\n}\n\n\n/* Free memory, checking for double free and corrupted heap. When DEBUG_BUILD\n   is set, the old memory will be also clobbered with 0xFF. */\n\nstatic inline void DFL_ck_free(void* mem) {\n\n  if (!mem) return;\n\n  CHECK_PTR(mem);\n\n#ifdef DEBUG_BUILD\n\n  /* Catch pointer issues sooner. */\n  memset(mem, 0xFF, ALLOC_S(mem));\n\n#endif /* DEBUG_BUILD */\n\n  ALLOC_C1(mem) = ALLOC_MAGIC_F;\n\n  free(mem - ALLOC_OFF_HEAD);\n\n}\n\n\n/* Re-allocate a buffer, checking for issues and zeroing any newly-added tail.\n   With DEBUG_BUILD, the buffer is always reallocated to a new addresses and the\n   old memory is clobbered with 0xFF. */\n\nstatic inline void* DFL_ck_realloc(void* orig, u32 size) {\n\n  void* ret;\n  u32   old_size = 0;\n\n  if (!size) {\n\n    DFL_ck_free(orig);\n    return NULL;\n\n  }\n\n  if (orig) {\n\n    CHECK_PTR(orig);\n\n#ifndef DEBUG_BUILD\n    ALLOC_C1(orig) = ALLOC_MAGIC_F;\n#endif /* !DEBUG_BUILD */\n\n    old_size  = ALLOC_S(orig);\n    orig     -= ALLOC_OFF_HEAD;\n\n    ALLOC_CHECK_SIZE(old_size);\n\n  }\n\n  ALLOC_CHECK_SIZE(size);\n\n#ifndef DEBUG_BUILD\n\n  ret = realloc(orig, size + ALLOC_OFF_TOTAL);\n  ALLOC_CHECK_RESULT(ret, size);\n\n#else\n\n  /* Catch pointer issues sooner: force relocation and make sure that the\n     original buffer is wiped. */\n\n  ret = malloc(size + ALLOC_OFF_TOTAL);\n  ALLOC_CHECK_RESULT(ret, size);\n\n  if (orig) {\n\n    memcpy(ret + ALLOC_OFF_HEAD, orig + ALLOC_OFF_HEAD, MIN(size, old_size));\n    memset(orig + ALLOC_OFF_HEAD, 0xFF, old_size);\n\n    ALLOC_C1(orig + ALLOC_OFF_HEAD) = ALLOC_MAGIC_F;\n\n    free(orig);\n\n  }\n\n#endif /* ^!DEBUG_BUILD */\n\n  ret += ALLOC_OFF_HEAD;\n\n  ALLOC_C1(ret) = ALLOC_MAGIC_C1;\n  ALLOC_S(ret)  = size;\n  ALLOC_C2(ret) = ALLOC_MAGIC_C2;\n\n  if (size > old_size)\n    memset(ret + old_size, 0, size - old_size);\n\n  return ret;\n\n}\n\n\n/* Re-allocate a buffer with ALLOC_BLK_INC increments (used to speed up\n   repeated small reallocs without complicating the user code). */\n\nstatic inline void* DFL_ck_realloc_block(void* orig, u32 size) {\n\n#ifndef DEBUG_BUILD\n\n  if (orig) {\n\n    CHECK_PTR(orig);\n\n    if (ALLOC_S(orig) >= size) return orig;\n\n    size += ALLOC_BLK_INC;\n\n  }\n\n#endif /* !DEBUG_BUILD */\n\n  return DFL_ck_realloc(orig, size);\n\n}\n\n\n/* Create a buffer with a copy of a string. Returns NULL for NULL inputs. */\n\nstatic inline u8* DFL_ck_strdup(u8* str) {\n\n  void* ret;\n  u32   size;\n\n  if (!str) return NULL;\n\n  size = strlen((char*)str) + 1;\n\n  ALLOC_CHECK_SIZE(size);\n  ret = malloc(size + ALLOC_OFF_TOTAL);\n  ALLOC_CHECK_RESULT(ret, size);\n\n  ret += ALLOC_OFF_HEAD;\n\n  ALLOC_C1(ret) = ALLOC_MAGIC_C1;\n  ALLOC_S(ret)  = size;\n  ALLOC_C2(ret) = ALLOC_MAGIC_C2;\n\n  return memcpy(ret, str, size);\n\n}\n\n\n/* Create a buffer with a copy of a memory block. Returns NULL for zero-sized\n   or NULL inputs. */\n\nstatic inline void* DFL_ck_memdup(void* mem, u32 size) {\n\n  void* ret;\n\n  if (!mem || !size) return NULL;\n\n  ALLOC_CHECK_SIZE(size);\n  ret = malloc(size + ALLOC_OFF_TOTAL);\n  ALLOC_CHECK_RESULT(ret, size);\n  \n  ret += ALLOC_OFF_HEAD;\n\n  ALLOC_C1(ret) = ALLOC_MAGIC_C1;\n  ALLOC_S(ret)  = size;\n  ALLOC_C2(ret) = ALLOC_MAGIC_C2;\n\n  return memcpy(ret, mem, size);\n\n}\n\n\n/* Create a buffer with a block of text, appending a NUL terminator at the end.\n   Returns NULL for zero-sized or NULL inputs. */\n\nstatic inline u8* DFL_ck_memdup_str(u8* mem, u32 size) {\n\n  u8* ret;\n\n  if (!mem || !size) return NULL;\n\n  ALLOC_CHECK_SIZE(size);\n  ret = malloc(size + ALLOC_OFF_TOTAL + 1);\n  ALLOC_CHECK_RESULT(ret, size);\n  \n  ret += ALLOC_OFF_HEAD;\n\n  ALLOC_C1(ret) = ALLOC_MAGIC_C1;\n  ALLOC_S(ret)  = size;\n  ALLOC_C2(ret) = ALLOC_MAGIC_C2;\n\n  memcpy(ret, mem, size);\n  ret[size] = 0;\n\n  return ret;\n\n}\n\n\n#ifndef DEBUG_BUILD\n\n/* In non-debug mode, we just do straightforward aliasing of the above functions\n   to user-visible names such as ck_alloc(). */\n\n#define ck_alloc          DFL_ck_alloc\n#define ck_alloc_nozero   DFL_ck_alloc_nozero\n#define ck_realloc        DFL_ck_realloc\n#define ck_realloc_block  DFL_ck_realloc_block\n#define ck_strdup         DFL_ck_strdup\n#define ck_memdup         DFL_ck_memdup\n#define ck_memdup_str     DFL_ck_memdup_str\n#define ck_free           DFL_ck_free\n\n#define alloc_report()\n\n#else\n\n/* In debugging mode, we also track allocations to detect memory leaks, and the\n   flow goes through one more layer of indirection. */\n\n/* Alloc tracking data structures: */\n\n#define ALLOC_BUCKETS     4096\n\nstruct TRK_obj {\n  void *ptr;\n  char *file, *func;\n  u32  line;\n};\n\n#ifdef AFL_MAIN\n\nstruct TRK_obj* TRK[ALLOC_BUCKETS];\nu32 TRK_cnt[ALLOC_BUCKETS];\n\n#  define alloc_report() TRK_report()\n\n#else\n\nextern struct TRK_obj* TRK[ALLOC_BUCKETS];\nextern u32 TRK_cnt[ALLOC_BUCKETS];\n\n#  define alloc_report()\n\n#endif /* ^AFL_MAIN */\n\n/* Bucket-assigning function for a given pointer: */\n\n#define TRKH(_ptr) (((((u32)(_ptr)) >> 16) ^ ((u32)(_ptr))) % ALLOC_BUCKETS)\n\n\n/* Add a new entry to the list of allocated objects. */\n\nstatic inline void TRK_alloc_buf(void* ptr, const char* file, const char* func,\n                                 u32 line) {\n\n  u32 i, bucket;\n\n  if (!ptr) return;\n\n  bucket = TRKH(ptr);\n\n  /* Find a free slot in the list of entries for that bucket. */\n\n  for (i = 0; i < TRK_cnt[bucket]; i++)\n\n    if (!TRK[bucket][i].ptr) {\n\n      TRK[bucket][i].ptr  = ptr;\n      TRK[bucket][i].file = (char*)file;\n      TRK[bucket][i].func = (char*)func;\n      TRK[bucket][i].line = line;\n      return;\n\n    }\n\n  /* No space available - allocate more. */\n\n  TRK[bucket] = DFL_ck_realloc_block(TRK[bucket],\n    (TRK_cnt[bucket] + 1) * sizeof(struct TRK_obj));\n\n  TRK[bucket][i].ptr  = ptr;\n  TRK[bucket][i].file = (char*)file;\n  TRK[bucket][i].func = (char*)func;\n  TRK[bucket][i].line = line;\n\n  TRK_cnt[bucket]++;\n\n}\n\n\n/* Remove entry from the list of allocated objects. */\n\nstatic inline void TRK_free_buf(void* ptr, const char* file, const char* func,\n                                u32 line) {\n\n  u32 i, bucket;\n\n  if (!ptr) return;\n\n  bucket = TRKH(ptr);\n\n  /* Find the element on the list... */\n\n  for (i = 0; i < TRK_cnt[bucket]; i++)\n\n    if (TRK[bucket][i].ptr == ptr) {\n\n      TRK[bucket][i].ptr = 0;\n      return;\n\n    }\n\n  WARNF(\"ALLOC: Attempt to free non-allocated memory in %s (%s:%u)\",\n        func, file, line);\n\n}\n\n\n/* Do a final report on all non-deallocated objects. */\n\nstatic inline void TRK_report(void) {\n\n  u32 i, bucket;\n\n  fflush(0);\n\n  for (bucket = 0; bucket < ALLOC_BUCKETS; bucket++)\n    for (i = 0; i < TRK_cnt[bucket]; i++)\n      if (TRK[bucket][i].ptr)\n        WARNF(\"ALLOC: Memory never freed, created in %s (%s:%u)\",\n              TRK[bucket][i].func, TRK[bucket][i].file, TRK[bucket][i].line);\n\n}\n\n\n/* Simple wrappers for non-debugging functions: */\n\nstatic inline void* TRK_ck_alloc(u32 size, const char* file, const char* func,\n                                 u32 line) {\n\n  void* ret = DFL_ck_alloc(size);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void* TRK_ck_realloc(void* orig, u32 size, const char* file,\n                                   const char* func, u32 line) {\n\n  void* ret = DFL_ck_realloc(orig, size);\n  TRK_free_buf(orig, file, func, line);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void* TRK_ck_realloc_block(void* orig, u32 size, const char* file,\n                                         const char* func, u32 line) {\n\n  void* ret = DFL_ck_realloc_block(orig, size);\n  TRK_free_buf(orig, file, func, line);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void* TRK_ck_strdup(u8* str, const char* file, const char* func,\n                                  u32 line) {\n\n  void* ret = DFL_ck_strdup(str);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void* TRK_ck_memdup(void* mem, u32 size, const char* file,\n                                  const char* func, u32 line) {\n\n  void* ret = DFL_ck_memdup(mem, size);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void* TRK_ck_memdup_str(void* mem, u32 size, const char* file,\n                                      const char* func, u32 line) {\n\n  void* ret = DFL_ck_memdup_str(mem, size);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void TRK_ck_free(void* ptr, const char* file,\n                                const char* func, u32 line) {\n\n  TRK_free_buf(ptr, file, func, line);\n  DFL_ck_free(ptr);\n\n}\n\n/* Aliasing user-facing names to tracking functions: */\n\n#define ck_alloc(_p1) \\\n  TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_alloc_nozero(_p1) \\\n  TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_realloc(_p1, _p2) \\\n  TRK_ck_realloc(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_realloc_block(_p1, _p2) \\\n  TRK_ck_realloc_block(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_strdup(_p1) \\\n  TRK_ck_strdup(_p1, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_memdup(_p1, _p2) \\\n  TRK_ck_memdup(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_memdup_str(_p1, _p2) \\\n  TRK_ck_memdup_str(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_free(_p1) \\\n  TRK_ck_free(_p1, __FILE__, __FUNCTION__, __LINE__)\n\n#endif /* ^!DEBUG_BUILD */\n\n#endif /* ! _HAVE_ALLOC_INL_H */\n"
  },
  {
    "path": "afl_progs/config.h",
    "content": "/*\n   american fuzzy lop - vaguely configurable bits\n   ----------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015, 2016 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n */\n\n#ifndef _HAVE_CONFIG_H\n#define _HAVE_CONFIG_H\n\n#include \"types.h\"\n\n/* Version string: */\n\n#define VERSION             \"2.52b\"\n\n/******************************************************\n *                                                    *\n *  Settings that may be of interest to power users:  *\n *                                                    *\n ******************************************************/\n\n/* Comment out to disable terminal colors (note that this makes afl-analyze\n   a lot less nice): */\n\n#define USE_COLOR\n\n/* Comment out to disable fancy ANSI boxes and use poor man's 7-bit UI: */\n\n#define FANCY_BOXES\n\n/* Default timeout for fuzzed code (milliseconds). This is the upper bound,\n   also used for detecting hangs; the actual value is auto-scaled: */\n\n#define EXEC_TIMEOUT        1000\n\n/* Timeout rounding factor when auto-scaling (milliseconds): */\n\n#define EXEC_TM_ROUND       20\n\n/* Default memory limit for child process (MB): */\n\n#ifndef __x86_64__ \n#  define MEM_LIMIT         25\n#else\n#  define MEM_LIMIT         50\n#endif /* ^!__x86_64__ */\n\n/* Default memory limit when running in QEMU mode (MB): */\n\n#define MEM_LIMIT_QEMU      200\n\n/* Number of calibration cycles per every new test case (and for test\n   cases that show variable behavior): */\n\n#define CAL_CYCLES          8\n#define CAL_CYCLES_LONG     40\n\n/* Number of subsequent timeouts before abandoning an input file: */\n\n#define TMOUT_LIMIT         250\n\n/* Maximum number of unique hangs or crashes to record: */\n\n#define KEEP_UNIQUE_HANG    500\n#define KEEP_UNIQUE_CRASH   5000\n\n/* Baseline number of random tweaks during a single 'havoc' stage: */\n\n#define HAVOC_CYCLES        256\n#define HAVOC_CYCLES_INIT   1024\n\n/* Maximum multiplier for the above (should be a power of two, beware\n   of 32-bit int overflows): */\n\n#define HAVOC_MAX_MULT      16\n\n/* Absolute minimum number of havoc cycles (after all adjustments): */\n\n#define HAVOC_MIN           16\n\n/* Maximum stacking for havoc-stage tweaks. The actual value is calculated\n   like this: \n\n   n = random between 1 and HAVOC_STACK_POW2\n   stacking = 2^n\n\n   In other words, the default (n = 7) produces 2, 4, 8, 16, 32, 64, or\n   128 stacked tweaks: */\n\n#define HAVOC_STACK_POW2    7\n\n/* Caps on block sizes for cloning and deletion operations. Each of these\n   ranges has a 33% probability of getting picked, except for the first\n   two cycles where smaller blocks are favored: */\n\n#define HAVOC_BLK_SMALL     32\n#define HAVOC_BLK_MEDIUM    128\n#define HAVOC_BLK_LARGE     1500\n\n/* Extra-large blocks, selected very rarely (<5% of the time): */\n\n#define HAVOC_BLK_XL        32768\n\n/* Probabilities of skipping non-favored entries in the queue, expressed as\n   percentages: */\n\n#define SKIP_TO_NEW_PROB    99 /* ...when there are new, pending favorites */\n#define SKIP_NFAV_OLD_PROB  95 /* ...no new favs, cur entry already fuzzed */\n#define SKIP_NFAV_NEW_PROB  75 /* ...no new favs, cur entry not fuzzed yet */\n\n/* Splicing cycle count: */\n\n#define SPLICE_CYCLES       15\n\n/* Nominal per-splice havoc cycle length: */\n\n#define SPLICE_HAVOC        32\n\n/* Maximum offset for integer addition / subtraction stages: */\n\n#define ARITH_MAX           35\n\n/* Limits for the test case trimmer. The absolute minimum chunk size; and\n   the starting and ending divisors for chopping up the input file: */\n\n#define TRIM_MIN_BYTES      4\n#define TRIM_START_STEPS    16\n#define TRIM_END_STEPS      1024\n\n/* Maximum size of input file, in bytes (keep under 100MB): */\n\n#define MAX_FILE            (1 * 1024 * 1024)\n\n/* The same, for the test case minimizer: */\n\n#define TMIN_MAX_FILE       (10 * 1024 * 1024)\n\n/* Block normalization steps for afl-tmin: */\n\n#define TMIN_SET_MIN_SIZE   4\n#define TMIN_SET_STEPS      128\n\n/* Maximum dictionary token size (-x), in bytes: */\n\n#define MAX_DICT_FILE       128\n\n/* Length limits for auto-detected dictionary tokens: */\n\n#define MIN_AUTO_EXTRA      3\n#define MAX_AUTO_EXTRA      32\n\n/* Maximum number of user-specified dictionary tokens to use in deterministic\n   steps; past this point, the \"extras/user\" step will be still carried out,\n   but with proportionally lower odds: */\n\n#define MAX_DET_EXTRAS      200\n\n/* Maximum number of auto-extracted dictionary tokens to actually use in fuzzing\n   (first value), and to keep in memory as candidates. The latter should be much\n   higher than the former. */\n\n#define USE_AUTO_EXTRAS     50\n#define MAX_AUTO_EXTRAS     (USE_AUTO_EXTRAS * 10)\n\n/* Scaling factor for the effector map used to skip some of the more\n   expensive deterministic steps. The actual divisor is set to\n   2^EFF_MAP_SCALE2 bytes: */\n\n#define EFF_MAP_SCALE2      3\n\n/* Minimum input file length at which the effector logic kicks in: */\n\n#define EFF_MIN_LEN         128\n\n/* Maximum effector density past which everything is just fuzzed\n   unconditionally (%): */\n\n#define EFF_MAX_PERC        90\n\n/* UI refresh frequency (Hz): */\n\n#define UI_TARGET_HZ        5\n\n/* Fuzzer stats file and plot update intervals (sec): */\n\n#define STATS_UPDATE_SEC    60\n#define PLOT_UPDATE_SEC     5\n\n/* Smoothing divisor for CPU load and exec speed stats (1 - no smoothing). */\n\n#define AVG_SMOOTHING       16\n\n/* Sync interval (every n havoc cycles): */\n\n#define SYNC_INTERVAL       5\n\n/* Output directory reuse grace period (minutes): */\n\n#define OUTPUT_GRACE        25\n\n/* Uncomment to use simple file names (id_NNNNNN): */\n\n// #define SIMPLE_FILES\n\n/* List of interesting values to use in fuzzing. */\n\n#define INTERESTING_8 \\\n  -128,          /* Overflow signed 8-bit when decremented  */ \\\n  -1,            /*                                         */ \\\n   0,            /*                                         */ \\\n   1,            /*                                         */ \\\n   16,           /* One-off with common buffer size         */ \\\n   32,           /* One-off with common buffer size         */ \\\n   64,           /* One-off with common buffer size         */ \\\n   100,          /* One-off with common buffer size         */ \\\n   127           /* Overflow signed 8-bit when incremented  */\n\n#define INTERESTING_16 \\\n  -32768,        /* Overflow signed 16-bit when decremented */ \\\n  -129,          /* Overflow signed 8-bit                   */ \\\n   128,          /* Overflow signed 8-bit                   */ \\\n   255,          /* Overflow unsig 8-bit when incremented   */ \\\n   256,          /* Overflow unsig 8-bit                    */ \\\n   512,          /* One-off with common buffer size         */ \\\n   1000,         /* One-off with common buffer size         */ \\\n   1024,         /* One-off with common buffer size         */ \\\n   4096,         /* One-off with common buffer size         */ \\\n   32767         /* Overflow signed 16-bit when incremented */\n\n#define INTERESTING_32 \\\n  -2147483648LL, /* Overflow signed 32-bit when decremented */ \\\n  -100663046,    /* Large negative number (endian-agnostic) */ \\\n  -32769,        /* Overflow signed 16-bit                  */ \\\n   32768,        /* Overflow signed 16-bit                  */ \\\n   65535,        /* Overflow unsig 16-bit when incremented  */ \\\n   65536,        /* Overflow unsig 16 bit                   */ \\\n   100663045,    /* Large positive number (endian-agnostic) */ \\\n   2147483647    /* Overflow signed 32-bit when incremented */\n\n/***********************************************************\n *                                                         *\n *  Really exotic stuff you probably don't want to touch:  *\n *                                                         *\n ***********************************************************/\n\n/* Call count interval between reseeding the libc PRNG from /dev/urandom: */\n\n#define RESEED_RNG          10000\n\n/* Maximum line length passed from GCC to 'as' and used for parsing\n   configuration files: */\n\n#define MAX_LINE            8192\n\n/* Environment variable used to pass SHM ID to the called program. */\n\n#define SHM_ENV_VAR         \"__AFL_SHM_ID\"\n\n/* Other less interesting, internal-only variables. */\n\n#define CLANG_ENV_VAR       \"__AFL_CLANG_MODE\"\n#define AS_LOOP_ENV_VAR     \"__AFL_AS_LOOPCHECK\"\n\n/* In-code signatures for deferred and persistent mode. */\n\n#define PERSIST_SIG         \"##SIG_AFL_PERSISTENT##\"\n#define DEFER_SIG           \"##SIG_AFL_DEFER_FORKSRV##\"\n\n/* Distinctive bitmap signature used to indicate failed execution: */\n\n#define EXEC_FAIL_SIG       0xfee1dead\n\n/* Distinctive exit code used to indicate MSAN trip condition: */\n\n#define MSAN_ERROR          86\n\n/* Designated file descriptors for forkserver commands (the application will\n   use FORKSRV_FD and FORKSRV_FD + 1): */\n\n#define FORKSRV_FD          198\n\n/* Fork server init timeout multiplier: we'll wait the user-selected\n   timeout plus this much for the fork server to spin up. */\n\n#define FORK_WAIT_MULT      10\n\n/* Calibration timeout adjustments, to be a bit more generous when resuming\n   fuzzing sessions or trying to calibrate already-added internal finds.\n   The first value is a percentage, the other is in milliseconds: */\n\n#define CAL_TMOUT_PERC      125\n#define CAL_TMOUT_ADD       50\n\n/* Number of chances to calibrate a case before giving up: */\n\n#define CAL_CHANCES         3\n\n/* Map size for the traced binary (2^MAP_SIZE_POW2). Must be greater than\n   2; you probably want to keep it under 18 or so for performance reasons\n   (adjusting AFL_INST_RATIO when compiling is probably a better way to solve\n   problems with complex programs). You need to recompile the target binary\n   after changing this - otherwise, SEGVs may ensue. */\n\n#define MAP_SIZE_POW2       16\n#define MAP_SIZE            (1 << MAP_SIZE_POW2)\n\n/* Maximum allocator request size (keep well under INT_MAX): */\n\n#define MAX_ALLOC           0x40000000\n\n/* A made-up hashing seed: */\n\n#define HASH_CONST          0xa5b35705\n\n/* Constants for afl-gotcpu to control busy loop timing: */\n\n#define  CTEST_TARGET_MS    5000\n#define  CTEST_CORE_TRG_MS  1000\n#define  CTEST_BUSY_CYCLES  (10 * 1000 * 1000)\n\n/* Uncomment this to use inferior block-coverage-based instrumentation. Note\n   that you need to recompile the target binary for this to have any effect: */\n\n// #define COVERAGE_ONLY\n\n/* Uncomment this to ignore hit counts and output just one bit per tuple.\n   As with the previous setting, you will need to recompile the target\n   binary: */\n\n// #define SKIP_COUNTS\n\n/* Uncomment this to use instrumentation data to record newly discovered paths,\n   but do not use them as seeds for fuzzing. This is useful for conveniently\n   measuring coverage that could be attained by a \"dumb\" fuzzing algorithm: */\n\n// #define IGNORE_FINDS\n\n#endif /* ! _HAVE_CONFIG_H */\n"
  },
  {
    "path": "afl_progs/debug.h",
    "content": "/*\n   american fuzzy lop - debug / error handling macros\n   --------------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015, 2016 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n */\n\n#ifndef _HAVE_DEBUG_H\n#define _HAVE_DEBUG_H\n\n#include <errno.h>\n\n#include \"types.h\"\n#include \"config.h\"\n\n/*******************\n * Terminal colors *\n *******************/\n\n#ifdef USE_COLOR\n\n#  define cBLK \"\\x1b[0;30m\"\n#  define cRED \"\\x1b[0;31m\"\n#  define cGRN \"\\x1b[0;32m\"\n#  define cBRN \"\\x1b[0;33m\"\n#  define cBLU \"\\x1b[0;34m\"\n#  define cMGN \"\\x1b[0;35m\"\n#  define cCYA \"\\x1b[0;36m\"\n#  define cLGR \"\\x1b[0;37m\"\n#  define cGRA \"\\x1b[1;90m\"\n#  define cLRD \"\\x1b[1;91m\"\n#  define cLGN \"\\x1b[1;92m\"\n#  define cYEL \"\\x1b[1;93m\"\n#  define cLBL \"\\x1b[1;94m\"\n#  define cPIN \"\\x1b[1;95m\"\n#  define cLCY \"\\x1b[1;96m\"\n#  define cBRI \"\\x1b[1;97m\"\n#  define cRST \"\\x1b[0m\"\n\n#  define bgBLK \"\\x1b[40m\"\n#  define bgRED \"\\x1b[41m\"\n#  define bgGRN \"\\x1b[42m\"\n#  define bgBRN \"\\x1b[43m\"\n#  define bgBLU \"\\x1b[44m\"\n#  define bgMGN \"\\x1b[45m\"\n#  define bgCYA \"\\x1b[46m\"\n#  define bgLGR \"\\x1b[47m\"\n#  define bgGRA \"\\x1b[100m\"\n#  define bgLRD \"\\x1b[101m\"\n#  define bgLGN \"\\x1b[102m\"\n#  define bgYEL \"\\x1b[103m\"\n#  define bgLBL \"\\x1b[104m\"\n#  define bgPIN \"\\x1b[105m\"\n#  define bgLCY \"\\x1b[106m\"\n#  define bgBRI \"\\x1b[107m\"\n\n#else\n\n#  define cBLK \"\"\n#  define cRED \"\"\n#  define cGRN \"\"\n#  define cBRN \"\"\n#  define cBLU \"\"\n#  define cMGN \"\"\n#  define cCYA \"\"\n#  define cLGR \"\"\n#  define cGRA \"\"\n#  define cLRD \"\"\n#  define cLGN \"\"\n#  define cYEL \"\"\n#  define cLBL \"\"\n#  define cPIN \"\"\n#  define cLCY \"\"\n#  define cBRI \"\"\n#  define cRST \"\"\n\n#  define bgBLK \"\"\n#  define bgRED \"\"\n#  define bgGRN \"\"\n#  define bgBRN \"\"\n#  define bgBLU \"\"\n#  define bgMGN \"\"\n#  define bgCYA \"\"\n#  define bgLGR \"\"\n#  define bgGRA \"\"\n#  define bgLRD \"\"\n#  define bgLGN \"\"\n#  define bgYEL \"\"\n#  define bgLBL \"\"\n#  define bgPIN \"\"\n#  define bgLCY \"\"\n#  define bgBRI \"\"\n\n#endif /* ^USE_COLOR */\n\n/*************************\n * Box drawing sequences *\n *************************/\n\n#ifdef FANCY_BOXES\n\n#  define SET_G1   \"\\x1b)0\"       /* Set G1 for box drawing    */\n#  define RESET_G1 \"\\x1b)B\"       /* Reset G1 to ASCII         */\n#  define bSTART   \"\\x0e\"         /* Enter G1 drawing mode     */\n#  define bSTOP    \"\\x0f\"         /* Leave G1 drawing mode     */\n#  define bH       \"q\"            /* Horizontal line           */\n#  define bV       \"x\"            /* Vertical line             */\n#  define bLT      \"l\"            /* Left top corner           */\n#  define bRT      \"k\"            /* Right top corner          */\n#  define bLB      \"m\"            /* Left bottom corner        */\n#  define bRB      \"j\"            /* Right bottom corner       */\n#  define bX       \"n\"            /* Cross                     */\n#  define bVR      \"t\"            /* Vertical, branch right    */\n#  define bVL      \"u\"            /* Vertical, branch left     */\n#  define bHT      \"v\"            /* Horizontal, branch top    */\n#  define bHB      \"w\"            /* Horizontal, branch bottom */\n\n#else\n\n#  define SET_G1   \"\"\n#  define RESET_G1 \"\"\n#  define bSTART   \"\"\n#  define bSTOP    \"\"\n#  define bH       \"-\"\n#  define bV       \"|\"\n#  define bLT      \"+\"\n#  define bRT      \"+\"\n#  define bLB      \"+\"\n#  define bRB      \"+\"\n#  define bX       \"+\"\n#  define bVR      \"+\"\n#  define bVL      \"+\"\n#  define bHT      \"+\"\n#  define bHB      \"+\"\n\n#endif /* ^FANCY_BOXES */\n\n/***********************\n * Misc terminal codes *\n ***********************/\n\n#define TERM_HOME     \"\\x1b[H\"\n#define TERM_CLEAR    TERM_HOME \"\\x1b[2J\"\n#define cEOL          \"\\x1b[0K\"\n#define CURSOR_HIDE   \"\\x1b[?25l\"\n#define CURSOR_SHOW   \"\\x1b[?25h\"\n\n/************************\n * Debug & error macros *\n ************************/\n\n/* Just print stuff to the appropriate stream. */\n\n#ifdef MESSAGES_TO_STDOUT\n#  define SAYF(x...)    printf(x)\n#else \n#  define SAYF(x...)    fprintf(stderr, x)\n#endif /* ^MESSAGES_TO_STDOUT */\n\n/* Show a prefixed warning. */\n\n#define WARNF(x...) do { \\\n    SAYF(cYEL \"[!] \" cBRI \"WARNING: \" cRST x); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Show a prefixed \"doing something\" message. */\n\n#define ACTF(x...) do { \\\n    SAYF(cLBL \"[*] \" cRST x); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Show a prefixed \"success\" message. */\n\n#define OKF(x...) do { \\\n    SAYF(cLGN \"[+] \" cRST x); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Show a prefixed fatal error message (not used in afl). */\n\n#define BADF(x...) do { \\\n    SAYF(cLRD \"\\n[-] \" cRST x); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Die with a verbose non-OS fatal error message. */\n\n#define FATAL(x...) do { \\\n    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \"\\n[-] PROGRAM ABORT : \" \\\n         cBRI x); \\\n    SAYF(cLRD \"\\n         Location : \" cRST \"%s(), %s:%u\\n\\n\", \\\n         __FUNCTION__, __FILE__, __LINE__); \\\n    exit(1); \\\n  } while (0)\n\n/* Die by calling abort() to provide a core dump. */\n\n#define ABORT(x...) do { \\\n    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \"\\n[-] PROGRAM ABORT : \" \\\n         cBRI x); \\\n    SAYF(cLRD \"\\n    Stop location : \" cRST \"%s(), %s:%u\\n\\n\", \\\n         __FUNCTION__, __FILE__, __LINE__); \\\n    abort(); \\\n  } while (0)\n\n/* Die while also including the output of perror(). */\n\n#define PFATAL(x...) do { \\\n    fflush(stdout); \\\n    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \"\\n[-]  SYSTEM ERROR : \" \\\n         cBRI x); \\\n    SAYF(cLRD \"\\n    Stop location : \" cRST \"%s(), %s:%u\\n\", \\\n         __FUNCTION__, __FILE__, __LINE__); \\\n    SAYF(cLRD \"       OS message : \" cRST \"%s\\n\", strerror(errno)); \\\n    exit(1); \\\n  } while (0)\n\n/* Die with FAULT() or PFAULT() depending on the value of res (used to\n   interpret different failure modes for read(), write(), etc). */\n\n#define RPFATAL(res, x...) do { \\\n    if (res < 0) PFATAL(x); else FATAL(x); \\\n  } while (0)\n\n/* Error-checking versions of read() and write() that call RPFATAL() as\n   appropriate. */\n\n#define ck_write(fd, buf, len, fn) do { \\\n    u32 _len = (len); \\\n    s32 _res = write(fd, buf, _len); \\\n    if (_res != _len) RPFATAL(_res, \"Short write to %s\", fn); \\\n  } while (0)\n\n#define ck_read(fd, buf, len, fn) do { \\\n    u32 _len = (len); \\\n    s32 _res = read(fd, buf, _len); \\\n    if (_res != _len) RPFATAL(_res, \"Short read from %s\", fn); \\\n  } while (0)\n\n#endif /* ! _HAVE_DEBUG_H */\n"
  },
  {
    "path": "afl_progs/hash.h",
    "content": "/*\n   american fuzzy lop - hashing function\n   -------------------------------------\n\n   The hash32() function is a variant of MurmurHash3, a good\n   non-cryptosafe hashing function developed by Austin Appleby.\n\n   For simplicity, this variant does *NOT* accept buffer lengths\n   that are not divisible by 8 bytes. The 32-bit version is otherwise\n   similar to the original; the 64-bit one is a custom hack with\n   mostly-unproven properties.\n\n   Austin's original code is public domain.\n\n   Other code written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2016 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n */\n\n#ifndef _HAVE_HASH_H\n#define _HAVE_HASH_H\n\n#include \"types.h\"\n\n#ifdef __x86_64__\n\n#define ROL64(_x, _r)  ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r))))\n\nstatic inline u32 hash32(const void* key, u32 len, u32 seed) {\n\n  const u64* data = (u64*)key;\n  u64 h1 = seed ^ len;\n\n  len >>= 3;\n\n  while (len--) {\n\n    u64 k1 = *data++;\n\n    k1 *= 0x87c37b91114253d5ULL;\n    k1  = ROL64(k1, 31);\n    k1 *= 0x4cf5ad432745937fULL;\n\n    h1 ^= k1;\n    h1  = ROL64(h1, 27);\n    h1  = h1 * 5 + 0x52dce729;\n\n  }\n\n  h1 ^= h1 >> 33;\n  h1 *= 0xff51afd7ed558ccdULL;\n  h1 ^= h1 >> 33;\n  h1 *= 0xc4ceb9fe1a85ec53ULL;\n  h1 ^= h1 >> 33;\n\n  return h1;\n\n}\n\n#else \n\n#define ROL32(_x, _r)  ((((u32)(_x)) << (_r)) | (((u32)(_x)) >> (32 - (_r))))\n\nstatic inline u32 hash32(const void* key, u32 len, u32 seed) {\n\n  const u32* data  = (u32*)key;\n  u32 h1 = seed ^ len;\n\n  len >>= 2;\n\n  while (len--) {\n\n    u32 k1 = *data++;\n\n    k1 *= 0xcc9e2d51;\n    k1  = ROL32(k1, 15);\n    k1 *= 0x1b873593;\n\n    h1 ^= k1;\n    h1  = ROL32(h1, 13);\n    h1  = h1 * 5 + 0xe6546b64;\n\n  }\n\n  h1 ^= h1 >> 16;\n  h1 *= 0x85ebca6b;\n  h1 ^= h1 >> 13;\n  h1 *= 0xc2b2ae35;\n  h1 ^= h1 >> 16;\n\n  return h1;\n\n}\n\n#endif /* ^__x86_64__ */\n\n#endif /* !_HAVE_HASH_H */\n"
  },
  {
    "path": "afl_progs/llvm_mode/Makefile",
    "content": "#\n# american fuzzy lop - LLVM instrumentation\n# -----------------------------------------\n#\n# Written by Laszlo Szekeres <lszekeres@google.com> and\n#            Michal Zalewski <lcamtuf@google.com>\n#\n# LLVM integration design comes from Laszlo Szekeres.\n#\n# Copyright 2015, 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at:\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n\nPREFIX      ?= /usr/local\nHELPER_PATH  = $(PREFIX)/lib/afl\nBIN_PATH     = $(PREFIX)/bin\n\nVERSION     = $(shell grep '^\\#define VERSION ' ../config.h | cut -d '\"' -f2)\n\nLLVM_CONFIG ?= llvm-config\n\nCFLAGS      ?= -O3 -funroll-loops\nCFLAGS      += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \\\n               -DAFL_PATH=\\\"$(HELPER_PATH)\\\" -DBIN_PATH=\\\"$(BIN_PATH)\\\" \\\n               -DVERSION=\\\"$(VERSION)\\\" \nifdef AFL_TRACE_PC\n  CFLAGS    += -DUSE_TRACE_PC=1\nendif\n\nCXXFLAGS    ?= -O3 -funroll-loops\nCXXFLAGS    += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \\\n               -DVERSION=\\\"$(VERSION)\\\" -Wno-variadic-macros\n\nCLANG_CFL    = `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fpic $(CXXFLAGS)\nCLANG_LFL    = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)\n\n# User teor2345 reports that this is required to make things work on MacOS X.\n\nifeq \"$(shell uname)\" \"Darwin\"\n  CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress\nendif\n\n# We were using llvm-config --bindir to get the location of clang, but\n# this seems to be busted on some distros, so using the one in $PATH is\n# probably better.\n\nifeq \"$(origin CC)\" \"default\"\n  CC         = clang\n  CXX        = clang++\nendif\n\nifndef AFL_TRACE_PC\n  PROGS      = ../afl-clang-fast ../afl-llvm-pass.so ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o\nelse\n  PROGS      = ../afl-clang-fast ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o\nendif\n\nall: test_deps $(PROGS) test_build all_done\n\ntest_deps:\nifndef AFL_TRACE_PC\n\t@echo \"[*] Checking for working 'llvm-config'...\"\n\t@which $(LLVM_CONFIG) >/dev/null 2>&1 || ( echo \"[-] Oops, can't find 'llvm-config'. Install clang or set \\$$LLVM_CONFIG or \\$$PATH beforehand.\"; echo \"    (Sometimes, the binary will be named llvm-config-3.5 or something like that.)\"; exit 1 )\nelse\n\t@echo \"[!] Note: using -fsanitize=trace-pc mode (this will fail with older LLVM).\"\nendif\n\t@echo \"[*] Checking for working '$(CC)'...\"\n\t@which $(CC) >/dev/null 2>&1 || ( echo \"[-] Oops, can't find '$(CC)'. Make sure that it's in your \\$$PATH (or set \\$$CC and \\$$CXX).\"; exit 1 )\n\t@echo \"[*] Checking for '../afl-showmap'...\"\n\t@test -f ../afl-showmap || ( echo \"[-] Oops, can't find '../afl-showmap'. Be sure to compile AFL first.\"; exit 1 )\n\t@echo \"[+] All set and ready to build.\"\n\n../afl-clang-fast: afl-clang-fast.c | test_deps\n\t$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)\n\tln -sf afl-clang-fast ../afl-clang-fast++\n\n../afl-llvm-pass.so: afl-llvm-pass.so.cc | test_deps\n\t$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)\n\n../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps\n\t$(CC) $(CFLAGS) -fPIC -c $< -o $@\n\n../afl-llvm-rt-32.o: afl-llvm-rt.o.c | test_deps\n\t@printf \"[*] Building 32-bit variant of the runtime (-m32)... \"\n\t@$(CC) $(CFLAGS) -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ \"$$?\" = \"0\" ]; then echo \"success!\"; else echo \"failed (that's fine)\"; fi\n\n../afl-llvm-rt-64.o: afl-llvm-rt.o.c | test_deps\n\t@printf \"[*] Building 64-bit variant of the runtime (-m64)... \"\n\t@$(CC) $(CFLAGS) -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ \"$$?\" = \"0\" ]; then echo \"success!\"; else echo \"failed (that's fine)\"; fi\n\ntest_build: $(PROGS)\n\t@echo \"[*] Testing the CC wrapper and instrumentation output...\"\n\tunset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO; AFL_QUIET=1 AFL_PATH=. AFL_CC=$(CC) ../afl-clang-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS)\n\techo 0 | ../afl-showmap -m none -q -o .test-instr0 ./test-instr\n\techo 1 | ../afl-showmap -m none -q -o .test-instr1 ./test-instr\n\t@rm -f test-instr\n\t@cmp -s .test-instr0 .test-instr1; DR=\"$$?\"; rm -f .test-instr0 .test-instr1; if [ \"$$DR\" = \"0\" ]; then echo; echo \"Oops, the instrumentation does not seem to be behaving correctly!\"; echo; echo \"Please ping <lcamtuf@google.com> to troubleshoot the issue.\"; echo; exit 1; fi\n\t@echo \"[+] All right, the instrumentation seems to be working!\"\n\nall_done: test_build\n\t@echo \"[+] All done! You can now use '../afl-clang-fast' to compile programs.\"\n\n.NOTPARALLEL: clean\n\nclean:\n\trm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 \n\trm -f $(PROGS) ../afl-clang-fast++\n"
  },
  {
    "path": "afl_progs/llvm_mode/README.llvm",
    "content": "============================================\nFast LLVM-based instrumentation for afl-fuzz\n============================================\n\n1) Introduction\n---------------\n\nThe code in this directory allows you to instrument programs for AFL using\ntrue compiler-level instrumentation, instead of the more crude\nassembly-level rewriting approach taken by afl-gcc and afl-clang. This has\nseveral interesting properties:\n\n  - The compiler can make many optimizations that are hard to pull off when\n    manually inserting assembly. As a result, some slow, CPU-bound programs will\n    run up to around 2x faster.\n\n    The gains are less pronounced for fast binaries, where the speed is limited\n    chiefly by the cost of creating new processes. In such cases, the gain will\n    probably stay within 10%.\n\n  - The instrumentation is CPU-independent. At least in principle, you should\n    be able to rely on it to fuzz programs on non-x86 architectures (after\n    building afl-fuzz with AFL_NO_X86=1).\n\n  - The instrumentation can cope a bit better with multi-threaded targets.\n\n  - Because the feature relies on the internals of LLVM, it is clang-specific\n    and will *not* work with GCC.\n\nOnce this implementation is shown to be sufficiently robust and portable, it\nwill probably replace afl-clang. For now, it can be built separately and\nco-exists with the original code.\n\nThe idea and much of the implementation comes from Laszlo Szekeres.\n\n2) How to use\n-------------\n\nIn order to leverage this mechanism, you need to have clang installed on your\nsystem. You should also make sure that the llvm-config tool is in your path\n(or pointed to via LLVM_CONFIG in the environment).\n\nUnfortunately, some systems that do have clang come without llvm-config or the\nLLVM development headers; one example of this is FreeBSD. FreeBSD users will\nalso run into problems with clang being built statically and not being able to\nload modules (you'll see \"Service unavailable\" when loading afl-llvm-pass.so).\n\nTo solve all your problems, you can grab pre-built binaries for your OS from:\n\n  http://llvm.org/releases/download.html\n\n...and then put the bin/ directory from the tarball at the beginning of your\n$PATH when compiling the feature and building packages later on. You don't need\nto be root for that.\n\nTo build the instrumentation itself, type 'make'. This will generate binaries\ncalled afl-clang-fast and afl-clang-fast++ in the parent directory. Once this\nis done, you can instrument third-party code in a way similar to the standard\noperating mode of AFL, e.g.:\n\n  CC=/path/to/afl/afl-clang-fast ./configure [...options...]\n  make\n\nBe sure to also include CXX set to afl-clang-fast++ for C++ code.\n\nThe tool honors roughly the same environmental variables as afl-gcc (see\n../docs/env_variables.txt). This includes AFL_INST_RATIO, AFL_USE_ASAN,\nAFL_HARDEN, and AFL_DONT_OPTIMIZE.\n\nNote: if you want the LLVM helper to be installed on your system for all\nusers, you need to build it before issuing 'make install' in the parent\ndirectory.\n\n3) Gotchas, feedback, bugs\n--------------------------\n\nThis is an early-stage mechanism, so field reports are welcome. You can send bug\nreports to <afl-users@googlegroups.com>.\n\n4) Bonus feature #1: deferred instrumentation\n---------------------------------------------\n\nAFL tries to optimize performance by executing the targeted binary just once,\nstopping it just before main(), and then cloning this \"master\" process to get\na steady supply of targets to fuzz.\n\nAlthough this approach eliminates much of the OS-, linker- and libc-level\ncosts of executing the program, it does not always help with binaries that\nperform other time-consuming initialization steps - say, parsing a large config\nfile before getting to the fuzzed data.\n\nIn such cases, it's beneficial to initialize the forkserver a bit later, once\nmost of the initialization work is already done, but before the binary attempts\nto read the fuzzed input and parse it; in some cases, this can offer a 10x+\nperformance gain. You can implement delayed initialization in LLVM mode in a\nfairly simple way.\n\nFirst, find a suitable location in the code where the delayed cloning can \ntake place. This needs to be done with *extreme* care to avoid breaking the\nbinary. In particular, the program will probably malfunction if you select\na location after:\n\n  - The creation of any vital threads or child processes - since the forkserver\n    can't clone them easily.\n\n  - The initialization of timers via setitimer() or equivalent calls.\n\n  - The creation of temporary files, network sockets, offset-sensitive file\n    descriptors, and similar shared-state resources - but only provided that\n    their state meaningfully influences the behavior of the program later on.\n\n  - Any access to the fuzzed input, including reading the metadata about its\n    size.\n\nWith the location selected, add this code in the appropriate spot:\n\n#ifdef __AFL_HAVE_MANUAL_CONTROL\n  __AFL_INIT();\n#endif\n\nYou don't need the #ifdef guards, but including them ensures that the program\nwill keep working normally when compiled with a tool other than afl-clang-fast.\n\nFinally, recompile the program with afl-clang-fast (afl-gcc or afl-clang will\n*not* generate a deferred-initialization binary) - and you should be all set!\n\n5) Bonus feature #2: persistent mode\n------------------------------------\n\nSome libraries provide APIs that are stateless, or whose state can be reset in\nbetween processing different input files. When such a reset is performed, a\nsingle long-lived process can be reused to try out multiple test cases,\neliminating the need for repeated fork() calls and the associated OS overhead.\n\nThe basic structure of the program that does this would be:\n\n  while (__AFL_LOOP()) {\n\n    /* Read input data. */\n    /* Call library code to be fuzzed. */\n    /* Reset state. */\n\n  }\n\n  /* Exit normally */\n\nThe numerical value specified within the loop controls the maximum number\nof iterations before AFL will restart the process from scratch. This minimizes\nthe impact of memory leaks and similar glitches; 1000 is a good starting point,\nand going much higher increases the likelihood of hiccups without giving you\nany real performance benefits.\n\nA more detailed template is shown in ../experimental/persistent_demo/.\nSimilarly to the previous mode, the feature works only with afl-clang-fast;\n#ifdef guards can be used to suppress it when using other compilers.\n\nNote that as with the previous mode, the feature is easy to misuse; if you\ndo not fully reset the critical state, you may end up with false positives or\nwaste a whole lot of CPU power doing nothing useful at all. Be particularly\nwary of memory leaks and of the state of file descriptors.\n\nPS. Because there are task switches still involved, the mode isn't as fast as\n\"pure\" in-process fuzzing offered, say, by LLVM's LibFuzzer; but it is a lot\nfaster than the normal fork() model, and compared to in-process fuzzing,\nshould be a lot more robust.\n\n6) Bonus feature #3: new 'trace-pc-guard' mode\n----------------------------------------------\n\nRecent versions of LLVM are shipping with a built-in execution tracing feature\nthat provides AFL with the necessary tracing data without the need to\npost-process the assembly or install any compiler plugins. See:\n\n  http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards\n\nAs of this writing, the feature is only available on SVN trunk, and is yet to\nmake it to an official release of LLVM. Nevertheless, if you have a\nsufficiently recent compiler and want to give it a try, build afl-clang-fast\nthis way:\n\n  AFL_TRACE_PC=1 make clean all\n\nNote that this mode is currently about 20% slower than \"vanilla\" afl-clang-fast,\nand about 5-10% slower than afl-clang. This is likely because the\ninstrumentation is not inlined, and instead involves a function call. On systems\nthat support it, compiling your target with -flto should help.\n\n\n"
  },
  {
    "path": "afl_progs/llvm_mode/afl-clang-fast.c",
    "content": "/*\n   american fuzzy lop - LLVM-mode wrapper for clang\n   ------------------------------------------------\n\n   Written by Laszlo Szekeres <lszekeres@google.com> and\n              Michal Zalewski <lcamtuf@google.com>\n\n   LLVM integration design comes from Laszlo Szekeres.\n\n   Copyright 2015, 2016 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This program is a drop-in replacement for clang, similar in most respects\n   to ../afl-gcc. It tries to figure out compilation mode, adds a bunch\n   of flags, and then calls the real compiler.\n\n */\n\n#define AFL_MAIN\n\n#include \"../config.h\"\n#include \"../types.h\"\n#include \"../debug.h\"\n#include \"../alloc-inl.h\"\n\n#include <stdio.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <string.h>\n\nstatic u8*  obj_path;               /* Path to runtime libraries         */\nstatic u8** cc_params;              /* Parameters passed to the real CC  */\nstatic u32  cc_par_cnt = 1;         /* Param count, including argv0      */\n\n\n/* Try to find the runtime libraries. If that fails, abort. */\n\nstatic void find_obj(u8* argv0) {\n\n  u8 *afl_path = getenv(\"AFL_PATH\");\n  u8 *slash, *tmp;\n\n  if (afl_path) {\n\n    tmp = alloc_printf(\"%s/afl-llvm-rt.o\", afl_path);\n\n    if (!access(tmp, R_OK)) {\n      obj_path = afl_path;\n      ck_free(tmp);\n      return;\n    }\n\n    ck_free(tmp);\n\n  }\n\n  slash = strrchr(argv0, '/');\n\n  if (slash) {\n\n    u8 *dir;\n\n    *slash = 0;\n    dir = ck_strdup(argv0);\n    *slash = '/';\n\n    tmp = alloc_printf(\"%s/afl-llvm-rt.o\", dir);\n\n    if (!access(tmp, R_OK)) {\n      obj_path = dir;\n      ck_free(tmp);\n      return;\n    }\n\n    ck_free(tmp);\n    ck_free(dir);\n\n  }\n\n  if (!access(AFL_PATH \"/afl-llvm-rt.o\", R_OK)) {\n    obj_path = AFL_PATH;\n    return;\n  }\n\n  FATAL(\"Unable to find 'afl-llvm-rt.o' or 'afl-llvm-pass.so'. Please set AFL_PATH\");\n \n}\n\n\n/* Copy argv to cc_params, making the necessary edits. */\n\nstatic void edit_params(u32 argc, char** argv) {\n\n  u8 fortify_set = 0, asan_set = 0, x_set = 0, maybe_linking = 1, bit_mode = 0;\n  u8 *name;\n\n  cc_params = ck_alloc((argc + 128) * sizeof(u8*));\n\n  name = strrchr(argv[0], '/');\n  if (!name) name = argv[0]; else name++;\n\n  if (!strcmp(name, \"afl-clang-fast++\")) {\n    u8* alt_cxx = getenv(\"AFL_CXX\");\n    cc_params[0] = alt_cxx ? alt_cxx : (u8*)\"clang++\";\n  } else {\n    u8* alt_cc = getenv(\"AFL_CC\");\n    cc_params[0] = alt_cc ? alt_cc : (u8*)\"clang\";\n  }\n\n  /* There are two ways to compile afl-clang-fast. In the traditional mode, we\n     use afl-llvm-pass.so to inject instrumentation. In the experimental\n     'trace-pc-guard' mode, we use native LLVM instrumentation callbacks\n     instead. The latter is a very recent addition - see:\n\n     http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards */\n\n#ifdef USE_TRACE_PC\n  cc_params[cc_par_cnt++] = \"-fsanitize-coverage=trace-pc-guard\";\n  cc_params[cc_par_cnt++] = \"-mllvm\";\n  cc_params[cc_par_cnt++] = \"-sanitizer-coverage-block-threshold=0\";\n#else\n  cc_params[cc_par_cnt++] = \"-Xclang\";\n  cc_params[cc_par_cnt++] = \"-load\";\n  cc_params[cc_par_cnt++] = \"-Xclang\";\n  cc_params[cc_par_cnt++] = alloc_printf(\"%s/afl-llvm-pass.so\", obj_path);\n#endif /* ^USE_TRACE_PC */\n\n  cc_params[cc_par_cnt++] = \"-Qunused-arguments\";\n\n  /* Detect stray -v calls from ./configure scripts. */\n\n  if (argc == 1 && !strcmp(argv[1], \"-v\")) maybe_linking = 0;\n\n  while (--argc) {\n    u8* cur = *(++argv);\n\n    if (!strcmp(cur, \"-m32\")) bit_mode = 32;\n    if (!strcmp(cur, \"-m64\")) bit_mode = 64;\n\n    if (!strcmp(cur, \"-x\")) x_set = 1;\n\n    if (!strcmp(cur, \"-c\") || !strcmp(cur, \"-S\") || !strcmp(cur, \"-E\"))\n      maybe_linking = 0;\n\n    if (!strcmp(cur, \"-fsanitize=address\") ||\n        !strcmp(cur, \"-fsanitize=memory\")) asan_set = 1;\n\n    if (strstr(cur, \"FORTIFY_SOURCE\")) fortify_set = 1;\n\n    if (!strcmp(cur, \"-shared\")) maybe_linking = 0;\n\n    if (!strcmp(cur, \"-Wl,-z,defs\") ||\n        !strcmp(cur, \"-Wl,--no-undefined\")) continue;\n\n    cc_params[cc_par_cnt++] = cur;\n\n  }\n\n  if (getenv(\"AFL_HARDEN\")) {\n\n    cc_params[cc_par_cnt++] = \"-fstack-protector-all\";\n\n    if (!fortify_set)\n      cc_params[cc_par_cnt++] = \"-D_FORTIFY_SOURCE=2\";\n\n  }\n\n  if (!asan_set) {\n\n    if (getenv(\"AFL_USE_ASAN\")) {\n\n      if (getenv(\"AFL_USE_MSAN\"))\n        FATAL(\"ASAN and MSAN are mutually exclusive\");\n\n      if (getenv(\"AFL_HARDEN\"))\n        FATAL(\"ASAN and AFL_HARDEN are mutually exclusive\");\n\n      cc_params[cc_par_cnt++] = \"-U_FORTIFY_SOURCE\";\n      cc_params[cc_par_cnt++] = \"-fsanitize=address\";\n\n    } else if (getenv(\"AFL_USE_MSAN\")) {\n\n      if (getenv(\"AFL_USE_ASAN\"))\n        FATAL(\"ASAN and MSAN are mutually exclusive\");\n\n      if (getenv(\"AFL_HARDEN\"))\n        FATAL(\"MSAN and AFL_HARDEN are mutually exclusive\");\n\n      cc_params[cc_par_cnt++] = \"-U_FORTIFY_SOURCE\";\n      cc_params[cc_par_cnt++] = \"-fsanitize=memory\";\n\n    }\n\n  }\n\n#ifdef USE_TRACE_PC\n\n  if (getenv(\"AFL_INST_RATIO\"))\n    FATAL(\"AFL_INST_RATIO not available at compile time with 'trace-pc'.\");\n\n#endif /* USE_TRACE_PC */\n\n  if (!getenv(\"AFL_DONT_OPTIMIZE\")) {\n\n    cc_params[cc_par_cnt++] = \"-g\";\n    cc_params[cc_par_cnt++] = \"-O3\";\n    cc_params[cc_par_cnt++] = \"-funroll-loops\";\n\n  }\n\n  if (getenv(\"AFL_NO_BUILTIN\")) {\n\n    cc_params[cc_par_cnt++] = \"-fno-builtin-strcmp\";\n    cc_params[cc_par_cnt++] = \"-fno-builtin-strncmp\";\n    cc_params[cc_par_cnt++] = \"-fno-builtin-strcasecmp\";\n    cc_params[cc_par_cnt++] = \"-fno-builtin-strncasecmp\";\n    cc_params[cc_par_cnt++] = \"-fno-builtin-memcmp\";\n\n  }\n\n  cc_params[cc_par_cnt++] = \"-D__AFL_HAVE_MANUAL_CONTROL=1\";\n  cc_params[cc_par_cnt++] = \"-D__AFL_COMPILER=1\";\n  cc_params[cc_par_cnt++] = \"-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1\";\n\n  /* When the user tries to use persistent or deferred forkserver modes by\n     appending a single line to the program, we want to reliably inject a\n     signature into the binary (to be picked up by afl-fuzz) and we want\n     to call a function from the runtime .o file. This is unnecessarily\n     painful for three reasons:\n\n     1) We need to convince the compiler not to optimize out the signature.\n        This is done with __attribute__((used)).\n\n     2) We need to convince the linker, when called with -Wl,--gc-sections,\n        not to do the same. This is done by forcing an assignment to a\n        'volatile' pointer.\n\n     3) We need to declare __afl_persistent_loop() in the global namespace,\n        but doing this within a method in a class is hard - :: and extern \"C\"\n        are forbidden and __attribute__((alias(...))) doesn't work. Hence the\n        __asm__ aliasing trick.\n\n   */\n\n  cc_params[cc_par_cnt++] = \"-D__AFL_LOOP()=\"\n    \"({ static volatile char *_B __attribute__((used)); \"\n    \" _B = (char*)\\\"\" PERSIST_SIG \"\\\"; \"\n#ifdef __APPLE__\n    \"__attribute__((visibility(\\\"default\\\"))) \"\n    \"int _L(void) __asm__(\\\"___afl_persistent_loop\\\"); \"\n#else\n    \"__attribute__((visibility(\\\"default\\\"))) \"\n    \"int _L(void) __asm__(\\\"__afl_persistent_loop\\\"); \"\n#endif /* ^__APPLE__ */\n    \"_L(); })\";\n\n  cc_params[cc_par_cnt++] = \"-D__AFL_INIT()=\"\n    \"do { static volatile char *_A __attribute__((used)); \"\n    \" _A = (char*)\\\"\" DEFER_SIG \"\\\"; \"\n#ifdef __APPLE__\n    \"__attribute__((visibility(\\\"default\\\"))) \"\n    \"void _I(void) __asm__(\\\"___afl_manual_init\\\"); \"\n#else\n    \"__attribute__((visibility(\\\"default\\\"))) \"\n    \"void _I(void) __asm__(\\\"__afl_manual_init\\\"); \"\n#endif /* ^__APPLE__ */\n    \"_I(); } while (0)\";\n\n  if (maybe_linking) {\n\n    if (x_set) {\n      cc_params[cc_par_cnt++] = \"-x\";\n      cc_params[cc_par_cnt++] = \"none\";\n    }\n\n    switch (bit_mode) {\n\n      case 0:\n        cc_params[cc_par_cnt++] = alloc_printf(\"%s/afl-llvm-rt.o\", obj_path);\n        break;\n\n      case 32:\n        cc_params[cc_par_cnt++] = alloc_printf(\"%s/afl-llvm-rt-32.o\", obj_path);\n\n        if (access(cc_params[cc_par_cnt - 1], R_OK))\n          FATAL(\"-m32 is not supported by your compiler\");\n\n        break;\n\n      case 64:\n        cc_params[cc_par_cnt++] = alloc_printf(\"%s/afl-llvm-rt-64.o\", obj_path);\n\n        if (access(cc_params[cc_par_cnt - 1], R_OK))\n          FATAL(\"-m64 is not supported by your compiler\");\n\n        break;\n\n    }\n\n  }\n\n  cc_params[cc_par_cnt] = NULL;\n\n}\n\n\n/* Main entry point */\n\nint main(int argc, char** argv) {\n\n  if (isatty(2) && !getenv(\"AFL_QUIET\")) {\n\n#ifdef USE_TRACE_PC\n    SAYF(cCYA \"afl-clang-fast [tpcg] \" cBRI VERSION  cRST \" by <lszekeres@google.com>\\n\");\n#else\n    SAYF(cCYA \"afl-clang-fast \" cBRI VERSION  cRST \" by <lszekeres@google.com>\\n\");\n#endif /* ^USE_TRACE_PC */\n\n  }\n\n  if (argc < 2) {\n\n    SAYF(\"\\n\"\n         \"This is a helper application for afl-fuzz. It serves as a drop-in replacement\\n\"\n         \"for clang, letting you recompile third-party code with the required runtime\\n\"\n         \"instrumentation. A common use pattern would be one of the following:\\n\\n\"\n\n         \"  CC=%s/afl-clang-fast ./configure\\n\"\n         \"  CXX=%s/afl-clang-fast++ ./configure\\n\\n\"\n\n         \"In contrast to the traditional afl-clang tool, this version is implemented as\\n\"\n         \"an LLVM pass and tends to offer improved performance with slow programs.\\n\\n\"\n\n         \"You can specify custom next-stage toolchain via AFL_CC and AFL_CXX. Setting\\n\"\n         \"AFL_HARDEN enables hardening optimizations in the compiled code.\\n\\n\",\n         BIN_PATH, BIN_PATH);\n\n    exit(1);\n\n  }\n\n\n  find_obj(argv[0]);\n\n  edit_params(argc, argv);\n\n  execvp(cc_params[0], (char**)cc_params);\n\n  FATAL(\"Oops, failed to execute '%s' - check your PATH\", cc_params[0]);\n\n  return 0;\n\n}\n"
  },
  {
    "path": "afl_progs/llvm_mode/afl-llvm-pass.so.cc",
    "content": "/*\n   american fuzzy lop - LLVM-mode instrumentation pass\n   ---------------------------------------------------\n\n   Written by Laszlo Szekeres <lszekeres@google.com> and\n              Michal Zalewski <lcamtuf@google.com>\n\n   LLVM integration design comes from Laszlo Szekeres. C bits copied-and-pasted\n   from afl-as.c are Michal's fault.\n\n   Copyright 2015, 2016 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This library is plugged into LLVM when invoking clang through afl-clang-fast.\n   It tells the compiler to add code roughly equivalent to the bits discussed\n   in ../afl-as.h.\n\n */\n\n#define AFL_LLVM_PASS\n\n#include \"../config.h\"\n#include \"../debug.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include \"llvm/ADT/Statistic.h\"\n#include \"llvm/IR/IRBuilder.h\"\n#include \"llvm/IR/LegacyPassManager.h\"\n#include \"llvm/IR/Module.h\"\n#include \"llvm/Support/Debug.h\"\n#include \"llvm/Transforms/IPO/PassManagerBuilder.h\"\n\nusing namespace llvm;\n\nnamespace {\n\n  class AFLCoverage : public ModulePass {\n\n    public:\n\n      static char ID;\n      AFLCoverage() : ModulePass(ID) { }\n\n      bool runOnModule(Module &M) override;\n\n      // StringRef getPassName() const override {\n      //  return \"American Fuzzy Lop Instrumentation\";\n      // }\n\n  };\n\n}\n\n\nchar AFLCoverage::ID = 0;\n\n\nbool AFLCoverage::runOnModule(Module &M) {\n\n  LLVMContext &C = M.getContext();\n\n  IntegerType *Int8Ty  = IntegerType::getInt8Ty(C);\n  IntegerType *Int32Ty = IntegerType::getInt32Ty(C);\n\n  /* Show a banner */\n\n  char be_quiet = 0;\n\n  if (isatty(2) && !getenv(\"AFL_QUIET\")) {\n\n    SAYF(cCYA \"afl-llvm-pass \" cBRI VERSION cRST \" by <lszekeres@google.com>\\n\");\n\n  } else be_quiet = 1;\n\n  /* Decide instrumentation ratio */\n\n  char* inst_ratio_str = getenv(\"AFL_INST_RATIO\");\n  unsigned int inst_ratio = 100;\n\n  if (inst_ratio_str) {\n\n    if (sscanf(inst_ratio_str, \"%u\", &inst_ratio) != 1 || !inst_ratio ||\n        inst_ratio > 100)\n      FATAL(\"Bad value of AFL_INST_RATIO (must be between 1 and 100)\");\n\n  }\n\n  /* Get globals for the SHM region and the previous location. Note that\n     __afl_prev_loc is thread-local. */\n\n  GlobalVariable *AFLMapPtr =\n      new GlobalVariable(M, PointerType::get(Int8Ty, 0), false,\n                         GlobalValue::ExternalLinkage, 0, \"__afl_area_ptr\");\n\n  GlobalVariable *AFLPrevLoc = new GlobalVariable(\n      M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, \"__afl_prev_loc\",\n      0, GlobalVariable::GeneralDynamicTLSModel, 0, false);\n\n  /* Instrument all the things! */\n\n  int inst_blocks = 0;\n\n  for (auto &F : M)\n    for (auto &BB : F) {\n\n      BasicBlock::iterator IP = BB.getFirstInsertionPt();\n      IRBuilder<> IRB(&(*IP));\n\n      if (AFL_R(100) >= inst_ratio) continue;\n\n      /* Make up cur_loc */\n\n      unsigned int cur_loc = AFL_R(MAP_SIZE);\n\n      ConstantInt *CurLoc = ConstantInt::get(Int32Ty, cur_loc);\n\n      /* Load prev_loc */\n\n      LoadInst *PrevLoc = IRB.CreateLoad(AFLPrevLoc);\n      PrevLoc->setMetadata(M.getMDKindID(\"nosanitize\"), MDNode::get(C, None));\n      Value *PrevLocCasted = IRB.CreateZExt(PrevLoc, IRB.getInt32Ty());\n\n      /* Load SHM pointer */\n\n      LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);\n      MapPtr->setMetadata(M.getMDKindID(\"nosanitize\"), MDNode::get(C, None));\n      Value *MapPtrIdx =\n          IRB.CreateGEP(MapPtr, IRB.CreateXor(PrevLocCasted, CurLoc));\n\n      /* Update bitmap */\n\n      LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);\n      Counter->setMetadata(M.getMDKindID(\"nosanitize\"), MDNode::get(C, None));\n      Value *Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1));\n      IRB.CreateStore(Incr, MapPtrIdx)\n          ->setMetadata(M.getMDKindID(\"nosanitize\"), MDNode::get(C, None));\n\n      /* Set prev_loc to cur_loc >> 1 */\n\n      StoreInst *Store =\n          IRB.CreateStore(ConstantInt::get(Int32Ty, cur_loc >> 1), AFLPrevLoc);\n      Store->setMetadata(M.getMDKindID(\"nosanitize\"), MDNode::get(C, None));\n\n      inst_blocks++;\n\n    }\n\n  /* Say something nice. */\n\n  if (!be_quiet) {\n\n    if (!inst_blocks) WARNF(\"No instrumentation targets found.\");\n    else OKF(\"Instrumented %u locations (%s mode, ratio %u%%).\",\n             inst_blocks, getenv(\"AFL_HARDEN\") ? \"hardened\" :\n             ((getenv(\"AFL_USE_ASAN\") || getenv(\"AFL_USE_MSAN\")) ?\n              \"ASAN/MSAN\" : \"non-hardened\"), inst_ratio);\n\n  }\n\n  return true;\n\n}\n\n\nstatic void registerAFLPass(const PassManagerBuilder &,\n                            legacy::PassManagerBase &PM) {\n\n  PM.add(new AFLCoverage());\n\n}\n\n\nstatic RegisterStandardPasses RegisterAFLPass(\n    PassManagerBuilder::EP_OptimizerLast, registerAFLPass);\n\nstatic RegisterStandardPasses RegisterAFLPass0(\n    PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLPass);\n"
  },
  {
    "path": "afl_progs/llvm_mode/afl-llvm-rt.o.c",
    "content": "/*\n   american fuzzy lop - LLVM instrumentation bootstrap\n   ---------------------------------------------------\n\n   Written by Laszlo Szekeres <lszekeres@google.com> and\n              Michal Zalewski <lcamtuf@google.com>\n\n   LLVM integration design comes from Laszlo Szekeres.\n\n   Copyright 2015, 2016 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This code is the rewrite of afl-as.h's main_payload.\n\n*/\n\n/*\n\tThis file has been modified from the original AFL version to incorporate into\n\tKillerbeez.  Specifically, the fork server has been modified to match the\n  Killerbeez fork server protocol.\n */\n\n#include \"../config.h\"\n#include \"../types.h\"\n\n#include \"../../instrumentation/forkserver_internal.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <signal.h>\n#include <unistd.h>\n#include <string.h>\n#include <assert.h>\n\n#include <sys/mman.h>\n#include <sys/shm.h>\n#include <sys/wait.h>\n#include <sys/types.h>\n\n/* This is a somewhat ugly hack for the experimental 'trace-pc-guard' mode.\n   Basically, we need to make sure that the forkserver is initialized after\n   the LLVM-generated runtime initialization pass, not before. */\n\n#ifdef USE_TRACE_PC\n#  define CONST_PRIO 5\n#else\n#  define CONST_PRIO 0\n#endif /* ^USE_TRACE_PC */\n\n\n/* Globals needed by the injected instrumentation. The __afl_area_initial region\n   is used for instrumentation output before __afl_map_shm() has a chance to run.\n   It will end up as .comm, so it shouldn't be too wasteful. */\n\nu8  __afl_area_initial[MAP_SIZE];\nu8* __afl_area_ptr = __afl_area_initial;\n\n__thread u32 __afl_prev_loc;\n\n\n/* Running in persistent mode? */\n\nstatic u8 is_persistent;\n\n\n/* SHM setup. */\n\nstatic void __afl_map_shm(void) {\n\n  u8 *id_str = getenv(SHM_ENV_VAR);\n\n  /* If we're running under AFL, attach to the appropriate region, replacing the\n     early-stage __afl_area_initial region that is needed to allow some really\n     hacky .init code to work correctly in projects such as OpenSSL. */\n\n  if (id_str) {\n\n    u32 shm_id = atoi(id_str);\n\n    __afl_area_ptr = shmat(shm_id, NULL, 0);\n\n    /* Whooooops. */\n    if (__afl_area_ptr == (void *)-1) _exit(1);\n\n  }\n\n}\n\n\n/* Fork server logic. */\n\nstatic void __afl_start_forkserver_persistence(void);\n\nstatic int max_cnt = 0;\nstatic int forkserver_cycle_cnt = 0;\nstatic int cycle_cnt = 0;\n\nstatic void __afl_start_forkserver(void) {\n\n  static int response = 0x41414141;\n  char command;\n  s32 child_pid;\n\n  /* Phone home and tell the parent that we're OK. If parent isn't there,\n     assume we're not running in forkserver mode and just execute program. */\n  if(write(FORKSRV_TO_FUZZER, &response, sizeof(int)) != sizeof(int))\n    return;\n\n  if(getenv(PERSIST_MAX_VAR)) {\n    __afl_start_forkserver_persistence();\n    return;\n  }\n\n  while (1) {\n    // Wait for parent by reading from the pipe. Exit if read fails.\n    if(read(FUZZER_TO_FORKSRV, &command, sizeof(command)) != sizeof(command))\n      _exit(1);\n\n    switch(command) {\n\n      case EXIT:\n      case RUN: //LLVM doesn't do the single RUN/FORK commands\n      case FORK: //but instead only implements FORK_RUN\n        _exit(0);\n        break;\n\n      case FORK_RUN:\n        child_pid = fork();\n        if(child_pid < 0)\n          _exit(1);\n\n        //In child process: close fds, resume execution.\n        if(!child_pid) {\n          close(FUZZER_TO_FORKSRV);\n          close(FORKSRV_TO_FUZZER);\n\n          //Reset the afl bitmap to a clean state\n          memset(__afl_area_ptr, 0, MAP_SIZE);\n          __afl_prev_loc = 0;\n          return;\n        }\n\n        response = child_pid;\n        break;\n\n      case GET_STATUS:\n        if(waitpid(child_pid, &response, 0) < 0)\n          _exit(1);\n        break;\n    }\n\n    if(write(FORKSRV_TO_FUZZER, &response, sizeof(int)) != sizeof(int))\n      _exit(1);\n  }\n}\n\nstatic void __afl_start_forkserver_persistence(void) {\n\n  int response = 0x41414141;\n  char command;\n  int child_pid = -1;\n\n  //Get the maximum number of persistent executions\n  max_cnt = atoi(getenv(PERSIST_MAX_VAR));\n  if(!max_cnt)\n    _exit(1);\n\n  while (1) {\n\n    // Wait for parent by reading from the pipe. Exit if read fails.\n    if(read(FUZZER_TO_FORKSRV, &command, sizeof(command)) != sizeof(command))\n      _exit(1);\n\n    switch(command) {\n\n      case FORK:\n      case RUN:\n      case EXIT:\n\n        if(child_pid != -1)\n          kill(child_pid, SIGKILL);\n        _exit(0);\n        break;\n\n      case FORK_RUN:\n\n        if(child_pid == -1 || forkserver_cycle_cnt == max_cnt) {\n          //If we need to (re)start the persistent child, do so\n\n          if(child_pid != -1 && forkserver_cycle_cnt == max_cnt) {\n            //if we've hit the maximum cycle count, continue the child, so it may exit\n            //and clean up.  We do this now, rather than in GET_STATUS commands, to ensure that\n            //the exit portion of the target process does not get traced.\n            kill(child_pid, SIGCONT);\n            if(waitpid(child_pid, &response, 0) < 0)\n              _exit(1);\n            forkserver_cycle_cnt = 0;\n          }\n\n          child_pid = fork();\n          if(child_pid < 0)\n            _exit(1);\n\n          //In child process: close fds, resume execution.\n          if(!child_pid) {\n            close(FUZZER_TO_FORKSRV);\n            close(FORKSRV_TO_FUZZER);\n            return;\n          }\n        } else {\n          //Otherwise, just tell it to continue\n          kill(child_pid, SIGCONT);\n        }\n\n        //Tell the target process to go\n        response = child_pid;\n        if(child_pid == -1) {\n          response = FORKSERVER_ERROR;\n          break;\n        }\n\n        forkserver_cycle_cnt++;\n        break;\n\n      case GET_STATUS:\n\n        if(waitpid(child_pid, &response, WUNTRACED) < 0)\n          _exit(1);\n\n        if(WIFEXITED(response) || WIFSIGNALED(response)) { //The process ended, either\n          child_pid = -1; //by hitting the max_cnt count and exiting, or by crashing\n          forkserver_cycle_cnt = 0;\n        }\n        else if(WIFSTOPPED(response)) //If we hit a SIGSTOP, then the child didn't\n          response = 0;               //die, just return 0 to the parent\n\n        break;\n    }\n\n    if(write(FORKSRV_TO_FUZZER, &response, sizeof(response)) != sizeof(response))\n      _exit(1);\n  }\n\n}\n\n/* A simplified persistent mode handler, used as explained in README.llvm. */\n\nint __afl_persistent_loop(void) {\n  static u8  first_pass = 1;\n\n  if (first_pass) {\n\n    if (is_persistent) {\n      memset(__afl_area_ptr, 0, MAP_SIZE);\n      __afl_prev_loc = 0;\n    }\n\n    cycle_cnt  = 0;\n    first_pass = 0;\n    return 1;\n  }\n\n  if (is_persistent) {\n\n    if(++cycle_cnt != max_cnt) {\n      raise(SIGSTOP);\n      memset(__afl_area_ptr, 0, MAP_SIZE);\n      __afl_prev_loc = 0;\n      return 1;\n\n    } else {\n\n      /* When exiting __AFL_LOOP(), make sure that the subsequent code that\n         follows the loop is not traced. We do that by pivoting back to the\n         dummy output region. */\n      __afl_area_ptr = __afl_area_initial;\n    }\n  }\n\n  return 0;\n}\n\n\n/* This one can be called from user code when deferred forkserver mode\n    is enabled. */\n\nvoid __afl_manual_init(void) {\n\n  static u8 init_done;\n\n  if (!init_done) {\n\n    __afl_map_shm();\n    __afl_start_forkserver();\n    init_done = 1;\n\n  }\n\n}\n\n\n/* Proper initialization routine. */\n\n__attribute__((constructor(CONST_PRIO))) void __afl_auto_init(void) {\n\n  is_persistent = !!getenv(PERSIST_MAX_VAR);\n\n  if (getenv(DEFER_ENV_VAR)) return;\n\n  __afl_manual_init();\n\n}\n\n\n/* The following stuff deals with supporting -fsanitize-coverage=trace-pc-guard.\n   It remains non-operational in the traditional, plugin-backed LLVM mode.\n   For more info about 'trace-pc-guard', see README.llvm.\n\n   The first function (__sanitizer_cov_trace_pc_guard) is called back on every\n   edge (as opposed to every basic block). */\n\nvoid __sanitizer_cov_trace_pc_guard(uint32_t* guard) {\n  __afl_area_ptr[*guard]++;\n}\n\n\n/* Init callback. Populates instrumentation IDs. Note that we're using\n   ID of 0 as a special value to indicate non-instrumented bits. That may\n   still touch the bitmap, but in a fairly harmless way. */\n\nvoid __sanitizer_cov_trace_pc_guard_init(uint32_t* start, uint32_t* stop) {\n\n  u32 inst_ratio = 100;\n  u8* x;\n\n  if (start == stop || *start) return;\n\n  x = getenv(\"AFL_INST_RATIO\");\n  if (x) inst_ratio = atoi(x);\n\n  if (!inst_ratio || inst_ratio > 100) {\n    fprintf(stderr, \"[-] ERROR: Invalid AFL_INST_RATIO (must be 1-100).\\n\");\n    abort();\n  }\n\n  /* Make sure that the first element in the range is always set - we use that\n     to avoid duplicate calls (which can happen as an artifact of the underlying\n     implementation in LLVM). */\n\n  *(start++) = R(MAP_SIZE - 1) + 1;\n\n  while (start < stop) {\n\n    if (R(100) < inst_ratio) *start = R(MAP_SIZE - 1) + 1;\n    else *start = 0;\n\n    start++;\n\n  }\n\n}\n"
  },
  {
    "path": "afl_progs/qemu_mode/README.qemu",
    "content": "\nThis directory contains the build script and patches for the QEMU-based\ninstrumentation. This instrumentation is copied from AFL with minor changes to\nfit into the killerbeez fork server framework (see\nhttp://lcamtuf.coredump.cx/afl/ for the original version).  Additionally this\nversion of the QEMU instrumentation has been patched with the following patches\nfrom vanhauser-thc's github repository (available at\nhttps://github.com/vanhauser-thc/afl-patches/):\n* afl-qemu-speed.diff\n* afl-qemu-ppc64.diff\n* afl_qemu_optimize_map.diff\n* afl_qemu_optimize_entrypoint.diff\n\nThe original AFL QEMU Readme is listed below:\n\n=========================================================\nHigh-performance binary-only instrumentation for afl-fuzz\n=========================================================\n\n  (See ../docs/README for the general instruction manual.)\n\n1) Introduction\n---------------\n\nThe code in this directory allows you to build a standalone feature that\nleverages the QEMU \"user emulation\" mode and allows callers to obtain\ninstrumentation output for black-box, closed-source binaries. This mechanism\ncan be then used by afl-fuzz to stress-test targets that couldn't be built\nwith afl-gcc.\n\nThe usual performance cost is 2-5x, which is considerably better than\nseen so far in experiments with tools such as DynamoRIO and PIN.\n\nThe idea and much of the implementation comes from Andrew Griffiths.\n\n2) How to use\n-------------\n\nThe feature is implemented with a fairly simple patch to QEMU 2.10.0. The\nsimplest way to build it is to run ./build_qemu_support.sh. The script will\ndownload, configure, and compile the QEMU binary for you.\n\nQEMU is a big project, so this will take a while, and you may have to\nresolve a couple of dependencies (most notably, you will definitely need\nlibtool and glib2-devel).\n\nOnce the binaries are compiled, you can leverage the QEMU tool by calling\nafl-fuzz and all the related utilities with -Q in the command line.\n\nNote that QEMU requires a generous memory limit to run; somewhere around\n200 MB is a good starting point, but considerably more may be needed for\nmore complex programs. The default -m limit will be automatically bumped up\nto 200 MB when specifying -Q to afl-fuzz; be careful when overriding this.\n\nIn principle, if you set CPU_TARGET before calling ./build_qemu_support.sh,\nyou should get a build capable of running non-native binaries (say, you\ncan try CPU_TARGET=arm). This is also necessary for running 32-bit binaries\non a 64-bit system (CPU_TARGET=i386).\n\nNote: if you want the QEMU helper to be installed on your system for all\nusers, you need to build it before issuing 'make install' in the parent\ndirectory.\n\n3) Notes on linking\n-------------------\n\nThe feature is supported only on Linux. Supporting BSD may amount to porting\nthe changes made to linux-user/elfload.c and applying them to\nbsd-user/elfload.c, but I have not looked into this yet.\n\nThe instrumentation follows only the .text section of the first ELF binary\nencountered in the linking process. It does not trace shared libraries. In\npractice, this means two things:\n\n  - Any libraries you want to analyze *must* be linked statically into the\n    executed ELF file (this will usually be the case for closed-source\n    apps).\n\n  - Standard C libraries and other stuff that is wasteful to instrument\n    should be linked dynamically - otherwise, AFL will have no way to avoid\n    peeking into them.\n\nSetting AFL_INST_LIBS=1 can be used to circumvent the .text detection logic\nand instrument every basic block encountered.\n\n4) Benchmarking\n---------------\n\nIf you want to compare the performance of the QEMU instrumentation with that of\nafl-gcc compiled code against the same target, you need to build the\nnon-instrumented binary with the same optimization flags that are normally\ninjected by afl-gcc, and make sure that the bits to be tested are statically\nlinked into the binary. A common way to do this would be:\n\n$ CFLAGS=\"-O3 -funroll-loops\" ./configure --disable-shared\n$ make clean all\n\nComparative measurements of execution speed or instrumentation coverage will be\nfairly meaningless if the optimization levels or instrumentation scopes don't\nmatch.\n\n5) Gotchas, feedback, bugs\n--------------------------\n\nIf you need to fix up checksums or do other cleanup on mutated test cases, see\nexperimental/post_library/ for a viable solution.\n\nDo not mix QEMU mode with ASAN, MSAN, or the likes; QEMU doesn't appreciate\nthe \"shadow VM\" trick employed by the sanitizers and will probably just\nrun out of memory.\n\nCompared to fully-fledged virtualization, the user emulation mode is *NOT* a\nsecurity boundary. The binaries can freely interact with the host OS. If you\nsomehow need to fuzz an untrusted binary, put everything in a sandbox first.\n\nQEMU does not necessarily support all CPU or hardware features that your\ntarget program may be utilizing. In particular, it does not appear to have\nfull support for AVX2 / FMA3. Using binaries for older CPUs, or recompiling them\nwith -march=core2, can help.\n\nBeyond that, this is an early-stage mechanism, so fields reports are welcome.\nYou can send them to <afl-users@googlegroups.com>.\n\n6) Alternatives: static rewriting\n---------------------------------\n\nStatically rewriting binaries just once, instead of attempting to translate\nthem at run time, can be a faster alternative. That said, static rewriting is\nfraught with peril, because it depends on being able to properly and fully model\nprogram control flow without actually executing each and every code path.\n\nIf you want to experiment with this mode of operation, there is a module\ncontributed by Aleksandar Nikolich:\n\n  https://github.com/vrtadmin/moflow/tree/master/afl-dyninst\n  https://groups.google.com/forum/#!topic/afl-users/HlSQdbOTlpg\n\nAt this point, the author reports the possibility of hiccups with stripped\nbinaries. That said, if we can get it to be comparably reliable to QEMU, we may\ndecide to switch to this mode, but I had no time to play with it yet.\n"
  },
  {
    "path": "afl_progs/qemu_mode/build_qemu_support.sh",
    "content": "#!/bin/sh\n#\n# american fuzzy lop - QEMU build script\n# --------------------------------------\n#\n# Written by Andrew Griffiths <agriffiths@google.com> and\n#            Michal Zalewski <lcamtuf@google.com>\n#\n# Copyright 2015, 2016, 2017 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at:\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# This script downloads, patches, and builds a version of QEMU with\n# minor tweaks to allow non-instrumented binaries to be run under\n# afl-fuzz. \n#\n# The modifications reside in patches/*. The standalone QEMU binary\n# will be written to ../afl-qemu-trace.\n#\n\n\nVERSION=\"2.10.0\"\nQEMU_URL=\"http://download.qemu-project.org/qemu-${VERSION}.tar.xz\"\nQEMU_SHA384=\"68216c935487bc8c0596ac309e1e3ee75c2c4ce898aab796faa321db5740609ced365fedda025678d072d09ac8928105\"\n\necho \"=================================================\"\necho \"AFL binary-only instrumentation QEMU build script\"\necho \"=================================================\"\necho\n\necho \"[*] Performing basic sanity checks...\"\n\nif [ ! \"`uname -s`\" = \"Linux\" ]; then\n\n  echo \"[-] Error: QEMU instrumentation is supported only on Linux.\"\n  exit 1\n\nfi\n\nif [ ! -f \"patches/afl-qemu-cpu-inl.h\" -o ! -f \"../config.h\" ]; then\n\n  echo \"[-] Error: key files not found - wrong working directory?\"\n  exit 1\n\nfi\n\n\nfor i in libtool wget python automake autoconf sha384sum bison iconv; do\n\n  T=`which \"$i\" 2>/dev/null`\n\n  if [ \"$T\" = \"\" ]; then\n\n    echo \"[-] Error: '$i' not found, please install first.\"\n    exit 1\n\n  fi\n\ndone\n\nif [ ! -d \"/usr/include/glib-2.0/\" -a ! -d \"/usr/local/include/glib-2.0/\" ]; then\n\n  echo \"[-] Error: devel version of 'glib2' not found, please install first.\"\n  exit 1\n\nfi\n\nif echo \"$CC\" | grep -qF /afl-; then\n\n  echo \"[-] Error: do not use afl-gcc or afl-clang to compile this tool.\"\n  exit 1\n\nfi\n\necho \"[+] All checks passed!\"\n\nARCHIVE=\"`basename -- \"$QEMU_URL\"`\"\n\nCKSUM=`sha384sum -- \"$ARCHIVE\" 2>/dev/null | cut -d' ' -f1`\n\nif [ ! \"$CKSUM\" = \"$QEMU_SHA384\" ]; then\n\n  echo \"[*] Downloading QEMU ${VERSION} from the web...\"\n  rm -f \"$ARCHIVE\"\n  wget -O \"$ARCHIVE\" -- \"$QEMU_URL\" || exit 1\n\n  CKSUM=`sha384sum -- \"$ARCHIVE\" 2>/dev/null | cut -d' ' -f1`\n\nfi\n\nif [ \"$CKSUM\" = \"$QEMU_SHA384\" ]; then\n\n  echo \"[+] Cryptographic signature on $ARCHIVE checks out.\"\n\nelse\n\n  echo \"[-] Error: signature mismatch on $ARCHIVE (perhaps download error?).\"\n  exit 1\n\nfi\n\necho \"[*] Uncompressing archive (this will take a while)...\"\n\nrm -rf \"qemu-${VERSION}\" || exit 1\ntar xf \"$ARCHIVE\" || exit 1\n\necho \"[+] Unpacking successful.\"\n\necho \"[*] Configuring QEMU for $CPU_TARGET...\"\n\nORIG_CPU_TARGET=\"$CPU_TARGET\"\n\ntest \"$CPU_TARGET\" = \"\" && CPU_TARGET=\"`uname -m`\"\ntest \"$CPU_TARGET\" = \"i686\" && CPU_TARGET=\"i386\"\n\ncd qemu-$VERSION || exit 1\n\necho \"[*] Applying patches...\"\n\npatch -p1 <../patches/elfload.diff || exit 1\npatch -p1 <../patches/cpu-exec.diff || exit 1\npatch -p1 <../patches/syscall.diff || exit 1\npatch -p1 <../patches/configure.diff || exit 1\npatch -p1 <../patches/memfd.diff || exit 1\npatch -p1 <../patches/translate-all.diff || exit 1\npatch -p1 <../patches/afl_qemu_optimize_entrypoint.diff || exit 1\n\necho \"[+] Patching done.\"\n\n# --enable-pie seems to give a couple of exec's a second performance\n# improvement, much to my surprise. Not sure how universal this is..\n\nCFLAGS=\"-O3 -ggdb\" ./configure --disable-system \\\n  --enable-linux-user --disable-gtk --disable-sdl --disable-vnc \\\n  --target-list=\"${CPU_TARGET}-linux-user\" --enable-pie --enable-kvm || exit 1\n\necho \"[+] Configuration complete.\"\n\necho \"[*] Attempting to build QEMU (fingers crossed!)...\"\n\nmake || exit 1\n\necho \"[+] Build process successful!\"\n\necho \"[*] Copying binary...\"\n\ncp -f \"${CPU_TARGET}-linux-user/qemu-${CPU_TARGET}\" \"../../afl-qemu-trace\" || exit 1\n\ncd ..\nls -l ../afl-qemu-trace || exit 1\n\necho \"[+] Successfully created '../afl-qemu-trace'.\"\n\necho \"[+] All set, you can now use the qemu mode in killerbeez!\"\n\nexit 0\n"
  },
  {
    "path": "afl_progs/qemu_mode/patches/afl-qemu-cpu-inl.h",
    "content": "/*\n   american fuzzy lop - high-performance binary-only instrumentation\n   -----------------------------------------------------------------\n\n   Written by Andrew Griffiths <agriffiths@google.com> and\n              Michal Zalewski <lcamtuf@google.com>\n\n   Idea & design very much by Andrew Griffiths.\n\n   TCG instrumentation and block chaining support by Andrea Biondo\n                                      <andrea.biondo965@gmail.com>\n\n   Copyright 2015, 2016, 2017 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This code is a shim patched into the separately-distributed source\n   code of QEMU 2.10.0. It leverages the built-in QEMU tracing functionality\n   to implement AFL-style instrumentation and to take care of the remaining\n   parts of the AFL fork server logic.\n\n   The resulting QEMU binary is essentially a standalone instrumentation\n   tool; for an example of how to leverage it for other purposes, you can\n   have a look at afl-showmap.c.\n\n */\n\n/*\n\tThis file has been modified from the original AFL version to incorporate into\n\tKillerbeez.  Specifically, the fork server has been modified to match the\n  Killerbeez fork server protocol.\n */\n\n#include <sys/shm.h>\n#include \"../../config.h\"\n#include \"../../../instrumentation/forkserver_internal.h\"\n\n/***************************\n * VARIOUS AUXILIARY STUFF *\n ***************************/\n\n/* This snippet kicks in when the instruction pointer is positioned at\n   _start and does the usual forkserver stuff, not very different from\n   regular instrumentation injected via afl-as.h. */\n\n#define AFL_QEMU_CPU_SNIPPET2 do { \\\n    if(itb->pc == afl_entry_point) { \\\n      afl_setup(); \\\n      afl_forkserver(cpu); \\\n    } \\\n  } while (0)\n\n/* We use one additional file descriptor to relay \"needs translation\"\n   messages between the child and the fork server. */\n\n#define TSL_FD QEMU_TSL_FD //import it from forkserver_internal.h\n\n/* This is equivalent to afl-as.h: */\n\nunsigned char dummy[65536];\nunsigned char *afl_area_ptr = dummy; /* Exported for afl_gen_trace */\n\n/* Exported variables populated by the code patched into elfload.c: */\n\nabi_ulong afl_entry_point, /* ELF entry point (_start) */\n          afl_start_code,  /* .text start pointer      */\n          afl_end_code;    /* .text end pointer        */\n\n/* Set in the child process in forkserver mode: */\n\nstatic unsigned char afl_fork_child;\nunsigned int afl_forksrv_pid;\n\n/* Instrumentation ratio: */\n\nunsigned int afl_inst_rms = MAP_SIZE; /* Exported for afl_gen_trace */\n\n/* Function declarations. */\n\nstatic void afl_setup(void);\nstatic void afl_forkserver(CPUState*);\n\nstatic void afl_wait_tsl(CPUState*, int);\nstatic void afl_request_tsl(target_ulong, target_ulong, uint32_t, TranslationBlock*, int);\n\n/* Data structures passed around by the translate handlers: */\n\nstruct afl_tb {\n  target_ulong pc;\n  target_ulong cs_base;\n  uint32_t flags;\n};\n\nstruct afl_tsl {\n  struct afl_tb tb;\n  char is_chain;\n};\n\nstruct afl_chain {\n  struct afl_tb last_tb;\n  int tb_exit;\n};\n\n/* Some forward decls: */\n\nTranslationBlock *tb_htable_lookup(CPUState*, target_ulong, target_ulong, uint32_t);\nstatic inline TranslationBlock *tb_find(CPUState*, TranslationBlock*, int);\n\n/*************************\n * ACTUAL IMPLEMENTATION *\n *************************/\n\n/* Set up SHM region and initialize other stuff. */\n\nstatic void afl_setup(void) {\n\n  char *id_str = getenv(SHM_ENV_VAR),\n       *inst_r = getenv(\"AFL_INST_RATIO\");\n\n  int shm_id;\n\n  if (inst_r) {\n\n    unsigned int r;\n\n    r = atoi(inst_r);\n\n    if (r > 100) r = 100;\n    if (!r) r = 1;\n\n    afl_inst_rms = MAP_SIZE * r / 100;\n\n  }\n\n  if (id_str) {\n\n    shm_id = atoi(id_str);\n    afl_area_ptr = shmat(shm_id, NULL, 0);\n\n    if (afl_area_ptr == (void*)-1) exit(1);\n\n    /* With AFL_INST_RATIO set to a low value, we want to touch the bitmap\n       so that the parent doesn't give up on us. */\n\n    if (inst_r) afl_area_ptr[0] = 1;\n\n\n  }\n\n  if (getenv(\"AFL_INST_LIBS\")) {\n\n    afl_start_code = 0;\n    afl_end_code   = (abi_ulong)-1;\n\n  }\n\n  /* pthread_atfork() seems somewhat broken in util/rcu.c, and I'm\n     not entirely sure what is the cause. This disables that\n     behaviour, and seems to work alright? */\n\n  rcu_disable_atfork();\n\n}\n\n\n/* Fork server logic, invoked once we hit _start. */\nstatic int forkserver_installed = 0;\nstatic void afl_forkserver(CPUState *cpu) {\n  static int response = 0x41414141;\n  char command;\n  int child_pid = -1;\n  int t_fd[2];\n\n  if (forkserver_installed == 1)\n    return;\n  forkserver_installed = 1;\n  //if (!afl_area_ptr) return;\n\n  /* Tell the parent that we're alive. If the parent doesn't want\n     to talk, assume that we're not running in forkserver mode. */\n  if(write(FORKSRV_TO_FUZZER, &response, sizeof(int)) != sizeof(int))\n    return;\n\n  afl_forksrv_pid = getpid();\n\n  /* All right, let's await orders... */\n\n  while (1) {\n\n    // Wait for parent by reading from the pipe. Exit if read fails.\n    if(read(FUZZER_TO_FORKSRV, &command, sizeof(command)) != sizeof(command))\n      _exit(1);\n\n    switch(command) {\n\n      case EXIT:\n      case RUN: //QEMU doesn't do the single RUN/FORK commands\n      case FORK: //but instead only implements FORK_RUN\n        _exit(0);\n        break;\n\n      case FORK_RUN:\n\n        /* Establish a channel with child to grab translation commands. We'll\n           read from t_fd[0], child will write to TSL_FD. */\n        if (pipe(t_fd) || dup2(t_fd[1], TSL_FD) < 0) exit(3);\n        close(t_fd[1]);\n\n        child_pid = fork();\n        if (child_pid < 0) exit(4);\n\n        if (!child_pid) {\n\n          /* Child process. Close descriptors and run free. */\n          afl_fork_child = 1;\n          close(FUZZER_TO_FORKSRV);\n          close(FORKSRV_TO_FUZZER);\n          close(t_fd[0]);\n          return;\n        }\n\n        /* Parent. */\n        response = child_pid;\n        if(write(FORKSRV_TO_FUZZER, &response, sizeof(int)) != sizeof(int))\n          _exit(1);\n\n        close(TSL_FD);\n\n        /* Collect translation requests until child dies and closes the pipe. */\n        afl_wait_tsl(cpu, t_fd[0]);\n        break;\n\n      case GET_STATUS:\n        /* Get and relay exit status to parent. */\n        if(waitpid(child_pid, &response, 0) < 0)\n          _exit(1);\n        if(write(FORKSRV_TO_FUZZER, &response, sizeof(int)) != sizeof(int))\n          _exit(1);\n        break;\n    }\n  }\n}\n\n/* This code is invoked whenever QEMU decides that it doesn't have a\n   translation of a particular block and needs to compute it, or when it\n   decides to chain two TBs together. When this happens, we tell the parent to\n   mirror the operation, so that the next fork() has a cached copy. */\n\nstatic void afl_request_tsl(target_ulong pc, target_ulong cb, uint32_t flags,\n                            TranslationBlock *last_tb, int tb_exit) {\n\n  struct afl_tsl t;\n  struct afl_chain c;\n\n  if (!afl_fork_child) return;\n\n  t.tb.pc      = pc;\n  t.tb.cs_base = cb;\n  t.tb.flags   = flags;\n  t.is_chain   = (last_tb != NULL);\n\n  if (write(TSL_FD, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl))\n    return;\n\n  if (t.is_chain) {\n    c.last_tb.pc      = last_tb->pc;\n    c.last_tb.cs_base = last_tb->cs_base;\n    c.last_tb.flags   = last_tb->flags;\n    c.tb_exit         = tb_exit;\n\n    if (write(TSL_FD, &c, sizeof(struct afl_chain)) != sizeof(struct afl_chain))\n      return;\n  }\n\n}\n\n/* This is the other side of the same channel. Since timeouts are handled by\n   afl-fuzz simply killing the child, we can just wait until the pipe breaks. */\n\nstatic void afl_wait_tsl(CPUState *cpu, int fd) {\n\n  struct afl_tsl t;\n  struct afl_chain c;\n  TranslationBlock *tb, *last_tb;\n\n  while (1) {\n\n    /* Broken pipe means it's time to return to the fork server routine. */\n\n    if (read(fd, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl))\n      break;\n\n    tb = tb_htable_lookup(cpu, t.tb.pc, t.tb.cs_base, t.tb.flags);\n\n    if(!tb) {\n      mmap_lock();\n      tb_lock();\n      tb = tb_gen_code(cpu, t.tb.pc, t.tb.cs_base, t.tb.flags, 0);\n      mmap_unlock();\n      tb_unlock();\n    }\n\n    if (t.is_chain) {\n      if (read(fd, &c, sizeof(struct afl_chain)) != sizeof(struct afl_chain))\n        break;\n\n      last_tb = tb_htable_lookup(cpu, c.last_tb.pc, c.last_tb.cs_base,\n                                 c.last_tb.flags);\n      if (last_tb) {\n        tb_lock();\n        if (!tb->invalid) {\n          tb_add_jump(last_tb, c.tb_exit, tb);\n        }\n        tb_unlock();\n      }\n    }\n\n  }\n\n  close(fd);\n\n}\n"
  },
  {
    "path": "afl_progs/qemu_mode/patches/afl-qemu-translate-inl.h",
    "content": "/*\n   american fuzzy lop - high-performance binary-only instrumentation\n   -----------------------------------------------------------------\n\n   Written by Andrew Griffiths <agriffiths@google.com> and\n              Michal Zalewski <lcamtuf@google.com>\n\n   Idea & design very much by Andrew Griffiths.\n\n   TCG instrumentation and block chaining support by Andrea Biondo\n                                      <andrea.biondo965@gmail.com>\n\n   Copyright 2015, 2016, 2017 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This code is a shim patched into the separately-distributed source\n   code of QEMU 2.10.0. It leverages the built-in QEMU tracing functionality\n   to implement AFL-style instrumentation and to take care of the remaining\n   parts of the AFL fork server logic.\n\n   The resulting QEMU binary is essentially a standalone instrumentation\n   tool; for an example of how to leverage it for other purposes, you can\n   have a look at afl-showmap.c.\n\n */\n\n#include \"../../config.h\"\n#include \"tcg-op.h\"\n\n/* Declared in afl-qemu-cpu-inl.h */\nextern unsigned char *afl_area_ptr;\nextern unsigned int afl_inst_rms;\nextern abi_ulong afl_start_code, afl_end_code;\n\n/* Generates TCG code for AFL's tracing instrumentation. */\nstatic void afl_gen_trace(target_ulong cur_loc)\n{\n  static __thread target_ulong prev_loc;\n  TCGv index, count, new_prev_loc;\n  TCGv_ptr prev_loc_ptr, count_ptr;\n\n  /* Optimize for cur_loc > afl_end_code, which is the most likely case on\n     Linux systems. */\n\n  if (cur_loc > afl_end_code || cur_loc < afl_start_code /*|| !afl_area_ptr*/)\n    return;\n\n  /* Looks like QEMU always maps to fixed locations, so ASAN is not a\n     concern. Phew. But instruction addresses may be aligned. Let's mangle\n     the value to get something quasi-uniform. */\n\n  cur_loc  = (cur_loc >> 4) ^ (cur_loc << 8);\n  cur_loc &= MAP_SIZE - 1;\n\n  /* Implement probabilistic instrumentation by looking at scrambled block\n     address. This keeps the instrumented locations stable across runs. */\n\n  if (cur_loc >= afl_inst_rms) return;\n\n  /* index = prev_loc ^ cur_loc */\n  prev_loc_ptr = tcg_const_ptr(&prev_loc);\n  index = tcg_temp_new();\n  tcg_gen_ld_tl(index, prev_loc_ptr, 0);\n  tcg_gen_xori_tl(index, index, cur_loc);\n\n  /* afl_area_ptr[index]++ */\n  count_ptr = tcg_const_ptr(afl_area_ptr);\n  tcg_gen_add_ptr(count_ptr, count_ptr, TCGV_NAT_TO_PTR(index));\n  count = tcg_temp_new();\n  tcg_gen_ld8u_tl(count, count_ptr, 0);\n  tcg_gen_addi_tl(count, count, 1);\n  tcg_gen_st8_tl(count, count_ptr, 0);\n\n  /* prev_loc = cur_loc >> 1 */\n  new_prev_loc = tcg_const_tl(cur_loc >> 1);\n  tcg_gen_st_tl(new_prev_loc, prev_loc_ptr, 0);\n}\n"
  },
  {
    "path": "afl_progs/qemu_mode/patches/afl_qemu_optimize_entrypoint.diff",
    "content": "--- qemu-2.10.0/linux-user/elfload.c.orig\t2018-03-16 11:43:21.000000000 +0100\n+++ qemu-2.10.0/linux-user/elfload.c\t2018-04-04 05:25:47.535020053 +0200\n@@ -2086,8 +2086,21 @@\n     info->end_data = 0;\n     info->brk = 0;\n     info->elf_flags = ehdr->e_flags;\n-\n-    if (!afl_entry_point) afl_entry_point = info->entry;\n+    \n+    if (!afl_entry_point) {\n+      char *ptr;\n+      if ((ptr = getenv(\"AFL_ENTRYPOINT\")) != NULL) {\n+        afl_entry_point = strtoul(ptr, NULL, 16);\n+      } else {\n+        if (!afl_entry_point) afl_entry_point = info->entry;\n+      }\n+#ifdef TARGET_ARM\n+      /* The least significant bit indicates Thumb mode. */\n+      afl_entry_point = afl_entry_point & ~(target_ulong)1;\n+#endif\n+      if (getenv(\"AFL_DEBUG\") != NULL)\n+        fprintf(stderr, \"AFL forkserver entrypoint: %p\\n\", (void*)afl_entry_point);\n+    } while(0);\n \n     for (i = 0; i < ehdr->e_phnum; i++) {\n         struct elf_phdr *eppnt = phdr + i;\n"
  },
  {
    "path": "afl_progs/qemu_mode/patches/configure.diff",
    "content": "--- a/configure\n+++ b/configure\n@@ -3855,7 +3855,7 @@ fi\n # check if memfd is supported\n memfd=no\n cat > $TMPC << EOF\n-#include <sys/memfd.h>\n+#include <sys/mman.h>\n \n int main(void)\n {\n"
  },
  {
    "path": "afl_progs/qemu_mode/patches/cpu-exec.diff",
    "content": "--- qemu-2.10.0-clean/accel/tcg/cpu-exec.c\t2017-08-30 18:50:40.000000000 +0200\n+++ qemu-2.10.0/accel/tcg/cpu-exec.c\t2018-09-22 13:21:23.612068407 +0200\n@@ -36,6 +36,8 @@\n #include \"sysemu/cpus.h\"\n #include \"sysemu/replay.h\"\n \n+#include \"../patches/afl-qemu-cpu-inl.h\"\n+\n /* -icount align implementation. */\n \n typedef struct SyncClocks {\n@@ -144,6 +146,8 @@\n     int tb_exit;\n     uint8_t *tb_ptr = itb->tc_ptr;\n \n+    AFL_QEMU_CPU_SNIPPET2;\n+\n     qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc,\n                            \"Trace %p [%d: \" TARGET_FMT_lx \"] %s\\n\",\n                            itb->tc_ptr, cpu->cpu_index, itb->pc,\n@@ -337,7 +341,7 @@\n     TranslationBlock *tb;\n     target_ulong cs_base, pc;\n     uint32_t flags;\n-    bool have_tb_lock = false;\n+    bool have_tb_lock = false, was_translated = false, was_chained = false;\n \n     /* we record a subset of the CPU state. It will\n        always be the same before a given translated block\n@@ -365,6 +369,7 @@\n             if (!tb) {\n                 /* if no translated code available, then translate it now */\n                 tb = tb_gen_code(cpu, pc, cs_base, flags, 0);\n+                was_translated = true;\n             }\n \n             mmap_unlock();\n@@ -390,11 +395,16 @@\n         }\n         if (!tb->invalid) {\n             tb_add_jump(last_tb, tb_exit, tb);\n+            was_chained = true;\n         }\n     }\n     if (have_tb_lock) {\n         tb_unlock();\n     }\n+    if (was_translated || was_chained) {\n+        afl_request_tsl(pc, cs_base, flags, was_chained ? last_tb : NULL,\n+                        tb_exit);\n+    }\n     return tb;\n }\n \n"
  },
  {
    "path": "afl_progs/qemu_mode/patches/elfload.diff",
    "content": "--- qemu-2.10.0.orig/linux-user/elfload.c\t2017-08-30 18:50:41.000000000 +0200\n+++ qemu-2.10.0/linux-user/elfload.c\t2018-10-23 12:48:16.421879765 +0200\n@@ -20,6 +20,8 @@\n \n #define ELF_OSABI   ELFOSABI_SYSV\n \n+extern abi_ulong afl_entry_point, afl_start_code, afl_end_code;\n+\n /* from personality.h */\n \n /*\n@@ -2085,6 +2087,8 @@\n     info->brk = 0;\n     info->elf_flags = ehdr->e_flags;\n \n+    if (!afl_entry_point) afl_entry_point = info->entry;\n+\n     for (i = 0; i < ehdr->e_phnum; i++) {\n         struct elf_phdr *eppnt = phdr + i;\n         if (eppnt->p_type == PT_LOAD) {\n@@ -2118,9 +2122,11 @@\n             if (elf_prot & PROT_EXEC) {\n                 if (vaddr < info->start_code) {\n                     info->start_code = vaddr;\n+                    if (!afl_start_code) afl_start_code = vaddr;\n                 }\n                 if (vaddr_ef > info->end_code) {\n                     info->end_code = vaddr_ef;\n+                    if (!afl_end_code) afl_end_code = vaddr_ef;\n                 }\n             }\n             if (elf_prot & PROT_WRITE) {\n@@ -2443,6 +2449,22 @@\n                                 info, (elf_interpreter ? &interp_info : NULL));\n     info->start_stack = bprm->p;\n \n+#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)\n+    // On PowerPC64 the entry point is the _function descriptor_\n+    // of the entry function. For AFL to properly initialize,\n+    // afl_entry_point needs to be set to the actual first instruction\n+    // as opposed executed by the target program. This as opposed to \n+    // where the function's descriptor sits in memory.\n+    \n+    // Shameless copy of PPC init_thread\n+    info_report(\"Adjusting afl_entry_point\");\n+    if (afl_entry_point && (get_ppc64_abi(info) < 2)) {\n+        uint64_t val;\n+        get_user_u64(val, afl_entry_point);\n+        afl_entry_point = val + info->load_bias;\n+    }\n+#endif\n+\n     /* If we have an interpreter, set that as the program's entry point.\n        Copy the load_bias as well, to help PPC64 interpret the entry\n        point as a function descriptor.  Do this after creating elf tables\n"
  },
  {
    "path": "afl_progs/qemu_mode/patches/memfd.diff",
    "content": "--- a/util/memfd.c\n+++ b/util/memfd.c\n@@ -31,9 +31,7 @@\n \n #include \"qemu/memfd.h\"\n \n-#ifdef CONFIG_MEMFD\n-#include <sys/memfd.h>\n-#elif defined CONFIG_LINUX\n+#if defined CONFIG_LINUX && !defined CONFIG_MEMFD\n #include <sys/syscall.h>\n #include <asm/unistd.h>\n"
  },
  {
    "path": "afl_progs/qemu_mode/patches/syscall.diff",
    "content": "--- qemu-2.10.0-rc3-clean/linux-user/syscall.c\t2017-08-15 11:39:41.000000000 -0700\n+++ qemu-2.10.0-rc3/linux-user/syscall.c\t2017-08-22 14:34:03.193088186 -0700\n@@ -116,6 +116,8 @@\n \n #include \"qemu.h\"\n \n+extern unsigned int afl_forksrv_pid;\n+\n #ifndef CLONE_IO\n #define CLONE_IO                0x80000000      /* Clone io context */\n #endif\n@@ -11688,8 +11690,21 @@\n         break;\n \n     case TARGET_NR_tgkill:\n-        ret = get_errno(safe_tgkill((int)arg1, (int)arg2,\n-                        target_to_host_signal(arg3)));\n+\n+        {\n+          int pid  = (int)arg1,\n+              tgid = (int)arg2,\n+              sig  = (int)arg3;\n+\n+          /* Not entirely sure if the below is correct for all architectures. */\n+\n+          if(afl_forksrv_pid && afl_forksrv_pid == pid && sig == SIGABRT)\n+              pid = tgid = getpid();\n+\n+          ret = get_errno(safe_tgkill(pid, tgid, target_to_host_signal(sig)));\n+\n+        }\n+\n         break;\n \n #ifdef TARGET_NR_set_robust_list\n"
  },
  {
    "path": "afl_progs/qemu_mode/patches/translate-all.diff",
    "content": "--- a/accel/tcg/translate-all.c\t2017-08-30 18:50:40.000000000 +0200\n+++ b/accel/tcg/translate-all.c\t2018-09-21 10:19:42.328766554 +0200\n@@ -60,6 +60,8 @@\n #include \"exec/log.h\"\n #include \"sysemu/cpus.h\"\n \n+#include \"../patches/afl-qemu-translate-inl.h\"\n+\n /* #define DEBUG_TB_INVALIDATE */\n /* #define DEBUG_TB_FLUSH */\n /* make various TB consistency checks */\n@@ -1280,6 +1282,7 @@\n     tcg_func_start(&tcg_ctx);\n \n     tcg_ctx.cpu = ENV_GET_CPU(env);\n+    afl_gen_trace(pc);\n     gen_intermediate_code(cpu, tb);\n     tcg_ctx.cpu = NULL;\n \n"
  },
  {
    "path": "afl_progs/test-instr.c",
    "content": "/*\n   american fuzzy lop - a trivial program to test the build\n   --------------------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2014 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n\nint main(int argc, char** argv) {\n\n  char buf[8];\n\n  if (read(0, buf, 8) < 1) {\n    printf(\"Hum?\\n\");\n    exit(1);\n  }\n\n  if (buf[0] == '0')\n    printf(\"Looks like a zero to me!\\n\");\n  else\n    printf(\"A non-zero value? How quaint!\\n\");\n\n  exit(0);\n\n}\n"
  },
  {
    "path": "afl_progs/types.h",
    "content": "/*\n   american fuzzy lop - type definitions and minor macros\n   ------------------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n */\n\n#ifndef _HAVE_TYPES_H\n#define _HAVE_TYPES_H\n\n#include <stdint.h>\n#include <stdlib.h>\n\ntypedef uint8_t  u8;\ntypedef uint16_t u16;\ntypedef uint32_t u32;\n\n/*\n\n   Ugh. There is an unintended compiler / glibc #include glitch caused by\n   combining the u64 type an %llu in format strings, necessitating a workaround.\n\n   In essence, the compiler is always looking for 'unsigned long long' for %llu.\n   On 32-bit systems, the u64 type (aliased to uint64_t) is expanded to\n   'unsigned long long' in <bits/types.h>, so everything checks out.\n\n   But on 64-bit systems, it is #ifdef'ed in the same file as 'unsigned long'.\n   Now, it only happens in circumstances where the type happens to have the\n   expected bit width, *but* the compiler does not know that... and complains\n   about 'unsigned long' being unsafe to pass to %llu.\n\n */\n\n#ifdef __x86_64__\ntypedef unsigned long long u64;\n#else\ntypedef uint64_t u64;\n#endif /* ^__x86_64__ */\n\ntypedef int8_t   s8;\ntypedef int16_t  s16;\ntypedef int32_t  s32;\ntypedef int64_t  s64;\n\n#ifndef MIN\n#  define MIN(_a,_b) ((_a) > (_b) ? (_b) : (_a))\n#  define MAX(_a,_b) ((_a) > (_b) ? (_a) : (_b))\n#endif /* !MIN */\n\n#define SWAP16(_x) ({ \\\n    u16 _ret = (_x); \\\n    (u16)((_ret << 8) | (_ret >> 8)); \\\n  })\n\n#define SWAP32(_x) ({ \\\n    u32 _ret = (_x); \\\n    (u32)((_ret << 24) | (_ret >> 24) | \\\n          ((_ret << 8) & 0x00FF0000) | \\\n          ((_ret >> 8) & 0x0000FF00)); \\\n  })\n\n#ifdef AFL_LLVM_PASS\n#  define AFL_R(x) (random() % (x))\n#else\n#  define R(x) (random() % (x))\n#endif /* ^AFL_LLVM_PASS */\n\n#define STRINGIFY_INTERNAL(x) #x\n#define STRINGIFY(x) STRINGIFY_INTERNAL(x)\n\n#define MEM_BARRIER() \\\n  asm volatile(\"\" ::: \"memory\")\n\n#define likely(_x)   __builtin_expect(!!(_x), 1)\n#define unlikely(_x)  __builtin_expect(!!(_x), 0)\n\n#endif /* ! _HAVE_TYPES_H */\n"
  },
  {
    "path": "corpus/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (corpus)\n\n# All of the Windows test programs have precompiled versions, as the DynamoRIO\n# instrumentation needs exact offsets into the program to know where to hook.\n# As such, we've included precompiled versions with and listed the offsets,\n# rather than having the user compile them.\nif (UNIX)\n\tSET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BUILD_DIRECTORY}/killerbeez/corpus/ )\n\tSET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${BUILD_DIRECTORY}/killerbeez/corpus/ )\n\tSET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${BUILD_DIRECTORY}/killerbeez/corpus/ )\n\n\tif (NOT APPLE)\n\t\tadd_subdirectory(persist)\n\tendif (NOT APPLE)\n\tadd_subdirectory(hang)\n\tadd_subdirectory(libtest)\n\tadd_subdirectory(test)\n\tadd_subdirectory(network)\n\nendif ()\n"
  },
  {
    "path": "corpus/afl_test/Makefile",
    "content": "\n\nall: test test32 test-qemu test-fast test-fast-persist test-fast-persist-hang test-fast-deferred test-fast-persist-deferred\n\nhelp:\n\techo \"\\n\\n This Makefile can be used to compile the example test program with AFL instrumentation.\\n\" \\\n\t\"Use the AFL_PATH environment variable to specify the path to afl-gcc/afl-clang-fast\\n\" \\\n\t\"\\n\" \\\n\t\"Example:\\n\" \\\n\t\"  make AFL_PATH=/path/to/afl/ all\" \\\n\t\"\\n\"\n\ncheck-afl-gcc:\n\tif [ ! \"$(shell sh -c 'ls $(AFL_PATH)/afl-gcc > /dev/null; echo $$?')\" = \"0\" ]; then \\\n\t\techo \"Bad compiler specified '$(AFL_PATH)'. Please use the AFL_PATH environment variable to specify the path to afl-gcc\"; \\\n\t\texit 1; \\\n\tfi\n\ncheck-afl-clang-fast:\n\tif [ ! \"$(shell sh -c 'ls $(AFL_PATH)/afl-clang-fast > /dev/null; echo $$?')\" = \"0\" ]; then \\\n\t\techo \"Bad compiler specified '$(AFL_PATH)'. Please use the AFL_PATH environment variable to specify the path to afl-clang-fast\"; \\\n\t\texit 1; \\\n\tfi\n\ntest: check-afl-gcc\n\t$(AFL_PATH)/afl-gcc test.c -o test\n\ntest32: check-afl-gcc\n\t$(AFL_PATH)/afl-gcc test.c -m32 -o test32\n\ntest-qemu:\n\t$(CC) test.c -o test-qemu\n\ntest-fast: check-afl-clang-fast\n\t$(AFL_PATH)/afl-clang-fast test.c -o test-fast\n\ntest-fast-persist: check-afl-clang-fast\n\t$(AFL_PATH)/afl-clang-fast test.c -o test-fast-persist          -DPERSIST\n\ntest-fast-persist-hang: check-afl-clang-fast\n\t$(AFL_PATH)/afl-clang-fast test.c -o test-fast-persist-hang     -DPERSIST -DHANG\n\ntest-fast-deferred: check-afl-clang-fast\n\t$(AFL_PATH)/afl-clang-fast test.c -o test-fast-deferred         -DSLOW_STARTUP -DDEFERRED\n\ntest-fast-persist-deferred: check-afl-clang-fast\n\t$(AFL_PATH)/afl-clang-fast test.c -o test-fast-persist-deferred -DSLOW_STARTUP -DDEFERRED -DPERSIST\n\nclean:\n\trm -f test test32 test-qemu test-fast test-fast-persist test-fast-persist-hang test-fast-deferred test-fast-persist-deferred\n"
  },
  {
    "path": "corpus/afl_test/test.c",
    "content": "#include <string.h>\n#include <stdio.h>\n#include <unistd.h>\n\nint test_func()\n{\n  char buffer[4];\n  char * nil = NULL;\n  memset(buffer, 0, 4);\n  read(0, buffer, sizeof(buffer));\n\n  if (buffer[0] == 'A')\n  {\n    if (buffer[1] == 'B')\n    {\n      if (buffer[2] == 'C')\n      {\n        if (buffer[3] == 'D')\n        {\n#ifdef HANG\n\t\t\t\t\twhile(1) {}\n#endif\n          *nil = 'E';\n        }\n        else\n        {\n          puts(\"Wrong 3\");\n        }\n      }\n      else\n      {\n        puts(\"Wrong 2\");\n      }\n    }\n    else\n    {\n      puts(\"Wrong 1\");\n    }\n  }\n  else\n  {\n    puts(\"Wrong 0\");\n  }\n\n  return 0;\n}\n\n\nint main()\n{\n#ifdef SLOW_STARTUP\n  sleep(5);\n#endif\n\n#ifdef DEFERRED\n  __AFL_INIT();\n#endif\n\n#ifdef PERSIST\n  while(__AFL_LOOP()) {\n#endif\n\n    test_func();\n\n#ifdef PERSIST\n  }\n#endif\n\n  return 0;\n}\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/README.md",
    "content": "# REMATCH_2--Mail_Server--Crackaddr\n\n## Author Information\n\ndebbie@cromulence.com\n\n### DARPA performer group\nCromulence LLC (CROMU)\n\n## Description\nThis binary mimics the function in sendmail that was vulnerable to CVE-2002-1337 commonly known as the crackaddr bug. Sendmail is an email server originally published in 1983. The CVE-2002-1337 was a buffer overflow in the crackaddr function for email address parsing. In 2011, 8 years after the bug was published, security researcher Thomas Dullien (AKA Halvar Flake) showcased the bug as something static analysis tools were unable to detect and created a simplified implementation to demonstrate that point. Since then, multiple teams have used the crackaddr bug as a litmus test for the real world viability of analysis tools. To date some tools have been able to detect the vulnerability in the simplified version but not the original. This implementation closely mimics the original bug in sendmail.  \n\n### Feature List\nThe crackaddr function in sendmail was created to parse addresses with a complex combination of embedded parenthesis, angle brackets, quotes, and grouping syntax. The function recreated here adds in some additional complexity from the original function and changes all the special characters to other ascii values. \n\n## Vulnerability\nThe vulnerability is an error in how the while loop keeps track of matching \"brackets\". A pointer is used to indicate the end of the expected output stream. That pointer is manipulated to make sure there is enough room to close out any opened brackets with matching close brackets. The error occurs when the pointer is incremented on a close bracket, but not decremented on the previous open bracket. This allows the pointer to end up pointing past the end of the actual output buffer, alowing the input stream to overwrite a portion of the stack. \n\n### Generic class of vulnerability\nBuffer Overflow\n\n### CWE classification\nCWE-120 Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')\n\n## Challenges\nThe crackaddr function poses a complex challenge to the CRS. The unbounded nature of the input prevents imposing a simple size restriction because that would lead to failing valid polls. The CRS must then interpret exactly which overly long inputs would result in an overflow of the output. The crackaddr function modifies the output bounds based on the sequence of input characters in a while loop which quickly leads to an unmanageable state equation for the CRS. \n \n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/inputs/ADDRESSBOOK.txt",
    "content": "ADDRESSBOOK\nQUIT\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/inputs/LIST.txt",
    "content": "LIST\nQUIT\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/inputs/LISTALL.txt",
    "content": "LISTALL\nQUIT\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/inputs/POST.txt",
    "content": "POST\nQUIT\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/inputs/READ.txt",
    "content": "READ\nQUIT\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/inputs/crash.txt",
    "content": "POST sender:sender!recipient:+BCcCcCcCcCcCcCcCcCcCcCcCcCcCcCcCcCcCcJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJIIIIHHHH!body:dump 1128775680!subject:subject!\nQUIT\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/cgc_ctype.h",
    "content": "/*\n\nCopyright (c) 2015 Cromulence LLC\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#ifndef __CTYPE_H__\n#define __CTYPE_H__\n\nint cgc_isdigit( int c );\nint cgc_islower( int c );\nint cgc_isupper( int c );\nint cgc_isalpha( int c );\nint cgc_isalnum( int c );\nint cgc_isprint( int c );\nint cgc_isspace( int c );\n\nint cgc_toupper( int c );\nint cgc_tolower( int c );\n\n#endif // __CTYPE_H__\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/cgc_libc.h",
    "content": "/*\n\nAuthor: Debbie Nuttall <debbie@cromulence.com>\n\nCopyright (c) 2015 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#ifndef LIBC_H\n#define LIBC_H\n\n#define FLAG_PAGE 0x4347c000\n\nint cgc_receive_all(char *buf, int length);\nint cgc_receive_all_fd(int fd, char *buf, int length);\nint cgc_send_all(char *buf, int length);\nint cgc_send_all_fd(int fd, char *buf, int length);\nint cgc_receive_until(char *buf, int length, char delim);\nint cgc_buffered_receive_until(char *buf, int length, char delim);\nint cgc_receive_until_fd(int fd, char *buf, int length, char delim);\nint cgc_equals(char *s, char *d);\nint cgc_replace(char *s, char find, char replace, int num);\nint cgc_force_newline(char *s, int size, int bytes);\nint cgc_getopt(int argc, char **argv, char *optstring, int *opt_index);\nvoid cgc_bcopy(char *s, char *d, cgc_size_t size);\nvoid cgc_exit(int e);\n\n#endif"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/cgc_malloc.h",
    "content": "/*\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nCopyright (c) 2015 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n\n#ifndef __MALLOC_H__\n#define __MALLOC_H__\n\n#include \"libcgc.h\"\n\nvoid *cgc_calloc( cgc_size_t);\nvoid *cgc_malloc( cgc_size_t );\nvoid cgc_free( void * );\n\n#endif\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/cgc_math.h",
    "content": "/*\n\nCopyright (c) 2015 Cromulence LLC\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#ifndef __MATH_H__\n#define __MATH_H__\n\ndouble cgc_round( double val );\ndouble cgc_floor( double val );\n\n#define isnan( val )  __builtin_isnan( val )\n#define isinf( val )  __builtin_isinf( val )\n\n#endif // __MATH_H__\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/cgc_prng.h",
    "content": "/*\n\nCopyright (c) 2015 Cromulence LLC\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#ifndef __PRNG_H__\n#define __PRNG_H__\n\n#include \"cgc_stdint.h\"\n\nvoid cgc_seed_prng_array( uint32_t *array_data, uint32_t array_size );\nvoid cgc_seed_prng( uint32_t seed_value );\nuint32_t cgc_prng( void );\nuint32_t cgc_random_in_range( uint32_t min, uint32_t max );\n\n#endif // __PRNG_H__\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/cgc_shell.h",
    "content": "/*\n\nAuthor: Debbie Nuttall <debbie@cromulence.com>\n\nCopyright (c) 2015 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#ifndef SHELL_H\n#define SHELL_H\n\n#define SECRET_PAGE 0x4347c000\n\nvoid cgc_runshellcommand(char *cmd);\nvoid cgc_shell();\n\n#endif // SHELL_H"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/cgc_stdarg.h",
    "content": "/*\n\nCopyright (c) 2015 Cromulence LLC\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#ifndef __STDARG_H__\n#define __STDARG_H__\n\n#ifdef WIN\n#include <stdarg.h>\n#else\ntypedef __builtin_va_list va_list;\n\n#define va_start(v, l)\t\t__builtin_va_start(v, l)\n#define va_arg(v, l)\t\t__builtin_va_arg(v, l)\n#define va_end(v)\t\t__builtin_va_end(v)\n#endif\n\n#endif // __STDARG_H__\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/cgc_stdint.h",
    "content": "/*\n\nCopyright (c) 2015 Cromulence LLC\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#ifndef __STDINT_H__\n#define __STDINT_H__\n\ntypedef unsigned long long uint64_t;\ntypedef long long int64_t;\ntypedef unsigned int uint32_t;\ntypedef signed int int32_t;\ntypedef unsigned short int uint16_t;\ntypedef signed short int int16_t;\ntypedef unsigned char uint8_t;\ntypedef signed char int8_t;\n\n#endif // __STDINT_H__\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/cgc_stdio.h",
    "content": "/*\n\nCopyright (c) 2015 Cromulence LLC\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#ifndef __STDIO_H__\n#define __STDIO_H__\n\n#include \"libcgc.h\"\n#include \"cgc_stdarg.h\"\n\nint cgc_putchar( int c );\n\nint cgc_printf( const char *format, ... );\nint fprintf( int fd, const char *format, ... );\nint vprintf( int fd, const char *format, va_list args );\nint cgc_sprintf( char *buf, const char *format, ... );\nint cgc_vsprintf( char *buf, const char *format, va_list args );\nint cgc_puts( const char *s );\n\n#endif // __STDIO_H__\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/cgc_stdlib.h",
    "content": "/*\n\nCopyright (c) 2015 Cromulence LLC\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#ifndef __STDLIB_H__\n#define __STDLIB_H__\n\n#include \"libcgc.h\"\n\n#define RAND_MAX\t2147483647\n\nint cgc_rand( void );\nvoid cgc_srand( unsigned int seed );\n\nint cgc_atoi( const char *pStr );\ndouble cgc_atof( char *pStr );\n \nchar *cgc_strcpy( char *pDest, const char *pSource );\nchar *cgc_strncpy( char *pDest, const char *pSource, cgc_size_t maxlen );\nvoid *cgc_memcpy( void *pDest, const void *pSrc, cgc_size_t nbytes );\nvoid get_cgc_random( void *dest, int size);\n\n#endif // STDLIB_H__\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/cgc_string.h",
    "content": "/*\n\nCopyright (c) 2015 Cromulence LLC\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#ifndef __STRING_H__\n#define __STRING_H__\n\n#include \"libcgc.h\"\n\ncgc_size_t cgc_strlen( const char *str );\nvoid cgc_bzero(void *s, cgc_size_t n);\nvoid *cgc_memset( void *ptr, int value, cgc_size_t num );\nchar *cgc_strchr(char *s, int c);\nchar *cgc_strtok(char *str, char *sep);\nint cgc_strcmp(const char *s1, const char *s2);\nint cgc_strncmp(const char *s1, const char *s2, cgc_size_t n);\nchar *cgc_strcat(char *restrict s1, const char *restrict s2);\nchar *cgc_strstr(char *s1, char *s2);\nchar *cgc_rindex(char *source, char match);\n\n#endif // __STRING_H__\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/ctype.c",
    "content": "/*\n\nCopyright (c) 2015 Cromulence LLC\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#include \"cgc_ctype.h\"\n\n#define\t\tDEL\t0x7f\n#define\t\tSPC\t0x20\n\n#define\t\tTAB\t0x09\n#define\t\tLF\t0x0a\n#define\t\tVT\t0x0b\n#define \tFF\t0x0c\n#define\t\tCR\t0x0d\n\nint cgc_isdigit( int c )\n{\n\tif ( c >= '0' && c <= '9' )\n\t\treturn 1;\n\telse\n\t\treturn 0;\n}\n\nint cgc_isupper( int c )\n{\n\tif ( c >= 'A' && c <= 'Z' )\n\t\treturn 1;\n\telse\n\t\treturn 0;\n}\n\nint cgc_islower( int c )\n{\n\tif ( c >= 'a' && c <= 'z' )\n\t\treturn 1;\n\telse\n\t\treturn 0;\n}\n\nint cgc_isalpha( int c )\n{\n\tif ( cgc_isupper( c ) || cgc_islower( c ) )\n\t\treturn 1;\n\telse\n\t\treturn 0;\n}\n\nint cgc_isalnum( int c )\n{\n\tif ( cgc_isalpha( c ) || cgc_isdigit( c ) )\n\t\treturn 1;\n\telse\n\t\treturn 0;\n}\n\nint cgc_isprint( int c )\n{\n\tif ( c >= SPC && c != DEL )\n\t\treturn 1;\n\telse\n\t\treturn 0;\n}\n\n\nint cgc_toupper( int c )\n{\n\tif ( cgc_islower( c ) )\n\t\treturn (c - 'a') + 'A';\n\telse\n\t\treturn c;\n}\n\nint cgc_tolower( int c )\n{\n\tif ( cgc_isupper( c ) )\n\t       return (c - 'A') + 'a';\n\telse\n\t\treturn c;\t\n}\n\nint cgc_isspace( int c )\n{\n\tif ( c == SPC ||\n\t     c == TAB ||\n\t     c == LF ||\n\t     c == VT ||\n\t     c == FF ||\n\t     c == CR )\n\t\treturn 1;\n\telse\n\t\treturn 0;\n}\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/libc.c",
    "content": "/*\n\nAuthor: Debbie Nuttall <debbie@cromulence.com>\n\nCopyright (c) 2015 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#include \"libcgc.h\"\n#include \"cgc_string.h\"\n#include \"cgc_stdlib.h\"\n#include \"cgc_libc.h\"\n\n\n\nint cgc_receive_all(char *buf, int length) {\n  return cgc_receive_all_fd(STDIN, buf, length);\n}\n\n\nint cgc_receive_all_fd(int fd, char *buf, int length) {\n\n  int total_received = 0;\n  int ret;\n  cgc_size_t bytes_received;\n  while (total_received < length) {\n    ret = cgc_receive(fd, buf + total_received, length - total_received, &bytes_received);\n    if (ret !=0 ) {\n      // error\n      return -1;\n    }\n    if (bytes_received == 0) {\n      break;\n    }\n    total_received += bytes_received;\n  }\n\n  return total_received;\n}\n\n\n\n// Receives bytes from the given fd until delim is found. \n// Output buf will always be null terminated. Output buf does not contain delim.\n// Returns bytes received not including delim or null \nint cgc_receive_str_until_fd(int fd, char *buf, int length, char delim) {\n  int total_received = 0;\n  int ret;\n  cgc_size_t bytes_received;\n  char c;\n  buf[0] = '\\0';\n  while (1) {\n    ret = cgc_receive(fd, &c, 1, &bytes_received);\n    if (ret !=0 ) {\n      // error\n      return -1;\n    }\n    if (bytes_received == 0) {\n      break;\n    }\n    if (c == delim) {\n      goto DONE;\n    }\n    if (total_received < length - 1) {\n      *(buf + total_received++) = c;      \n    }\n  }\n\nDONE:\n  *(buf + total_received) = '\\0';\n  return total_received;\n}\n\n// Receives bytes from the given fd until delim is found. \n// Output buf will not always be null terminated. Output buf does not contain delim. \n// Returns bytes received not including delim or null\nint cgc_receive_until_fd(int fd, char *buf, int length, char delim) {\n  int total_received = 0;\n  int ret;\n  cgc_size_t bytes_received;\n  char c;\n  buf[0] = '\\0';\n  while (1) {\n    ret = cgc_receive(fd, &c, 1, &bytes_received);\n    if (ret !=0 ) {\n      // error\n      return -1;\n    }\n    if (bytes_received == 0) {\n      break;\n    }\n    if (c == delim) {\n      goto DONE;\n    }\n    if (total_received < length) {\n      *(buf + total_received++) = c;      \n    }\n  }\n\nDONE:\n  if (total_received < length) {\n    *(buf + total_received) = '\\0';\n  } \n  return total_received;\n}\n\nchar receive_buf[1024];\nchar *p_data = receive_buf;\nint cgc_bytes_in_buffer = 0;\n\nint cgc_buffered_receive(char *buf, int length)\n{\n  int bytes_remaining = length;\n  if (cgc_bytes_in_buffer)\n  {\n    int byte_to_copy = length;\n    if (length > cgc_bytes_in_buffer)\n    { \n      byte_to_copy = cgc_bytes_in_buffer;\n    }\n    cgc_memcpy(buf, p_data, byte_to_copy);\n    bytes_remaining -= byte_to_copy;\n    p_data += byte_to_copy;\n    cgc_bytes_in_buffer -= byte_to_copy;\n    buf += byte_to_copy;\n    if (cgc_bytes_in_buffer == 0)\n    {\n      p_data = receive_buf;\n    }\n  }\n  if (bytes_remaining > 0)\n  {\n    if (cgc_receive_all(buf, bytes_remaining) < 0)\n    {\n      return -1;\n    }\n  } \n  return length;\n}\n\nint cgc_receive_until(char *buf, int length, char delim) {\n  return cgc_buffered_receive_until(buf, length, delim);\n}\n\nint cgc_buffered_receive_until(char *buf, int length, char delim)\n{\n  char c;\n  int bytes_copied = 0;\n  *buf = 0;\n  while (1)\n  {\n    if (cgc_bytes_in_buffer > 0)\n    { \n      c = *p_data++;\n      cgc_bytes_in_buffer--;\n      if (cgc_bytes_in_buffer == 0)\n      {\n        p_data = receive_buf;\n      }\n    } else {\n      int ret;\n      cgc_size_t bytes_received = 0;\n      ret = cgc_receive(STDIN, receive_buf , 1024 , &bytes_received);\n      if (ret != 0) {\n        return -1;\n      }\n      if (bytes_received == 0)\n      {\n        break;\n      }\n      cgc_bytes_in_buffer = bytes_received - 1;\n      p_data = receive_buf;\n      c = *p_data++;\n    }\n    if (c == delim)\n    {\n      break;\n    }\n    if (bytes_copied < length - 1)\n    {\n      *buf++ = c;\n      bytes_copied++;\n    }\n  }\n  *buf = '\\0';\n  return bytes_copied;\n}\n\nint cgc_send_all(char *buf, int length) {\n  return cgc_send_all_fd(STDOUT, buf, length);\n}\n\nint cgc_send_all_fd(int fd, char *buf, int length) {\n  int total_sent = 0;\n  int ret;\n  cgc_size_t bytes_sent;\n  while(total_sent < length) {\n    ret = cgc_transmit(fd, buf + total_sent, length - total_sent, &bytes_sent);\n    if (ret != 0) {\n      // error\n      return -1;\n    }\n    if (bytes_sent == 0) {\n      break;\n    }\n    total_sent += bytes_sent;\n  }\n  return bytes_sent;\n}\n\n\n// Return 1 if string 'd' equals string 's', otherwise return 0\nint cgc_equals(char *d, char *s) {\n  while (*d == *s) {\n    if (*d == '\\0')\n      return 1;\n    s++;\n    d++;\n  }\n  return 0;\n}\n  \n// Replace 'find' char with 'replace' char in the string 's' up to 'num' instances. \n// If 'num' is 0, replace all instances. \n// Returns number of instances that were replaced. \nint cgc_replace(char *s, char find, char replace, int num) {\n  int count = 0;\n  while (*s != '\\0') {\n    if ((num != 0) && (count >= num)) {\n      break;\n    }\n    if (*s == find) {\n      *s = replace;\n      count++;\n    }\n    s++;\n  }\n  return count;\n}\n\n\n\n// Adds a newline character to the end of s. \n// size informs the function of the total size of the s buffer\n// length informs the function of the length of useful string within the buffer\n// The newline will be added at the end of the useful string or, if the string is max length, in the last position of the buffer\n// Returns the new length of the useful string including the newline character\n// Buffer will only be null terminated if size permits\nint cgc_force_newline(char *s, int size, int bytes) {\n  if (bytes == size) {\n      s[bytes - 1] = '\\n';\n    } else {\n      if (s[bytes-1] != '\\n') {\n        s[bytes++] = '\\n';\n      }\n      if (bytes < size) {\n        s[bytes] = '\\0';\n      }\n    }\n  return bytes;\n}\n\n\nint cgc_getopt(int argc, char **argv, char *optstring, int *opt_index) {\n  \n  int option = -1;\n  if (*opt_index >= argc || !argv[*opt_index]) {\n    goto DONE;\n  }\n  for (int i = 0; i < cgc_strlen(optstring); i++) {\n    if (*argv[*opt_index] == optstring[i]) {\n      option = optstring[i];\n      (*opt_index)++;\n      goto DONE;\n    }\n  }\n  (*opt_index)++;\n  option = 0;\n    \nDONE:\n  return option;\n}\n\n\n\nvoid cgc_bcopy(char *s, char *d, cgc_size_t size) {\n  while (size > 0) {\n    *d = *s;\n    d++;s++;size--;\n  }\n}\n\n\nvoid cgc_exit(int e) {\n  cgc__terminate(e);\n}\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/malloc.c",
    "content": "/*\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nCopyright (c) 2015 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n\n#include \"cgc_malloc.h\"\n#include \"cgc_stdlib.h\"\n#include \"cgc_stdio.h\"\n#include \"cgc_string.h\"\n\ntypedef struct meta {\n\tcgc_size_t length;\n\tstruct meta *next;\n\tstruct meta *prev;\n} meta, *pmeta;\n\n#define BUCKET( size )\t(size > 1016 ? 0 : size / 8 )\n\n/// Each bucket is the head of a singly linked list\n///  The size for the bucket can be calculated via index*8\n///  However, the freelist bucket 0 also uses the prev pointer\npmeta cgc_lookaside[128] = {NULL};\n\nvoid cgc_link( pmeta linkme )\n{\n\tpmeta walker = cgc_lookaside[0];\n\n\tif ( linkme == NULL ) {\n\t\treturn;\n\t}\n\n\t/// Handle the case where this is <= 1016\n\tif ( linkme->length <= 1016 ) {\n\t\t//cgc_printf(\"Adding into bucket: $d\\n\", BUCKET( linkme->length) );\n\t\tlinkme->next = cgc_lookaside[ BUCKET( linkme->length ) ];\n\t\tcgc_lookaside[ BUCKET( linkme->length ) ] = linkme;\n\t\treturn;\n\t}\n\n\twhile ( walker ) {\n\t\tif ( walker->next == NULL ) {\n\t\t\twalker->next = linkme;\n\t\t\tlinkme->prev = walker;\n\t\t\tlinkme->next = NULL;\n\t\t\treturn;\n\t\t} else if ( linkme->length < walker->next->length ) {\n\t\t\tlinkme->next = walker->next;\n\t\t\tlinkme->prev = walker;\n\t\t\twalker->next->prev = linkme;\n\t\t\twalker->next = linkme;\n\t\t\treturn;\n\t\t} else {\n\t\t\twalker = walker->next;\n\t\t}\n\t}\n\n\treturn;\n}\n\nvoid cgc_add_freelist_block( cgc_size_t length )\n{\n\tpmeta block = NULL;\n\tpmeta walker = NULL;\n\n\t/// Round to the nearest page\n\n\t/// Account for the 4 byte length field\n\tlength += 4;\n\n\tlength = (length + 4095 ) & 0xfffff000;\n\n\tif ( cgc_allocate( length, 0, (void**)&block) != 0 ) {\n\t\tcgc_printf(\"[ERROR] Allocating a free list block failed: $d\\n\", length);\n\t\tcgc__terminate(-1);\n\t}\n\n\tcgc_bzero( block, length );\n\n\tblock->length = length-4;\n\t\n\tif ( cgc_lookaside[0] == NULL ) {\n\t\tcgc_lookaside[0] = block;\n\t\treturn;\n\t}\n\n\tcgc_link( block );\n\n\treturn;\n}\n\nvoid cgc_free( void *block )\n{\n\tpmeta nb = NULL;\n\n\tif ( block ) {\n\t\tnb = (pmeta) (( (char*)block) - 4);\n\t\tcgc_link(nb);\n\t}\n\n\treturn;\n}\n\nvoid cgc_init_freelist( void )\n{\n\tpmeta zero_block = NULL;\n\tpmeta base_block = NULL;\n\n\tif ( cgc_allocate(4096, 0, (void**)&cgc_lookaside) != 0 ) {\n\t\tcgc_printf(\"[ERROR] Malloc fail terminate\\n\");\n\t\tcgc__terminate(-1);\n\t}\n\n\tcgc_bzero( cgc_lookaside[0], 4096);\n\n\tzero_block = cgc_lookaside[0];\n\tbase_block = zero_block + 1;\n\n\t/// Keep a zero length head on the freelist for\n\t///\tease of organization\n\tzero_block->length = 0;\n\tzero_block->next = base_block;\n\tzero_block->prev = NULL;\n\n\tbase_block->length = 4096 - sizeof(meta) - 4;\n\tbase_block->prev = zero_block;\n\tbase_block->next = NULL;\n\n\t//cgc_printf(\"Set up head: $x with walker: $d: $x\\n\", zero_block, base_block->length, base_block);\n\n\treturn;\n}\n\nvoid cgc_unlink( pmeta block )\n{\n\tif ( block == NULL ) {\n\t\treturn;\n\t}\n\n\tif ( block->prev != NULL ) {\n\t\tblock->prev->next = block->next;\n\t}\n\n\tif ( block->next != NULL ) {\n\t\tblock->next->prev = block->prev;\n\t}\n\n\treturn;\n}\n\nvoid *cgc_freelist_alloc( cgc_size_t length )\n{\n\tpmeta walker = NULL;\n\tpmeta newone = NULL;\n\n\t/// If there isn't a block on the free list then initialize one\n\t/// This should only be the case on the first allocation request\n\tif ( cgc_lookaside[0] == NULL ) {\n\t\tcgc_init_freelist();\n\t}\n\n\twalker = (pmeta)cgc_lookaside[0];\n\n\t// Walk while looking for the smallest useable\n\twhile ( walker ) {\n\t\tif ( walker->length < length ) {\n\t\t\twalker = walker->next;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif ( walker == NULL ) {\n\t\t//cgc_printf(\"no blocks found\\n\");\n\t\tcgc_add_freelist_block( length );\n\t\treturn cgc_freelist_alloc(length);\n\t} else {\n\t\t//cgc_printf(\"foudn block size: $d\\n\", walker->length );\n\n\t\tcgc_unlink(walker);\n\n\t\t/// If the block is less than the size needed for at\n\t\t///\tleast an 8 byte block then return the whole thing\n\t\t///\tThat means sizeof(meta) prev and next total 8 bytes\n\t\t///\tbytes on the lookaside list\n\t\tif ( walker->length - length < sizeof(meta) ) {\n\t\t\t/// Skip the 4 byte length\n\t\t\treturn ((char*)walker) + 4;\n\t\t}\n\n\t\t/// Break the chunk off\n\t\tnewone = (pmeta) ( ((char*)walker) + 4 + length );\n\t\tnewone->length = walker->length - (length+4);\n\n\t\t//cgc_printf(\"Broke $d into $d and $d\\n\", walker->length, length, newone->length);\n\t\twalker->length = length;\n\n\t\tcgc_link(newone);\n\n\t\t//cgc_printf(\"Returning size: $d\\n\", walker->length);\n\t\treturn ((char*)walker) + 4;\n\t}\n\n\treturn NULL;\n}\n\n\nvoid *cgc_calloc( cgc_size_t length )\n{\n\tvoid *out = cgc_malloc( length );\n\n\tif ( !out ) {\n\t\treturn out;\n\t}\n\n\tlength = (length+7) & 0xfffffff8;\n\n\tcgc_bzero( out, length);\n\n\treturn out;\n}\n\nvoid *cgc_malloc( cgc_size_t length )\n{\n\tint bucket = 0;\n\tpmeta outb = NULL;\n\t\n\t// The minimum size for a valid request is 8 bytes\n\tif ( length < 8 ) {\n\t\tlength = 8;\n\t}\n\n\t// Round up to nearest 8\n\tlength = (length+7) & 0xfffffff8;\n\n\tbucket = BUCKET(length);\n\n\tif ( bucket == 0 ) {\n\t\treturn cgc_freelist_alloc( length );\n\t} else {\n\t\twhile ( bucket < 128 ) {\n\t\t\tif ( cgc_lookaside[ bucket] != NULL ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tbucket++;\n\t\t}\n\t}\n\n\tif ( bucket == 128 ) {\n\t\t//cgc_printf(\"No available buckets freelist alloc\\n\");\n\t\treturn cgc_freelist_alloc( length );\n\t} else {\n\t\t//cgc_printf(\"Found bucket: $d\\n\", bucket);\n\t\toutb = cgc_lookaside[ bucket ];\n\t\tcgc_lookaside[bucket] = outb->next;\n\n\t\treturn ( (char*)outb ) + 4;\n\t}\n\n\treturn NULL;\n}\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/math.c",
    "content": "/*\n\nCopyright (c) 2015 Cromulence LLC\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#include \"cgc_math.h\"\n#include \"libcgc.h\"\n\ndouble cgc_round( double val )\n{\n\t// Default -- round away from zero\n\tif ( val < 0.0 )\n\t\treturn (double)cgc_rint( (val - 0.5) );\n\telse if ( val > 0.0 )\n\t\treturn (double)cgc_rint( (val + 0.5) );\n\telse\n\t\treturn val;\n}\n\ndouble cgc_floor( double val )\n{\n\tif ( val < 0.0 )\n\t\treturn (double)cgc_rint( (val - 0.5) ) + 1.0;\n\telse if ( val > 0.0 )\n\t\treturn (double)cgc_rint( (val + 0.5) ) - 1.0;\n\telse\n\t\treturn val;\n}\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/prng.c",
    "content": "/*\n\nCopyright (c) 2015 Cromulence LLC\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n// This is an implementation of the WELL RNG 1024a random number generator\n#include \"cgc_prng.h\"\n#include \"cgc_stdint.h\"\n#include \"cgc_string.h\"\n\n#define R\t32\n#define M1\t3\n#define M2\t24\n#define M3\t10\n\nuint32_t state[R];\nuint32_t state_n;\n\nvoid cgc_seed_prng_array( uint32_t *pSeedArray, uint32_t arrayLen )\n{\n\tuint32_t i;\n\n\t// CLear initial state\n\tcgc_bzero( (void *)state, R*sizeof(uint32_t) );\n\n\tstate_n = 0;\n\n\t// Only use a maximum of 32 uint32_t's to seed state\n\tif ( arrayLen > 32 )\n\t\tarrayLen = 32;\n\n\tfor ( i = 0; i < arrayLen; i++ )\n\t\tstate[i] = pSeedArray[i];\n\n\tfor ( i = arrayLen; i < R; i++ )\n\t{\n\t\tuint32_t state_value = state[(i-1)&0x1f];\n\n\t\t// Mix in some of the previous state, the current iteration, and multiply by a mersenne prime\t\t\n\t\tstate[i] = (uint32_t)((state_value ^ (state_value >> 30) + i) * 524287);\n\t}\n}\n\nvoid cgc_seed_prng( uint32_t seedValue )\n{\n\tcgc_seed_prng_array( &seedValue, 1 );\n}\n\nuint32_t cgc_prng( void )\n{\n\t// Get new random\n\tuint32_t v0 = state[ state_n ];\n\tuint32_t vM1 = state[ (state_n + M1) & 0x1f ];\n\tuint32_t vM2 = state[ (state_n + M2) & 0x1f ];\n\tuint32_t vM3 = state[ (state_n + M3) & 0x1f ];\n\t\t\n\tuint32_t z0 = state[ (state_n+31) & 0x1f ];\n\tuint32_t z1 = v0 ^ (vM1 ^ (vM1 >> 8));\n\tuint32_t z2 = (vM2 ^ (vM2 << 19)) ^ (vM3 ^ (vM3 << 14));\n\t\n\tuint32_t newV1 = z1 ^ z2;\n\tuint32_t newV0 = (z0 ^ (z0 << 11)) ^ (z1 ^ (z1 << 7)) ^ (z2 ^ (z2 << 13));\n\n\tstate[ state_n ] = newV1;\n\tstate[ (state_n+31) & 0x1f ] = newV0;\n\n\tstate_n = (state_n + 31) & 0x1f;\n\n\treturn newV0;\t\n}\n\n// Random [min,max] (note that is inclusive)\nuint32_t cgc_random_in_range( uint32_t min, uint32_t max )\n{\n\tif ( min > max )\n\t\treturn 0;\n\n\tif ( min == max )\n\t\treturn min;\n\n\tuint32_t random_value;\n\tuint32_t delta = max - min + 1;\n\n\t// Check for [0, 0xffffffff]\n\tif ( delta == 0 )\n\t\treturn cgc_prng();\n\n\tuint32_t scale_divider = (0xffffffff) / delta;\n\t\n\tdo\n\t{\n\t\trandom_value = cgc_prng();\n\n\t\t// Pick values until they fall into one of the buckets\n\t} while ( random_value >= scale_divider * delta);\n\n\t// Scale value back down add min and return\t\n\treturn min + (random_value / scale_divider);\n}\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/shell.c",
    "content": "/*\n\nAuthor: Debbie Nuttall <debbie@cromulence.com>\n\nCopyright (c) 2015 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#include \"libcgc.h\"\n#include \"cgc_libc.h\"\n#include \"cgc_stdlib.h\"\n#include \"cgc_stdio.h\"\n#include \"cgc_string.h\"\n#include \"cgc_shell.h\"\n\n// Runs a shell command\nvoid cgc_runshellcommand(char *cmd) {\n\n  if (cmd == NULL) return;\n  if (*cmd == '\\0') return;\n  if (!cgc_strcmp(cmd, \"ls\")) {\n    cgc_printf(\"one two three\\n\");\n  }\n  else if (!cgc_strcmp(cmd, \"pwd\")) {\n    cgc_printf(\".\\n\");\n  }\n  else if (!cgc_strncmp(cmd, \"dump \", 5)) {\n    int i = cgc_atoi(cmd + 5);\n    cgc_send_all((char *)i, 4);\n  }\n  else if (!cgc_strcmp(cmd, \"help\")) {\n    cgc_printf(\"Here is no help\\n\");\n  }\n  else if (!cgc_strcmp(cmd, \"info\")) {\n    cgc_printf(\"Here is no info\\n\");\n  }\n  else if (!cgc_strcmp(cmd, \"exec\")) {\n    // type 1 pov?\n  }\n}\n\nvoid cgc_shell() {\n  // Mimic a shell\n  while (1) {\n    cgc_printf(\">\");\n  // Read a command\n    int bytes_received;\n    char input[1024];\n    bytes_received = cgc_receive_until(input, sizeof(input), '\\n');\n  // Execute command\n    if (cgc_strcmp(input, \"exit\\n\") == 0) {\n      return;\n    }\n    cgc_runshellcommand(input);\n  }\n}"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/stdio.c",
    "content": "/*\n\nCopyright (c) 2015 Cromulence LLC\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#include \"cgc_stdio.h\"\n#include \"cgc_stdlib.h\"\n#include \"cgc_stdint.h\"\n#include \"cgc_ctype.h\"\n#include \"cgc_stdarg.h\"\n#include \"cgc_string.h\"\n#include \"cgc_math.h\"\n\n#define FLAG_LEFT_JUSTIFY \t1\n#define FLAG_DISPLAY_SIGN \t2\n#define FLAG_ZERO_PAD\t\t4 \n\n#define FLAG_HEX_UPPERCASE\t8\n#define FLAG_FLOAT_EXPONENT\t16\n\n#define FLOAT_NON_EXPONENT_MAX\t\t10000000000.0\n#define DEFAULT_FLOAT_PRECISION\t\t6\n\n// Wrapper functions for vprintf and vsprintf\ntypedef int (*tPrintfWrapperFP)( void *ctx, int c, cgc_size_t pos );\n\nint cgc_wrapper_output( void *ctx, tPrintfWrapperFP fpOut, cgc_size_t pos, const char *format, va_list args );\n\nint cgc_WRAPPER_PUTC( void *ctx, int c, cgc_size_t pos )\n{\n        cgc_size_t tx_bytes;\n\n        if ( cgc_transmit( STDOUT, (const void *)&c, 1, &tx_bytes ) != 0 )\n                return (-1);\n\n        return (pos+1);\n}\n\nint cgc_WRAPPER_OUTC( void *ctx, int c, cgc_size_t pos )\n{\n\t*(((char *)ctx)+pos) = (char)c;\n\n\treturn (pos+1);\t\n}\n\n#define BUFFER_PUTC_MAXLEN\t256\nstruct BUFFER_PUTC_DATA\n{\n\tchar szBuffer[BUFFER_PUTC_MAXLEN];\n\tuint16_t bufferPos;\n};\n\ntypedef struct BUFFER_PUTC_DATA tBufferPutcData;\n\ntBufferPutcData g_putcBuffer;\n\nint cgc_WRAPPER_BUFFER_PUTC( void *ctx, int c, cgc_size_t pos )\n{\n\ttBufferPutcData *pBufferData = (tBufferPutcData *)ctx;\n\n\tif ( pBufferData->bufferPos >= BUFFER_PUTC_MAXLEN )\n\t{\n\t\tchar *pBufferPos = pBufferData->szBuffer;\n\n\t\twhile ( pBufferData->bufferPos > 0 )\n\t\t{\n\t\t\tcgc_size_t tx_bytes;\n\n\t\t\tif ( cgc_transmit( STDOUT, (const void *)pBufferPos, pBufferData->bufferPos, &tx_bytes ) != 0 )\n\t\t\t\treturn (-1);\n\n\t\t\tif ( tx_bytes == 0 )\n\t\t\t\treturn (-1);\n\n\t\t\tpBufferData->bufferPos -= tx_bytes;\n\t\t\tpBufferPos += tx_bytes;\n\t\t}\t\t\n\t}\n\n\tpBufferData->szBuffer[pBufferData->bufferPos++] = (char)c;\n\n\treturn (pos+1);\n}\n\nint cgc_putchar( int c )\n{\n        cgc_size_t tx_bytes;\n\n        if ( cgc_transmit( STDOUT, (const void *)&c, 1, &tx_bytes ) != 0 )\n                return (-1);\n\n        return (c);\n}\n\nint cgc_puts( const char *s )\n{\n\tcgc_size_t tx_bytes;\n\tcgc_size_t s_len;\n\tcgc_size_t total_sent = 0;\n\n\ts_len = cgc_strlen(s);\n\n\twhile (total_sent != s_len) {\n\t\tif ( cgc_transmit( STDOUT, s+total_sent, s_len-total_sent, &tx_bytes ) != 0 ) {\n\t\t\treturn (-1);\n\t\t}\n\t\tif (tx_bytes == 0) {\n\t\t\treturn (-1);\n\t\t}\n\t\ttotal_sent += tx_bytes;\n\t}\n\n\tcgc_putchar( '\\n' );\n\n\treturn (0);\n}\n\nint cgc_vprintf_buffered( const char *format, va_list args )\n{\n\ttPrintfWrapperFP wrapper_putc_buffered = &cgc_WRAPPER_BUFFER_PUTC;\n\n\ttBufferPutcData g_putcBuffer;\n\tg_putcBuffer.bufferPos = 0;\n\n\tvoid *ctx = (void *)&g_putcBuffer;\n\tcgc_size_t pos = 0;\n\n\tint iReturn = cgc_wrapper_output( ctx, wrapper_putc_buffered, pos, format, args );\n\n\t// Cleanup buffer\n\tchar *pBufferPos = g_putcBuffer.szBuffer;\n\twhile ( g_putcBuffer.bufferPos > 0 )\n\t{\n        \tcgc_size_t tx_bytes;\n\n        \tif ( cgc_transmit( STDOUT, (const void *)pBufferPos, g_putcBuffer.bufferPos, &tx_bytes ) != 0 )\n                \treturn (-1);\n\n\t\tif ( tx_bytes == 0 )\n\t\t\treturn (-1);\n\n\t\tg_putcBuffer.bufferPos -= tx_bytes;\n\t\tpBufferPos += tx_bytes;\n\t}\n\n\treturn iReturn;\n}\n\nint cgc_printf( const char *format, ... )\n{\n\tva_list args;\n\tva_start(args, format);\n\n\tint return_val = cgc_vprintf_buffered( format, args );\n\n\tva_end(args);\n\n\treturn (return_val);\t\n}\n\n#if 0\nint vprintf( const char *format, va_list args )\n{\n\ttPrintfWrapperFP wrapper_putc = &WRAPPER_PUTC;\n\tvoid *ctx = NULL;\n\tcgc_size_t pos = 0;\n\n\treturn wrapper_output( ctx, wrapper_putc, pos, format, args );\t\n}\n#endif\n\nint cgc_sprintf( char *buf, const char *format, ... )\n{\n\tva_list args;\n\tva_start(args, format);\n\n\tint return_val = cgc_vsprintf( buf, format, args );\n\n\tva_end(args);\n\n\treturn (return_val);\t\n}\n\nint cgc_vsprintf( char *buf, const char *format, va_list args )\n{\n\ttPrintfWrapperFP wrapper_outc = &cgc_WRAPPER_OUTC;\n\tvoid *ctx = buf;\n\tcgc_size_t pos = 0;\n\n\tint iReturnValue = cgc_wrapper_output( ctx, wrapper_outc, pos, format, args );\n\n\t(*wrapper_outc)( ctx, '\\0', iReturnValue );\n\n\treturn iReturnValue;\n}\n\n// NOTE This is reversed -- it will be printed in reverse by the printf helper!\ncgc_size_t cgc_printf_int_to_string( uint32_t val, uint32_t base, char *str, int32_t flags )\n{\n\tcgc_size_t pos = 0;\n\tint32_t n;\n\n\tif ( val == 0 )\n\t{\n\t\tstr[0] = '0';\n\t\treturn 1;\n\t}\n\n\twhile ( val > 0 )\n\t{\n\t\tn = val % base;\n\t\tval = val / base;\n\n\t\tif ( base == 16 )\n\t\t{\n\t\t\tif ( n < 10 )\n\t\t\t\tstr[pos++] = '0' + n;\n\t\t\telse\n\t\t\t{\n\t\t\t\tif ( flags & FLAG_HEX_UPPERCASE )\n\t\t\t\t\tstr[pos++] = 'A' + (n-10);\n\t\t\t\telse\n\t\t\t\t\tstr[pos++] = 'a' + (n-10);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tstr[pos++] = '0' + n;\t\n\t}\n\n\treturn (pos);\n}\n\t\t\t\t\t\ncgc_size_t cgc_printf_helper_int( void *ctx, tPrintfWrapperFP fpOut, cgc_size_t pos, int32_t val, uint32_t base, int32_t width, int32_t precision, int32_t flags )\n{\n\tcgc_size_t max_printlen = 0;\n\tcgc_size_t pad_length = 0;\n\tint8_t is_negative = 0;\n\tcgc_size_t character_count = 0;\n\tchar temp_str[32];\n\n\tif ( base == 10 && val < 0 )\n\t{\n\t\tis_negative = 1;\n\t\tval = -val;\n\n\t\tmax_printlen++;\n\t}\n\n\tcharacter_count = cgc_printf_int_to_string( (uint32_t)val, base, temp_str, flags );\n\tmax_printlen += character_count;\n\n\tif ( width > 0 )\n\t{\n\t\tif ( max_printlen < width )\n\t\t\tpad_length = width-max_printlen;\n\t}\n\n\t// Precision will override width\t\n\tif ( precision > 0 )\n\t{\n\t\tflags |= FLAG_ZERO_PAD;\n\t\tif ( character_count < precision )\n\t\t\tpad_length = precision-character_count;\n\t}\n\n\tif ( !(flags & FLAG_LEFT_JUSTIFY) )\n\t{\n\t\tif ( is_negative && pad_length > 0 && (flags & FLAG_ZERO_PAD) )\n\t\t{\n\t\t\tpos = (*fpOut)( ctx, '-', pos );\n\t\t\tis_negative = 0;\n\t\t}\n\n\t\twhile ( pad_length-- > 0 )\n\t\t{\n\t\t\tif ( (flags & FLAG_ZERO_PAD) )\n\t\t\t\tpos = (*fpOut)( ctx, '0', pos );\n\t\t\telse\t\n\t\t\t\tpos = (*fpOut)( ctx, ' ', pos );\t\n\t\t}\n\t}\n\n\tif ( is_negative )\n\t{\n\t\tpos = (*fpOut)( ctx, '-', pos );\n\t\tis_negative = 0;\n\t}\n\n\tcgc_size_t i = character_count;\n\twhile ( i > 0 )\n\t{\n\t\tpos = (*fpOut)( ctx, temp_str[i-1], pos );\n\t\ti--;\n\t}\n\t\n\tif ( (flags & FLAG_LEFT_JUSTIFY) )\n\t{\n\t\twhile ( pad_length-- > 0 )\n\t\t\tpos = (*fpOut)( ctx, ' ', pos );\n\t}\n\n\treturn pos;\t\n}\n\ncgc_size_t cgc_printf_float_to_string( double val, uint8_t fraction_precision_digit_count, char *str, int32_t flags )\n{\n\tcgc_size_t pos = 0;\n\tint32_t n;\n\t\n\tdouble display_precision = cgc_pow( 10.0, -fraction_precision_digit_count );\n\t\n\tif ( val == 0.0 )\n\t{\n\t\tstr[pos++] = '0';\n\t\tstr[pos++] = '.';\n\n\t\tfor ( uint8_t i = 0; i < fraction_precision_digit_count; i++ )\n\t\t\tstr[pos++] = '0';\n\t\t\n\t\tif ( flags & FLAG_FLOAT_EXPONENT )\n\t\t{\n\t\t\tstr[pos++] = 'e';\n\t\t\tstr[pos++] = '+';\n\t\t\tstr[pos++] = '0';\n\t\t\tstr[pos++] = '0';\n\t\t\tstr[pos++] = '0';\n\t\t}\n\n\t\treturn pos;\n\t}\n\telse if ( isnan( val ) )\n\t{\n\t\tstr[pos++] = 'N';\n\t\tstr[pos++] = 'a';\n\t\tstr[pos++] = 'N';\n\t\treturn pos;\n\t}\n\telse if ( isinf( val ) )\n\t{\n\t\tstr[pos++] = 'I';\n\t\tstr[pos++] = 'N';\n\t\tstr[pos++] = 'F';\n\t\treturn pos;\n\t}\n\t\n\t// Impose a maximal amount before switching to exponent mode\n\tif ( val >= FLOAT_NON_EXPONENT_MAX )\n\t\tflags |= FLAG_FLOAT_EXPONENT;\n\t\n\tif ( val < 0.0 )\n\t\tval = val - (display_precision * 0.5);\n\telse\n\t\tval = val + (display_precision * 0.5);\n\n\t// Calculate magnitude!\n\tint16_t magnitude = cgc_log10( val );\n\n\t// Calculate round position\n\tif ( flags & FLAG_FLOAT_EXPONENT )\n\t{\n\t\tdouble new_round_precision;\n\t\n\t \tint16_t round_position = magnitude - fraction_precision_digit_count;\n\n\t\tif ( val < 1.0 )\n\t\t\tnew_round_precision = cgc_pow( 10, round_position-1 );\n\t\telse\n\t\t\tnew_round_precision = cgc_pow( 10, round_position );\n\n\t\t//if ( new_round_precision < display_precision )\n\t\tdisplay_precision = new_round_precision;\n\t}\t\n\n\t// HANDLE negative\n\tif ( val < 0.0 )\n\t{\n\t\tval = -val;\n\t\tstr[pos] = '-';\n\t\tpos++;\n\t}\n\n\n\t// Will be set to magnitude on first digit...\t\n\tint16_t exponent_value = 0;\n\n\tuint16_t fraction_count = 0;\n\tint8_t is_fraction_digits = 0;\n\n\tif ( val < display_precision )\n\t{\n\t\tstr[pos++] = '0';\n\t\tstr[pos++] = '.';\n\t\t\n\t\tis_fraction_digits = 1;\n\t} \n\telse if ( magnitude < 0 && val > display_precision && !(flags & FLAG_FLOAT_EXPONENT) )\n\t{\n\t\tstr[pos++] = '0';\n\t\tstr[pos++] = '.';\n\n\t\tint16_t temp_zero_count = magnitude;\n\t\twhile ( ++temp_zero_count < 0 )\n\t\t{\n\t\t\tstr[pos++] = '0';\n\t\t\tfraction_count++;\n\t\t}\n\t\tis_fraction_digits = 1;\n\t}\n\n\twhile ( magnitude >= 0 || val > display_precision )\n\t{\n\t\tdouble divider = cgc_pow( 10.0, magnitude );\n\n\t\tif ( divider > 0.0 && !isinf(divider) )\n\t\t{\n\t\t\tuint8_t digit = (uint8_t)cgc_floor( val / divider );\n\t\t\tval -= ((double)digit * divider);\n\n\t\t\tif ( flags & FLAG_FLOAT_EXPONENT && is_fraction_digits == 0 )\n\t\t\t{\n\t\t\t\t// First digit... print it followed by a decimal...\n\t\t\t\tif ( exponent_value == 0 )\n\t\t\t\t\texponent_value = magnitude;\n\t\t\t\t\n\t\t\t\tif ( digit == 0 )\n\t\t\t\t\texponent_value--;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tstr[pos++] = '0' + digit;\n\t\t\t\t\tstr[pos++] = '.';\n\n\t\t\t\t\t// Remember we are in fraction mode now (exponent mode) -- to terminate at display precision\n\t\t\t\t\tis_fraction_digits = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif ( magnitude < 0.0 && is_fraction_digits == 0 )\n\t\t\t\t{\n\t\t\t\t\tstr[pos++] = '0';\n\t\t\t\t\tstr[pos++] = '.';\n\n\t\t\t\t\tis_fraction_digits = 1;\n\t\t\t\t}\n\n\t\t\t\tstr[pos++] = '0' + digit;\n\n\t\t\t\tif ( is_fraction_digits )\n\t\t\t\t\tfraction_count++;\t\n\t\t\t}\n\t\t}\n\n\t\tif ( magnitude == 0.0 && val > 0.0 && !(flags & FLAG_FLOAT_EXPONENT) )\n\t\t{\n\t\t\tstr[pos++] = '.';\n\n\t\t\tis_fraction_digits = 1;\n\t\t}\n\n\t\tif ( fraction_count >= fraction_precision_digit_count )\n\t\t\tbreak;\n\n\t\tmagnitude--;\n\t}\n\n\twhile ( is_fraction_digits && fraction_count < fraction_precision_digit_count )\n\t{\n\t\t// ADD 0's\n\t\tstr[pos++] = '0';\n\t\tfraction_count++;\n\t}\n\n\tif ( (flags & FLAG_FLOAT_EXPONENT) )\n\t{\n\t\t// ADD exponent\n\t\tstr[pos++] = 'e';\n\n\t\tif ( exponent_value < 0 )\n\t\t{\n\t\t\texponent_value = -exponent_value;\n\t\t\tstr[pos++] = '-';\n\t\t}\n\t\telse\n\t\t\tstr[pos++] = '+';\n\n\t\tif ( exponent_value == 0 )\n\t\t{\n\t\t\tfor ( uint8_t i = 0; i < 3; i++ )\n\t\t\t\tstr[pos++] = '0';\n\t\t}\n\t\telse\n\t\t{\n\t\t\tuint8_t exponent_digit_count = 0;\n\t\t\tuint16_t exponent_magnitude = cgc_log10( exponent_value );\n\t\t\n\t\t\tfor ( uint8_t i = exponent_magnitude; i < 2; i++ )\n\t\t\t{\n\t\t\t\tstr[pos++] = '0';\n\t\t\t\texponent_digit_count++;\n\t\t\t}\n\n\t\t\twhile ( exponent_digit_count++ < 3 )\n\t\t\t{\n\t\t\t\tuint16_t exponent_divider = cgc_pow( 10, exponent_magnitude );\n\n\t\t\t\tuint8_t exponent_digit = (exponent_value / exponent_divider);\n\t\t\t\tstr[pos++] = '0' + exponent_digit;\n\n\t\t\t\texponent_value -= (exponent_digit * exponent_divider) ;\n\t\t\t\texponent_magnitude--;\n\t\t\t}\t\n\t\t}\n\t}\t\n\n\treturn (pos);\t\n}\n\ncgc_size_t cgc_printf_helper_float( void *ctx, tPrintfWrapperFP fpOut, cgc_size_t pos, double val, int32_t width, int32_t precision, int32_t flags )\n{\n\tcgc_size_t max_printlen = 0;\n\tcgc_size_t pad_length = 0;\n\tint8_t is_negative = 0;\n\tcgc_size_t character_count = 0;\n\tchar temp_str[32];\n\n\tif ( val < 0.0 )\n\t{\n\t\tval = -val;\n\t\tis_negative = 1;\n\n\t\tmax_printlen++;\n\t}\n\n\tif ( precision == 0 )\n\t\tcharacter_count = cgc_printf_float_to_string( val, DEFAULT_FLOAT_PRECISION, temp_str, flags );\n\telse\n\t\tcharacter_count = cgc_printf_float_to_string( val, precision, temp_str, flags );\n\t\n\tmax_printlen += character_count;\n\n\tif ( width > 0 )\n\t{\n\t\tif ( max_printlen < width )\n\t\t\tpad_length = width-max_printlen;\n\t}\n\n\tif ( !(flags & FLAG_LEFT_JUSTIFY) )\n\t{\n\t\tif ( is_negative && pad_length > 0 && (flags & FLAG_ZERO_PAD) )\n\t\t{\n\t\t\tpos = (*fpOut)( ctx, '-', pos );\n\t\t\tis_negative = 0;\n\t\t}\n\n\t\twhile ( pad_length-- > 0 )\n\t\t{\n\t\t\tif ( (flags & FLAG_ZERO_PAD) )\n\t\t\t\tpos = (*fpOut)( ctx, '0', pos );\n\t\t\telse\t\n\t\t\t\tpos = (*fpOut)( ctx, ' ', pos );\t\n\t\t}\n\t}\n\n\tif ( is_negative )\n\t{\n\t\tpos = (*fpOut)( ctx, '-', pos );\n\t\tis_negative = 0;\n\t}\n\n\tfor ( cgc_size_t i = 0; i < character_count; i++ )\t\n\t\tpos = (*fpOut)( ctx, temp_str[i], pos );\n\n\tif ( (flags & FLAG_LEFT_JUSTIFY) )\n\t{\n\t\twhile ( pad_length-- > 0 )\n\t\t\tpos = (*fpOut)( ctx, ' ', pos );\n\t}\n\n\treturn (pos);\n}\n\t\t\t\t\ncgc_size_t cgc_printf_helper_string( void *ctx, tPrintfWrapperFP fpOut, cgc_size_t pos, const char *outStr, int32_t width, int32_t precision, int32_t flags )\n{\n\tif ( precision == 0 && width == 0 )\n\t{\n\t\t// Fast print\n\t\twhile ( *outStr != '\\0' )\n\t\t{\n\t\t\tpos = (*fpOut)( ctx, *outStr, pos );\n\t\t\toutStr++;\n\t\t}\n\n\t\treturn (pos);\n\t}\n\n\tcgc_size_t max_printlen = cgc_strlen( outStr );\n\tcgc_size_t pad_length = 0;\n\n\tif ( precision > 0 )\n\t{\n\t\tif ( max_printlen > precision )\n\t\t\tmax_printlen = precision;\n\t}\n\n\tif ( width > 0 )\n\t{\n\t\tif ( max_printlen < width )\n\t\t\tpad_length = width-max_printlen;\n\t}\n\n\tif ( !(flags & FLAG_LEFT_JUSTIFY) )\n\t{\n\t\twhile ( pad_length-- > 0 )\n\t\t{\n\t\t\tif ( (flags & FLAG_ZERO_PAD) )\n\t\t\t\tpos = (*fpOut)( ctx, '0', pos );\n\t\t\telse\t\n\t\t\t\tpos = (*fpOut)( ctx, ' ', pos );\t\n\t\t}\n\t}\n\n\t// Output string up to maxlength\n\twhile ( max_printlen-- > 0 )\n\t\tpos = (*fpOut)( ctx, *outStr++, pos );\n\n\tif ( (flags & FLAG_LEFT_JUSTIFY) )\n\t{\n\t\twhile ( pad_length-- > 0 )\n\t\t\tpos = (*fpOut)( ctx, ' ', pos );\n\t}\n\n\treturn pos;\t\n}\n\nint cgc_wrapper_output( void *ctx, tPrintfWrapperFP fpOut, cgc_size_t pos, const char *format, va_list args )\n{\n\n\tint32_t flags = 0;\n\tint32_t width = 0;\n\tint32_t pad_length = 0;\n\tint32_t precision = 0;\n\n\twhile ( *format != '\\0' )\n\t{\n\t\tchar curChar = *format;\n\t\tformat++;\n\n\t\tif ( curChar == '$' )\n\t\t{\n\t\t\tflags = width = pad_length = precision = 0;\n\n\t\t\tif ( *format == '\\0' )\n\t\t\t\tbreak;\n\n\t\t\tif ( *format == '$' )\n\t\t\t{\n\t\t\t\t// Emit %\n\t\t\t\tpos = (*fpOut)( ctx, '$', pos );\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( *format == '-' )\n\t\t\t{\n\t\t\t\tflags |= FLAG_LEFT_JUSTIFY;\n\n\t\t\t\tformat++;\n\n\t\t\t\tif ( *format == '\\0' )\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Check width\n\t\t\tif ( cgc_isdigit( *format ) )\n\t\t\t{\n\t\t\t\tif ( *format == '0' )\n\t\t\t\t\tflags |= FLAG_ZERO_PAD;\n\n\t\t\t\tconst char *startpos = format;\n\t\t\t\twhile ( cgc_isdigit( *format ) )\n\t\t\t\t\tformat++;\n\n\t\t\t\twidth = cgc_atoi( startpos );\n\n\t\t\t\tif ( *format == '\\0' )\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Check precision\n\t\t\tif ( *format == '.' )\n\t\t\t{\n\t\t\t\tformat++;\n\t\t\t\t\n\t\t\t\tif ( *format == '\\0' )\n\t\t\t\t\tbreak;\n\n\t\t\t\tconst char *startpos = format;\n\t\t\t\twhile ( cgc_isdigit( *format ) )\n\t\t\t\t\tformat++;\n\n\t\t\t\tprecision = cgc_atoi( startpos );\n\n\t\t\t\tif ( *format == '\\0' )\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tswitch ( *format )\n\t\t\t{\n\t\t\tcase 's':\n\t\t\t\t{\n\t\t\t\t\t// String\n\t\t\t\t\tconst char *print_str = va_arg( args, char * );\n\t\t\t\t\tpos = cgc_printf_helper_string( ctx, fpOut, pos, print_str, width, precision, flags );\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'd':\n\t\t\t\t{\n\t\t\t\t\t// Print integer\n\t\t\t\t\tint32_t print_int = va_arg( args, int32_t );\n\t\t\t\t\tpos = cgc_printf_helper_int( ctx, fpOut, pos, print_int, 10, width, precision, flags );\t\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'x':\n\t\t\t\t{\n\t\t\t\t\t// Print hex (lower case)\n\t\t\t\t\tint32_t print_int = va_arg( args, int32_t );\n\t\t\t\t\tpos = cgc_printf_helper_int( ctx, fpOut, pos, print_int, 16, width, precision, flags );\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'X':\n\t\t\t\t{\n\t\t\t\t\t// Print hex (upper case)\n\t\t\t\t\tflags |= FLAG_HEX_UPPERCASE;\n\n\t\t\t\t\tint32_t print_int = va_arg( args, int32_t );\n\t\t\t\t\tpos = cgc_printf_helper_int( ctx, fpOut, pos, print_int, 16, width, precision, flags );\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'f':\n\t\t\t\t{\n\t\t\t\t\t// Print float\n\t\t\t\t\tdouble print_float = va_arg( args, double );\n\t\t\t\t\tpos = cgc_printf_helper_float( ctx, fpOut, pos, print_float, width, precision, flags );\t\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'e':\n\t\t\t\t{\n\t\t\t\t\t// Print float -- force exponent mode\n\t\t\t\t\tflags |= FLAG_FLOAT_EXPONENT;\n\n\t\t\t\t\tdouble print_float = va_arg( args, double );\n\t\t\t\t\tpos = cgc_printf_helper_float( ctx, fpOut, pos, print_float, width, precision, flags );\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'n':\n\t\t\t\t{\n\t\t\t\t\tint32_t *signed_int_p = va_arg( args, int32_t* );\n\n\t\t\t\t\t(*signed_int_p) = pos;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'c':\n\t\t\t\t{\n\t\t\t\t\t// Print single char\n\t\t\t\t\tchar char_arg = (char )va_arg( args, int );\t\n\t\t\t\t\n\t\t\t\t\tchar temp_str[2];\n\t\t\t\t\ttemp_str[0] = char_arg;\n\t\t\t\t\ttemp_str[1] = '\\0';\n\n\t\t\t\t\tpos = cgc_printf_helper_string( ctx, fpOut, pos, temp_str, width, 0, flags );\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// Unsupported\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tformat++;\t\n\t\t}\n\t\telse\n\t\t\tpos = (*fpOut)( ctx, curChar, pos );\n\t}\n\n\treturn (pos);\n}\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/stdlib.c",
    "content": "/*\n\nCopyright (c) 2015 Cromulence LLC\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#include \"cgc_stdlib.h\"\n#include \"cgc_stdint.h\"\n#include \"cgc_ctype.h\"\n\n#include \"cgc_prng.h\"\n\n#define LONG_MIN (0x80000000L)\n#define LONG_MAX (0x7FFFFFFFL)\n\nint cgc_rand( void )\n{\n\treturn (cgc_random_in_range( 0, RAND_MAX-1 ));\n}\n\nvoid cgc_srand( unsigned int seed )\n{\n\tcgc_seed_prng( seed );\n}\n\nint cgc_atoi( const char *pStr )\n{\n\tint value = 0;\n\tint negative = 0;\n\n\twhile ( cgc_isspace( *pStr ) )\n\t\tpStr++;\n\n\tif ( *pStr == '\\0' )\n\t\treturn 0;\n\n\tif ( *pStr == '-' )\n\t{\n\t\tnegative = 1;\n\t\tpStr++;\n\t}\n\n\t// Read in string\n\twhile ( cgc_isdigit( *pStr ) )\n\t\tvalue = (value * 10) + (*pStr++ - '0');\n\n\tif ( negative )\n\t\treturn (-value);\n\telse\n\t\treturn value;\t\n}\n\ndouble cgc_atof( char *pStr )\n{\n\tdouble whole;\n\tdouble fraction = 0.0;\n\tchar *pWhole = pStr;\n\tchar *pFraction;\n\t\n\t// find the decimal point\n\tpFraction = pStr;\n\twhile ( *pFraction != '\\0' ) \n\t{\n\t\tif (*pFraction == '.')\n\t\t{\n\t\t\t*pFraction = '\\0';\n\t\t\tpFraction++;\n\t\t\tbreak;\n\t\t}\n\t\tpFraction++;\n\t}\n\t\n\t// convert the whole part\n\twhole = cgc_atoi(pWhole);\n\n\t// convert the fractional part\n\tif (*pFraction != '\\0') {\n\t\tfraction = cgc_atoi(pFraction);\n\t\twhile ( pFraction != '\\0' && cgc_isdigit( *pFraction ) ) {\n\t\t\tfraction /= 10.0;\n\t\t\tpFraction++;\n\t\t}\n\t}\n\n\treturn ( whole + fraction );\n\t\n}\n\t\n\nchar *cgc_strcpy( char *pDest, const char *pSrc )\n{\n\tchar *pDestReturn = pDest;\n\n\twhile ( *pSrc != '\\0' )\n\t\t*pDest++ = *pSrc++;\n\n\t*pDest = '\\0'; \n\n\treturn (pDestReturn);\n}\n\nchar *cgc_strncpy( char *pDest, const char *pSrc, cgc_size_t maxlen )\n{\n\tcgc_size_t n;\n\n\tfor ( n = 0; n < maxlen; n++ )\n\t{\n\t\tif ( pSrc[n] == '\\0' )\n\t\t\tbreak;\n\n\t\tpDest[n] = pSrc[n];\n\t}\n\n\tfor ( ; n < maxlen; n++ )\n\t\tpDest[n] = '\\0';\n\n\treturn (pDest);\n}\n\nvoid *cgc_memcpy( void *pDest, const void *pSource, cgc_size_t nbytes )\n{\n\tvoid *pDestReturn = pDest;\n\n\twhile ( nbytes >= 4 )\n\t{\n\t\t*((uint32_t*)pDest) = *((uint32_t*)pSource);\n\n\t\tpDest += 4;\n\t\tpSource += 4;\n\t\tnbytes-=4;\t\t\n\t}\n\n\twhile ( nbytes > 0 )\n\t{\n\t\t*((uint8_t*)pDest) = *((uint8_t*)pSource);\n\n\t\tpDest++;\n\t\tpSource++;\n\t\tnbytes--;\n\t}\n\n\treturn (pDestReturn);\n}\n\nlong int cgc_strtol( const char *str, char **endptr, int base )\n{\n\tlong int value = 0;\n\tint neg = 0;\n\n\tif ( str == NULL )\n\t\treturn (0);\n\n\tif ( base >= 16 )\n\t\tbase = 16;\n\n\t// Skip whitespace\t\n\twhile ( cgc_isspace( *str ) )\n\t\tstr++;\n\n\tif ( *str == '-' )\n\t{\n\t\tneg = 1;\n\t\tstr++;\n\t}\n\telse if ( *str == '+' )\n\t\tstr++;\n\n\tif ( (base == 16 || base == 0) && *str == '0' && (*(str+1) == 'x' || *(str+1) == 'X') )\n\t{\n\t\tstr+=2;\n\t\tbase = 16;\n\t}\n\telse if ( (base == 0 || base == 2 ) && *str == '0' && (*(str+1) == 'b' || *(str+1) == 'B') )\n\t{\n\t\tstr+=2;\n\t\tbase = 2;\n\t}\n\n\tif ( base == 0 )\n\t{\n\t\tif ( *str == '0' )\n\t\t{\n\t\t\tbase = 8;\n\t\t}\n\t\telse\n\t\t\tbase = 10;\n\t}\n\n\tunsigned long cutoff_value = 0;\n\tif ( neg )\n\t\tcutoff_value = -(unsigned long)LONG_MIN;\n\telse\n\t\tcutoff_value = (unsigned long)LONG_MAX;\n\tlong int cutlim_value = cutoff_value % (unsigned long)base;\n\t\n\tcutoff_value /= base;\n\n\twhile ( *str != '\\0' )\n\t{\n\t\tint c = *str;\n\n\t\tif ( cgc_isdigit( c ) )\n\t\t\tc -= '0';\n\t\telse if ( cgc_isalpha(c) )\n\t\t{\n\t\t\tif ( cgc_isupper(c) )\n\t\t\t\tc -= ('A' - 10);\n\t\t\telse\n\t\t\t\tc -= ('a' - 10);\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t\n\t\tif ( c >= base )\n\t\t\tbreak;\n\n\t\tif ( value > cutoff_value || (value == cutoff_value && c > cutlim_value) )\n\t\t\tbreak;\n\t\telse\n\t\t{\n\t\t\tvalue *= base;\n\t\t\tvalue += c;\n\t\t}\n\n\t\tstr++;\t\n\t}\n\n\t// Check if we should set endptr\n\tif ( endptr )\n\t\t*endptr = (char *)str;\n\n\tif ( neg )\n\t\treturn -value;\n\telse\n\t\treturn value;\t\n}\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/lib/string.c",
    "content": "/*\n\nCopyright (c) 2015 Cromulence LLC\n\nAuthors: Cromulence <cgc@cromulence.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#include \"cgc_string.h\"\n#include \"cgc_stdint.h\"\n\ncgc_size_t cgc_strlen( const char *str )\n{\n\tcgc_size_t len = 0;\n\twhile ( *str++ != '\\0' )\n\t\tlen++;\n\n\treturn len;\n}\n\nvoid cgc_bzero(void *s, cgc_size_t n) {\n        while (n) {\n                ((char *)s)[--n] = '\\0';\n        }\n        ((char *)s)[n] = '\\0';\n}\n\nvoid *cgc_memset( void *ptr, int value, cgc_size_t num )\n{\n\tvoid *ptr_temp = ptr;\n\tuint8_t set_value_byte = (uint8_t)value;\n\tuint32_t set_value_dword = (set_value_byte << 24) | (set_value_byte << 16) | (set_value_byte << 8) | set_value_byte;\n\n\twhile ( num >= 4 )\n\t{\n\t\t*((uint32_t*)ptr) = set_value_dword;\t\n\t\tptr+=4;\n\t\tnum-=4;\t\n\t}\n\n\twhile ( num > 0 )\n\t{\n\t\t*((uint8_t*)ptr++) = set_value_byte;\t\n\t\tnum--;\n\t}\n\n\treturn (ptr_temp);\n}\n\nchar *cgc_strchr(char *s, int c) {\n\tuint32_t i;\n\n\tif (!s) {\n\t\treturn(NULL);\n\t}\n\tfor (i = 0; i < cgc_strlen(s); i++) {\n\t\tif (s[i] == c) {\n\t\t\treturn(s+i);\n\t\t}\n\t}\n\n\treturn(NULL);\n\n}\n\nchar *cgc_StrtokNext = NULL;\nchar *cgc_strtok(char *str, char *sep) {\n\tuint32_t i, j;\n\tuint32_t str_len;\n\tchar *tok;\n\n\tif (!sep) {\n\t\treturn(NULL);\n\t}\n\n\tif (!str) {\n\t\tif (!cgc_StrtokNext) {\n\t\t\treturn(NULL);\n\t\t} else {\n\t\t\tstr = cgc_StrtokNext;\n\t\t}\n\t}\n\n\t// deal with any leading sep chars\n\twhile (cgc_strchr(sep, *str) && *str != '\\0') {\n\t\tstr++;\n\t}\n\tif (*str == '\\0') {\n\t\tcgc_StrtokNext = NULL;\n\t\treturn(NULL);\n\t}\n\n\tstr_len = cgc_strlen(str);\n\tfor (i = 0; i < str_len; i++) {\n\t\tif (cgc_strchr(sep, str[i])) {\n\t\t\t// found a sep character\n\t\t\tstr[i] = '\\0';\n\t\t\t// see if there are any subsequent tokens\n\t\t\tfor (j = i+1; j < str_len; j++) {\n\t\t\t\tif (cgc_strchr(sep, str[j])) {\n\t\t\t\t\t// found one\n\t\t\t\t\tstr[j] = '\\0';\n\t\t\t\t} else {\n\t\t\t\t\t// no more tokens\n\t\t\t\t\tcgc_StrtokNext = str+j;\n\t\t\t\t\treturn(str);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (j == str_len) {\n\t\t\t\tcgc_StrtokNext = NULL;\n\t\t\t}\n\t\t\treturn(str);\n\t\t}\n\t}\n\n\t// made it to the end of the string without any new tokens\n\tcgc_StrtokNext = NULL;\n\treturn(str);\n}\n\nint cgc_strcmp(const char *s1, const char *s2) {\n\twhile (*s1 != '\\0' && *s1 == *s2) {\n\t\ts1++; s2++;\n\t}\n\treturn *s1 - *s2;\n}\n\nint cgc_strncmp(const char *s1, const char *s2, cgc_size_t n) {\n\twhile (*s1 != '\\0' && *s1 == *s2 && n > 0) {\n\t\ts1++; s2++; n--;\n\t}\n\tif (n == 0) {\n\t\treturn 0;\n\t}\n\telse {\n\t\treturn *s1 - *s2;\n\t}\n}\n\nchar *cgc_strcat(char *restrict s1, const char *restrict s2) {\n\tchar *dest = s1;\n\twhile(*dest != '\\0') dest++;\n\twhile (*s2 != '\\0') {\n\t\t*dest++ = *s2++;\n\t}\n\t*dest = '\\0';\n\treturn s1;\n}\n\nchar *cgc_strstr(char *s1, char *s2) {\n\tif ((s1 == NULL) || (s2 == NULL)) {\n\t\treturn NULL;\n\t}\n\tint s2len = cgc_strlen(s2);\n\twhile(*s1 != '\\0') {\n\t\tif (cgc_strncmp(s1, s2, s2len) == 0) {\n\t\t\treturn s1;\n\t\t}\n\t\ts1++;\n\t}\n\treturn NULL;\n}\n\n\nchar *cgc_rindex(char *source, char match) {\n\tint length = cgc_strlen(source);\n\tfor(int i=length; i>=0; i--) {\n\t\tif (source[i] == match) {\n\t\t\treturn (source + i);\n\t\t}\n\t}\n\treturn NULL;\n}\n\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/notes.txt",
    "content": "In the compiled REMATCH_2--Mail_Server--Crackaddr.exe executable, the main\nfunction is at offset 0x8340 (0x408340 address).  Also, I replaced the random\nseed with 0x11223344 to try to reduce the instability in the code coverage.\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/src/cgc_crackaddr.h",
    "content": "#ifndef CRACKADDR_H\n#define CRACKADDR_H\n\n#define MAX_LINE 2500\n#define MAX_NAME 1024\n\n#define TRUE 1\n#define FALSE 0\n\nchar *cgc_crackaddr(char *addr, char *output);\n\n\n#endif"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/src/cgc_sendmail.h",
    "content": "/*\n\nAuthor: Debbie Nuttall <debbie@cromulence.com>\n\nCopyright (c) 2015 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#ifndef SENDMAIL_H\n#define SENDMAIL_H\n\ntypedef struct address_s {\n  char *name;\n  char *home_server;\n  int mode;\n  struct address_s *next;\n}address;\n\ntypedef struct message_s {\n  address *sender;\n  address *recipient;\n  char *subject;\n  int content_type;\n  char *data;\n  int data_length;\n  struct message_s *next;\n}message;\n\ntypedef struct address_book_s {\n  int num_entries;    \n  address *root;\n} address_book;\n\ntypedef struct mail_queue_s {\n  int num_messages;\n  char *name;\n  message *root;\n  struct mail_queue_s *next;\n}mail_queue;\n\nextern address_book *abook;\nextern mail_queue *root_queue;\nchar *cgc_gen_random_string(int min, int max);\naddress *cgc_add_random_addressbook_entry() ;\nvoid cgc_initialize_address_book() ;\naddress *cgc_pick_address() ;\nmail_queue *cgc_add_random_queue() ;\nmessage *cgc_add_random_message(mail_queue *mq);\nvoid cgc_initialize_mail_queues();\nvoid cgc_print_address_book();\nvoid cgc_sendmail_post(char *line);\nmail_queue *cgc_locate_queue(char *name);\n\nvoid cgc_list_queue(char *line);\nvoid cgc_list_all_queues() ;\n\n#endif"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/src/crackaddr.c",
    "content": " /*\n\nAuthor: Debbie Nuttall <debbie@cromulence.com>\n\nCopyright (c) 2015 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#include \"cgc_stdio.h\"\n#include \"cgc_ctype.h\"\n#include \"cgc_libc.h\"\n#include \"cgc_crackaddr.h\"\n\n\n\nchar *cgc_crackaddr(char *addr, char *output) {\n\tchar *outp = output;\n\tchar *endp = output + MAX_NAME - 5;\n\tchar c;\n\n\tif (addr == NULL) {\n\t\treturn NULL;\n\t}\n\n\t// strip whitespace\n\twhile (*addr && cgc_isspace(*addr))\n\t\taddr++;\n\t\n\t// Setup state\n\tint inA, inC;\n\tinA = inC = 0;\n\tint Blevel, Blevelout;\n\tBlevel = Blevelout = 0;\n\tint full;\n\tint Dmode = 0;\n\tint outputLevel = 0;\n\n\twhile (*addr != '\\0') {\n\t\tc = *addr++;\n\t\tfull = outp >= endp;\n\n\t\tif ((!full) && (outputLevel > 0)){\n\t\t\t*outp++ = c;\n\t\t}\n\n\t\tif (c == 'A') {\n\t\t \toutputLevel = 0;\n\t\t \tif (!inA) {\n\t\t\t\tinA = TRUE;\n\t\t\t\tendp--;\n\t\t\t}\n\t\t}\n\t\tif (c == 'a') {\n\t\t\toutputLevel++;\n\t\t\tif (outputLevel <= 1) {\n\t\t\t\t *outp++ = c;\n\t\t\t}\n\t\t\tif (inA) {\n\t\t\t\tinA = FALSE;\n\t\t\t\tendp++;\n\t\t\t}\n\t\t}\n\n\t\t// Equivalent to parents from original crackaddr\n\t\t// Bb can be embedded in other Bb\n\t\tif (c == 'B') {\n\t\t\tBlevel++;\n\t\t\tif (!full) {\n\t\t\t\tBlevelout++;\n\t\t\t\tendp--;\n\t\t\t\toutputLevel++;\n\t\t\t}\n\t\t}\n\t\tif ((c == 'b') && (Blevel > 0)) {\n\t\t\tBlevel--;\n\t\t\toutputLevel--;\n\t\t\tif (!full) {\n\t\t\t\tBlevelout--;\n\t\t\t\tendp++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t} else if (c == 'b') {\n\t\t\t// Syntax error unmatched 'b'\n\t\t\tif ((!full) && (outputLevel > 0)){\n\t\t\t\toutp--;\n\t\t\t}\n\t\t}\n\n\t\t// Equivalent to angle brackets from original crackaddr\n\t\tif ((c == 'C') && (!inC)) {\n\t\t\tinC = TRUE;\n#ifdef PATCHED_1\n\t\t\tendp--;\n#endif\n\t\t}\n\t\tif ((c == 'c') && (inC)) {\n\t\t\tinC = FALSE;\n\t\t\tendp++;\n\t\t}\n\n\t\tif (c == 'D') {\n\t\t\tDmode = !Dmode;\n\t\t}\n\n\n\t\t// Escapes next char\n\t\tif ((c == 'F') && (!full)) {\n\t\t\tif (*addr != '\\0') { \n\t\t\t\t*outp++ = *addr++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Skips next char\n\t\tif (c == 'G') {\n\t\t\tif (*addr != '\\0') { \n\t\t\t\taddr++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t}\n\n\tif (inA) {\n\t\t*outp++ = 'a';\n\t}\n\twhile((Blevelout-- > 0)&&(outp < endp - 2)) {\n\t\t*outp++ = 'b';\n\t}\n\t\n\tif (inC) {\n\t\t*outp++ = 'c';\n\t}\n\n\tif (Dmode) {\n\t\t*outp++ = 'D';\n\t}\n\n\t*outp++ = '\\0';\n\n\treturn output;\n\n\t}\t\n\n\n"
  },
  {
    "path": "corpus/cgc/REMATCH_2--Mail_Server--Crackaddr/src/sendmail.c",
    "content": "/*\n\nAuthor: Debbie Nuttall <debbie@cromulence.com>\n\nCopyright (c) 2015 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#include \"libcgc.h\"\n#include \"cgc_stdio.h\"\n#include \"cgc_libc.h\"\n#include \"cgc_stdlib.h\"\n#include \"cgc_string.h\"\n#include \"cgc_ctype.h\"\n#include \"cgc_malloc.h\"\n#include \"cgc_shell.h\"\n#include \"cgc_prng.h\"\n#include \"cgc_crackaddr.h\"\n#include \"cgc_sendmail.h\"\n\n#define FD_FROM_MAIN STDIN\n#define FD_TO_MAIN 5\n\n\nint cgc_debug_mode = 0;\n\naddress_book *abook;\nmail_queue *root_queue;\n\nchar *cgc_gen_random_string(int min, int max) {\n    int length = cgc_random_in_range(min, max);\n    char *s = cgc_calloc(length);\n    for(int i=0; i<length - 2; i++) {\n        s[i] = cgc_random_in_range(0x2e, 0x7e);\n    }\n    return s;\n}\n\naddress *cgc_add_random_addressbook_entry() {\n    \n    address *a = cgc_calloc(sizeof(address));\n    a->name = cgc_gen_random_string(5, 32);\n    a->home_server = cgc_gen_random_string(5, 32);\n    a->mode = cgc_random_in_range(0,1);\n    address *n = abook->root;\n    if (n == NULL) {\n        // First Entry\n        abook->root = a;\n    } else {\n        while (n->next != NULL) {\n            n = n->next;\n        }\n        n->next = a;\n    }\n    abook->num_entries++;\n    return a;\n}\n\n\nvoid cgc_initialize_address_book() {\n    abook->num_entries = 0;\n    abook->root = 0;\n    for (int i = 0; i < 20; i++) {\n        cgc_add_random_addressbook_entry();\n    }\n} \n\naddress *cgc_pick_address() {\n    int i = 0;\n    address *next = abook->root;\n    while (next != NULL) {\n        i++;\n        next = next->next;\n    }\n    int pick = cgc_random_in_range(0, i-1);\n    next = abook->root;\n    while (next->next != NULL && pick > 0) {\n        next = next->next;\n        pick--;\n    }\n    return next;\n}\n\naddress *cgc_lookup_name(char *name) {\n    address *next = abook->root;\n    while (next != NULL) {\n        if (cgc_strcmp(next->name, name) == 0) {\n            break;\n        }\n        next = next->next;\n    }\n    return next;\n}\n\nmail_queue *cgc_add_random_queue() {\n    mail_queue *mq = cgc_calloc(sizeof(mail_queue));\n    address *sender = cgc_pick_address();\n    mq->name = sender->name;\n    mq->root = cgc_add_random_message(mq);\n// TODO add more messages\n\n    if (root_queue != NULL) {\n        mail_queue *next = root_queue;\n        while (next->next != NULL) {\n            next = next->next;\n        }\n        next->next = mq;\n    }\n    return mq;\n}\n\nmessage *cgc_add_random_message(mail_queue *mq) {\n    message *m = cgc_calloc(sizeof(message));\n    m->sender = cgc_pick_address();\n    m->recipient = cgc_pick_address();\n    m->subject = cgc_gen_random_string(5, 32);\n    m->data = cgc_gen_random_string(5,256);\n    m->data_length = cgc_strlen(m->data);\n\n    if (mq->root != NULL) {\n        message *next = mq->root;\n        while (next->next != NULL) {\n            next = next->next;\n        }\n        next->next = m;\n    }\n    return m;\n}\n\nvoid cgc_initialize_mail_queues() {\n    // Setup mail queues\n    root_queue = cgc_add_random_queue();\n    for(int i = 0; i< 32; i++) {\n        cgc_add_random_queue();\n    }\n}\n\nvoid cgc_print_address_book() {\n    cgc_printf(\"Address Book:\\n\");\n    address *a = abook->root;\n    int i = 1;\n    while (a != NULL) {\n        cgc_printf(\"$d) $s@$s [$d]\\n\", i, a->name, a->home_server, a->mode);\n        i++;\n        a = a->next;\n    }\n}\n\nchar *cgc_make_string(char *str) {\n    if (str == NULL) {\n        return NULL;\n    }\n    char *s = cgc_calloc(cgc_strlen(str) + 1);\n    cgc_strcpy(s, str);\n    return s;\n}\n\n// Creates a new message and adds to appropriate mail queue. \nvoid cgc_sendmail_post(char *line) {\n    char output[MAX_NAME];\n    char *sender, *recipient, *subject, *body;\n    char *end;\n    sender = cgc_strstr(line, \"sender:\");\n    if (sender == NULL) {\n        return;\n    }\n    sender += 7;\n    \n    recipient = cgc_strstr(line, \"recipient:\");\n    if (recipient == NULL) {\n        return;\n    } \n    recipient += 10;\n    \n    \n    body = cgc_strstr(line, \"body:\");\n    if (body == NULL) {\n        return;\n    }\n    body += 5;\n    \n    subject = cgc_strstr(line, \"subject:\");\n    if (subject == NULL) {\n        return;\n    }\n    subject += 8;\n    \n    end = cgc_strstr(sender, \"!\");\n    if (end != NULL) {\n        *end = '\\0';\n    }\n    end = cgc_strstr(recipient, \"!\");\n    if (end != NULL) {\n        *end = '\\0';\n    }\n    end = cgc_strstr(body, \"!\");\n    if (end != NULL) {\n        *end = '\\0';\n    }\n    end = cgc_strstr(subject, \"!\");\n    if (end != NULL) {\n        *end = '\\0';\n    }\n    message *msg = cgc_calloc(sizeof(message));\n    msg->sender = cgc_lookup_name(sender);\n    \n    if (recipient[0] == '+') {\n        \n        cgc_crackaddr(recipient, output);\n        cgc_printf(\"addr:$s\\n\", output);\n        return;\n    }\n    msg->recipient = cgc_lookup_name(recipient);\n    if (msg->recipient == NULL) {\n        return;\n    }\n    if (msg->sender == NULL) {\n        return;\n    }\n    msg->data = cgc_make_string(body);\n    msg->data_length = cgc_strlen(body);\n    msg->subject = cgc_make_string(subject);\n\n \n\n    mail_queue *mq = cgc_locate_queue(msg->sender->name);\n    if (mq == NULL) {\n        mq = cgc_calloc(sizeof(mail_queue));\n        mq->name = cgc_make_string(msg->sender->name);\n        mq->root = msg;\n        mail_queue *next = root_queue;\n        while (next->next != NULL) {\n            next = next->next;\n        }\n        next->next = mq;\n    } else {\n        message *next = mq->root;\n        if (next == NULL) {\n            mq->root = msg;\n        } else {\n            while (next->next != NULL) {\n                next = next->next;\n            }\n            next->next = msg;\n        }\n    }\n    cgc_printf(\"Message Received\\n\");\n}   \n\n\nmail_queue *cgc_locate_queue(char *name) {\n    mail_queue *mq = root_queue;\n    while (mq != NULL) {\n        if (cgc_strcmp(mq->name, name)==0) {\n            return mq;\n        }\n        mq = mq->next;\n    }\n    return 0;\n}\n\nvoid cgc_list_queue(char *line) {\n    char *name = line;\n    // Find a queue for that username\n    mail_queue *mq = cgc_locate_queue(name);\n    if (mq == 0) {\n        cgc_printf(\"Mail Queue Not Found\\n\");\n        return;\n    }\n    int i = 0;\n    message *msg = mq->root;\n    while (msg != NULL) {\n        if (msg ->sender != NULL && msg->recipient!= NULL) {\n            cgc_printf(\"$d) From:$s To: $s SUBJECT:$s\\n\", i, msg->sender->name, msg->recipient->name, msg->subject);\n        } else {\n            cgc_printf(\"$d) Malformed Message\\n\");\n        }\n        i++;\n        msg = msg->next;\n    }\n}\n\nvoid cgc_list_all_queues() {\n    mail_queue *mq = root_queue;\n    while (mq != NULL) {\n        int i = 0;\n        cgc_printf(\"QUEUE: $s\\n\", mq->name);\n        message *msg = mq->root;\n        while (msg != NULL) {\n            if (msg ->sender != NULL && msg->recipient!= NULL) {\n                cgc_printf(\"$d) From:$s To: $s SUBJECT:$s\\n\", i, msg->sender->name, msg->recipient->name, msg->subject);\n            } else {\n                cgc_printf(\"$d) Malformed Message\\n\");\n            }\n            i++;\n            msg = msg->next;\n        }\n        cgc_printf(\"\\n\");\n        mq = mq->next;\n    }\n}\n\nvoid cgc_read_message(char *line) {\n    char *name = line;\n    while ((*line != ' ') && (*line != '\\0')) line++;\n    *line++ = '\\0';\n    int msg_num = cgc_atoi(line);\n    mail_queue *mq = cgc_locate_queue(name);\n    if (mq == NULL) {\n        return;\n    }\n    int i=0;\n    message *next = mq->root;\n    while (next != NULL && i != msg_num) {\n        i++;\n        next = next->next;\n    }\n    if (msg_num == i) {\n        cgc_printf(\"$d) Subject:$s Body:$s\\n\", i, next->subject, next->data);\n    }\n}\n    \n    \n\nint main(int cgc_argc, char *cgc_argv[]) {\n    int quit = 0;\n    \n    // Initialize mail server\n    //cgc_seed_prng(*(uint32_t *)FLAG_PAGE);\n\tcgc_seed_prng(0x11223344);\n    int num_mailq = 0;\n    abook = cgc_calloc(sizeof(address_book));\n    cgc_initialize_address_book();\n    cgc_initialize_mail_queues();\n\n    // run a mail server\n    char line[MAX_LINE+1];\n    int line_size = 0;\n    cgc_printf(\"sendmail:\");\n    do {\n        // Read a line\n        if ((line_size = cgc_receive_until(line, MAX_LINE, '\\n')) <= 0) {\n            break;\n        }\n        line[line_size] = '\\0';\n        // Process the command\n        char *next = line;\n        // Terminate first command word\n        while ((*next != ' ') && (*next != '\\0')) next++;\n        *next++ = '\\0';\n        if (cgc_strcmp(line, \"LIST\")==0) {\n            // List one mail queue\n            cgc_list_queue(next);\n        } else if (cgc_strcmp(line, \"LISTALL\")==0) {\n            // List all mail queues\n            cgc_list_all_queues();\n        } else if (cgc_strcmp(line, \"POST\")==0) {\n            // Post a message\n            cgc_sendmail_post(next);\n        } else if (cgc_strcmp(line, \"READ\")==0) {\n            // Read a message\n            cgc_read_message(next);\n        } else if (cgc_strcmp(line, \"ADDRESSBOOK\")==0) {\n            // Print address book\n            cgc_print_address_book();\n        } else if (cgc_strcmp(line, \"QUIT\")==0) {\n            // Quit mail server\n            break;\n        } else {\n            // Invalid command\n            cgc_printf(\"Invalid Command!\\n\");\n            quit = 1;\n        }\n\n    } while (quit == 0);\n\n    cgc_printf(\"Goodbye.\\n\");\n}\n"
  },
  {
    "path": "corpus/cgc/SOLFEDGE/README.md",
    "content": "# CGC Challenge Binary Template\n\n## Author Information\n\n\"Nick Davis\" <info@narfindustries.com>\n\n### DARPA performer group\n\nNarf Industries (NRFIN)\n\n## Description\n\nSOLFEDGE is state of the art software used by ARRRRGH, the Academy of Really, Really, Really, Really, Great Harmony, to translate their music between notes and syllables (Solmization).\n\nARRRRGH teaches their classes in French, so SOFEDGE is designed to use the French 'fixed do' method of solfedge and only recognizes the C major scale.\n\n### Feature List\n\nThis service is a translation engine, so it has 2 primary functions:\n\n* It accepts large strings of notes and converts them to syllables.\n* It accepts large strings of syllables and converts them to notes.\n\nValid notes are:\n* C\n* D\n* E\n* F\n* G\n* A\n* B\n\nAnd valid syllables are:\n* Ut\n* Re\n* Mi\n* Fa\n* Sol\n* La\n* Si\n\nA single harmony can contain up to 2048 syllables or notes.\n\n## Vulnerability\n\nThe buffer that stores syllables is 4096 bytes long. Assuming syllables are 2 bytes, that allows 2048 syllables. The syllable 'sol' is 3 bytes long, while the rest are 2 chars long. So, if the user provides a harmony that contains 2048 notes and one or more of those notes corresponds to the syllable 'sol', then writing those notes as syllables will go beyond the syllables buffer (page) and cause a segfault.\n\nMore specifically, in operation.c:process\\_notes, the while loop will cause write\\_syllable\\_to\\_buf to write into the syllables\\_buf until one of 3 conditions happens. 1) an error is returned, 2) all of the input bytes have been processed, and 3) the total chars written to the syllable buf has reached the MAX\\_SYLLABLES\\_BYTES. The comparison (total\\_bytes\\_written < MAX\\_SYLLABLES\\_BYTES) is a form of an off-by-one error, because each iteration of the loop can write 2 or 3 bytes. So, if total\\_bytes\\_written is 1 or 2 less than MAX\\_SYLLABLES\\_BYTES, the loop will run one more iteration. If it is 1 less, that iteration will cause a segfault with both a 2-btye and 3-byte syllable. If it is 2 less, that iteration will cause segfault with a 3-byte syllable.\n\nThe segfault will occur in operations.c:write\\_syllable\\_to\\_buf at either line 224 or 227.\n\n\nThere are multiple ways to patch this vuln. The provided PATCHED version uses a more optimal patch that covers both failure conditions. It is also possible to put a much more restrictive bound on total\\_bytes\\_written (i.e. 100 or 2000), that will prevent the overflow, but will also greatly shorten the possible harmony length.\n\nA more extensive patch, that is unlikely for automated patching is to pass the total\\_bytes\\_written value into write\\_syllable\\_to\\_buf, and perform a check that can calculate how many more bytes will fit into the buffer before it writes any bytes. It could then return an error value if there are not enough bytes remaining to complete the write.\n\n\n### Generic class of vulnerability\n\nImproper Input Validation\nImproper Validation of Array Index\nOff-by-one Error\n\n### CWE classification\n\nImproper Input Validation\nCWE-20\n\nImproper Validation of Array Index\nCWE-129\n\nOff-by-one Error\nCWE-193\n\n\n## Challenges\n* This CB is intentionally on the easier side. A SAT solver should be able to reason about the difference between the syllables' buffer size and the amount of data that can be written to it.\n* The way in which a team patches the vuln should indicate if they can reason that both failure points are due to a common cause. If they simply try to patch both failure points separately, they may not have been able to correlate the 2 failure points.\n* \n"
  },
  {
    "path": "corpus/cgc/SOLFEDGE/lib/cgc_libc.h",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n#include \"libcgc.h\"\n\n#ifndef NARF_LIBC_H\n#define NARF_LIBC_H\n\ntypedef signed char int8_t;\ntypedef signed int int32_t;\ntypedef unsigned int uint32_t;\ntypedef unsigned char uint8_t;\n\n#define SUCCESS 0\n#define ERRNO_ALLOC 505\n\n\n// libc libs borrowed from EAGLE_00004\n\nint cgc_send(const char *buf, const cgc_size_t size);\nint cgc_transmit_all(int fd, const char *buf, const cgc_size_t size);\nunsigned int cgc_recv_all(char *res_buf, cgc_size_t res_buf_size);\nunsigned int cgc_read_all(int fd, char *buf, unsigned int size);\n\nvoid *cgc_memset(void *dst, int c, unsigned int n);\n\n#endif\n"
  },
  {
    "path": "corpus/cgc/SOLFEDGE/lib/libc.c",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n\n#include \"cgc_libc.h\"\n\n\n// libc libs borrowed from EAGLE_00004\n\n\n// I/O functions\nint cgc_send(const char *buf, const cgc_size_t size) {\n    if(cgc_transmit_all(STDOUT, buf, size)) {\n        cgc__terminate(111);\n    }\n\n    return 0;\n}\n\nint cgc_transmit_all(int fd, const char *buf, const cgc_size_t size) {\n    cgc_size_t sent = 0;\n    cgc_size_t sent_now = 0;\n    int ret;\n\n    if (!buf)\n        return 1;\n\n    if (!size)\n        return 2;\n\n    while (sent < size) {\n        ret = cgc_transmit(fd, buf + sent, size - sent, &sent_now);\n        if (ret != 0) {\n            return 3;\n        }\n        sent += sent_now;\n    }\n\n    return 0;\n}\n\n// returns number of bytes received\nunsigned int cgc_recv_all(char *res_buf, cgc_size_t res_buf_size) {\n    return cgc_read_all(STDIN, res_buf, res_buf_size);\n}\n\nunsigned int cgc_read_all(int fd, char *buf, unsigned int size) {\n   char ch;\n   unsigned int total = 0;\n   cgc_size_t nbytes;\n   while (size) {\n      if (cgc_receive(fd, &ch, 1, &nbytes) != 0 || nbytes == 0) {\n         break;\n      }\n      buf[total++] = ch;\n      size--;\n   }\n   return total;\n}\n\n// stdlib functions\n\n// overwrites the first n chars of dst with char c.\nvoid *cgc_memset(void *dst, int c, unsigned int n) {\n   char *d = (char*)dst;\n   while (n--) {*d++ = (char)c;}\n   return dst;\n}\n\n"
  },
  {
    "path": "corpus/cgc/SOLFEDGE/notes.txt",
    "content": "In the compiled SOLFEDGE.exe executable, the main function is at offset 0x23E0\n(0x4023E0 address).\n"
  },
  {
    "path": "corpus/cgc/SOLFEDGE/src/cgc_operation.h",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n\n\n#ifndef OPERATION_H\n#define OPERATION_H 1\n\n#define ALLOC(sz,p) if (SUCCESS != cgc_allocate(sz, 0, (void **)p)) {cgc__terminate(ERRNO_ALLOC);}\n#define RECV(v,s) if(s != cgc_recv_all((char *)v, s)) {cgc__terminate(ERR_RECV_FAILED);}\n#define SENDSI(v) cgc_send((char *)&v, sizeof(int32_t));\n\n// 4096 syllables bytes, assuming 2 bytes per syllable is 2048 syllables\n// this assumption is wrong because one syllable is 3 bytes.\n#define MAX_SYLLABLES_BYTES 4096\n// 2048 notes bytes, assyming 1 byte per note is 2048 notes\n// this assumption is correct. However, when the notes\n// get converted to syllables, if any note relates to the one\n// 3 byte syllable, then the total syllable bytes will exceed 4096 bytes.\n#define MAX_NOTES_BYTES 2048\n#define BUFFER_LEN 4096\n\n// notes\nenum {\n\tC = 1,\n\tD = 2,\n\tE = 3,\n\tF = 4,\n\tG = 5,\n\tA = 6,\n\tB = 7,\n};\n\n// syllables\nenum {\n\tUt = 1,\n\tRe = 2,\n\tMi = 3,\n\tFa = 4,\n\tSol = 5,\n\tLa = 6,\n\tSi = 7,\n};\n\nenum {\n\tERR_RECV_FAILED = -900,\n\tERR_INVALID_CMD = -901,\n\tERR_INVALID_NOTE = -902,\n\tERR_INVALID_SYLLABLE = -903,\n\tERR_TOO_MANY_NOTES = -904,\n\tERR_TOO_MANY_SYLLABLES = -905,\n\tERR_NO_NOTES = -906,\n\tERR_NO_SYLLABLES = -907,\n};\n\nextern int cgc_to_syllables(char *syllables_buf, char *notes_buf);\nextern int cgc_to_notes(char *syllables_buf, char *notes_buf);\n\n#endif"
  },
  {
    "path": "corpus/cgc/SOLFEDGE/src/cgc_service.h",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n\n\n#ifndef SERVICE_H\n#define SERVICE_H 1\n\n\n\n\n#endif\n"
  },
  {
    "path": "corpus/cgc/SOLFEDGE/src/operation.c",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n#include \"libcgc.h\"\n#include \"cgc_libc.h\"\n#include \"cgc_operation.h\"\n\n/*\n * Convert the note to the associated syllable and save the\n * syllable into syllable_buf.\n *\n * Returns:\n *  Success: 2 or 3 (number of letters written to syllable_buf)\n *  Failure: ERR_INVALID_NOTE\n */\nint cgc_get_syllable_for_note_id(int note_id, char *syllable_buf) {\n\n\tswitch(note_id) {\n\tcase C:\n\t\tsyllable_buf[0] = 'U';\n\t\tsyllable_buf[1] = 't';\n\t\treturn 2;\n\tcase D:\n\t\tsyllable_buf[0] = 'R';\n\t\tsyllable_buf[1] = 'e';\n\t\treturn 2;\n\tcase E:\n\t\tsyllable_buf[0] = 'M';\n\t\tsyllable_buf[1] = 'i';\n\t\treturn 2;\n\tcase F:\n\t\tsyllable_buf[0] = 'F';\n\t\tsyllable_buf[1] = 'a';\n\t\treturn 2;\n\tcase G:\n\t\tsyllable_buf[0] = 'S';\n\t\tsyllable_buf[1] = 'o';\n\t\tsyllable_buf[2] = 'l';\n\t\treturn 3;\n\tcase A:\n\t\tsyllable_buf[0] = 'L';\n\t\tsyllable_buf[1] = 'a';\n\t\treturn 2;\n\tcase B:\n\t\tsyllable_buf[0] = 'S';\n\t\tsyllable_buf[1] = 'i';\n\t\treturn 2;\n\tdefault:\n\t\treturn ERR_INVALID_NOTE;\n\t}\n}\n\n/*\n * Convert the syllable to the associated note and save the\n * note into note_buf.\n *\n * If syllable is invalid, note_buf is undefined.\n *\n * Returns:\n *  Success: SUCCESS\n *  Failure: ERR_INVALID_SYLLABLE\n */\nint cgc_get_note_for_syllable_id(int syllable_id, char *note_buf) {\n\n\tswitch(syllable_id) {\n\tcase Ut:\n\t\tnote_buf[0] = 'C';\n\t\treturn SUCCESS;\n\tcase Re:\n\t\tnote_buf[0] = 'D';\n\t\treturn SUCCESS;\n\tcase Mi:\n\t\tnote_buf[0] = 'E';\n\t\treturn SUCCESS;\n\tcase Fa:\n\t\tnote_buf[0] = 'F';\n\t\treturn SUCCESS;\n\tcase Sol:\n\t\tnote_buf[0] = 'G';\n\t\treturn SUCCESS;\n\tcase La:\n\t\tnote_buf[0] = 'A';\n\t\treturn SUCCESS;\n\tcase Si:\n\t\tnote_buf[0] = 'B';\n\t\treturn SUCCESS;\n\tdefault:\n\t\treturn ERR_INVALID_SYLLABLE;\n\t}\n}\n\n/*\n * Read the string and return the id of the first note.\n *\n * str is not expected to be null terminated.\n *\n * Returns:\n *  Success: 1 thru 7 from notes enum\n *  Failure: ERR_INVALID_NOTE\n */\nint cgc_get_next_note_id(const char *str) {\n\n\tswitch(str[0]) {\n\tcase 'C':\n\t\treturn C;\n\tcase 'D':\n\t\treturn D;\n\tcase 'E':\n\t\treturn E;\n\tcase 'F':\n\t\treturn F;\n\tcase 'G':\n\t\treturn G;\n\tcase 'A':\n\t\treturn A;\n\tcase 'B':\n\t\treturn B;\n\tdefault:\n\t\treturn ERR_INVALID_NOTE;\n\t}\n}\n\n/*\n * Read the string and return the id of the \n * syllable at the beginning of the string.\n *\n * bytes_read is a 1 byte char buffer.\n * str is not expected to be null terminated.\n *\n * If an invaild syllable is encountered, bytes_read is undefined.\n *  And the syllables in the remainder of the string are undefined.\n *\n * Returns:\n *  Success: 1 thru 7 in syllables enum\n *  Failure: ERR_INVALID_SYLLABLE\n */\nint cgc_get_next_syllable_id(const char *str, char *bytes_read) {\n\n\tchar s0 = str[0];\n\tchar s1 = str[1];\n\tchar s2 = str[2];\n\tif ('U' == s0 && 't' == s1) {\n\t\tbytes_read[0] = 2;\n\t\treturn Ut;\n\t} else \tif ('R' == s0 && 'e' == s1) {\n\t\tbytes_read[0] = 2;\n\t\treturn Re;\n\t} else \tif ('M' == s0 && 'i' == s1) {\n\t\tbytes_read[0] = 2;\n\t\treturn Mi;\n\t} else \tif ('F' == s0 && 'a' == s1) {\n\t\tbytes_read[0] = 2;\n\t\treturn Fa;\n\t} else \tif ('S' == s0 && 'o' == s1 && 'l' == s2) {\n\t\tbytes_read[0] = 3;\n\t\treturn Sol;\n\t} else \tif ('L' == s0 && 'a' == s1) {\n\t\tbytes_read[0] = 2;\n\t\treturn La;\n\t} else \tif ('S' == s0 && 'i' == s1) {\n\t\tbytes_read[0] = 2;\n\t\treturn Si;\n\t} else {\n\t\treturn ERR_INVALID_SYLLABLE;\n\t}\n}\n\n/*\n * Write the note matching syllable_id into notes_buf.\n *\n * Returns:\n *  Success: 1 (number of bytes written)\n *  Failure: ERR_INVALID_SYLLABLE\n */\nint cgc_write_note_to_buf(int syllable_id, char *notes_buf) {\n\n\tint ret = 1;\n\tchar note = 0;\n\n\tret = cgc_get_note_for_syllable_id(syllable_id, &note);\n\tif (SUCCESS == ret) {\n\t\tnotes_buf[0] = note;\n\t\tret = 1;\n\t}\n\treturn ret;\n}\n\n/*\n * Write the syllable matching note_id into syllable_buf.\n *\n * Returns:\n *  Success: 2 or 3 (number of bytes written)\n *  Failure: ERR_INVALID_NOTE\n */\nint cgc_write_syllable_to_buf(int note_id, char *syllable_buf) {\n\n\tint ret = 2;\n\tchar syllable[3] = {0};\n\n\tret = cgc_get_syllable_for_note_id(note_id, syllable);\n\tif (0 < ret) {\n\t\tsyllable_buf[0] = syllable[0];\n\t\tsyllable_buf[1] = syllable[1];\n\t}\n\tif (3 == ret) {\n\t\tsyllable_buf[2] = syllable[2];\n\t}\n\treturn ret;\n}\n\n/*\n * Loop through syllables in syllables_buf, convert them to notes and\n *  cgc_write them to notes_buf.\n *\n * Processing will stop when either an invalid syllable is found,\n * or bytes_count syllables have been processed.\n *\n * Returns:\n *  Success: total bytes written to notes_buf (> 0)\n *  Failure: ERR_INVALID_SYLLABLE\n */\nint cgc_process_syllables(uint32_t bytes_count, char *syllables_buf, char *notes_buf) {\n\n\tint ret = 1;\n\tchar *s_buf_ptr = syllables_buf;\n\tchar *n_buf_ptr = notes_buf;\n\tint syllable_id = 0;\n\tchar bytes_read[1] = {0};\n\tint total_bytes_written = 0;\n\n\twhile ((0 < ret) && (0 < bytes_count)) {\n\t\tsyllable_id = cgc_get_next_syllable_id(s_buf_ptr, bytes_read);\n\t\tif (0 < syllable_id) {\n\t\t\ts_buf_ptr += bytes_read[0];\n\t\t\tbytes_count -= bytes_read[0];\n\n\t\t\tret = cgc_write_note_to_buf(syllable_id, n_buf_ptr);\n\t\t\tif (1 == ret) {\n\t\t\t\tn_buf_ptr += ret;\n\t\t\t\ttotal_bytes_written += ret;\n\t\t\t}\n\t\t} else {\n\t\t\tret = syllable_id;\n\t\t}\n\n\t}\n\n\t// ret == 0 not possible.\n\tif (0 < ret) {\n\t\tret = total_bytes_written;\n\t}\n\n\treturn ret;\n}\n\n/*\n * Loop through notes in notes_buf, convert them to syllables and\n *  cgc_write them to syllables_buf.\n *\n * Processing will stop when either an invalid note is found,\n * or bytes_count notes have been processed.\n *\n * Returns:\n *  Success: total bytes written to syllables_buf (> 0)\n *  Failure: ERR_INVALID_NOTE, ERR_TOO_MANY_NOTES\n */\nint cgc_process_notes(uint32_t bytes_count, char *syllables_buf, char *notes_buf) {\n\n\tint ret = 1;\n\tchar *s_buf_ptr = syllables_buf;\n\tchar *n_buf_ptr = notes_buf;\n\tint note_id = 0;\n\tint total_bytes_written = 0;\n\n#if PATCHED\n\twhile ((0 < ret) && ((MAX_SYLLABLES_BYTES - 2) > total_bytes_written) && (0 < bytes_count)) {\n#else\n\twhile ((0 < ret) && (MAX_SYLLABLES_BYTES > total_bytes_written) && (0 < bytes_count)) {\n#endif\n\t\tnote_id = cgc_get_next_note_id(n_buf_ptr);\n\t\tif (0 < note_id) {\n\t\t\tn_buf_ptr++;\n\t\t\tbytes_count--;\n\n\t\t\tret = cgc_write_syllable_to_buf(note_id, s_buf_ptr);\n\t\t\tif ((2 == ret) || (3 == ret)) {\n\t\t\t\ts_buf_ptr += ret;\n\t\t\t\ttotal_bytes_written += ret;\n\t\t\t}\n\t\t} else {\n\t\t\tret = note_id;\n\t\t}\n\t}\n\n\t// ret == 0 not possible.\n\tif (0 < ret) {\n\t\tret = total_bytes_written;\n\t}\n\n\treturn ret;\n}\n\n/*\n * Send resultant syllables to client.\n */\nvoid cgc_send_syllables(uint32_t bytes_count, char *syllable_buf) {\n\tcgc_send(syllable_buf, bytes_count * sizeof(char));\n}\n\n/*\n * Send resultant notes to client.\n */\nvoid cgc_send_notes(uint32_t bytes_count, char *notes_buf) {\n\tcgc_send(notes_buf, bytes_count * sizeof(char));\t\n}\n\n/*\n * Receive the token count.\n *\n * Returns:\n *  Token count >= 0\n */\nuint32_t cgc_recv_bytes_count() {\n    uint32_t count[1] = {0};\n    RECV(count, sizeof(uint32_t));\n\treturn count[0];\n}\n\n/*\n * Control operation to convert received notes into syllables\n * and send resulting syllables back to client.\n *\n * Returns:\n *  Success: SUCCESS\n *  Failure: ERR_INVALID_NOTE, ERR_TOO_MANY_NOTES,\n * \t\t\t ERR_NO_NOTES, ERR_NO_SYLLABLES\n */\nint cgc_to_syllables(char *syllables_buf, char *notes_buf) {\n\n\tint ret = 0;\n\tint total_bytes_written = 0;\n\n\tuint32_t bytes_count = cgc_recv_bytes_count();\n\n\tif (0 >= bytes_count) {\n\t\treturn ERR_NO_NOTES;\n\t}\n\n\tif (MAX_NOTES_BYTES < bytes_count) {\n\t\treturn ERR_TOO_MANY_NOTES;\n\t}\n\n\tRECV(notes_buf, bytes_count);\n\n\ttotal_bytes_written = cgc_process_notes(bytes_count, syllables_buf, notes_buf);\n\n\tif (0 < total_bytes_written) {\n\t\tcgc_send_syllables(total_bytes_written, syllables_buf);\n\t\tret = SUCCESS;\n\t} else if (0 == total_bytes_written) {\n\t\tret = ERR_NO_SYLLABLES;\n\t} else {\n\t\tret = total_bytes_written;\n\t}\n\n\treturn ret;\n}\n\n/*\n * Control operation to convert received syllables into notes\n * and send resulting notes back to client.\n *\n * Returns:\n *  Success: SUCCESS\n *  Failure: ERR_INVALID_SYLLABLE, ERR_TOO_MANY_SYLLABLES, \n *\t\t\t ERR_NO_SYLLABLES, ERR_NO_NOTES\n */\nint cgc_to_notes(char *syllables_buf, char *notes_buf) {\n\n\tint ret = 0;\n\tint total_bytes_written = 0;\n\n\tuint32_t bytes_count = cgc_recv_bytes_count();\n\n\tif (0 >= bytes_count) {\n\t\treturn ERR_NO_SYLLABLES;\n\t}\n\n\tif (MAX_SYLLABLES_BYTES < bytes_count) {\n\t\treturn ERR_TOO_MANY_SYLLABLES;\n\t}\n\n\tRECV(syllables_buf, bytes_count);\n\n\ttotal_bytes_written = cgc_process_syllables(bytes_count, syllables_buf, notes_buf);\n\n\tif (0 < total_bytes_written) {\n\t\tcgc_send_notes(total_bytes_written, notes_buf);\n\t\tret = SUCCESS;\n\t} else if (0 == total_bytes_written) {\n\t\tret = ERR_NO_NOTES;\n\t} else {\n\t\tret = total_bytes_written;\n\t}\n\n\treturn ret;\n}"
  },
  {
    "path": "corpus/cgc/SOLFEDGE/src/service.c",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n#include \"libcgc.h\"\n#include \"cgc_libc.h\"\n#include \"cgc_operation.h\"\n#include \"cgc_service.h\"\n\nenum {\n    CMD_TO_SYLLABLES = 804619,\n    CMD_TO_NOTES = 1128809,\n};\n\nint main(int cgc_argc, char *cgc_argv[]) {\n\n    uint32_t command[1] = {0};\n    int ret = 0;\n\n    char *syllables_buf_p;\n    ALLOC(BUFFER_LEN, &syllables_buf_p);\n\n    char *notes_buf_p;\n    ALLOC(BUFFER_LEN, &notes_buf_p);\n\n    while (1) {\n        RECV(command, sizeof(uint32_t));\n\n        switch (command[0]) {\n            case CMD_TO_SYLLABLES:\n                ret = cgc_to_syllables(syllables_buf_p, notes_buf_p);\n                break;\n            case CMD_TO_NOTES:\n                ret = cgc_to_notes(syllables_buf_p, notes_buf_p);\n                break;\n            default:\n                ret = ERR_INVALID_CMD;\n        }\n\n        if (ret < 0) {\n            SENDSI(ret);\n            return ret;\n        } else {\n            cgc_memset((void *)syllables_buf_p, 0, BUFFER_LEN);\n            cgc_memset((void *)notes_buf_p, 0, BUFFER_LEN);\n        }\n    }\n    return ret;\n}\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/README.md",
    "content": "# CGC Challenge Binary 00024 - String Storage and Retrieval\n\n## Author Information\n\nSteve Wood <swood@cromulence.co>\n\n### DARPA performer group\n\nCromulence\n\n## Description\n\nThe program is an application for the storage and quick retrieval of string data.  Internally, a token is created for each string and the token is used as the key for a Binary Search Tree where the data is stored.  This allows for very quick retrieval of strings, provided that data is not stored in such a sequence that the tree degenerates into a linked list.  Most BST's do not allow for duplicate keys, but this implimentation does, storing the data common to one key in a linked list that must be sequentially searched.  However, key collisions should be rare and therefore sequential searches very short.  In addition, identical string data is not allowed, further limiting the possibility of key overlap.  \n\n### Feature List\n\nThe program allows for strings to be a)dded, d)eleted, f)ound, the entire tree to be w)alked, and tree s)tatistics to be printed. Strings are added by the command a/<string to be added> for example.  Strings to be added must be at least 10 characters in width.\n\n## Vulnerability\n\nThe vulnerability occurs in the processing of how data for duplicate keys is handled.  If more than one data element resolves to the same key, the data items are stored in a linked list attached to that that BST node.  During find or delete operations, they key is used to rapidly find the node and the attached linked list is sequentially walked and the string data compared to that being searched for.  If a match is found, the operation completes.  The vulnerability lies in an improper update of a pointer during a delete operation.  If there is a linked list, and the last node of the list is being deleted, the current pointer is updated to the \"next\" pointer before the memory is released with free().  At the end of the list, this causes a null pointer to be passed to free(), resulting in a SEGFAULT.\n\n\n### Generic class of vulnerability\n\nNULL Pointer Dereference.\n\n### CWE classification\n\nCWE-476\n\n## Challenges\n\nThis vulnerability requires two steps to demonstrate it crashing the program.  First two values with the same resulting token must be found, and then the second and only the second one being deleted will result in a SEGFAULT.  It is certainly an \"edge case\" condition for the program that would not readily show up with purely random fuzzing.\n\n\n\n\n\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/inputs/crash.txt",
    "content": "a/\u0001aaaaaaaa\na/gaaaaaaaa\nd/gaaaaaaaa\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/inputs/input.txt",
    "content": "a/one\na/two\na/three\nf/two\nd/two\nw\ns\nx\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/lib/cgc_mymath.h",
    "content": "/*\n\nAuthor: Jason Williams <jdw@cromulence.com>\n\nCopyright (c) 2014 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#ifndef __MYMATH_H__\n#define __MYMATH_H__\n\ndouble cgc_floor( double );\ndouble cgc_round( double, double n );\n\n#endif // __MYMATH_H__\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/lib/cgc_stdarg.h",
    "content": "/*\n\nAuthor: Jason Williams <jdw@cromulence.com>\n\nCopyright (c) 2014 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#ifndef __STDARG_H__\n#define __STDARG_H__\n\n#ifdef WIN\n#include <stdarg.h>\n#else\ntypedef __builtin_va_list __gnuc_va_list;\n\n#define va_start(v,l)   __builtin_va_start(v,l)\n#define va_end(v)       __builtin_va_end(v)\n#define va_arg(v,l)     __builtin_va_arg(v,l)\n\n\ntypedef __gnuc_va_list va_list;\n#endif\n\n#endif // __STDARG_H__\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/lib/cgc_stdint.h",
    "content": "/*\n\nAuthor: Jason Williams <jdw@cromulence.com>\n\nCopyright (c) 2014 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#ifndef __STDINT_H__\n#define __STDINT_H__\n\ntypedef signed char int8_t;\ntypedef short int int16_t;\ntypedef int int32_t;\ntypedef long long int int64_t;\n\ntypedef unsigned char uint8_t;\ntypedef unsigned short int uint16_t;\ntypedef unsigned int uint32_t;\ntypedef unsigned long long int uint64_t;\n\n#endif // __STDINT_H__\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/lib/cgc_stdlib.h",
    "content": "/*\n\nAuthor: Jason Williams <jdw@cromulence.com>\n\nCopyright (c) 2014 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#ifndef __STDLIB_H__\n#define __STDLIB_H__\n\n#define INUSE_FLAG 1\n#define FREE_FLAG 2\n\n#include \"libcgc.h\"\n\n//typedef unsigned long cgc_size_t;\n\ntypedef struct _heap_block_header {\n\tcgc_size_t remaining_size;\n\tstruct _heap_block_header *next;\n\tchar data[1];\n} heap_block_header;\n\n\ntypedef struct _heap_header {\n\tcgc_size_t size;\n\tchar flags;\n} heap_header;\n\ntypedef struct _heap_metadata {\n\tcgc_size_t mem_commit;\n\tcgc_size_t mem_free;\n\tcgc_size_t mem_inuse;\n\theap_block_header *blocks;\n} heap_metadata;\n\nvoid *cgc_calloc(cgc_size_t count, cgc_size_t size);\nvoid cgc_free(void *ptr);\nvoid *cgc_malloc(cgc_size_t size);\n\n\n\nint cgc_isspace( int c );\nint cgc_isdigit( int c );\nint cgc_isnan( double val );\nint cgc_isinf( double val );\ndouble cgc_atof(const char *str);\nint cgc_atoi(const char *str);\nint cgc_islower( int c );\nint cgc_isupper( int c );\nint cgc_isalpha( int c );\nint cgc_isalnum( int c );\nint cgc_memcpy( void *dest, void *src, cgc_size_t n);\n\nchar *cgc_strcpy( char *dest, char *src );\nchar *cgc_strncpy( char *, const char *, cgc_size_t );\nint cgc_putc( int );\nint cgc_printf( const char *fmt, ... );\nint cgc_sprintf( char *str, const char *fmt, ... );\nvoid cgc_bzero( void *, cgc_size_t );\nvoid *cgc_memset(void *, int, cgc_size_t);\nint cgc_strcmp( const char *, const char * );\nchar *cgc_strncat( char *dest, const char *src, cgc_size_t n );\ncgc_size_t cgc_getline( char *buffer, cgc_size_t len);\ncgc_size_t cgc_receive_until( char *, char, cgc_size_t );\nint cgc_receive_bytes (unsigned char *buffer, cgc_size_t size) ;\ncgc_size_t cgc_strcat( char *, char* );\ncgc_size_t cgc_strlen( char * );\ncgc_size_t cgc_itoa( char *, cgc_size_t, cgc_size_t );\nvoid cgc_puts( char *t );\nchar *cgc_strchr(const char *, int);\nchar *cgc_strtok(char *, const char *);\ncgc_size_t cgc_write( const void *, cgc_size_t );\nchar *cgc_strdup( char * );\n\n#endif // __STDLIB_H__\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/lib/malloc.c",
    "content": "/*\n\nAuthor: Jason Williams <jdw@cromulence.com>\n\nCopyright (c) 2014 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#include \"cgc_stdlib.h\"\n#include \"cgc_malloc.h\"\n\n#define ALLOC_PAGE_SIZE     (4096)\n\n#define FREE_BLOCK_NEXT( block )    (((tMallocAllocFtr *)((void *)block + (((tMallocAllocHdr *)block)->alloc_size & ~0x3)-sizeof(tMallocAllocHdr)))->pNext)\n#define FREE_BLOCK_PREV( block )    (((tMallocAllocFtr *)((void *)block + (((tMallocAllocHdr *)block)->alloc_size & ~0x3)-sizeof(tMallocAllocHdr)))->pPrev)\n\n#define SET_BIT( val, bit ) (val |= (bit))\n#define CLEAR_BIT( val, bit ) (val &= ~(bit))\n#define IS_BIT_SET( val, bit ) (val & (bit))\n\ntMallocManager g_memManager;\n\nvoid *cgc_calloc( cgc_size_t count, cgc_size_t obj_size )\n{\n    cgc_size_t allocation_size = (count * obj_size);\n    void *pMemBuffer;\n\n    pMemBuffer = cgc_malloc( allocation_size );\n\n    cgc_memset( pMemBuffer, 0, allocation_size );\n\n    return (pMemBuffer);\n}\n\nvoid *cgc_add_free_list( cgc_size_t request_size )\n{\n    // Include header\n    cgc_size_t grow_size = (request_size + 4);\n\n    // Increases the size of the free list\n    if ( grow_size % ALLOC_PAGE_SIZE != 0 )\n    {\n        grow_size = (grow_size / ALLOC_PAGE_SIZE) + 1;\n        grow_size *= ALLOC_PAGE_SIZE;\n    }\n\n    void *pAllocLocation;\n\n    if ( cgc_allocate( grow_size, 0, &pAllocLocation ) != 0 )\n    {\n        // Out of memory\n        cgc__terminate( -2 );\n    }\n\n    // Provision allocation\n    tMallocAllocHdr *pNewAllocHdr = (tMallocAllocHdr *)pAllocLocation;\n    tMallocAllocFtr *pNewAllocFtr = (tMallocAllocFtr *)(pAllocLocation + (grow_size-sizeof(tMallocAllocFtr)));\n\n    pNewAllocHdr->alloc_size = (grow_size-sizeof(tMallocAllocHdr));\n\n    // Link at front\n    pNewAllocFtr->pPrev = NULL;\n    pNewAllocFtr->pNext = g_memManager.pFreeList;\n    g_memManager.pFreeList = pNewAllocHdr;\n\n    return (void*)pNewAllocHdr;\n}\n\nvoid *cgc_malloc( cgc_size_t alloc_size )\n{\n    // Allocate\n    if ( alloc_size < 8 )\n        alloc_size = 8;\n    else if ( alloc_size % 4 != 0 )\n    {\n        alloc_size = (alloc_size >> 2) + 1;\n        alloc_size = (alloc_size << 2);\n    }\n\n    // Scan free list for available objects\n    void *pFreeCur;\n\n    pFreeCur = g_memManager.pFreeList;\n\n    for (;;)\n    {\n        if ( pFreeCur == NULL )\n        {\n            // End of list -- no suitable allocations available\n            pFreeCur = cgc_add_free_list( alloc_size );\n        }\n\n        tMallocAllocHdr *pFreeCurHeader = ((tMallocAllocHdr *)pFreeCur);\n        tMallocAllocFtr *pFreeCurFooter = ((tMallocAllocFtr *)(pFreeCur + (pFreeCurHeader->alloc_size & ~0x3)-sizeof(tMallocAllocHdr)));\n\n        // Check for a suitable allocation\n        if ( pFreeCurHeader->alloc_size >= alloc_size )\n        {\n            // Claim this allocation\n            void *pClaimAllocation = (pFreeCur + sizeof(tMallocAllocHdr));\n\n            // Split chunk\n            cgc_size_t size_remaining = pFreeCurHeader->alloc_size - alloc_size;\n\n            // Allocate this chunk and set size...\n            pFreeCurHeader->alloc_size = alloc_size;\n\n            // Set it to being inuse\n            SET_BIT( pFreeCurHeader->alloc_size, MALLOC_INUSE_FLAG_BIT );\n\n            if ( size_remaining >= (sizeof(tMallocAllocHdr) + sizeof(tMallocAllocFtr)) )\n            {\n                // Build a new free block\n                void *pNewChunk = (pFreeCur + (alloc_size + sizeof(tMallocAllocHdr)));\n\n                tMallocAllocHdr *pNewChunkHeader = ((tMallocAllocHdr *)pNewChunk);\n                pNewChunkHeader->alloc_size = (size_remaining - sizeof(tMallocAllocHdr));\n\n                tMallocAllocFtr *pNewChunkFooter = pFreeCurFooter;\n\n                if ( ((void *)pNewChunkHeader + (pNewChunkHeader->alloc_size & ~0x3)-sizeof(tMallocAllocHdr)) != pFreeCurFooter )\n                {\n                    cgc_printf( \"Footer != in malloc\" );\n                    cgc__terminate( -3 );\n                }\n\n                // Fix top link (if we need to)\n                if ( g_memManager.pFreeList == pFreeCur )\n                {\n                    g_memManager.pFreeList = (void *)pNewChunkHeader;\n\n                    if ( pNewChunkFooter->pNext )\n                        FREE_BLOCK_PREV( pNewChunkFooter->pNext ) = pNewChunkHeader;\n                }\n                else\n                {\n                    // Fix up links\n                    if ( pNewChunkFooter->pPrev )\n                        FREE_BLOCK_NEXT( pNewChunkFooter->pPrev ) = pNewChunk;\n\n                    if ( pNewChunkFooter->pNext )\n                        FREE_BLOCK_PREV( pNewChunkFooter->pNext ) = pNewChunk;\n                }\n\n                // Mark the object as having a next object (aids in coalescing)\n                SET_BIT( pFreeCurHeader->alloc_size, MALLOC_NEXT_FLAG_BIT );\n            }\n            else\n            {\n                // Fix link (if we need to)\n                if ( g_memManager.pFreeList == pFreeCur )\n                {\n                    g_memManager.pFreeList = (void *)pFreeCurFooter->pNext;\n\n                    if ( pFreeCurFooter->pNext )\n                        FREE_BLOCK_PREV( pFreeCurFooter->pNext ) = NULL;\n                }\n                else\n                {\n                    // Link around\n                    if ( pFreeCurFooter->pPrev )\n                        FREE_BLOCK_NEXT( pFreeCurFooter->pPrev ) = pFreeCurFooter->pNext;\n\n                    if ( pFreeCurFooter->pNext )\n                        FREE_BLOCK_PREV( pFreeCurFooter->pNext ) = pFreeCurFooter->pPrev;\n                }\n            }\n\n\n            // Clear the allocation\n            cgc_memset( (void *)(pFreeCur + sizeof(tMallocAllocHdr)), 0, alloc_size );\n\n            // Return the allocated memory\n            return (pFreeCur+sizeof(tMallocAllocHdr));\n        }\n\n        // Goto NEXT\n        pFreeCur = pFreeCurFooter->pNext;\n    }\n}\n\nvoid cgc_free( void *pItem )\n{\n    // Free an object and coalesce to neighboring block if available\n\n    // Check neighbor for coalescing\n    tMallocAllocHdr *pItemHdr = (tMallocAllocHdr *)(pItem - sizeof(tMallocAllocHdr));\n\n    // Verify inuse bit is set\n    if ( !IS_BIT_SET(pItemHdr->alloc_size, MALLOC_INUSE_FLAG_BIT) )\n    {\n        // Error object cannot be freed (inuse bit is not set)\n        cgc__terminate( -2 );\n    }\n\n    // Do we have a neighbor??? IF so perform coalescing\n    if ( IS_BIT_SET( pItemHdr->alloc_size, MALLOC_NEXT_FLAG_BIT) )\n    {\n        tMallocAllocHdr *pNeighbor = (pItem + (pItemHdr->alloc_size & ~0x3));\n\n        // Is neighbor inuse? If not -- go ahead and coalesce\n        if ( !IS_BIT_SET(pNeighbor->alloc_size, MALLOC_INUSE_FLAG_BIT) )\n        {\n            // Coalesce!\n            cgc_size_t coalesceSize = (pItemHdr->alloc_size & ~0x3) + (pNeighbor->alloc_size & ~0x3) + sizeof(tMallocAllocHdr);\n\n            // Set size\n            // The inuse bit is cleared here\n            pItemHdr->alloc_size = coalesceSize;\n\n            // Set the next flag if the neighbor block has a next flag set\n            if ( IS_BIT_SET( pNeighbor->alloc_size, MALLOC_NEXT_FLAG_BIT ) )\n                SET_BIT( pItemHdr->alloc_size, MALLOC_NEXT_FLAG_BIT );\n\n            // Relink\n            if ( g_memManager.pFreeList == pNeighbor )\n            {\n                g_memManager.pFreeList = pItemHdr;\n\n                tMallocAllocFtr *pItemFtr = ((tMallocAllocFtr *)((void *)pItemHdr + coalesceSize-sizeof(tMallocAllocHdr)));\n\n                if ( pItemFtr->pNext )\n                    FREE_BLOCK_PREV( pItemFtr->pNext ) = pItemHdr;\n            }\n            else\n            {\n                tMallocAllocFtr *pItemFtr = ((tMallocAllocFtr *)((void *)pItemHdr + coalesceSize-sizeof(tMallocAllocHdr)));\n\n                // Fix up links\n                if ( pItemFtr->pPrev )\n                    FREE_BLOCK_NEXT( pItemFtr->pPrev ) = pItemHdr;\n\n                if ( pItemFtr->pNext )\n                    FREE_BLOCK_PREV( pItemFtr->pNext ) = pItemHdr;\n            }\n\n            // Done\n            return;\n        }\n    }\n\n    // No coalesce possible, just link it to the top of the list\n    CLEAR_BIT( pItemHdr->alloc_size, MALLOC_INUSE_FLAG_BIT );\n\n    tMallocAllocFtr *pItemFtr = ((tMallocAllocFtr *)((void *)pItemHdr + (pItemHdr->alloc_size & ~0x3)-sizeof(tMallocAllocHdr)));\n\n    pItemFtr->pNext = g_memManager.pFreeList;\n    pItemFtr->pPrev = NULL;\n\n    if ( g_memManager.pFreeList )\n        FREE_BLOCK_PREV( g_memManager.pFreeList ) = pItemHdr;\n\n    // Move to top of list\n    g_memManager.pFreeList = pItemHdr;\n\n    // Done\n    return;\n}\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/lib/mymath.c",
    "content": "/*\n\nAuthor: Jason Williams <jdw@cromulence.com>\n\nCopyright (c) 2014 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#include \"libcgc.h\"\n#include \"cgc_mymath.h\"\n#include \"cgc_stdint.h\"\n\ndouble cgc_floor( double val )\n{\n    if ( val > 0.0 )\n        return cgc_rint( val + 0.5 ) - 1.0;\n    else if ( val < 0.0 )\n        return cgc_rint( val - 0.5 ) + 1.0;\n    else\n        return 0.0;\n}\n\ndouble cgc_round_away_from_zero( double val )\n{\n    if ( val > 0.0 )\n        return cgc_rint( val + 0.5 );\n    else if ( val < 0.0 )\n        return cgc_rint( val - 0.5 );\n    else\n        return 0.0;\n}\n\ndouble cgc_round( double val, double n )\n{\n    // Round to n digits\n    n = cgc_rint( n );\n\n    double high_pow10 = cgc_pow( 10, n );\n    double low_pow10 = cgc_pow( 10, -n );\n\n    return (cgc_round_away_from_zero( val * high_pow10 ) * low_pow10);\n}\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/lib/new_printf.c",
    "content": "/*\n\nAuthor: Jason Williams <jdw@cromulence.co>\n\nCopyright (c) 2014 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#include \"libcgc.h\"\n#include \"cgc_stdarg.h\"\n#include \"cgc_stdlib.h\"\n#include \"cgc_stdint.h\"\n#include \"cgc_mymath.h\"\n\n// 5 digits of precision\n#define F32_PRECISION       0.00001\n\nint cgc_putc( int c )\n{\n    cgc_size_t tx_count;\n\n    if ( cgc_transmit( STDOUT, &c, 1, &tx_count ) != 0 )\n        cgc__terminate(2);\n\n    return c;\n}\n\nvoid cgc_int_to_str( int val, char *buf )\n{\n    char temp_buf[32];\n    char *c = temp_buf;\n    int count = 0;\n\n    if ( buf == NULL )\n        return;\n\n    if ( val < 0 )\n    {\n        *buf = '-';\n        buf++;\n\n        val *= -1;\n    }\n\n    do\n    {\n        *c = (val % 10) + '0';\n        val /= 10;\n\n        c++;\n        count++;\n    } while ( val != 0 );\n\n    while ( count-- > 0 )\n    {\n        c--;\n        *buf = *c;\n        buf++;\n    }\n\n    *buf = '\\0';\n}\n\n\nvoid cgc_uint_to_str( unsigned int val, char *buf )\n{\n    char temp_buf[32];\n    char *c = temp_buf;\n    int count = 0;\n\n    if ( buf == NULL )\n        return;\n\n    do\n    {\n        *c = (val % 10) + '0';\n        val /= 10;\n\n        c++;\n        count++;\n    } while ( val != 0 );\n\n    while ( count-- > 0 )\n    {\n        c--;\n        *buf = *c;\n        buf++;\n    }\n\n    *buf = '\\0';\n}\n\n\nvoid cgc_int_to_hex( unsigned int val, char *buf )\n{\n    char temp_buf[32];\n    char *c = temp_buf;\n    int count = 0;\n\n    if ( buf == NULL )\n        return;\n\n    do\n    {\n        *c = (val % 16) + '0';\n\tif (*c > '9') {\n\t\t*c += 7;\n\t}\n        val /= 16;\n\n        c++;\n        count++;\n    } while ( val != 0 );\n\n    while ( count-- > 0 )\n    {\n        c--;\n        *buf = *c;\n        buf++;\n    }\n\n    *buf = '\\0';\n}\n\nvoid cgc_float_to_str( double val, char *buf, int precision )\n{\n    if ( buf == NULL )\n        return;\n\n    if ( cgc_isnan( val ) )\n    {\n        cgc_strcpy( buf, \"nan\" );\n    }\n    else if ( cgc_isinf( val ) )\n    {\n        cgc_strcpy( buf, \"inf\" );\n    }\n    else if ( val == 0.0 )\n    {\n        cgc_strcpy( buf, \"0.00000\" );\n    }\n    else\n    {\n        int digit;\n        int m;\n        int m1;\n        int fraction_digit;\n        int in_fraction;\n        int neg = 0;\n        char *c = buf;\n\n        if ( val > 0.0 )\n            val = val + (F32_PRECISION * 0.5);\n        else\n            val = val - (F32_PRECISION * 0.5);\n\n        // Negative numbers\n        if ( val < 0.0 )\n        {\n            neg = 1;\n            *(c++) = '-';\n            val = -val;\n        }\n\n        // Calculate magnitude\n        m = cgc_log10( val );\n\n        if ( m < 1.0 )\n            m = 0;\n\n        fraction_digit = 0;\n        in_fraction = 0;\n        while ( val > F32_PRECISION || m >= 0 )\n        {\n            double weight = cgc_pow( 10.0, m );\n            if ( weight > 0 && !cgc_isinf(weight) )\n            {\n                digit = cgc_floor( val / weight );\n                val -= (digit * weight);\n\n                *(c++) = '0' + digit;\n\n                if ( in_fraction )\n                    fraction_digit++;\n            }\n\n            if ( m == 0 && val > 0.0 )\n            {\n                *(c++) = '.';\n                in_fraction = 1;\n                fraction_digit = 0;\n            }\n\n            m--;\n        }\n\n        while ( in_fraction && fraction_digit < precision )\n        {\n            *(c++) = '0';\n            fraction_digit++;\n        }\n\n        *c = '\\0';\n    }\n}\n\nint cgc_vprintf( const char *fmt, va_list arg )\n{\n    int character_count = 0;\n    char temp_buf[64];\n    int width, precision, zero_padding, left_justification;\n    int i;\n    int pad_len;\n\n    if ( fmt == NULL )\n        return -1;\n\n    while ( *fmt )\n    {\n        if ( *fmt == '@' )\n        {\n            fmt++;\n\n            width=0;\n            precision=0;\n            zero_padding=0;\n            left_justification=0;\n            pad_len=0;\n\n            // We handle width, precision, and justification (but not for floats yet)\n            if (*fmt == '@') {\n\n                cgc_putc('@');\n                fmt++;\n                character_count++;\n                continue;\n            }\n\n            if (*fmt == '-') {\n\n                left_justification=1;\n                ++fmt;\n            }\n\n            if (cgc_isdigit(*fmt)) {\n\n                if (*fmt == '0') {\n\n                    zero_padding = 1;\n                    fmt++;\n                }\n\n                if (cgc_isdigit(*fmt)) {\n\n                    width = cgc_atoi(fmt);\n\n                    // skip past the width specification\n                    while (cgc_isdigit(*fmt))\n                        fmt++;\n                }\n            }\n\n            if (*fmt == '.') {\n\n                // skip over the '.'\n                fmt++;\n\n                precision=cgc_atoi(fmt);\n\n                // now skip past the integer precision value\n                while (cgc_isdigit(*fmt))\n                    fmt++;\n\n            }\n\n                // single char\n            if (*fmt == 'c') {\n                \n                char c = (char )va_arg(arg, int);\n\n                pad_len = width - 1;\n\n                // justify right \n                if (!left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        if (zero_padding)\n                            cgc_putc('0');\n                        else\n                            cgc_putc(' ');\n\n                        character_count++;\n                    }\n                }\n\n                // output the char itself\n                cgc_putc(c);\n                character_count++;\n\n                // justify to the left\n                if (left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        // the option to pad with 0 is ignored when left justified\n                        cgc_putc(' ');\n                        character_count++;\n                    }\n                }\n\n                fmt++;\n                continue;\n            }\n\n                 // Integer \n            if (*fmt == 'd')  {\n\n                int int_arg = va_arg( arg, int );\n                char *c;\n\n                cgc_int_to_str( int_arg, temp_buf );\n\n                // is the output string shorter than the desired width?\n                pad_len = width - cgc_strlen(temp_buf);\n\n                // right justification\n                if (!left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        if (zero_padding)\n                            cgc_putc('0');\n                        else\n                            cgc_putc(' ');\n\n                        character_count++;\n                    }\n                }\n\n                // now output the integer value\n                c = temp_buf;\n                while ( *c )\n                {\n                    cgc_putc( *c );\n                    character_count++;\n                    c++;\n                }\n\n                // left justification\n                if (left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        // the option to pad with 0 is ignored when left justified\n                        cgc_putc(' ');\n                        character_count++;\n                    }\n                }\n\n                fmt++;\n                continue;\n\n            }\n\n\n                 // Integer \n            if (*fmt == 'u')  {\n\n                unsigned int int_arg = va_arg( arg, int );\n                char *c;\n\n                cgc_uint_to_str( int_arg, temp_buf );\n\n                // is the output string shorter than the desired width?\n                pad_len = width - cgc_strlen(temp_buf);\n\n                // right justification\n                if (!left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        if (zero_padding)\n                            cgc_putc('0');\n                        else\n                            cgc_putc(' ');\n\n                        character_count++;\n                    }\n                }\n\n                // now output the integer value\n                c = temp_buf;\n                while ( *c )\n                {\n                    cgc_putc( *c );\n                    character_count++;\n                    c++;\n                }\n\n                // left justification\n                if (left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        // the option to pad with 0 is ignored when left justified\n                        cgc_putc(' ');\n                        character_count++;\n                    }\n                }\n\n                fmt++;\n                continue;\n\n            }\n\n\n\n\n                // hex\n            if ( *fmt == 'x')  {\n            \n                unsigned int int_arg = va_arg( arg, unsigned int );\n                char *c;\n\n                cgc_int_to_hex( int_arg, temp_buf );\n\n                // is the output string shorter than the desired width?\n                pad_len = width - cgc_strlen(temp_buf);\n\n                // right justification\n                if (!left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        if (zero_padding)\n                            cgc_putc('0');\n                        else\n                            cgc_putc(' ');\n\n                        character_count++;\n                    }\n                }\n\n                // now output the hex string\n                c = temp_buf;\n                while ( *c )\n                {\n                    cgc_putc( *c );\n                    character_count++;\n                    c++;\n                }\n\n                // left justification\n                if (left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        // the option to pad with 0 is ignored when left justified\n                        cgc_putc(' ');\n                        character_count++;\n                    }\n                }\n\n                fmt++;\n                continue;\n            }\n\n                // Float\n            if (*fmt =='f' ) {\n\n                    // currently does not support precision specification for float type\n                    // need the float_to_str() updated to support the rounding necessary\n\n                double float_arg = va_arg( arg, double );\n                char *c;\n\n                cgc_float_to_str( float_arg, temp_buf, precision);\n\n                // is the output string shorter than the desired width?\n                pad_len = width - cgc_strlen(temp_buf);\n\n                // pad the output with spaces or zeros\n                if (!left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        if (zero_padding)\n                            cgc_putc('0');\n                        else\n                            cgc_putc(' ');\n\n                        character_count++;\n                    }\n                }\n\n                // now output the float value\n                c = temp_buf;\n                while ( *c )\n                {\n                    cgc_putc( *c );\n                    character_count++;\n                    c++;\n                }\n                fmt++;\n                continue;\n            }\n\n            if (*fmt== 's' )  {\n                // String\n                char *string_arg = va_arg( arg, char * );\n                int output_strlen;\n\n                if (precision > 0 && precision < cgc_strlen(string_arg))\n\n                    output_strlen = precision;\n                else\n                    output_strlen = cgc_strlen(string_arg);\n\n\n                pad_len = width - output_strlen;\n\n                // pad the output with spaces or zeros\n                // right justification\n                if (!left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        if (zero_padding)\n                            cgc_putc('0');\n                        else\n                            cgc_putc(' ');\n\n                        character_count++;\n                    }\n                }\n\n#if 1\n                cgc_size_t tmp_out = 0;\n                int tmp_ret = cgc_transmit(STDOUT, string_arg, cgc_strlen(string_arg), &tmp_out);\n                if (tmp_ret != 0)\n                    cgc__terminate(1);\n\n                character_count += tmp_out;\n#else\n                while ( *string_arg && output_strlen > 0 )\n                {\n                    putc( *string_arg );\n                    character_count++;\n                    string_arg++;\n                    --output_strlen;\n                }\n#endif\n\n                // left justification\n                if (left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        // the option to pad with 0 is ignored when left justified\n                        cgc_putc(' ');\n                        character_count++;\n                    }\n                }\n\n                fmt++;\n                continue;\n\n            }\n\n        }\n        else\n        {\n            cgc_putc( *fmt );\n            fmt++;\n\n            character_count++;\n        }\n    }\n\n    return (character_count);\n}\n\n\n\n\nint cgc_vsprintf( char *str, const char *fmt, va_list arg )\n{\n    int character_count = 0;\n    char temp_buf[64];\n    int width, precision, zero_padding, left_justification;\n    int i;\n    int pad_len;\n\n    if ( fmt == NULL )\n        return -1;\n\n    while ( *fmt )\n    {\n        if ( *fmt == '@' )\n        {\n            fmt++;\n\n            width=0;\n            precision=0;\n            zero_padding=0;\n            left_justification=0;\n            pad_len=0;\n\n            \n            if (*fmt == '@') {\n\n                str[character_count]='@';\n                fmt++;\n                character_count++;\n                continue;\n            }\n\n            if (*fmt == '-') {\n\n                left_justification=1;\n                ++fmt;\n            }\n\n            if (cgc_isdigit(*fmt)) {\n\n                if (*fmt == '0') {\n\n                    zero_padding = 1;\n                    fmt++;\n                }\n\n                if (cgc_isdigit(*fmt)) {\n\n                    width = cgc_atoi(fmt);\n\n                    while (cgc_isdigit(*fmt))\n                        fmt++;\n                }\n            }\n\n            if (*fmt == '.') {\n\n                // skip over the '.'\n                fmt++;\n\n                precision=cgc_atoi(fmt);\n\n                // now skip past the integer precision value\n                while (cgc_isdigit(*fmt))\n                    fmt++;\n\n            }\n\n                // single char\n            if (*fmt == 'c') {\n                \n                char c = (char )va_arg(arg, int);\n\n                pad_len = width - 1;\n\n                // justify right \n                if (!left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        if (zero_padding)\n                            str[character_count]='0';\n                        else\n                            str[character_count]=' ';\n\n                        character_count++;\n                    }\n                }\n\n                str[character_count]=c;\n                character_count++;\n\n                // justify to the left\n                if (left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        // the option to pad with 0 is ignored when left justified\n                        str[character_count]=' ';\n                        character_count++;\n                    }\n                }\n\n                fmt++;\n                continue;\n            }\n\n                 // Integer \n            if (*fmt == 'd')  {\n\n                int int_arg = va_arg( arg, int );\n                char *c;\n\n                cgc_int_to_str( int_arg, temp_buf );\n\n                // is the output string shorter than the desired width?\n                pad_len = width - cgc_strlen(temp_buf);\n\n                // right justification\n                if (!left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        if (zero_padding)\n                            str[character_count]='0';\n                        else\n                            str[character_count]=' ';\n\n                        character_count++;\n                    }\n                }\n\n                // now output the integer value\n                c = temp_buf;\n                while ( *c )\n                {\n                    str[character_count]=*c;\n                    character_count++;\n                    c++;\n                }\n\n                // left justification\n                if (left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        // the option to pad with 0 is ignored when left justified\n                        str[character_count]= ' ';\n                        character_count++;\n                    }\n                }\n\n                fmt++;\n                continue;\n\n            }\n\n                // hex\n            if ( *fmt == 'x')  {\n            \n                unsigned int int_arg = va_arg( arg, unsigned int );\n                char *c;\n\n                cgc_int_to_hex( int_arg, temp_buf );\n\n                // is the output string shorter than the desired width?\n                pad_len = width - cgc_strlen(temp_buf);\n\n                // right justification\n                if (!left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        if (zero_padding)\n                            str[character_count] = '0';\n                        else\n                            str[character_count] = ' ';\n\n                        character_count++;\n                    }\n                }\n\n                // now output the hex string\n                c = temp_buf;\n                while ( *c )\n                {\n                    str[character_count]=*c;\n                    character_count++;\n                    c++;\n                }\n\n                // left justification\n                if (left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        // the option to pad with 0 is ignored when left justified\n                        str[character_count]=' ';\n                        character_count++;\n                    }\n                }\n\n                fmt++;\n                continue;\n            }\n\n                // Float\n            if (*fmt =='f' ) {\n\n\n                double float_arg = va_arg( arg, double );\n                char *c;\n\n                cgc_float_to_str( float_arg, temp_buf, precision);\n\n                // is the output string shorter than the desired width?\n                pad_len = width - cgc_strlen(temp_buf);\n\n                // pad the output with spaces or zeros\n                if (!left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        if (zero_padding)\n                            str[character_count]='0';\n                        else\n                            str[character_count]=' ';\n\n                        character_count++;\n                    }\n                }\n\n                // now output the float value\n                c = temp_buf;\n                while ( *c )\n                {\n                    str[character_count]= *c;\n                    character_count++;\n                    c++;\n                }\n                fmt++;\n                continue;\n            }\n\n            if (*fmt== 's' )  {\n                // String\n                char *string_arg = va_arg( arg, char * );\n                int output_strlen;\n\n                if (precision > 0 && precision < cgc_strlen(string_arg))\n\n                    output_strlen = precision;\n                else\n                    output_strlen = cgc_strlen(string_arg);\n\n\n                pad_len = width - output_strlen;\n\n                // pad the output with spaces or zeros\n                // right justification\n                if (!left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        if (zero_padding)\n                            str[character_count]='0';\n                        else\n                            str[character_count]=' ';\n                        character_count++;\n                    }\n                }\n\n                while ( *string_arg && output_strlen > 0 )\n                {\n                    str[character_count]= *string_arg;\n                    character_count++;\n                    string_arg++;\n                    --output_strlen;\n                }\n\n                // left justification\n                if (left_justification) {\n                    for (i=0; i< pad_len; ++i) {\n\n                        // the option to pad with 0 is ignored when left justified\n                        str[character_count]=' ';\n                        character_count++;\n                    }\n                }\n\n                fmt++;\n                continue;\n\n            }\n\n        }\n        else\n        {\n            str[character_count]= *fmt;\n            fmt++;\n\n            character_count++;\n        }\n    }\n\n    return (character_count);\n}\n\nint cgc_printf( const char *fmt, ... )\n{\n    va_list arg;\n    int done;\n    char large_buff[4096];\n    cgc_size_t tx_count;\n\n    va_start( arg, fmt );\n\n   // done = vsprintf(large_buff, fmt, arg);\n   // transmit( STDOUT, large_buff, done, &tx_count );\n    \n    done = cgc_vprintf( fmt, arg );\n    va_end( arg );\n\n    return done;\n}\n\nint cgc_sprintf( char *str, const char *fmt, ... )\n{\n    va_list arg;\n    int done;\n\n    va_start( arg, fmt );\n    done = cgc_vsprintf( str, fmt, arg );\n    va_end( arg );\n\n    return done;\n}\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/lib/stdlib.c",
    "content": "/*\n\nAuthor: Jason Williams <jdw@cromulence.com>\n\nCopyright (c) 2014 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#include \"libcgc.h\"\n#include \"cgc_stdlib.h\"\n#include \"cgc_stdint.h\"\n\nint cgc_memcpy( void *dest, void *src, cgc_size_t n )\n{\n        cgc_size_t index = 0;\n\n        while ( index < n ) {\n                ((char*)dest)[index] = ((char*)src)[index];\n                index++;\n        }\n\n        return index;\n}\n\nint cgc_islower( int c )\n{\n        if ( c >= 0x61 && c <= 0x7a )\n                return 1;\n        else\n                return 0;\n}\n\nint cgc_isupper( int c )\n{\n        if ( c >= 0x41 && c <= 0x5a )\n                return 1;\n        else\n                return 0;\n}\n\nint cgc_isalpha( int c )\n{\n        return cgc_islower( c ) | cgc_isupper( c );\n}\n\nint cgc_isalnum( int c )\n{\n        return cgc_isalpha( c ) | cgc_isdigit( c );\n}\n\nint cgc_isspace( int c )\n{\n    if ( c == ' ' ||\n         c == '\\t' ||\n         c == '\\n' ||\n         c == '\\v' ||\n         c == '\\f' ||\n         c == '\\r' )\n        return 1;\n    else\n        return 0;\n}\n\nint cgc_isdigit( int c )\n{\n    if ( c >= '0' && c <= '9' )\n        return 1;\n    else\n        return 0;\n}\n\nint cgc_isnan( double val )\n{\n    return __builtin_isnan( val );\n}\n\nint cgc_isinf( double val )\n{\n    return __builtin_isinf( val );\n}\n\ndouble cgc_atof(const char* str)\n{\n    if ( str == NULL )\n        return 0.0;\n\n    double val = 0.0;\n    double scale = 0.1;\n    int sign = 1;\n    int part;\n\n    // Skip whitespace\n    while ( cgc_isspace( str[0] ) )\n        str++;\n\n    part = 0; // First part (+/-/./number is acceptable)\n\n    while( str[0] != '\\0' )\n    {\n        if ( str[0] == '-' )\n        {\n            if ( part != 0 )\n                return 0.0;\n\n            sign = -1;\n            part++;\n        }\n        else if ( str[0] == '+' )\n        {\n            if ( part != 0 )\n                return 0.0;\n\n            part++;\n        }\n        else if ( str[0] == '.' )\n        {\n            if ( part == 0 || part == 1 )\n                part = 2;\n            else\n                return 0.0;\n        }\n        else if ( cgc_isdigit( *str ) )\n        {\n            if ( part == 0 || part == 1 )\n            {\n                // In integer part\n                part = 1;\n                val = (val * 10.0) + (*str - '0');\n            }\n            else if ( part == 2 )\n            {\n                val += ((*str - '0') * scale);\n                scale /= 10.0;\n            }\n            else\n            {\n                // part invalid\n                return 0.0;\n            }\n        }\n        else\n            break;\n\n        str++;\n    }\n\n    return (sign * val);\n}\n\n\nint cgc_atoi(const char* str)\n{\n    if ( str == NULL )\n        return 0;\n\n    int integer_part = 0;\n    int sign = 1;\n    int part;\n    int digit_count = 0;\n\n    // Skip whitespace\n    while ( cgc_isspace( str[0] ) )\n        str++;\n\n    part = 0; // First part (+/-/number is acceptable)\n\n    while( str[0] != '\\0' )\n    {\n        if ( str[0] == '-' )\n        {\n            if ( part != 0 )\n                return 0;\n\n            sign = -1;\n            part++;\n        }\n        else if ( str[0] == '+' )\n        {\n            if ( part != 0 )\n                return 0;\n\n            part++;\n        }\n        else if ( cgc_isdigit( *str ) )\n        {\n            if ( part == 0 || part == 1 )\n            {\n                // In integer part\n                part = 1;\n                integer_part = (integer_part * 10) + (*str - '0');\n\n                digit_count++;\n\n                if ( digit_count == 10 )\n                    break;\n            }\n            else\n            {\n                // part invalid\n                return 0;\n            }\n        }\n        else\n            break;\n\n        str++;\n    }\n\n    return (sign * integer_part);\n}\n\nchar *cgc_strcpy( char *dest, char *src )\n{\n    cgc_size_t i;\n\n    for ( i = 0; ; i++ )\n    {\n        if ( src[i] == '\\0' )\n            break;\n\n        dest[i] = src[i];\n    }\n    dest[i] = '\\0';\n\n    return (dest);\n}\n\nchar *cgc_strncpy( char *dest, const char *src, cgc_size_t n )\n{\n    cgc_size_t i;\n\n    for ( i = 0; i < n && src[i] != '\\0'; i++)\n        dest[i] = src[i];\n    for ( ; i < n; i++)\n        dest[i] = '\\0';\n\n    return (dest);\n}\n\nvoid cgc_bzero( void *buff, cgc_size_t len )\n{\n    cgc_size_t index = 0;\n    unsigned char *c = buff;\n\n    if ( buff == NULL ) {\n        goto end;\n    }\n\n    if ( len == 0 ) {\n        goto end;\n    }\n\n    for ( index = 0; index < len; index++ ) {\n        c[index] = 0x00;\n    }\n\nend:\n    return;\n}\n\nvoid *cgc_memset(void *s, int c, cgc_size_t n)\n{\n    unsigned char *t = (unsigned char *)s;\n    while (--n)\n        t[n] = (unsigned char)c;\n    t[n] = (unsigned char)c;\n    return(s);\n}\n\nint cgc_strcmp( const char *s1, const char *s2 )\n{\n    while ( *s1 && (*s1 == *s2) )\n    {\n      s1++,s2++;\n    }\n    return (*(const unsigned char *)s1 - *(const unsigned char *)s2);\n}\n\nchar *cgc_strncat ( char *dest, const char *src, cgc_size_t n )\n{\n    cgc_size_t dest_len = cgc_strlen(dest);\n    cgc_size_t i;\n\n    if (dest == NULL || src == NULL)\n    {\n      return(dest);\n    }\n    for (i = 0; i < n && src[i] != '\\0'; i++)\n    {\n      dest[dest_len+i] = src[i];\n    }\n    dest[dest_len+i] = '\\0';\n\n    return(dest);\n}\n\nint cgc_flush_input(int fd) {\n    cgc_fd_set read_fds;\n    int err;\n    int ready_fd;\n    struct cgc_timeval tv;\n    char buffer[1024];\n    cgc_size_t rcv_cnt;\n\n    while (1)  {\n\n        cgc_bzero((char *)&read_fds, sizeof(read_fds));\n        FD_SET(fd, &read_fds);\n\n        tv.tv_sec = 0;\n        tv.tv_usec = 10;\n\n        err = cgc_fdwait(fd + 1, &read_fds, NULL, &tv, &ready_fd);\n        if (err != 0) {\n            return err;\n        }\n\n        if (!FD_ISSET(fd, &read_fds))\n            break;\n        else\n            cgc_receive(fd, buffer, 1024, &rcv_cnt);\n     \n    }  \n\n    return 0;\n} // flush_input()\n\ncgc_size_t cgc_getline( char *buffer, cgc_size_t len)  {\nint count;\n\n    count = cgc_receive_until(buffer, '\\n', len);\n\n    if (count==len)\n        buffer[len-1]=0;\n    else {\n        buffer[count]=0;\n    }\n\n    return (count);\n    \n}\ncgc_size_t cgc_receive_until( char *dst, char delim, cgc_size_t max )\n{\n    cgc_size_t len = 0;\n    cgc_size_t rx = 0;\n    char c = 0;\n\n    while( len < max ) {\n        dst[len] = 0x00;\n\n        if ( cgc_receive( STDIN, &c, 1, &rx ) != 0 ) {\n            len = 0;\n            goto end;\n        }\n\n        if ( c == delim ) {\n\n            goto end;\n        }\n\n        dst[len] = c;\n        len++;\n    }\nend:\n\n    if (len == max)\n        cgc_flush_input(STDIN);\n\n    return len;\n}\n\nint cgc_receive_bytes (unsigned char *buffer, cgc_size_t size) \n{\ncgc_size_t count=0;\ncgc_size_t remaining = 0;\ncgc_size_t rxbytes=0;\n\n    remaining = size - count;\n\n    while(remaining)  {\n\n        if (!cgc_receive(STDIN, buffer+count, remaining, &rxbytes) ) {\n\n            remaining-=rxbytes;\n            count+=rxbytes;\n        }\n        \n        else {\n\n            return(-1);\n        }\n\n\n    }\n\nreturn 0;\n\n}\n\ncgc_size_t cgc_strcat( char *dest, char* src )\n{\n    cgc_size_t length = 0;\n    cgc_size_t start = 0;\n\n    if ( dest == NULL || src == NULL) {\n        goto end;\n    }\n\n    start = cgc_strlen( dest );\n\n    for ( ; src[length] != 0x00 ; start++, length++ ) {\n        dest[start] = src[length];\n    }\n\n    length = start;\nend:\n    return length;\n}\n\ncgc_size_t cgc_strlen( char * str )\n{\n    cgc_size_t length = 0;\n\n    if ( str == NULL ) {\n        goto end;\n    }\n\n    while ( str[length] ) { length++; }\n\nend:\n    return length;\n}\n\ncgc_size_t cgc_itoa( char *out, cgc_size_t val, cgc_size_t max )\n{\n    cgc_size_t length = 0;\n    cgc_size_t end = 0;\n    cgc_size_t temp = 0;\n\n    if ( out == NULL ) {\n        goto end;\n    }\n\n    // Calculate the needed length\n    temp = val;\n    do {\n        end++;\n        temp /= 10;\n    } while ( temp );\n\n    // ensure we have enough room\n    if ( end >= max ) {\n        goto end;\n    }\n\n    length = end;\n\n    // Subtract one to skip the null\n    end--;\n\n    do {\n        out[end] = (val % 10) + 0x30;\n        val /= 10;\n        end--;\n    } while ( val );\n\n    out[length] = 0x00;\nend:\n    return length;\n}\n\nvoid cgc_puts( char *t )\n{\n    cgc_size_t size;\n    cgc_transmit(STDOUT, t, cgc_strlen(t), &size);\n    cgc_transmit(STDOUT, \"\\n\", 1, &size);\n}\n\nchar *cgc_strchr(const char *s, int c) {\n\twhile (*s != '\\0') {\n\t\tif (*s == c) {\n\t\t\treturn((char *)s);\n\t\t}\n\t\ts++;\n\t}\n\tif (*s == c) {\n\t\treturn((char *)s);\n\t}\n\treturn(NULL);\n}\n\nchar *cgc_token = NULL;\nchar *cgc_prev_str = NULL;\nunsigned int cgc_prev_str_len = 0;\nchar *cgc_prev_str_ptr = NULL;\nchar *cgc_strtok(char *str, const char *delim) {\n\tchar *start;\n\tchar *end;\n\tchar *t;\n\tint i;\n\n\t// invalid input\n\tif (delim == NULL) {\n\t\treturn(NULL);\n\t}\n\t\n\t// called on existing string\n\tif (str == NULL) {\n\t\tif (cgc_prev_str == NULL) {\n\t\t\treturn(NULL);\n\t\t}\n\t\t// already parsed through end of original str\n\t\tif (cgc_prev_str_ptr >= cgc_prev_str+cgc_prev_str_len) {\n\t\t\treturn(NULL);\n\t\t}\n\t} else {\n\t\t// called with new string, so free the old one\n\t\tif (cgc_prev_str) {\n\t\t\tcgc_deallocate(cgc_prev_str, cgc_prev_str_len);\n\t\t\tcgc_prev_str = NULL;\n\t\t\tcgc_prev_str_len = 0;\n\t\t\tcgc_prev_str_ptr = NULL;\n\t\t}\n\t}\n\n\t// not been called before, so make a copy of the string\n\tif (cgc_prev_str == NULL) {\n\t\tif (cgc_strlen(str) > 4096) {\n\t\t\t// too big\n\t\t\treturn(NULL);\n\t\t} \n\t\tcgc_prev_str_len = cgc_strlen(str);\n\t\tif (cgc_allocate(cgc_prev_str_len, 0, (void *)&cgc_prev_str)) {\n\t\t\treturn(NULL);\n\t\t}\n\t\tcgc_strcpy(cgc_prev_str, str);\n\t\tcgc_prev_str_ptr = cgc_prev_str;\n\t}\n\n\tstr = cgc_prev_str_ptr;\n\n\t// make sure the string isn't starting with a delimeter\n\twhile (cgc_strchr(delim, str[0]) && str < cgc_prev_str+cgc_prev_str_len) {\n\t\tstr++;\n\t}\n\tif (str >= cgc_prev_str+cgc_prev_str_len) {\n\t\treturn(NULL);\n\t}\n\n\t// find the earliest next delimiter\n\tstart = str;\n\tend = str+cgc_strlen(str);\n\tfor (i = 0; i < cgc_strlen((char *)delim); i++) {\n\t\tif ((t = cgc_strchr(start, delim[i]))) {\n\t\t\tif (t != NULL && t < end) {\n\t\t\t\tend = t;\n\t\t\t}\n\t\t}\n\t}\n\t\n\t// populate the new token\n\tcgc_token = start;\n\t*end = '\\0';\n\n\tcgc_prev_str_ptr = end+1;\n\n\treturn(cgc_token);\n}\n\ncgc_size_t cgc_write( const void *buf, cgc_size_t count )\n{\n\tcgc_size_t size;\n\n\tcgc_transmit(STDOUT, buf, count, &size);\n\n\tif (count != size)\n\t\treturn(-1);\n\n\treturn(size);\n\n}\n\nchar *cgc_strdup(char *s) \n{\n        char *retval;\n\n        if (!s) {\n                return(NULL);\n        }\n\n        if (cgc_allocate(cgc_strlen(s)+1, 0, (void *)&retval)) {\n                return(NULL);\n        }\n\n        cgc_bzero(retval, cgc_strlen(s)+1);\n        cgc_strcpy(retval, s);\n\n        return(retval);\n}\n\n\n\n\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/notes.txt",
    "content": "In the compiled String_Storage_and_Retrieval.exe executable, the main function\nis at offset 0x6ac0 (0x406ac0 address).\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/src/bst.c",
    "content": "/*\n\nAuthor: Steve Wood <swood@cromulence.co>\n\nCopyright (c) 2014 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n\n#include \"libcgc.h\"\n#include \"cgc_bst.h\"\n#include \"cgc_malloc.h\"\n#include \"cgc_stdlib.h\"\n#include \"cgc_service.h\"\n\n    \nint cgc_insert_node(bst_node_type **head, data_item_type *data, unsigned long make_key()) {\n\nbst_node_type *tmp_node;\nunsigned long key_val=0;\ndata_item_type *next_ptr;\n\t\n\n\t// if no data was passed in, return error\n\tif (data==0)\n\t\treturn(-1);\n\n\n\t// make sure the tree already exists\n\tif (!*head) {\n\n\t\t*head=(bst_node_type *)cgc_calloc(1, sizeof(bst_node_type));\n\n\t\t// memory allocation failed\n\t\tif (!*head) {\n\n\t\t\treturn(-1);\n\t\t}\n\n\t\t// it does exist now, so just stick our data in it since no searching necessary\n\t\tkey_val=make_key(data);\n\n\t\tif (key_val > 0) {\n\n\t\t\t(*head)->data=data;\n\t\t\t(*head)->data_count = 1;\n\t\t\t(*head)->key=key_val;\n\t\t\treturn(0);\n\t\t}\n\t\telse {\n\n\t\t\treturn(-1);\n\t\t}\n\n\n\t}  // if (!head)\n\n\n\tkey_val=make_key(data);\n\n\n\ttmp_node=*head;\n\n\n\twhile (1) {\n\n\t\tif (key_val < tmp_node->key) {\n\n\t\t\tif (tmp_node->left != 0) {\n\n\t\t\t\ttmp_node=tmp_node->left;\n\t\t\t}\n\t\t\telse {\n\n\t\t\t\ttmp_node->left=(bst_node_type *)cgc_calloc(1, sizeof(bst_node_type));\n\n\t\t\t\tif (!tmp_node->left) {\n\t\t\t\t\treturn(-1);\n\t\t\t\t}\n\n\t\t\t\ttmp_node->left->data=data;\n\t\t\t\ttmp_node->left->data_count=1;\n\t\t\t\ttmp_node->left->key=key_val;\n\t\t\t\treturn(0);\n\t\t\t}\n\t\t}\n\t\t\t\n\t\telse if (key_val > tmp_node->key) {\n\n\n\t\t\tif (tmp_node->right !=0) {\n\n\t\t\t\ttmp_node=tmp_node->right;\n\t\t\t}\n\t\t\telse {\n\n\t\t\t\ttmp_node->right=(bst_node_type *)cgc_calloc(1, sizeof(bst_node_type));\n\n\t\t\t\tif (!tmp_node->right) {\n\t\t\t\t\treturn(-1);\n\t\t\t\t}\n\n\t\t\t\ttmp_node->right->data=data;\n\t\t\t\ttmp_node->right->data_count=1;\n\t\t\t\ttmp_node->right->key=key_val;\n\t\t\t\treturn(0);\n\t\t\t}\n\n\t\t}\n\t\t// should only happen if the keys are equal\n\t\telse   {  \n\t\t\n\t\t\t// if the strings don't match, its a key collision\n\t\t\tif (cgc_strcmp(tmp_node->data->name, data->name)!=0) {\n\n\t\t\t\t// so move to the end of the linked list and add the new data\n\t\t\t\tnext_ptr=tmp_node->data;\n\n\t\t\t\twhile (next_ptr->next != 0)\n\t\t\t\t\tnext_ptr=next_ptr->next;\n\n\t\t\t\tnext_ptr->next = data;\n\n\t\t\t\t// increment the count of the number in this linked list\n\t\t\t\ttmp_node->data_count++;\n\n\n\t\t\t}\n\t\t\treturn(0);\n\n\t\t}\n\t\t\t\n\t}\n\n\n}  // insert_node()\n\n\n\nint cgc_delete_node(bst_node_type **head, char *str, unsigned long key) {\n\nbst_node_type *tmp_node, *promote_node, *previous_node;\ndata_item_type *prev_ptr, *next_ptr;\n\n\tif (!*head) {\n\n\t\treturn(0);\n\t}\n\n\t// first locate the node\n\ttmp_node=*head;\n\n\twhile(tmp_node->key != key) {\n\n\t\tprevious_node=tmp_node;\n\n\t\tif (key < tmp_node->key) {\n\n\t\t\ttmp_node=tmp_node->left;\n\t\t}\n\t\telse {\n\n\t\t\ttmp_node=tmp_node->right;\n\t\t}\n\n\t\t// didn't find the key, just return\n\t\tif (tmp_node==0) {\n\n\t\t\treturn(0);\n\t\t}\n\n\t}\n\n\t// a new special case since this implementation allows for multiple values stored for the same key\n\t// if there is more than one data element in the matching node, the node won't get deleted\n\tif (tmp_node->data_count > 1) {\n\n\t\tprev_ptr=tmp_node->data;\n\t\tnext_ptr=prev_ptr->next;\n\n\t\t// check the first entry because if its the match we need to update the pointer stored in the BST node\n\t\tif (cgc_strcmp(tmp_node->data->name, str)==0) {\n\n\t\t\tcgc_free(prev_ptr);\n\t\t\ttmp_node->data=next_ptr;\n\t\t\ttmp_node->data_count--;\n\t\t\treturn (0);\n\n\t\t}\n\n\t\t// otherwise, cycle through the remainder of the linked list looking for a match\n\t\twhile (next_ptr!= 0) {\n\n\t\t\t//\tcgc_printf(\"looking for appended element\\n\");\n\t\t\tif (cgc_strcmp(next_ptr->name, str)==0) {\n\n\t\t\t\tprev_ptr->next = next_ptr->next;\n\t\t\t\ttmp_node->data_count--;\n\n#ifdef PATCHED\n#else\t\t\t\t\n\t\t\t\tnext_ptr=next_ptr->next;\n#endif\n\t\t\t\tcgc_free(next_ptr);\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse {\n\n\t\t\t\tprev_ptr=next_ptr;\n\t\t\t\tnext_ptr=next_ptr->next;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn(0);\n\t}\n\n\t// if the node has no children, delete it\n\tif (tmp_node->left == 0 && tmp_node->right == 0) {\n\n\t\t//cgc_printf(\"only one child node on this delete\\n\");\n\t\tif (tmp_node==*head) {\n\n\t\t\tcgc_free((*head)->data);\n\t\t\tcgc_free(*head);\n\t\t\t*head=0;\n\t\t\treturn 0;\n\t\t}\n\n\t\tif (previous_node->key > key) \n\t\t\tprevious_node->left=0;\n\n\t\telse\n\t\t\tprevious_node->right=0;\n\n\t\tcgc_free(tmp_node->data);\n\t\tcgc_free(tmp_node);\n\t}\n\n\t// if the node has two children, promote its in-order predecessor and then delete the old node.\n\telse if (tmp_node->left != 0 && tmp_node->right !=0 ) {\n\n\t\t// first find the node to be promoted.  Go left in the tree, and then all the way right.\n\t\tprevious_node=tmp_node;\n\t\tpromote_node=tmp_node->left;\n\n\t\twhile (promote_node->right != 0) {\n\t\t\tprevious_node=promote_node;\n\t\t\tpromote_node=promote_node->right;\n\t\t}\n\n\t\t// Now delete the data from the node to be deleted  and move the promote node's data there\n\t\tcgc_free(tmp_node->data);\n\t\ttmp_node->data=promote_node->data;\n\t\t\n\n\t\t// now delete the old location of the promote node\n\t\tif (promote_node->key > previous_node->key) {\n\n\t\t\tprevious_node->right=promote_node->left;\n\n\t\t}\n\t\telse {\n\t\t\tprevious_node->left=promote_node->left;\n\n\t\t}\n\n\t\ttmp_node->key=promote_node->key;\n\t\ttmp_node->data_count=promote_node->data_count;\n\t\tcgc_free(promote_node);\n\n\n\t}\n\t// if the node has one child, promote that child\n\telse {\n\n\n\t\tif (tmp_node==*head) {\n\n\t\t\tcgc_free((*head)->data);\n\n\t\t\tif (tmp_node->left !=0)\n\t\t\t\t*head=(*head)->left;\n\t\t\telse\n\t\t\t\t*head=(*head)->right;\n\n\t\t\tcgc_free(tmp_node);\n\n\t\t\treturn 0;\n\t\t}\n\n\n\t\tif (tmp_node->left != 0) \n\t\t\tpromote_node=tmp_node->left;\n\t\telse\n\t\t\tpromote_node=tmp_node->right;\n\n\t\tif (previous_node->key > key) \n\t\t\tprevious_node->left=promote_node;\n\n\t\telse\n\t\t\tprevious_node->right=promote_node;\n\n\t\tcgc_free(tmp_node->data);\n\t\tcgc_free(tmp_node);\t\n\n\t}\n\nreturn(0);\n\n\n} // delete_node()\n\nvoid *cgc_find_node_by_key(bst_node_type *head, unsigned long key) {\n\nbst_node_type *tmp_node;\n\n\n\tif (!head) {\n\n\t\treturn(0);\n\t}\n\n\ttmp_node=head;\n\n\twhile(tmp_node->key != key) {\n\n\t\tif (key < tmp_node->key) {\n\n\t\t\ttmp_node=tmp_node->left;\n\t\t}\n\t\telse {\n\n\t\t\ttmp_node=tmp_node->right;\n\t\t}\n\n\t\t// key not found, return 0\n\t\tif (tmp_node==0) {\n\n\t\t\treturn(0);\n\t\t}\n\n\t}\n\n\t// otherwise, return the address of the node\n\treturn(tmp_node->data);\n\n\n} // find_node()\n\n\n\nint cgc_walk_tree(bst_node_type *node) {\ndata_item_type *tmp_ptr;\n\n\tif (node==0)\n\t\treturn 0;\n\n\t// recursively walk the tree and print out the data from each node\n\t// classically called in-order traversal\n\n\t// first go left\n\tif (node->left != 0)\n\t\tcgc_walk_tree(node->left);\n\n\t// now process this node\n\t// since this can now be a linked list of data, set a pointer to the head\n\ttmp_ptr=node->data;\n\n\t// walk the linked list\n\twhile (tmp_ptr!= 0) {\n\t\tcgc_printf(\"@s\\n\", tmp_ptr->name);\n\t\ttmp_ptr=tmp_ptr->next;\n\t}\n\n\t// now walk the right side of the node\n\tif (node->right !=0)\n\t\tcgc_walk_tree(node->right);\n\n\treturn(0);\n\n} // walk_tree()\n\n\n// this is used to make a key for the BST based on the input string\nunsigned long cgc_make_key_from_name(void *data_item) {\n\nunsigned long key_val;\nchar *tmp;\n\n\n\tkey_val = 0;\n\n\ttmp=((data_item_type *)data_item)->name;\n\n\tkey_val=cgc_str_token(tmp);\n\n\treturn(key_val);\n\n}\n\n// count the nodes in the tree, noting how many are in the left vs right of the tree\nint cgc_count_bst_stats(bst_node_type *head, bst_stats_type *stats) {\n\n\tunsigned int total_node_count;\n\tunsigned int left_node_count;\n\tunsigned int right_node_count;\n\tunsigned int percent_left;\n\tunsigned int percent_right;\n\n\tbst_stats_type left_stats, right_stats;\n\n\tif (head == 0 || stats == 0)\n\t\treturn -1;\n\n\tstats->node_count = 0;\n\tleft_stats.node_count = 0;\n\tright_stats.node_count = 0;\n\n\t// first count the left side of the tree\n\tif (head->left != 0) {\n\n\t\tcgc_count_nodes(head->left, & left_stats);\n\t}\n\n\tleft_node_count= left_stats.node_count;\n\n\n\t// then count the right side\n\tif (head->right != 0) {\n\n\t\tcgc_count_nodes(head->right, &right_stats);\n\t}\n\n\tright_node_count= right_stats.node_count;\n\n\ttotal_node_count = left_node_count + right_node_count;\n\n\t// include the head node in the total count if there's data\n\tif (head->data)\n\t\ttotal_node_count++;\n\n\tstats->node_count = total_node_count;\n\n\n\t// if there are less than 2 nodes, there can't be any in the left or right subtrees.\n\tif (total_node_count < 2) {\n\n\t\tstats->percent_left = 0;\n\t\tstats->percent_right = 0;\n\t}\n\telse { \n\t\t// but don't include it when calculating the balance of the tree so sub 1\n\t\tstats->percent_left = left_node_count * 100 / (total_node_count - 1);\n\t\tstats->percent_right = right_node_count * 100 / (total_node_count - 1);\n\t}\n\n\nreturn 0;\n\n}\n\n \n // recursive function to count the number of nodes in the tree\nint cgc_count_nodes(bst_node_type *node, bst_stats_type *stats) {\n\n\n\tif (node->left != 0) {\n\n\t\tcgc_count_nodes(node->left, stats);\n\t}\n\n\tstats->node_count++;\n\n\n\tif (node->right != 0) {\n\n\t\tcgc_count_nodes(node->right, stats);\n\t}\n\n\treturn 0;\n\n}\n\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/src/delete_matches.c",
    "content": "/*\n\nAuthor: Steve Wood <swood@cromulence.co>\n\nCopyright (c) 2014 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n\n#include \"cgc_bst.h\"\n#include \"cgc_stdlib.h\"\n\n\nvoid cgc_delete_matches(bst_node_type **head, int arg_count, char **args)  {\n    \n\n\n    cgc_delete_node(head, args[1], cgc_make_key_from_name(args[1]));\n \n}"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/src/find_matches.c",
    "content": "/*\n\nAuthor: Steve Wood <swood@cromulence.co>\n\nCopyright (c) 2014 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n#include \"cgc_bst.h\"\n#include \"cgc_stdlib.h\"\n\n\nvoid cgc_find_matches(bst_node_type *head, int arg_count, char **args)  {\n    \n    data_item_type *item;\n\n\n   \titem=0;\n\n\n    //use the built-in functionality of a BST and find by the key value\n\n    item=cgc_find_node_by_key(head, cgc_make_key_from_name(args[1]));\n\n    if (item) {\n\n        while (item!= 0) {\n\n            if (cgc_strcmp(args[1], item->name)==0 ) {\n                cgc_printf(\"@s\\n\", item->name);\n                break;\n            }\n            else\n                item=item->next;\n\n        }\n        \n    }\n}\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/src/parse.c",
    "content": "/*\n\nAuthor: Steve Wood <swood@cromulence.co>\n\nCopyright (c) 2014 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n\n#include \"cgc_stdlib.h\"\n\n\nint cgc_parse_command(char *buffer, char separator, char ***args) {\n\t\n\tint arg_count;\n\tchar *tmp;\n\tint i;\n\n\t\n\tif (*buffer != 0) {\n\n\t\t// there is at least 1 because this function was called with a string\n\t\targ_count = 1;\n\t\ttmp=buffer;\n\t}\n\telse\n\t\treturn -1;\n\n\t// count how many fields are on the command so memory can be allocated for the pointers\n\twhile(*tmp++ != 0) {\n\n\t\tif (*tmp==separator)\n\t\t\t++arg_count;\n\t} // while\n\n\t// allocate one char pointer for each field in the command\n\t*args=cgc_calloc(arg_count, sizeof(char *));\n\n\t// failed to allocate the memory\n\tif (*args==0) {\n\t\treturn -1;\n\t}\n\n\t// start back from the beginning of the buffer\n\ttmp=buffer;\n\n\t// for each field, store a pointer to the first char\n\tfor (i=0;i< arg_count; ++i) {\n\n\t\t(*args)[i]=tmp;\n\n\t\twhile (*tmp!= separator && *tmp != 0)\n\t\t\t++tmp;\n\n\t\t// if we found the separator, overwrite it with a null so our args will be properly terminated\n\t\tif (*tmp !=0) {\n\n\t\t\t*tmp=0;\n\t\t\t++tmp;\n\t\t}\n\n\n\t} //for \n\n\treturn (arg_count);\n\n}"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/src/service.c",
    "content": "/*\n\nAuthor: Steve Wood <swood@cromulence.co>\n\nCopyright (c) 2014 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n\n#include \"libcgc.h\"\n#include \"cgc_stdlib.h\"\n#include \"cgc_service.h\"\n#include \"cgc_bst.h\"\n\n\nint main(int cgc_argc, char *cgc_argv[]) {\n    \n    bst_node_type *head;\n    data_item_type *item;\n    bst_stats_type stats;\n    long value;\n    char buffer[2048];  \n    cgc_size_t size;\n    char **args;\n    int arg_count;\n    int i;\n\n\n\n    // loop forever receiving command strings from STDIN.\n    while (1) {\n\n        size=cgc_getline(buffer, sizeof(buffer));\n\n        // ignore that a blank line was entered\n        if (size==0)\n            continue;\n\n        // break the command into an array \n        arg_count=cgc_parse_command(buffer, '/', &args);\n\n        if (arg_count == -1)\n            continue;\n        \n        // add a new element to the database\n        if (args[0][0]=='a' && arg_count==2 ) {\n\n            // if the string to add is less than 10 chars, ignore the add command\n            if (cgc_strlen(args[1]) < 10) {\n\n                cgc_free(args);\n                continue;\n            }\n\n            item=cgc_calloc(1, sizeof(data_item_type));\n\n            if (!item) {\n\n                cgc_printf(\"Unable to allocate memory\\n\");\n                return(-1);\n            }\n\n            cgc_strncpy(item->name, args[1], sizeof(item->name)-1);\n            item->next = 0;\n\n            cgc_insert_node(&head, item, cgc_make_key_from_name);\n\n        }\n        // search for elements of the database\n        else if (args[0][0]=='f' && arg_count==2) {\n\n            cgc_find_matches(head, arg_count, args);\n\n        }\n        // delete an element from the database\n        else if (args[0][0]=='d' && arg_count==2) {\n\n            cgc_delete_matches(&head, arg_count, args);\n\n        }\n        // time to cgc_exit\n        else if (args[0][0]=='x') {\n\n            return(0);\n        }\n        // walk the database and show all entries\n        else if (args[0][0]=='w' ) {\n\n            cgc_walk_tree(head);\n        }\n        else if (args[0][0]=='s' ) {\n\n            // clear the stats\n            cgc_bzero(&stats, sizeof(stats));\n\n            cgc_count_bst_stats(head, &stats);\n\n            cgc_printf(\"# of Nodes: @d\\n\", stats.node_count);\n            cgc_printf(\"\\% left nodes: @d\\n\", stats.percent_left);\n            cgc_printf(\"\\% right nodes: @d\\n\", stats.percent_right);\n\n        }\n        \n        cgc_free(args);\n    }\n\n \n}  // main  \n\n"
  },
  {
    "path": "corpus/cgc/String_Storage_and_Retrieval/src/string_token.c",
    "content": "/*\n\nAuthor: Steve Wood <swood@cromulence.co>\n\nCopyright (c) 2014 Cromulence LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n\n#include \"cgc_stdlib.h\"\n\nunsigned long cgc_str_token( char *str) {\n\t\n\tunsigned long tmp_token;\n\tint i;\n\n\tif (str==0)\n\t\treturn 0;\n\n\t// seed the token algorithm\n\ttmp_token = 5381;\n\n\twhile (*str) { \n\n\t\ttmp_token = ((tmp_token << 5)+ tmp_token) + *str;\n\n\t\t++str;\n\n\t}\n\n\treturn tmp_token;\n}"
  },
  {
    "path": "corpus/cgc/UTF-late/README.md",
    "content": "# CGC Challenge Binary Template\n\n## Author Information\n\n\"Maxwell Koo\" <info@narfindustries.com>\n\n### DARPA performer group\n\nNarf Industries (NRFIN)\n\n## Description\n\nI'm so UTF-8, you so UTF-late. This is a network-enabled file server, which\nkeeps all user files in memory for blazing-quick access. The API exposes a\npublic dropbox folder, while preventing access to the protected admin area. The\nfilesystem is UTF-8 aware, allowing arbitrary unicode filenames of a fixed\nlength.\n\nCommands take the form of a 4-byte command identifier, followed by optional\narguments. Commands may produce output, but will always end in a 4-byte success\ncode, 0 on success or -1 on failure.\n\n### Feature List\n\nThe following features are available:\n - Read file, accepts a filename and returns the contents of that file\n - Write file, accepts a filename and a size, writes the contents to a file\n - List files, lists all files in the dropbox folder\n\n## Vulnerability\n\nThe UTF-8 decoding function does not properly handle overlong encodings, so it\nis possible to defeat the input validation protecting the admin area and write\nto files in that area. Files in the admin area contain a user-controlled pointer\nvalue, which allows arbitrary write access to a large portion of the process'\naddress space.\n\n### Generic class of vulnerability\n\nImproper handling of unicode encoding\n\n### CWE classification\n\nCWE-20 Improper input validation\nCWE-22 Improper limitation of a pathname to a restricted directory\nCWE-176 Improper handling of unicode encoding\nCWE-822 Untrusted pointer dereference\n\n## Challenges\n\nThis CB is designed to test the ability for a CRS to comprehend complex string\nfunctions and stateful processes spanning multiple invocations of a function.\nUTF-8 is a complex variable-width encoding with many possible invalid byte\nsequences. The decoder implemented in this CB handles this by running each\ncharacter through a state machine, invoking a function on each byte which\nrecords its state into a output variable and its return code. Reasoning over\nseparate invocations of the decoder function is necessary in order to determine\nan input which will lead to triggering the vulnerability. This CB is inspired by\nseveral real-world path traversal and unicode vulnerabilities, including\nCVE-2000-0884 in Microsoft IIS.\n\n"
  },
  {
    "path": "corpus/cgc/UTF-late/lib/cgc_libc.h",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n/**\n * @file libc.h\n *\n * Reusable standard C functions.\n */\n\n#ifndef LIBC_H_\n#define LIBC_H_\n\n#include \"libcgc.h\"\n\n#define EXIT_SUCCESS 0\n#define EXIT_FAILURE -1\n\n#define PAGE_SIZE (1 << 12)\n\n/**\n * Return the lesser of a and b\n * \n * @param a The first value\n * @param b The second value\n * @return a if a < b else b\n */\n#define MIN(a, b) ((a) < (b) ? (a) : (b))\n\n/**\n * Return the greater of a and b\n *\n * @param a The first value\n * @param b The second value\n * @return a if a > b else b\n */\n#define MAX(a, b) ((a) > (b) ? (a) : (b))\n\n/**\n * Find the offset of a struct member\n *\n * @param type The struct type to examine\n * @param member The member to calculate the offset of\n * @return The offset of member in type\n */\n#define OFFSETOF(type, member) ((cgc_size_t)(&((type *)NULL)->member))\n\n/**\n * Find the container structure from a pointer to a member.\n *\n * @param type The struct type to examine\n * @param member The member ptr points to\n * @param ptr A pointer to a member\n * @return A pointer to the containing structure\n */\n#define CONTAINEROF(type, member, ptr) ({                               \\\n    char *__ptr = (char *)(ptr);                                        \\\n    __ptr ? ((type *)(__ptr - OFFSETOF(type, member))) : NULL;          \\\n})\n\n/**\n * Read exactly n bytes from fd to a buffer.\n *\n * @param fd A file descriptor\n * @param buf The destination buffer\n * @param n The number of bytes to cgc_read\n * @return The number of bytes cgc_read, or negative on failure\n */\ncgc_ssize_t cgc_read_all(int fd, void *buf, cgc_size_t n);\n\n/**\n * Write exactly n bytes to an fd from a buffer.\n *\n * @param fd A file descriptor\n * @param buf The source buffer\n * @param n The number of bytes to cgc_write\n * @return The number of bytes written, or negative on failure\n */\ncgc_ssize_t cgc_write_all(int fd, void *buf, cgc_size_t n);\n\n/**\n * Allocate a chunk of memory on the heap.\n *\n * @param size The size of the chunk to allocate\n * @return A pointer to the new chunk, or NULL if allocation failed\n */\nvoid *cgc_malloc(cgc_size_t size);\n\n/**\n * Free a chunk of memory allocated with malloc().\n *\n * @param ptr The chunk to free\n */\nvoid cgc_free(void *ptr);\n\n/**\n * Allocate a zeroed chunk of memory on the heap.\n *\n * Note: This differs from standard libc malloc by taking the full size of the\n *      chunk to allocate as its only parameter.\n *\n * @param size The size of the chunk to allocate\n * @return A pointer to the new chunk, or NULL if allocation failed\n */\nvoid *cgc_calloc(cgc_size_t size);\n\n/**\n * Resize a chunk of memory allocated with malloc().\n *\n * @param ptr The chunk to resize\n * @param size The new size of the chunk\n * @return A pointer to the new chunk, or NULL if allocation failed\n */\nvoid *cgc_realloc(void *ptr, cgc_size_t size);\n\n/**\n * Set the first n bytes of a block of memory to a value.\n *\n * @param ptr_ A pointer to a block of memory\n * @param val The value to set each byte to, interpretted as an unsigned char\n * @param n The number of bytes to set\n * @return ptr\n */\nvoid *cgc_memset(void *ptr_, int val, cgc_size_t n);\n\n/**\n * Copy n bytes from src to dst.\n *\n * @param dst_ The destination buffer\n * @param src_ The source buffer\n * @param n The number of bytes to copy\n * @return dst\n */\nvoid *cgc_memcpy(void *dst_, const void *src_, cgc_size_t n);\n\n/**\n * Copy at most the first n characters of a null-terminated string from src to\n * dst.\n *\n * @param dst The destination buffer\n * @param src The source buffer\n * @param n The maximum number of bytes to copy\n * @return dst\n */\nchar *cgc_strncpy(char *dst, const char *src, cgc_size_t n);\n\n/**\n * Return the length of a null-terminated string.\n * \n * @param s The string\n * @return The length of s\n */\ncgc_size_t cgc_strlen(const char *s);\n\n/**\n * Compare two null-terminated strings\n *\n * @param a The first string\n * @param b The second string\n * @return negative if a < b, 0 if a == b, positive if a > b\n */\nint cgc_strcmp(const char *a, const char *b);\n\n/**\n * Compare the first n bytes of two null-terminated strings\n *\n * @param a The first string\n * @param b The second string\n * @param n The number of bytes to compare\n * @return negative if a < b, 0 if a == b, positive if a > b\n */\nint cgc_strncmp(const char *a, const char *b, cgc_size_t n);\n\n/**\n * Find the first instance of character c in s.\n *\n * @param s The string to search\n * @param c The character to find\n * @return A pointer to the first instance of c in s or NULL if not found\n */\nchar *cgc_strchr(const char *s, char c);\n\n/**\n * Find the last instance of character c in s.\n *\n * @param s The string to search\n * @param c The character to find\n * @return A pointer to the last instance of c in s or NULL if not found\n */\nchar *cgc_strrchr(const char *s, char c);\n\n/**\n * Break up a string into tokens separated by a character.\n *\n * NOTE: This differs from standard strtok by only accepting on delimiter\n * character.\n *\n * @param s The string to tokenize or NULL to continue, may be modified\n * @param d The delimeter character\n * @return The next token\n */\nchar *cgc_strtok(char *s, char d);\n\n/* The following is verbatim from EAGLE_00004, but isn't included in the \n * released binary (DEBUG is not defined), so this reuse shouldn't be a concern.\n */\n#ifdef DEBUG\n\n#define _FILE_STATE_OPEN  1\n#define _FILE_STATE_ERROR 2\n#define _FILE_STATE_EOF   4\n#define _FILE_HAVE_LAST   8\n\ntypedef struct _FILE {\n   int fd;\n   int state;\n   int last;\n} FILE;\n\nextern FILE *cgc_stdin;\nextern FILE *cgc_stdout;\nextern FILE *cgc_stderr;\n\n/**\n * Formatted output to a stream.\n *\n * @param stream The stream to cgc_write to\n * @param format The format specifier\n * @return number of bytes written\n */\nint fprintf(FILE * stream, const char *format, ...);\n\n/**\n * Formatted output to cgc_stdout.\n *\n * @param stream The stream to cgc_write to\n * @param format The format specifier\n * @return number of bytes written\n */\nint cgc_printf(const char *format, ...);\n\n#endif /* DEBUG */\n\n#endif /* LIBC_H_ */\n\n"
  },
  {
    "path": "corpus/cgc/UTF-late/lib/cgc_list.h",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n/**\n* @file list.h\n*\n* Routines for manipulating intrusive doubly-linked lists, based on Linux kernel list.h\n*   interface\n*/\n\n#ifndef LIST_H_\n#define LIST_H_\n\n#include \"cgc_libc.h\"\n\nstruct list_node {\n    struct list_node *next, *prev;\n};\n\nstruct list {\n    struct list_node *head, *tail;\n};\n\n/**\n * Initialize a list\n *\n * @param list A pointer to the list\n */\n#define list_init(list) do { (list)->head = (list)->tail = NULL; } while (0)\n\n/**\n * Get the entry associated with a particular node.\n *\n * @param type The type of the list entry\n * @param member The member of the entry containing the list node\n * @param node The list node\n * @return The entry associated with the node\n */\n#define list_entry(type, member, node) CONTAINEROF(type, member, node)\n\n/**\n * Traverse a list in the forward direction.\n *\n * @param list A pointer to the list\n * @param cur The variable to use as an iterator\n */\n#define list_for_each(list, cur)                                        \\\n    for (cur = (list)->head; cur != NULL; cur = (cur)->next)\n\n/**\n * Traverse a list in the backwards direction.\n *\n * @param list A pointer to the list\n * @param cur The variable to use as an iterator\n */\n#define list_for_each_reverse(list, cur)                                \\\n    for (cur = (list)->tail; cur != NULL; cur = (cur)->prev)\n\n/**\n * Traverse a list's entries in the forward direction.\n *\n * @param type The type of each list entry\n * @param member The member of each entry containing the list's nodes\n * @param list A pointer to the list\n * @param cur The variable to use as an iterator\n */\n#define list_for_each_entry(type, member, list, cur)                    \\\n    for (cur = list_entry(type, member, (list)->head);                  \\\n         cur != NULL;                                                   \\\n         cur = list_entry(type, member, (cur)->member.next))\n\n/**\n * Traverse a list's entries in the backwards direction.\n *\n * @param type The type of each list entry\n * @param member The member of each entry containing the list's nodes\n * @param list A pointer to the list\n * @param cur The variable to use as an iterator\n */\n#define list_for_each_entry_reverse(type, member, list, cur)            \\\n    for (cur = list_entry(type, member, (list)->tail);                  \\\n         cur != NULL;                                                   \\\n         cur = list_entry(type, member, (cur)->member.prev))\n\n/**\n * Safely traverse a list in the forward direction using a temporary.\n *\n * @param list A pointer to the list\n * @param n Temporary variable\n * @param cur The variable to use as an iterator\n */\n#define list_for_each_safe(list, n, cur)                                \\\n    for (cur = (list)->head, n = cur ? cur->next : NULL;                \\\n         cur != NULL;                                                   \\\n         cur = n, n = cur ? (cur)->next : NULL)\n\n/**\n * Safely traverse a list in the backwards direction using a temporary.\n *\n * @param list A pointer to the list\n * @param n Temporary variable\n * @param cur The variable to use as an iterator\n */\n#define list_for_each_safe_reverse(list, n, cur)                        \\\n    for (cur = (list)->tail, n = cur ? cur->prev : NULL;                \\\n         cur != NULL;                                                   \\\n         cur = n, n = cur ? (cur)->prev : NULL)\n\n/**\n * Safely traverse a list's entries in the forward direction using a temporary.\n *\n * @param type The type of each list entry\n * @param member The member of each entry containing the list's nodes\n * @param list A pointer to the list\n * @param n Temporary variable\n * @param cur The variable to use as an iterator\n */\n#define list_for_each_entry_safe(type, member, list, n, cur)            \\\n    for (cur = list_entry(type, member, (list)->head),                  \\\n         n = cur ? list_entry(type, member, (cur)->member.next) : NULL; \\\n         cur != NULL;                                                   \\\n         cur = n,                                                       \\\n         n = cur ? list_entry(type, member, (cur)->member.next) : NULL)\n\n/**\n * Safely traverse a list's entries in the backwards direction using a\n * temporary.\n *\n * @param type the type of each list entry\n * @param member the member of each entry containing the list's nodes\n * @param list a pointer to the list\n * @param n Temporary variable\n * @param cur The variable to use as an iterator\n */\n#define list_for_each_entry_safe_reverse(type, member, list, n, cur)    \\\n    for (cur = list_entry(type, member, (list)->tail),                  \\\n         n = cur ? list_entry(type, member, (cur)->member.prev) : NULL; \\\n         cur != NULL;                                                   \\\n         cur = n,                                                       \\\n         n = cur ? list_entry(type, member, (cur)->member.prev) : NULL)\n\n/**\n * Get the length of a list.\n *\n * @param list The list\n * @return The length of the list\n */\nstatic inline unsigned int\nlist_length(struct list *list)\n{\n    unsigned int ret = 0;\n    struct list_node *cur;\n\n    list_for_each(list, cur)\n        ret++;\n\n    return ret;\n}\n\n/**\n * Insert a new node before a specific node.\n *\n * @param list The list\n * @param succ The node to insert before\n * @param toadd The node to add\n */\nstatic inline void\ncgc_list_insert_before(struct list *list, struct list_node *succ,\n        struct list_node *toadd)\n{\n    if (toadd == NULL)\n        return;\n\n    toadd->next = toadd->prev = NULL;\n    if (list->head == NULL && list->tail == NULL) {\n        // Singleton list\n        list->head = list->tail = toadd;\n    } else if (succ == NULL) {\n        // Insert at tail\n        toadd->prev = list->tail;\n        list->tail->next = toadd;\n        toadd->next = NULL;\n        list->tail = toadd;\n    } else if (succ == list->head) {\n        // Insert at head\n        toadd->next = list->head;\n        list->head->prev = toadd;\n        toadd->prev = NULL;\n        list->head = toadd;\n    } else {\n        // General case\n        toadd->prev = succ->prev;\n        toadd->next = succ;\n        succ->prev->next = toadd;\n        succ->prev = toadd;\n    }\n}\n\n/**\n * Insert a new entry before a specific entry.\n *\n * @param type The type of the list entry\n * @param member The member of each entry containing the list's nodes\n * @param list A pointer to the list\n * @param succ The entry to insert before\n * @param toadd The entry to add\n */\n#define list_insert_entry_before(type, member, list, succ, toadd)       \\\n    list_insert_before(list, succ ? &((type *)(succ))->member : NULL,   \\\n            &(toadd)->member)\n\n/**\n * Insert a new node after a specific node.\n *\n * @param list The list\n * @param pred The node to insert after\n * @param toadd The node to add\n */\nstatic inline void\ncgc_list_insert_after(struct list *list, struct list_node *pred,\n        struct list_node *toadd)\n{\n    if (pred == NULL)\n        cgc_list_insert_before(list, list->head, toadd);\n    else\n        cgc_list_insert_before(list, pred->next, toadd);\n}\n\n/**\n * Insert a new entry after a specific entry.\n *\n * @param type The type of the list entry\n * @param member The member of each entry containing the list's nodes\n * @param list The list\n * @param pred The entry to insert after\n * @param toadd The entry to add\n */\n#define list_insert_entry_after(type, member, list, pred, toadd)        \\\n    list_insert_after(list, pred ? &((type *)(pred))->member : NULL,    \\\n            &(toadd)->member)\n\n/**\n * Insert a new node at the head of a list.\n *\n * @param list The list\n * @param toadd The node to add\n */\nstatic inline void\ncgc_list_push_front(struct list *list, struct list_node *toadd)\n{\n    cgc_list_insert_before(list, list->head, toadd);\n}\n\n/**\n * Insert a new entry at the head of a list.\n *\n * @param type The type of the list entry\n * @param member The member of each entry containing the list's nodes\n * @param list A pointer to the list\n * @param toadd The entry to add\n */\n#define list_push_entry_front(type, member, list, toadd)                \\\n    cgc_list_push_front(list, &(toadd)->member)\n\n/**\n * Insert a new node at the tail of a list.\n *\n * @param list The list\n * @param toadd The node to add\n */\nstatic inline void\ncgc_list_push_back(struct list *list, struct list_node *toadd)\n{\n    cgc_list_insert_after(list, list->tail, toadd);\n}\n\n/**\n * Insert a new entry at the tail of a list.\n *\n * @param type The type of the list entry\n * @param member The member of each entry containing the list's nodes\n * @param list A pointer to the list\n * @param toadd The entry to add\n */\n#define list_push_entry_back(type, member, list, toadd)                 \\\n    list_push_back(list, &(toadd)->member)\n\n/**\n * Insert a new node in order as specified by a comparison function.\n *\n * @param list The list\n * @param toadd The node to add\n * @param cmp The comparison function\n */\nstatic inline void\ncgc_list_insert_in_order(struct list *list, struct list_node *toadd,\n        int (*cmp)(const struct list_node *, const struct list_node *))\n{\n    struct list_node *cur;\n    list_for_each(list, cur)\n        if (cmp(toadd, cur) >= 0) {\n            cgc_list_insert_before(list, cur, toadd);\n            return;\n        }\n\n    cgc_list_push_back(list, toadd);\n}\n\n/**\n * Insert a new entry in order as specified by a comparison function.\n *\n * Note: the comparision function still operates on struct list_nodes.\n *\n * @param type The type of each list entry\n * @param member The member of each entry containing the list's nodes\n * @param list A pointer to the list\n * @param toadd The entry to add\n * @param cmp The comparison function\n */\n#define list_insert_entry_in_order(type, member, list, toadd, cmp)      \\\n    cgc_list_insert_in_order(list, &(toadd)->member, cmp)\n\n/**\n * Find a node in the list based on a predicate function.\n *\n * @param list The list\n * @param pred The predicate function\n * @param data Data to pass to the predicate function\n * @return The first list_node that matches from the head of the list, or NULL\n *      if not found\n */\nstatic inline struct list_node *\ncgc_list_find(const struct list *list, int (*pred)(const struct list_node *, void *),\n        void *data)\n{\n    struct list_node *cur;\n    list_for_each(list, cur)\n        if (pred(cur, data))\n            return cur;\n\n    return NULL;\n}\n\n/**\n * Find an entry in the list based on a predicate function.\n *\n * Note: the predicate function still operates on struct list_nodes.\n *\n * @param type The type of each list entry\n * @param member The member of each entry containing the list's nodes\n * @param list A pointer to the list\n * @param pred The predicate function\n * @param data Data to pass to the predicate function\n * @return The first entry that matches from the head of the list, or NULL if\n *      not found\n */\n#define list_find_entry(type, member, list, pred, data)                 \\\n    list_entry(type, member, cgc_list_find(list, pred, data))\n\n/**\n * Remove a node from a list.\n *\n * @param list The list\n * @param torem The node to remove\n */\nstatic inline void\ncgc_list_remove(struct list *list, struct list_node *torem)\n{\n    if (torem == NULL)\n        return;\n\n    if (torem->prev == NULL)\n        list->head = torem->next;\n    else\n        torem->prev->next = torem->next;\n\n    if (torem->next == NULL)\n        list->tail = torem->prev;\n    else\n        torem->next->prev = torem->prev;\n}\n\n/**\n * Remove an entry from a list.\n *\n * @param type The type of each list entry\n * @param member The member of each entry containing the list's nodes\n * @param list A pointer to the list\n * @param torem The entry to remove\n */\n#define list_remove_entry(type, member, list, torem) ({                 \\\n    type *__torem = (torem);                                            \\\n    cgc_list_remove(list, __torem ? &__torem->member : NULL);               \\\n})\n\n/**\n * Remove and return the node at the head of the list.\n *\n * @param list The list\n * @return The node at the head of the list\n */\nstatic inline struct list_node *\nlist_pop_front(struct list *list)\n{\n    struct list_node *ret = list->head;\n    cgc_list_remove(list, ret);\n    return ret;\n}\n\n/**\n * Remove and return the entry at the head of the list.\n *\n * @param type The type of each list entry\n * @param member The member of each entry containing the list's nodes\n * @param list A pointer to the list\n * @return The entry at the head of the list\n */\n#define list_pop_entry_front(type, member, list)                        \\\n    list_entry(type, member, list_pop_front(list))\n\n/**\n * Remove and return the node at the tail of the list.\n *\n * @param list The list\n * @return The node at the tail of the list\n */\nstatic inline struct list_node *\nlist_pop_back(struct list *list)\n{\n    struct list_node *ret = list->tail;\n    cgc_list_remove(list, ret);\n    return ret;\n}\n\n/**\n * Remove and return the entry at the tail of the list.\n *\n * @param type The type of each list entry\n * @param member The member of each entry containing the list's nodes\n * @param list A pointer to the list\n * @return The entry at the tail of the list\n */\n#define list_pop_entry_back(type, member, list)                         \\\n    list_entry(type, member, list_pop_back(list))\n\n#endif /* LIST_H_ */\n"
  },
  {
    "path": "corpus/cgc/UTF-late/lib/cgc_utf8.h",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n/**\n * @file utf8.h\n *\n * Encode and decode UTF-8 encoded strings.\n */\n\n#ifndef UTF8_H_\n#define UTF8_H_\n\n#include \"libcgc.h\"\n\nenum utf8_decode_state {\n    ACCEPT,\n    REJECT,\n    TWO_BYTE,\n    THREE_BYTE,\n    FOUR_BYTE\n};\n\ntypedef unsigned char utf8char;\ntypedef unsigned int ucscodepoint;\n\nenum utf8_decode_state cgc_utf8_decode(enum utf8_decode_state state, utf8char c, ucscodepoint *out);\ncgc_ssize_t cgc_utf8_encode(ucscodepoint in, utf8char *out, cgc_size_t size);\n\ncgc_size_t cgc_utf8_canonicalize(utf8char *dst, const utf8char *src, cgc_size_t n);\n\n#endif /* UTF8_H_ */\n\n"
  },
  {
    "path": "corpus/cgc/UTF-late/lib/cgc_vfs.h",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n/**\n * @file vfs.h\n *\n * In-memory virtual file system.\n */\n\n#ifndef VFS_H_\n#define VFS_H_\n\n#include \"cgc_libc.h\"\n#include \"cgc_list.h\"\n#include \"cgc_utf8.h\"\n\n#define MAX_FILE_NAME_LENGTH 16\n\nstruct directory {\n    utf8char name[MAX_FILE_NAME_LENGTH];\n    struct directory *parent;\n    struct list subdirectories;\n    struct list files;\n    struct list_node list;\n};\n\nstruct file {\n    utf8char name[MAX_FILE_NAME_LENGTH];\n    struct directory *parent;\n    cgc_size_t size;\n    unsigned char *contents;\n    struct list_node list;\n};\n\nstruct vfs {\n    struct directory *root;\n};\n\nint cgc_vfs_init(struct vfs *vfs);\nvoid cgc_vfs_destroy(struct vfs *vfs);\n\nstruct directory *cgc_lookup_dir(const struct vfs *vfs, const utf8char *path);\nstruct file *cgc_lookup_file(const struct vfs *vfs, const utf8char *path);\n\nstruct directory *cgc_create_dir(struct vfs *vfs, const utf8char *path);\nstruct directory *cgc_create_dir_in_dir(struct vfs *vfs, struct directory *dir, const utf8char *name);\nstruct file *cgc_create_file(struct vfs *vfs, const utf8char *path);\nstruct file *cgc_create_file_in_dir(struct vfs *vfs, struct directory *dir, const utf8char *name);\n\nvoid cgc_delete_file(struct vfs *vfs, struct file *file);\n\n#ifdef DEBUG\nvoid dump_vfs(const struct vfs *vfs);\n#endif\n\n#endif /* VFS_H_ */\n\n"
  },
  {
    "path": "corpus/cgc/UTF-late/lib/libc.c",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"libcgc.h\"\n#include \"cgc_libc.h\"\n\ncgc_ssize_t\ncgc_read_all(int fd, void *buf, cgc_size_t n)\n{\n    cgc_ssize_t ret = 0;\n    cgc_size_t cgc_read;\n\n    while (n) {\n        if (cgc_receive(fd, (char *)(buf + ret), n, &cgc_read) != 0)\n            return -1;\n\n        n -= cgc_read;\n        ret += cgc_read;\n    }\n\n    return ret;\n}\n\ncgc_ssize_t\ncgc_write_all(int fd, void *buf, cgc_size_t n)\n{\n    cgc_ssize_t ret = 0;\n    cgc_size_t written;\n\n    while (n) {\n        if (cgc_transmit(fd, (char *)(buf + ret), n, &written) != 0)\n            return -1;\n\n        n -= written;\n        ret += written;\n    }\n\n    return ret;\n}\n\nvoid *\ncgc_memset(void *ptr_, int val, cgc_size_t n)\n{\n    unsigned char *ptr = ptr_;\n    while (n--)\n        *ptr++ = (unsigned char)val;\n    return ptr_;\n}\n\nvoid *\ncgc_memcpy(void *dst_, const void *src_, cgc_size_t n)\n{\n    unsigned char *dst = dst_;\n    const unsigned char *src = src_;\n    while (n--)\n        *dst++ = *src++;\n    return dst_;\n}\n\ncgc_size_t\ncgc_strlen(const char *s) {\n    cgc_size_t ret = 0;\n    while (*s++)\n        ret++;\n    return ret;\n}\n\nint\ncgc_strcmp(const char *a, const char *b)\n{\n    for (; *a && *a == *b; a++, b++)\n        ;\n    return *(const unsigned char *)a - *(const unsigned char *)b;\n}\n\nint\ncgc_strncmp(const char *a, const char *b, cgc_size_t n)\n{\n    for (; --n && *a && *a == *b; a++, b++)\n        ;\n    return *(const unsigned char *)a - *(const unsigned char *)b;\n}\n\nchar *\ncgc_strncpy(char *dst, const char *src, cgc_size_t n)\n{\n    cgc_size_t i = 0;\n    for (; i < n && src[i]; i++)\n        dst[i] = src[i];\n    for (; i < n; i++)\n        dst[i] = '\\0';\n\n    return dst;\n}\n\nchar *\ncgc_strchr(const char *s, char c)\n{\n    for (; *s; s++)\n        if (*s == c)\n            return (char *)s;\n    return NULL;\n}\n\nchar *\ncgc_strrchr(const char *s, char c)\n{\n    const char *orig_s = s;\n    for (; *s; s++)\n        ;\n    for (; s >= orig_s; s--)\n        if (*s == c)\n            return (char *)s;\n    return NULL;\n}\n\nchar *\ncgc_strtok(char *s, char d)\n{\n    static char *prev = NULL;\n    char *token, *ret;\n\n    if (s == NULL && prev == NULL)\n        return NULL;\n\n    if (prev == NULL)\n        prev = s;\n\n    ret = prev;\n    while (*ret == d)\n        ret++;\n\n    if ((token = cgc_strchr(prev, d)) != NULL) {\n        *token = '\\0';\n        prev = token + 1;\n    } else {\n        prev = NULL;\n    }\n\n    return ret;\n}\n\n/* The following is verbatim from EAGLE_00004, but isn't included in the\n * released binary (DEBUG is not defined), so this reuse shouldn't be a concern.\n */\n#ifdef DEBUG\n\n#ifdef WIN\n#include <stdarg.h>\n#else\ntypedef __builtin_va_list va_list;\n#define va_start(ap, param) __builtin_va_start(ap, param)\n#define va_end(ap) __builtin_va_end(ap)\n#define va_arg(ap, type) __builtin_va_arg(ap, type)\n#endif\n\nstatic FILE std_files[3] = { {0, _FILE_STATE_OPEN}, {1, _FILE_STATE_OPEN}, {2, _FILE_STATE_OPEN} };\n\nFILE *cgc_stdin = &std_files[0];\nFILE *cgc_stdout = &std_files[1];\nFILE *cgc_stderr = &std_files[2];\n\nint vfprintf(FILE *stream, const char *format, va_list ap);\nint vdprintf(int fd, const char *format, va_list ap);\n\n#define IS_DIGIT     1\n#define IS_UPPER     2\n#define IS_LOWER     4\n#define IS_SPACE     8\n#define IS_XDIGIT    16\n#define IS_CTRL      32\n#define IS_BLANK     64\n\n#define IS_ALPHA     (IS_LOWER | IS_UPPER)\n#define IS_ALNUM     (IS_ALPHA | IS_DIGIT)\n\nstatic unsigned char type_flags[256] = {\n     0, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL,\n     IS_CTRL, IS_SPACE | IS_BLANK, IS_SPACE, IS_SPACE, IS_SPACE, IS_SPACE, IS_CTRL, IS_CTRL,\n\n     IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL,\n     IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL,\n\n     IS_SPACE | IS_BLANK, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\n     IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT,\n     IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT, 0, 0, 0, 0, 0, 0,\n\n     0, IS_UPPER | IS_XDIGIT, IS_UPPER | IS_XDIGIT, IS_UPPER | IS_XDIGIT, IS_UPPER | IS_XDIGIT, IS_UPPER | IS_XDIGIT, IS_UPPER | IS_XDIGIT, IS_UPPER,\n     IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER,\n\n     IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER,\n     IS_UPPER, IS_UPPER, IS_UPPER, 0, 0, 0, 0, 0,\n\n     0, IS_LOWER | IS_XDIGIT, IS_LOWER | IS_XDIGIT, IS_LOWER | IS_XDIGIT, IS_LOWER | IS_XDIGIT, IS_LOWER | IS_XDIGIT, IS_LOWER | IS_XDIGIT, IS_LOWER,\n     IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER,\n\n     IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER,\n     IS_LOWER, IS_LOWER, IS_LOWER, 0, 0, 0, 0, 0,\n};\n\nint isalpha(int c) {\n   return (type_flags[c & 0xff] & IS_ALPHA) != 0;\n}\n\nint isdigit(int c) {\n   return (type_flags[c & 0xff] & IS_DIGIT) != 0;\n}\n\nint isxdigit(int c) {\n   return (type_flags[c & 0xff] & IS_XDIGIT) != 0;\n}\n\nint toupper(int c) {\n   if (isalpha(c)) {\n      return c & ~0x20;\n   }\n   return c;\n}\n\nint vfprintf(FILE * stream, const char *format, va_list ap) {\n   return vdprintf(stream->fd, format, ap);\n}\n\nint fprintf(FILE * stream, const char *format, ...) {\n   va_list va;\n   va_start(va, format);\n   return vfprintf(stream, format, va);\n}\n\nint cgc_printf(const char *format, ...) {\n   va_list va;\n   va_start(va, format);\n   return vfprintf(cgc_stdout, format, va);\n}\n\nstruct _fd_printer {\n   int fd;\n   int err;\n   unsigned int count;\n};\n\n//if flag != 0 return number of chars output so far\nstatic unsigned int fd_printer(char ch, void *_fp, int flag) {\n   struct _fd_printer *fp = (struct _fd_printer *)_fp;\n   if (flag) {\n      return fp->count;\n   }\n   else {\n      fp->count++;\n      cgc_transmit(fp->fd, &ch, 1, NULL);\n   }\n   return 0;\n}\n\n#define STATE_NORMAL 0\n#define STATE_ESCAPE 1\n#define STATE_PERCENT 2\n#define STATE_OCTAL 3\n#define STATE_HEX 4\n#define STATE_FLAGS 5\n#define STATE_WIDTH 6\n#define STATE_PRECISION 7\n#define STATE_LENGTH 8\n#define STATE_CONVERSION 9\n#define STATE_WIDTH_ARG 10\n#define STATE_WIDTH_VAL 11\n#define STATE_PRECISION_ARG 12\n#define STATE_PRECISION_VAL 13\n#define STATE_NARG 15\n\n#define FLAGS_TICK 1\n#define FLAGS_LEFT 2\n#define FLAGS_SIGN 4\n#define FLAGS_SPACE 8\n#define FLAGS_HASH 16\n#define FLAGS_ZERO 32\n\n#define LENGTH_H 1\n#define LENGTH_HH 2\n#define LENGTH_L 3\n#define LENGTH_J 5\n#define LENGTH_Z 6\n#define LENGTH_T 7\n#define LENGTH_CAPL 8\n\nstatic char *r_utoa(unsigned int val, char *outbuf) {\n   char *p = outbuf;\n   *p = '0';\n   while (val) {\n      *p++ = (val % 10) + '0';\n      val /= 10;\n   }\n   return p != outbuf ? (p - 1) : p;\n}\n\n//outbuf needs to be at least 22 chars\nstatic char *r_llotoa(unsigned long long val, char *outbuf) {\n   char *p = outbuf;\n   *p = '0';\n   while (val) {\n      *p++ = (val & 7) + '0';\n      val >>= 3;\n   }\n   return p != outbuf ? (p - 1) : p;\n}\n\nstatic char *r_otoa(unsigned int val, char *outbuf) {\n   return r_llotoa(val, outbuf);\n}\n\n//outbuf needs to be at least 22 chars\nstatic char *r_llxtoa(unsigned long long val, char *outbuf, int caps) {\n   char *p = outbuf;\n   *p = '0';\n   while (val) {\n      char digit = (char)(val & 0xf);\n      if (digit < 10) {\n         digit += '0';\n      }\n      else {\n         digit = caps ? (digit + 'A' - 10) : (digit + 'a' - 10);\n      }\n      *p++ = digit;\n      val >>= 4;\n   }\n   return p != outbuf ? (p - 1) : p;\n}\n\nstatic char *r_xtoa(unsigned int val, char *outbuf, int caps) {\n   return r_llxtoa(val, outbuf, caps);\n}\n\nstatic int hex_value_of(char ch) {\n   if (isdigit(ch)) {\n      return ch - '0';\n   }\n   else if (isalpha(ch)) {\n      return toupper(ch) - 'A' + 10;\n   }\n   return -1;\n}\n\n//func is responsible for outputing the given character\n//user is a pointer to data required by func\nstatic void printf_core(unsigned int (*func)(char, void *, int), void *user, const char *format, va_list ap) {\n   int state = STATE_NORMAL;\n   int flags;\n   int digit_count = 0;\n   int value = 0;\n   char ch;\n   int arg_count = 0;\n   int width_value;\n   int prec_value;\n   int field_arg;\n   int length;\n   char **args = (char**)ap;\n   for (ch = *format++; ch; ch = *format++) {\n      switch (state) {\n         case STATE_NORMAL:\n            if (ch == '%') {\n               state = STATE_PERCENT;\n            }\n            else if (ch == '\\\\') {\n               state = STATE_ESCAPE;\n            }\n            else {\n               func(ch, user, 0);\n            }\n            break;\n         case STATE_ESCAPE:\n            switch (ch) {\n               case 'n':\n                  func('\\n', user, 0);\n                  break;\n               case 't':\n                  func('\\t', user, 0);\n                  break;\n               case 'r':\n                  func('\\r', user, 0);\n                  break;\n               case 'b':\n                  func('\\b', user, 0);\n                  break;\n               case 'f':\n                  func('\\f', user, 0);\n                  break;\n               case 'v':\n                  func('\\v', user, 0);\n                  break;\n               case '\\\\': case '\\'': case '\"':\n                  func(ch, user, 0);\n                  break;\n               case 'x':\n                  state = STATE_HEX;\n                  digit_count = 0;\n                  value = 0;\n                  break;\n               default:\n                  if (ch > '0' && ch < '8') {\n                     state = STATE_OCTAL;\n                     digit_count = 1;\n                     value = ch - '0';\n                  }\n                  else {\n                     func(*format, user, 0);\n                  }\n                  break;\n            }\n            if (state == STATE_ESCAPE) {\n               state = STATE_NORMAL;\n            }\n            break;\n         case STATE_PERCENT:\n            if (ch == '%') {\n               func(ch, user, 0);\n               state = STATE_NORMAL;\n            }\n            else {\n               state = STATE_NARG;\n               flags = 0;\n               format--;\n            }\n            break;\n         case STATE_OCTAL:\n            if (ch > '0' && ch < '8' && digit_count < 3) {\n               digit_count++;\n               value = value * 8 + (ch - '0');\n               if (digit_count == 3) {\n                  func(value, user, 0);\n                  state = STATE_NORMAL;\n               }\n            }\n            else {\n               func(value, user, 0);\n               state = STATE_NORMAL;\n               format--;\n            }\n            break;\n         case STATE_HEX:\n            if (isxdigit(ch) && digit_count < 2) {\n               digit_count++;\n               value = value * 16 + hex_value_of(ch);\n               if (digit_count == 2) {\n                  func(value, user, 0);\n                  state = STATE_NORMAL;\n               }\n            }\n            else {\n               func(value, user, 0);\n               state = STATE_NORMAL;\n               format--;\n            }\n            break;\n         case STATE_NARG:\n            width_value = -1;\n            prec_value = -1;\n            flags = 0;\n            length = 0;\n            field_arg = -1;\n            if (ch == '0') {\n               format--;\n               state = STATE_FLAGS;\n               break;\n            }\n            if (isdigit(ch)) {\n               //could be width or could be arg specifier or a 0 flag\n               //width and arg values don't start with 0\n               width_value = 0;\n               while (isdigit(ch)) {\n                  width_value = width_value * 10 + (ch - '0');\n                  ch = *format++;\n               }\n               if (ch == '$') {\n                  field_arg = width_value - 1;\n                  width_value = 0;\n                  state = STATE_FLAGS;\n               }\n               else {\n                  //this was a width\n                  format--;\n                  state = STATE_PRECISION;\n               }\n            }\n            else {\n               format--;\n               state = STATE_FLAGS;\n            }\n            break;\n         case STATE_FLAGS:\n            switch (ch) {\n               case '\\'':\n                  flags |= FLAGS_TICK;\n                  break;\n               case '-':\n                  flags |= FLAGS_LEFT;\n                  break;\n               case '+':\n                  flags |= FLAGS_SIGN;\n                  break;\n               case ' ':\n                  flags |= FLAGS_SPACE;\n                  break;\n               case '#':\n                  flags |= FLAGS_HASH;\n                  break;\n               case '0':\n                  flags |= FLAGS_ZERO;\n                  break;\n               default:\n                  format--;\n                  if ((flags & (FLAGS_ZERO | FLAGS_LEFT)) == (FLAGS_ZERO | FLAGS_LEFT)) {\n                     //if both '-' and '0' appear, '0' is ignored\n                     flags &= ~FLAGS_ZERO;\n                  }\n                  state = STATE_WIDTH;\n                  break;\n            }\n            break;\n         case STATE_WIDTH:\n            if (ch == '*') {\n               ch = *format++;\n               int width_arg = 0;\n               if (isdigit(ch)) {\n                  while (isdigit(ch)) {\n                     width_arg = width_arg * 10 + (ch - '0');\n                     ch = *format++;\n                  }\n                  width_arg--;\n                  if (ch != '$') {\n                     //error\n                  }\n               }\n               else {\n                  width_arg = arg_count++;\n                  format--;\n               }\n               width_value = (int)args[width_arg];\n            }\n            else if (isdigit(ch)) {\n               width_value = 0;\n               while (isdigit(ch)) {\n                  width_value = width_value * 10 + (ch - '0');\n                  ch = *format++;\n               }\n               format--;\n            }\n            else {\n               //no width specified\n               format--;\n            }\n            state = STATE_PRECISION;\n            break;\n         case STATE_PRECISION:\n            if (ch == '.') {\n               //have a precision\n               ch = *format++;\n               if (ch == '*') {\n                  ch = *format++;\n                  int prec_arg = 0;\n                  if (isdigit(ch)) {\n                     while (isdigit(ch)) {\n                        prec_arg = prec_arg * 10 + (ch - '0');\n                        ch = *format++;\n                     }\n                     prec_arg--;\n                     if (ch != '$') {\n                        //error\n                     }\n                  }\n                  else {\n                     prec_arg = arg_count++;\n                     format--;\n                  }\n                  prec_value = (int)args[prec_arg];\n               }\n               else if (isdigit(ch)) {\n                  prec_value = 0;\n                  while (isdigit(ch)) {\n                     prec_value = prec_value * 10 + (ch - '0');\n                     ch = *format++;\n                  }\n                  format--;\n               }\n               else {\n                  //no precision specified\n                  format--;\n               }\n            }\n            else {\n               //no precision specified\n               format--;\n            }\n            state = STATE_LENGTH;\n            break;\n         case STATE_LENGTH:\n            switch (ch) {\n               case 'h':\n                  length = LENGTH_H;\n                  if (*format == 'h') {\n                     length++;\n                     format++;\n                  }\n                  break;\n               case 'l':\n                  length = LENGTH_L;\n                  if (*format == 'l') {\n//                     length++;\n                     format++;\n                  }\n                  break;\n               case 'j':\n                  length = LENGTH_J;\n                  break;\n               case 'z':\n                  length = LENGTH_Z;\n                  break;\n               case 't':\n                  length = LENGTH_T;\n                  break;\n               case 'L':\n                  length = LENGTH_CAPL;\n                  break;\n               default:\n                  format--;\n                  break;\n            }\n            state = STATE_CONVERSION;\n            break;\n         case STATE_CONVERSION: {\n            char num_buf[32];\n            char *num_ptr;\n            int use_caps = 1;\n            int sign;\n            int val;\n            if (field_arg == -1) {\n               field_arg = arg_count++;\n            }\n            switch (ch) {\n               case 'd': case 'i': {\n                  int len;\n                  switch (length) {\n                     case LENGTH_H:\n                        val = (short)(int)args[field_arg];\n                        sign = val < 0;\n                        if (sign) {\n                           val = -val;\n                        }\n                        num_ptr = r_utoa(val, num_buf);\n                        break;\n                     case LENGTH_HH:\n                        val = (char)(int)args[field_arg];\n                        sign = val < 0;\n                        if (sign) {\n                           val = -val;\n                        }\n                        num_ptr = r_utoa(val, num_buf);\n                        break;\n                     case LENGTH_L:\n                     default:\n                        val = (long)args[field_arg];\n                        sign = val < 0;\n                        if (sign) {\n                           val = -val;\n                        }\n                        num_ptr = r_utoa(val, num_buf);\n                        break;\n                  }\n                  len = num_ptr - num_buf + 1;\n                  if (width_value == -1) {\n                     //by default min length is the entire value\n                     width_value = len;\n                     if (sign || (flags & FLAGS_SIGN)) {\n                        width_value++;\n                     }\n                  }\n                  if (prec_value == -1) {\n                     //by default max is entire value\n                     prec_value = len;\n                     if ((flags & FLAGS_ZERO) != 0 && prec_value < width_value) {\n                        //widen precision if necessary to pad to width with '0'\n                        if (sign || (flags & FLAGS_SIGN)) {\n                           prec_value = width_value - 1;\n                        }\n                        else {\n                           prec_value = width_value;\n                        }\n                     }\n                  }\n                  else {\n                     if (prec_value < len) {\n                        prec_value = len;\n                     }\n                     //number won't need leading zeros\n                     flags &= ~FLAGS_ZERO;\n                  }\n                  if (flags & FLAGS_LEFT) {\n                     if (sign) {\n                        func('-', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     else if ((flags & FLAGS_SIGN) != 0) {\n                        func('+', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (width_value != 0) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                  }\n                  else {\n                     while (width_value > (prec_value + 1)) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     if (sign) {\n                        func('-', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     else if ((flags & FLAGS_SIGN) != 0) {\n                        func('+', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     if (width_value > prec_value) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                     }\n                  }\n                  break;\n               }\n               case 'o': {\n                  int len;\n                  switch (length) {\n                     case LENGTH_H:\n                        num_ptr = r_otoa((unsigned short)(unsigned int)args[field_arg], num_buf);\n                        break;\n                     case LENGTH_HH:\n                        num_ptr = r_otoa((unsigned char)(unsigned int)args[field_arg], num_buf);\n                        break;\n                     case LENGTH_L:\n                     default:\n                        num_ptr = r_otoa((unsigned long)args[field_arg], num_buf);\n                        break;\n                  }\n                  if (flags & FLAGS_HASH) {\n                     if (*num_ptr != '0') {\n                        num_ptr++;\n                        *num_ptr = '0';\n                     }\n                  }\n                  len = num_ptr - num_buf + 1;\n                  if (width_value == -1) {\n                     //by default min length is the entire value\n                     width_value = len;\n                  }\n                  if (prec_value == -1) {\n                     //by default max is entire value\n                     prec_value = len;\n                     if ((flags & FLAGS_ZERO) != 0 && prec_value < width_value) {\n                        //widen precision if necessary to pad to width with '0'\n                        prec_value = width_value;\n                     }\n                  }\n                  else {\n                     if (prec_value < len) {\n                        prec_value = len;\n                     }\n                     flags &= ~FLAGS_ZERO;\n                  }\n                  if (flags & FLAGS_LEFT) {\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (width_value != 0) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                  }\n                  else {\n                     while (width_value > prec_value) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                     }\n                  }\n                  break;\n               }\n               case 'u': {\n                  int len;\n                  switch (length) {\n                     case LENGTH_H:\n                        num_ptr = r_utoa((unsigned short)(unsigned int)args[field_arg], num_buf);\n                        break;\n                     case LENGTH_HH:\n                        num_ptr = r_utoa((unsigned char)(unsigned int)args[field_arg], num_buf);\n                        break;\n                     case LENGTH_L:\n                     default:\n                        num_ptr = r_utoa((unsigned long)args[field_arg], num_buf);\n                        break;\n                  }\n                  len = num_ptr - num_buf + 1;\n                  if (width_value == -1) {\n                     //by default min length is the entire value\n                     width_value = len;\n                  }\n                  if (prec_value == -1) {\n                     //by default max is entire value\n                     prec_value = len;\n                     if ((flags & FLAGS_ZERO) != 0 && prec_value < width_value) {\n                        //widen precision if necessary to pad to width with '0'\n                        prec_value = width_value;\n                     }\n                  }\n                  else {\n                     if (prec_value < len) {\n                        prec_value = len;\n                     }\n                     flags &= ~FLAGS_ZERO;\n                  }\n                  if (flags & FLAGS_LEFT) {\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (width_value != 0) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                  }\n                  else {\n                     while (width_value > prec_value) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                     }\n                  }\n                  break;\n               }\n               case 'x':\n                  use_caps = 0;  //now fall into X case\n               case 'X': {\n                  int len;\n                  switch (length) {\n                     case LENGTH_H:\n                        num_ptr = r_xtoa((unsigned short)(unsigned int)args[field_arg], num_buf, use_caps);\n                        break;\n                     case LENGTH_HH:\n                        num_ptr = r_xtoa((unsigned char)(unsigned int)args[field_arg], num_buf, use_caps);\n                        break;\n                     case LENGTH_L:\n                     default:\n                        num_ptr = r_xtoa((unsigned long)args[field_arg], num_buf, use_caps);\n                        break;\n                  }\n                  len = num_ptr - num_buf + 1;\n                  if (width_value == -1) {\n                     //by default min length is the entire value\n                     width_value = len;\n                  }\n                  if (prec_value == -1) {\n                     //by default max is entire value\n                     prec_value = len;\n                     if ((flags & FLAGS_ZERO) != 0 && prec_value < width_value) {\n                        //widen precision if necessary to pad to width with '0'\n                        prec_value = width_value;\n                     }\n                  }\n                  else {\n                     if (prec_value < len) {\n                        prec_value = len;\n                     }\n                     flags &= ~FLAGS_ZERO;\n                  }\n                  if (flags & FLAGS_LEFT) {\n                     if (flags & FLAGS_HASH && (len != 1 || *num_ptr != '0')) {\n                        func('0', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                        func(use_caps ? 'X' : 'x', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (width_value != 0) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                  }\n                  else {\n                     while (width_value > (prec_value + 2)) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     if (flags & FLAGS_HASH && (len != 1 || *num_ptr != '0')) {\n                        func('0', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                        func(use_caps ? 'X' : 'x', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     else {\n                        while (width_value > prec_value) {\n                           func(' ', user, 0);\n                           width_value--;\n                        }\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                     }\n                  }\n                  break;\n               }\n               case 'f': case 'F':\n                  break;\n               case 'e': case 'E':\n                  break;\n               case 'g': case 'G':\n                  break;\n               case 'a': case 'A':\n                  break;\n               case 'c': {\n                  unsigned char ch = (unsigned char)(unsigned int)args[field_arg];\n                  if (width_value == -1) {\n                     width_value = 1;\n                  }\n                  if (flags & FLAGS_LEFT) {\n                     func((char)ch, user, 0);\n                     if (width_value > 0) {\n                        width_value--;\n                     }\n                     while (width_value != 0) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                  }\n                  else {\n                     while (width_value > 1) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     func(ch, user, 0);\n                  }\n                  break;\n               }\n               case 's': {\n                  const char *s_arg = (const char *)args[field_arg];\n                  int len = cgc_strlen(s_arg);\n                  if (width_value == -1) {\n                     //by default min length is the entire string\n                     width_value = len;\n                  }\n                  if (prec_value == -1 || prec_value > len) {\n                     //by default max is entire string but no less than width\n                     prec_value = len;\n                  }\n                  if (flags & FLAGS_LEFT) {\n                     while (prec_value != 0) {\n                        func(*s_arg++, user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (width_value != 0) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                  }\n                  else {\n                     while (width_value > prec_value) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     while (prec_value != 0) {\n                        func(*s_arg++, user, 0);\n                        prec_value--;\n                     }\n                  }\n                  break;\n               }\n               case 'p': {\n                  int len;\n                  flags |= FLAGS_HASH;\n                  num_ptr = r_xtoa((unsigned int)args[field_arg], num_buf, 0);\n                  len = num_ptr - num_buf + 1;\n                  if (prec_value == -1) {\n                     //by default max is entire value\n                     prec_value = len;\n                  }\n                  else {\n                     if (prec_value < len) {\n                        prec_value = len;\n                     }\n                     flags &= ~FLAGS_ZERO;\n                  }\n                  if (width_value == -1) {\n                     //by default min length is the entire value\n                     width_value = prec_value + 2;\n                  }\n                  if (flags & FLAGS_LEFT) {\n                     func('0', user, 0);\n                     if (width_value > 0) {\n                        width_value--;\n                     }\n                     func('x', user, 0);\n                     if (width_value > 0) {\n                        width_value--;\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (width_value != 0) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                  }\n                  else {\n                     while (width_value > (prec_value + 2)) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     func('0', user, 0);\n                     if (width_value > 0) {\n                        width_value--;\n                     }\n                     func('x', user, 0);\n                     if (width_value > 0) {\n                        width_value--;\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                     }\n                  }\n                  break;\n               }\n               case 'n': {\n                  void *np = (void*)args[field_arg];\n                  unsigned int len = func(0, user, 1);\n                  switch (length) {\n                     case LENGTH_HH:\n                        *(unsigned char*)np = (unsigned char)len;\n                        break;\n                     case LENGTH_H:\n                        *(unsigned short*)np = (unsigned short)len;\n                        break;\n                     case LENGTH_L:\n                     default:\n                        *(unsigned int*)np = len;\n                        break;\n                  }\n                  break;\n               }\n               case 'C':\n                  break;\n               case 'S':\n                  break;\n               default:\n                  break;\n            }\n            state = STATE_NORMAL;\n            break;\n         }\n      }\n   }\n}\n\nint vdprintf(int fd, const char *format, va_list ap) {\n   struct _fd_printer fp;\n   fp.fd = fd;\n   fp.err = 0;\n   fp.count = 0;\n   printf_core(fd_printer, &fp, format, ap);\n   return fp.count;\n}\n\n#endif /* DEBUG */\n\n"
  },
  {
    "path": "corpus/cgc/UTF-late/lib/malloc.c",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"libcgc.h\"\n\n#include \"cgc_libc.h\"\n#include \"cgc_list.h\"\n\nstruct chunk {\n    cgc_size_t header;\n    struct list_node list;\n} __attribute__((packed));\n\nstatic cgc_size_t size_class_sizes[] = {\n    16, 32, 64, 128, 256, 512, 1024, 2048\n};\n\n#define NUM_SIZE_CLASSES (sizeof(size_class_sizes) / sizeof(cgc_size_t))\n\nstatic struct list freelists[NUM_SIZE_CLASSES] = {};\n\n#define ALIGN(x, a) (((x) + (a - 1)) & ~(a - 1))\n#define IS_PAGE_ALIGNED(a) ((((cgc_size_t)a) & (PAGE_SIZE - 1)) == 0)\n#define CHUNK_OVERHEAD (2 * sizeof(cgc_size_t))\n#define MIN_SIZE (size_class_sizes[0])\n#define MAX_SIZE (PAGE_SIZE - 1)\n#define SIZE_CLASS_INDEX(size) (cgc_log_base_two(size) - cgc_log_base_two(MIN_SIZE))\n\n#define CHUNK_SIZE(chunk) ((chunk)->header & ~1)\n#define IS_ALLOCATED(chunk) ((chunk)->header & 1)\n#define FOOTER(chunk) ((cgc_size_t *)((char *)chunk + CHUNK_SIZE(chunk) - sizeof(cgc_size_t)))\n#define NEXT_CHUNK(chunk) ((struct chunk *)((char *)chunk + CHUNK_SIZE(chunk)))\n#define PREV_SIZE(chunk) (CHUNK_SIZE(((struct chunk *)((cgc_size_t *)chunk - 1))))\n#define PREV_CHUNK(chunk) ((struct chunk *)((char *)chunk - PREV_SIZE(chunk)))\n\nstatic inline unsigned int\ncgc_log_base_two(unsigned int x)\n{\n    unsigned long ret = 0;\n    while (x >>= 1)\n        ret++;\n    return ret;\n}\n\nstatic inline void *\ncgc_chunk_to_ptr(struct chunk *chunk)\n{\n    return (char *)chunk + OFFSETOF(struct chunk, list);\n}\n\nstatic inline struct chunk *\ncgc_ptr_to_chunk(void *ptr)\n{\n    return CONTAINEROF(struct chunk, list, ptr);\n}\n\nstatic void\ncgc_mark_allocated(struct chunk *chunk)\n{\n    chunk->header |= 1;\n    *FOOTER(chunk) = chunk->header;\n}\n\nstatic void\ncgc_mark_free(struct chunk *chunk)\n{\n    chunk->header &= ~1;\n    *FOOTER(chunk) = chunk->header;\n}\n\nstatic int\ncgc_find_fit(const struct list_node *chunk_, void *size_)\n{\n    cgc_size_t size = (cgc_size_t)size_;\n    struct chunk *chunk = list_entry(struct chunk, list, chunk_);\n\n    return CHUNK_SIZE(chunk) >= size;\n}\n\nstatic int\ncgc_size_cmp(const struct list_node *a_, const struct list_node *b_)\n{\n    const struct chunk *a = list_entry(struct chunk, list, a_);\n    const struct chunk *b = list_entry(struct chunk, list, b_);\n\n    return CHUNK_SIZE(b) - CHUNK_SIZE(a);\n}\n\nstatic void *\ncgc_allocate_large_chunk(cgc_size_t size)\n{\n    struct chunk *chunk;\n\n    if (cgc_allocate(size, 0, (void **)&chunk) != 0)\n        return NULL;\n\n    chunk->header = size;\n    cgc_mark_allocated(chunk);\n\n    return cgc_chunk_to_ptr(chunk);\n}\n\nstatic struct chunk *\ncgc_grow_heap(void)\n{\n    struct chunk *chunk;\n\n    if (cgc_allocate(PAGE_SIZE, 0, (void **)&chunk) != 0)\n        return NULL;\n\n    chunk->header = PAGE_SIZE;\n    cgc_mark_free(chunk);\n\n    return chunk;\n}\n\nstatic struct chunk *\ncgc_split_chunk(struct chunk *chunk, cgc_size_t size)\n{\n    struct chunk *new = (struct chunk *)((char *)chunk + size);\n    cgc_size_t orig_size = CHUNK_SIZE(chunk);\n\n    if (CHUNK_SIZE(chunk) <= size + MIN_SIZE)\n        return chunk;\n\n    chunk->header = size;\n    cgc_mark_allocated(chunk);\n\n    new->header = orig_size - size;\n    cgc_mark_allocated(new);\n    cgc_free(cgc_chunk_to_ptr(new));\n\n    return chunk;\n}\n\nstatic struct chunk *\ncgc_coalesce(struct chunk *chunk)\n{\n    struct chunk *next = NULL, *prev = NULL;\n    unsigned int size_class;\n\n    if (!IS_PAGE_ALIGNED(chunk))\n        prev = PREV_CHUNK(chunk);\n\n    if (!IS_PAGE_ALIGNED(NEXT_CHUNK(chunk)))\n        next = NEXT_CHUNK(chunk);\n\n    if (prev && !IS_ALLOCATED(prev)) {\n        size_class = SIZE_CLASS_INDEX(CHUNK_SIZE(prev));\n        if (size_class < NUM_SIZE_CLASSES) {\n            list_remove_entry(struct chunk, list, &freelists[size_class], prev);\n            prev->header = CHUNK_SIZE(chunk) + CHUNK_SIZE(prev);\n            cgc_mark_free(prev);\n\n            chunk = prev;\n        }\n    }\n\n    if (next && !IS_ALLOCATED(next)) {\n        size_class = SIZE_CLASS_INDEX(CHUNK_SIZE(next));\n        if (size_class < NUM_SIZE_CLASSES) {\n            list_remove_entry(struct chunk, list, &freelists[size_class], next);\n            chunk->header = CHUNK_SIZE(chunk) + CHUNK_SIZE(next);\n            cgc_mark_free(chunk);\n        }\n    }\n\n    return chunk;\n}\n\nvoid *\ncgc_malloc(cgc_size_t size)\n{\n    struct chunk *chunk = NULL;\n    unsigned int size_class;\n\n    if (ALIGN(size, sizeof(cgc_size_t)) + CHUNK_OVERHEAD < size)\n        return NULL;\n\n    size = ALIGN(size, sizeof(cgc_size_t)) + CHUNK_OVERHEAD;\n\n    if (size < MIN_SIZE)\n        size = MIN_SIZE;\n\n    if (size > MAX_SIZE)\n        return cgc_allocate_large_chunk(size);\n\n    size_class = SIZE_CLASS_INDEX(size);\n    if (size_class >= NUM_SIZE_CLASSES)\n        return NULL;\n\n    while (chunk == NULL && size_class < NUM_SIZE_CLASSES)\n        chunk = list_find_entry(struct chunk, list, &freelists[size_class++],\n                cgc_find_fit, (void *)size);\n\n    if (chunk == NULL)\n        chunk = cgc_grow_heap();\n    else\n        list_remove_entry(struct chunk, list, &freelists[size_class - 1], chunk);\n\n    cgc_mark_allocated(chunk);\n    if (CHUNK_SIZE(chunk) > size)\n        chunk = cgc_split_chunk(chunk, size);\n\n    return cgc_chunk_to_ptr(chunk);\n}\n\nvoid\ncgc_free(void *ptr)\n{\n    struct chunk *chunk = cgc_ptr_to_chunk(ptr);\n    unsigned int size_class;\n\n    if (ptr == NULL)\n        return;\n\n    // This should only happen if allocated through allocate_large_chunk(). If\n    // it's not page_aligned, something bad happened and we just leak the chunk.\n    if (CHUNK_SIZE(chunk) > MAX_SIZE) {\n        if (IS_PAGE_ALIGNED(chunk))\n            cgc_deallocate(chunk, ALIGN(CHUNK_SIZE(chunk), PAGE_SIZE));\n\n        return;\n    }\n\n    cgc_mark_free(chunk);\n    chunk = cgc_coalesce(chunk);\n\n    size_class = SIZE_CLASS_INDEX(CHUNK_SIZE(chunk));\n    if (size_class >= NUM_SIZE_CLASSES)\n        return;\n\n    list_insert_entry_in_order(struct chunk, list, &freelists[size_class],\n            chunk, cgc_size_cmp);\n}\n\nvoid *\ncgc_calloc(cgc_size_t size)\n{\n    void *ret = cgc_malloc(size);\n    if (ret)\n        cgc_memset(ret, '\\0', size);\n    return ret;\n}\n\nvoid *\ncgc_realloc(void *ptr, cgc_size_t size)\n{\n    cgc_size_t orig_size;\n    void *ret;\n\n    if (ptr == NULL)\n        return cgc_malloc(size);\n\n    orig_size = CHUNK_SIZE(cgc_ptr_to_chunk(ptr)) - CHUNK_OVERHEAD;\n    if (size == orig_size)\n        return ptr;\n   \n    ret = cgc_malloc(size);\n    cgc_memcpy(ret, ptr, MIN(size, orig_size));\n    cgc_free(ptr);\n\n    return ret;\n}\n\n"
  },
  {
    "path": "corpus/cgc/UTF-late/lib/utf8.c",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"libcgc.h\"\n\n#include \"cgc_utf8.h\"\n\nenum utf8_decode_state\ncgc_utf8_decode(enum utf8_decode_state state, utf8char c, ucscodepoint *out)\n{\n    switch (state) {\n    case ACCEPT:\n    case REJECT:\n        if ((c & 0x80) == 0) {\n            *out = c;\n            return ACCEPT;\n        } else if ((c & 0xe0) == 0xc0) {\n            *out = (c & 0x1f) << 6;\n            return TWO_BYTE;\n        } else if ((c & 0xf0) == 0xe0) {\n            *out = (c & 0x0f) << 12;\n            return THREE_BYTE;\n        } else if ((c & 0xf4) == 0xf0) {\n            *out = (c & 0x07) << 18;\n            return FOUR_BYTE;\n        }\n        break;\n    case FOUR_BYTE:\n#ifdef PATCHED\n        if ((c & 0xc0) == 0x80 && *out) {\n#else\n        if ((c & 0xc0) == 0x80) {\n#endif\n            *out |= (c & 0x3f) << 12;\n            // Catch 4-byte seqences decoding to over 0x10ffff\n            if (*out > 0x10ffff)\n                break;\n\n            return THREE_BYTE;\n        }\n        break;\n    case THREE_BYTE:\n#ifdef PATCHED\n        if ((c & 0xc0) == 0x80 && *out) {\n#else\n        if ((c & 0xc0) == 0x80) {\n#endif\n            *out |= (c & 0x3f) << 6;\n            return TWO_BYTE;\n        }\n        break;\n    case TWO_BYTE:\n#ifdef PATCHED\n        if ((c & 0xc0) == 0x80 && *out) {\n#else\n        if ((c & 0xc0) == 0x80) {\n#endif\n            *out |= (c & 0x3f);\n            return ACCEPT;\n        }\n        break;\n    }\n\n    *out = 0xfffd;\n    return REJECT;\n}\n\ncgc_ssize_t\ncgc_utf8_encode(ucscodepoint in, utf8char *out, cgc_size_t size)\n{\n    if (in < 0x80) {\n        if (size < 1)\n            return 0;\n\n        *out++ = in;\n        return 1;\n    } else if (in > 0x80 && in < 0x7ff) {\n        if (size < 2)\n            return 0;\n\n        *out++ = 0xc0 | (in & (0x1f << 6) >> 6);\n        *out++ = 0x80 | (in & 0x3f);\n        return 2;\n    } else if (in > 0x800 && in < 0xffff) {\n        if (size < 3)\n            return 0;\n\n        if (in >= 0xd800 && in <= 0xdfff)\n            return -1;\n\n        *out++ = 0xe0 | (in & (0xf << 12) >> 12);\n        *out++ = 0x80 | (in & (0x3f << 6) >> 6);\n        *out++ = 0x80 | (in & 0x3f);\n        return 3;\n    } else if (in > 0x10000 && in < 0x10ffff && size > 3) {\n        if (size < 4)\n            return 0;\n\n        *out++ = 0xf0 | (in & (0x7 << 18) >> 18);\n        *out++ = 0x80 | (in & (0x3f << 12) >> 12);\n        *out++ = 0x80 | (in & (0x3f << 6) >> 6);\n        *out++ = 0x80 | (in & 0x3f);\n        return 4;\n    }\n\n    return -1;\n}\n\ncgc_size_t\ncgc_utf8_canonicalize(utf8char *dst, const utf8char *src, cgc_size_t n)\n{\n    cgc_size_t i, ret = 0;\n    ucscodepoint cp;\n    cgc_ssize_t encoded;\n    enum utf8_decode_state state = ACCEPT;\n\n    // Guarantee we have space for null terminator\n    n--;\n\n    for (i = 0; n && src[i]; i++) {\n        state = cgc_utf8_decode(state, src[i], &cp);\n        if (state == ACCEPT || state == REJECT) {\n            encoded = cgc_utf8_encode(cp, dst, n);\n            if (encoded < 0)\n                return ret;\n\n            ret += encoded;\n            dst += encoded;\n            n -= encoded;\n        }\n    }\n\n    *dst = '\\0';\n    return ret;\n}\n\n"
  },
  {
    "path": "corpus/cgc/UTF-late/lib/vfs.c",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"cgc_libc.h\"\n#include \"cgc_list.h\"\n\n#include \"cgc_vfs.h\"\n\nint\ncgc_vfs_init(struct vfs *vfs)\n{\n    return (vfs->root = cgc_calloc(sizeof(struct directory))) ? 0 : -1;\n}\n\nstatic void\ncgc_directory_destroy(struct directory *dir)\n{\n    struct file *cur_file, *n_file;\n    struct directory *cur_dir, *n_dir;\n\n    list_for_each_entry_safe(struct file, list, &dir->files, n_file, cur_file) {\n        cgc_free(cur_file->contents);\n        cgc_free(cur_file);\n    }\n\n    list_for_each_entry_safe(struct directory, list, &dir->subdirectories, n_dir, cur_dir)\n        cgc_directory_destroy(cur_dir);\n\n    cgc_free(dir);\n}\n\nvoid\ncgc_vfs_destroy(struct vfs *vfs)\n{\n    cgc_directory_destroy(vfs->root);\n}\n\nstatic int\ncgc_dir_eq(const struct list_node *dir_, void *name_)\n{\n    const struct directory *dir = list_entry(struct directory, list, dir_);\n    const utf8char *name = (const utf8char *)name_;\n\n    return cgc_strncmp(dir->name, name, MAX_FILE_NAME_LENGTH) == 0;\n}\n\nstatic int\ncgc_file_eq(const struct list_node *file_, void *name_)\n{\n    const struct file *file = list_entry(struct file, list, file_);\n    const utf8char *name = (const utf8char *)name_;\n\n    return cgc_strncmp(file->name, name, MAX_FILE_NAME_LENGTH) == 0;\n}\n\nstruct directory *\ncgc_lookup_dir(const struct vfs *vfs, const utf8char *path)\n{\n    struct directory *ret = NULL;\n    struct directory *dir = vfs->root;\n    cgc_size_t path_len;\n    utf8char *path_dup, *cur, *next;\n\n    while (*path == '/')\n        path++;\n\n    path_len = cgc_strlen(path);\n    if (path_len == 0)\n        return vfs->root;\n\n    if ((path_dup = cgc_calloc(path_len + 1)) == NULL)\n        return NULL;\n\n    cgc_strncpy(path_dup, path, path_len);\n    for (cur = cgc_strtok(path_dup, '/'), next = cgc_strtok(NULL, '/');\n            dir && next != NULL;\n            cur = next, next = cgc_strtok(NULL, '/'))\n    {\n        if (cgc_strcmp(cur, \".\") == 0)\n            continue;\n\n        if (cgc_strcmp(cur, \"..\") == 0) {\n            dir = dir->parent;\n            continue;\n        }\n\n        if ((dir = list_find_entry(struct directory, list, &dir->subdirectories,\n                        cgc_dir_eq, (void *)cur)) == NULL) {\n            goto free_path;\n        }\n    }\n\n    ret = list_find_entry(struct directory, list, &dir->subdirectories, cgc_dir_eq, (void *)cur);\n\nfree_path:\n    cgc_free(path_dup);\n    return ret;\n}\n\nstruct file *\ncgc_lookup_file(const struct vfs *vfs, const utf8char *path)\n{\n    struct file *ret = NULL;\n    struct directory *dir = vfs->root;\n    cgc_size_t path_len;\n    utf8char *path_dup, *name;\n\n    path_len = cgc_strlen(path);\n    if (path[path_len - 1] == '/')\n        return NULL;\n\n    if ((path_dup = cgc_calloc(path_len + 1)) == NULL)\n        return NULL;\n\n    cgc_strncpy(path_dup, path, path_len + 1);\n\n    if ((name = cgc_strrchr(path_dup, '/')) != NULL) {\n        *name++ = '\\0';\n        dir = cgc_lookup_dir(vfs, path_dup);\n    } else {\n        name = path_dup;\n    }\n\n    if (dir != NULL)\n        ret = list_find_entry(struct file, list, &dir->files, cgc_file_eq, (void *)name);\n\n    cgc_free(path_dup);\n    return ret;\n}\n\nstruct directory *\ncgc_create_dir(struct vfs *vfs, const utf8char *path)\n{\n    struct directory *ret = NULL;\n    struct directory *dir = vfs->root;\n    cgc_size_t path_len;\n    utf8char *path_dup, *name;\n\n    path_len = cgc_strlen(path);\n    if ((path_dup = cgc_calloc(path_len + 1)) == NULL)\n        return NULL;\n\n    cgc_strncpy(path_dup, path, path_len + 1);\n    while (path_dup[path_len - 1] == '/')\n        path_dup[(path_len--) - 1] = '\\0';\n\n    if ((name = cgc_strrchr(path_dup, '/')) != NULL) {\n        *name++ = '\\0';\n        dir = cgc_lookup_dir(vfs, path_dup);\n    } else {\n        name = path_dup;\n    }\n\n    if (dir != NULL)\n        ret = cgc_create_dir_in_dir(vfs, dir, name);\n\n    cgc_free(path_dup);\n    return ret;\n}\n\nstruct directory *\ncgc_create_dir_in_dir(struct vfs *vfs, struct directory *dir, const utf8char *name)\n{\n    struct directory *ret;\n\n    // Suppress unused warning\n    (void)(vfs);\n\n    // Ensure we can't create a file with the same name as a file\n    if (cgc_list_find(&dir->files, cgc_file_eq, (void *)name) != NULL)\n        return NULL;\n\n    // If the directory arelady exists, return it\n    if ((ret = list_find_entry(struct directory, list, &dir->subdirectories,\n                    cgc_dir_eq, (void *)name)) != NULL) {\n        return ret;\n    }\n\n    if ((ret = cgc_calloc(sizeof(struct directory))) != NULL) {\n        cgc_strncpy(ret->name, name, MAX_FILE_NAME_LENGTH);\n        ret->parent = dir;\n        list_push_entry_front(struct directory, list, &dir->subdirectories, ret);\n    }\n\n    return ret;\n}\n\nstruct file *\ncgc_create_file(struct vfs *vfs, const utf8char *path)\n{\n    struct file *ret = NULL;\n    struct directory *dir = vfs->root;\n    cgc_size_t path_len;\n    utf8char *path_dup, *name;\n\n    path_len = cgc_strlen(path);\n    if (path[path_len - 1] == '/')\n        return NULL;\n\n    if ((path_dup = cgc_calloc(path_len + 1)) == NULL)\n        return NULL;\n\n    cgc_strncpy(path_dup, path, path_len + 1);\n    if ((name = cgc_strrchr(path_dup, '/')) != NULL) {\n        *name++ = '\\0';\n        dir = cgc_lookup_dir(vfs, path_dup);\n    } else {\n        name = path_dup;\n    }\n\n    if (dir != NULL)\n        ret = cgc_create_file_in_dir(vfs, dir, name);\n\n    cgc_free(path_dup);\n    return ret;\n}\n\nstruct file *\ncgc_create_file_in_dir(struct vfs *vfs, struct directory *dir, const utf8char *name)\n{\n    struct file *ret;\n\n    // Suppress unused warning\n    (void)vfs;\n\n    // Ensure we can't create a file with the same name as a directory\n    if (cgc_list_find(&dir->subdirectories, cgc_dir_eq, (void *)name) != NULL)\n        return NULL;\n\n    // If file already exists, return it\n    if ((ret = list_find_entry(struct file, list, &dir->files,\n                    cgc_file_eq, (void *)name)) != NULL) {\n        return ret;\n    }\n\n    if ((ret = cgc_calloc(sizeof(struct file))) != NULL) {\n        cgc_strncpy(ret->name, name, MAX_FILE_NAME_LENGTH);\n        ret->parent = dir;\n        list_push_entry_front(struct file, list, &dir->files, ret);\n    }\n\n    return ret;\n}\n\nvoid\ncgc_delete_file(struct vfs *vfs, struct file *file)\n{\n    // Suppress unused warning\n    (void)vfs;\n\n    list_remove_entry(struct file, list, &file->parent->files, file);\n    cgc_free(file->contents);\n    cgc_free(file);\n}\n\n#ifdef DEBUG\nstatic void\ndump_directory(const struct directory *dir, unsigned int level)\n{\n    unsigned int i;\n    struct file *cur_file;\n    struct directory *cur_dir;\n\n    list_for_each_entry(struct directory, list, &dir->subdirectories, cur_dir) {\n        for (i = 0; i < level; i++)\n            cgc_printf(\"\\t\");\n        cgc_printf(\"%s/\\n\", cur_dir->name);\n        dump_directory(cur_dir, level + 1);\n    }\n\n    list_for_each_entry(struct file, list, &dir->files, cur_file) {\n        for (i = 0; i < level; i++)\n            cgc_printf(\"\\t\");\n        cgc_printf(\"%s\\n\", cur_file->name);\n    }\n}\n\nvoid\ndump_vfs(const struct vfs *vfs)\n{\n    cgc_printf(\"/\\n\");\n    dump_directory(vfs->root, 1);\n}\n#endif\n\n"
  },
  {
    "path": "corpus/cgc/UTF-late/notes.txt",
    "content": "In the compiled UTF-late.exe executable, the main function is at offset 0x4540\n(0x404540 address).\n"
  },
  {
    "path": "corpus/cgc/UTF-late/src/service.c",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"libcgc.h\"\n#include \"cgc_libc.h\"\n#include \"cgc_utf8.h\"\n#include \"cgc_vfs.h\"\n\nstatic const utf8char pubroot_path[] = \"/public/\";\nstatic struct vfs vfs;\nstatic struct directory *pubroot = NULL;\nstatic struct directory *admin = NULL;\n\n#define MAX_FILE_SIZE (PAGE_SIZE - 2 * sizeof(cgc_size_t))\n#define MAX_PATH_LENGTH (sizeof(ucscodepoint) * (sizeof(pubroot_path) + MAX_FILE_NAME_LENGTH))\n\nenum fileserver_ops {\n    READ_FILE,\n    WRITE_FILE,\n    LIST_FILES\n};\n\nstatic int\ncgc_canonicalize_path(utf8char *dst, const utf8char *src)\n{\n#ifdef PATCHED\n    cgc_strncpy(dst, pubroot_path, sizeof(pubroot_path));\n    cgc_utf8_canonicalize(dst + sizeof(pubroot_path) - 1, src, MAX_PATH_LENGTH);\n\n    if (cgc_strchr(dst + sizeof(pubroot_path) - 1, '/') != NULL)\n        return -1;\n#else\n    if (cgc_strchr(src, '/') != NULL)\n        return -1;\n\n    cgc_strncpy(dst, pubroot_path, sizeof(pubroot_path));\n    cgc_utf8_canonicalize(dst + sizeof(pubroot_path) - 1, src, MAX_PATH_LENGTH);\n#endif\n\n    return 0;\n}\n\nstatic int\ncgc_read_file(void)\n{\n    struct file *file;\n    utf8char filename[MAX_FILE_NAME_LENGTH + 1];\n    utf8char path[MAX_PATH_LENGTH];\n\n    if (cgc_read_all(STDIN, filename, MAX_FILE_NAME_LENGTH) != MAX_FILE_NAME_LENGTH)\n        return -1;\n    filename[MAX_FILE_NAME_LENGTH] = '\\0';\n\n    if (cgc_canonicalize_path(path, filename) != 0)\n        return -1;\n\n    if ((file = cgc_lookup_file(&vfs, path)) == NULL)\n        return -1;\n\n    if (cgc_write_all(STDOUT, file->contents, file->size) != file->size)\n        return -1;\n\n    return 0;\n}\n\nstatic int\ncgc_write_file(void)\n{\n    struct file *file;\n    cgc_size_t size;\n    utf8char filename[MAX_FILE_NAME_LENGTH + 1];\n    utf8char path[MAX_PATH_LENGTH];\n\n    if (cgc_read_all(STDIN, filename, MAX_FILE_NAME_LENGTH) != MAX_FILE_NAME_LENGTH)\n        return -1;\n    filename[MAX_FILE_NAME_LENGTH] = '\\0';\n\n    if (cgc_read_all(STDIN, &size, sizeof(size)) != sizeof(size))\n        return -1;\n\n    if (size > MAX_FILE_SIZE)\n        return -1;\n\n    if (cgc_canonicalize_path(path, filename) != 0)\n        return -1;\n\n    if (cgc_lookup_file(&vfs, path) != NULL)\n        return -1;\n\n    if ((file = cgc_create_file(&vfs, path)) == NULL)\n        return -1;\n\n    file->size = size;\n\n    // Special admin files\n    if (file->parent == admin) {\n        file->contents = *(unsigned char **)filename;\n    } else {\n        if ((file->contents = cgc_calloc(size)) == NULL) {\n            cgc_delete_file(&vfs, file);\n            return -1;\n        }\n    }\n\n    if (cgc_read_all(STDIN, file->contents, file->size) != file->size) {\n        cgc_delete_file(&vfs, file);\n        return -1;\n    }\n\n    return 0;\n}\n\nstatic int\ncgc_list_files(void)\n{\n    struct file *cur;\n\n    list_for_each_entry(struct file, list, &pubroot->files, cur)\n        if (cgc_write_all(STDOUT, cur->name, MAX_FILE_NAME_LENGTH) != MAX_FILE_NAME_LENGTH)\n            return -1;\n\n    return 0;\n}\n\nint\nmain(int cgc_argc, char *cgc_argv[]) {\n    int cmd, cmd_ret;\n\n    // Set up filesystem\n    cgc_vfs_init(&vfs);\n    pubroot = cgc_create_dir(&vfs, pubroot_path);\n    admin = cgc_create_dir(&vfs, \"/admin\");\n\n    while (1) {\n        if (cgc_read_all(STDIN, &cmd, sizeof(cmd)) != sizeof(cmd))\n            continue;\n\n        if (cmd == -1)\n            break;\n\n        switch (cmd) {\n        case READ_FILE:\n            cmd_ret = cgc_read_file();\n            break;\n        case WRITE_FILE:\n            cmd_ret = cgc_write_file();\n            break;\n        case LIST_FILES:\n            cmd_ret = cgc_list_files();\n            break;\n        default:\n            continue;\n        }\n\n        cgc_write_all(STDOUT, &cmd_ret, sizeof(cmd_ret));\n    }\n\n    cgc_vfs_destroy(&vfs);\n\n    return 0;\n}\n\n"
  },
  {
    "path": "corpus/cgc/cotton_swab_arithmetic/README.md",
    "content": "# INTERPRETTHIS Challenge Binary\n\n## Author Information\n\n\"Narf Industries\" <info@narfindustries.com>\n\n### DARPA performer group\n\nNarf Industries (NRFIN)\n\n## Description\n\nDo the mice have enough cotton swabs to cross the wastebasket chasm and reach the cheese on the counter?  They're not sure; this sounds like a job for arithmetic!\n\nOne complicating factor: they need to do this math on their laptop, phones, watch and car.  Because why not?\n\nWhat better way to achieve cross-platform compatibility than to write arithmetic expressions in machine-agnostic bytecode?  There's probably a bunch of better ways, but this is what they settled on.\n\nYou're the cat and you must exploit the mice's cross-platform arithmetic machine. Good luck.\n\n### Feature List\n\nInterfacing with the CB is very simple.  CRSs provide bytecode for verification and - if it passes - execution.  \n\nThe bytecode executes on a single register (ACC) + memory virtual machine. Available operations are the 4 standard arithmetic operations (add, subtract, multiply and divide) plus a special OUT operation that writes whatever is currently in ACC into the output parameter for return back to the CRS.\n\nFlags in the opcode dictate where the result of an operation is to be stored (ACC or a memory location), what constitutes the operands (is ACC an operand?) and how the operands are to be interpreted (are they immediate values or memory references?).  More details provided in service.h\n\nHere's a summary:\n#) CB: allocate() memory for bytecode and scratch space (temporary storage)\n#) CRS -> CB: bytecode instructions\n#) CB: validate bytecode \n#) CB: execute bytecode\n#) CB -> CRS: output\n\t- Output is the contents of a 32bit output register, populated with the \n\tcontents of ACC each time OPCODE_OUT is executed.\n\n## Vulnerabilities\n\nThe vulnerability is present in the verification stage.\n\nPatched code will bound memory accesses to only the scratch area. Unpatched code will incorrectly bound memory accesses to the scratch area + the bytecode area (which is immediately adjacent), effectively allowing bytecode to modify subsequent bytecode instructions after validation but prior to execution.\n\nThe ability to modify bytecode via the vulnerability allows modification after Time of Check (verification), but prior to Time of Use (execution). Bytecode that seemed valid during verification becomes invalid during execution.  Thisis a classic TOCTOU vulnerability.\n\nInvalid bytecode provides CRSs with an arbitrary, relative RW primitive across the entire address space.\n\n### CWE classification\n\n20: Improper Input Validation\n119: Improper Restriction of Operations within the Bounds of a Memory Buffer\n125: Out-of-Bounds Read\n367: Time-of-Chceck Time-of-Use (TOCTOU)\n476: NULL Pointer Dereference\n787: Out-of-Bounds Write\n\n## Challenges\n\nWe expect this CB to be relatively easy to attack (crash), but difficult to patch.  The \"correct\" way to patch is somewhat non-obvious from an autonomous analysis perspective.  We relax this difficulty by not explicitly testing error conditions explicitly in our poller, improving patch flexibility.\n\nAmong many possibilities, we expect competitors may try to:\n#) Disallow outside-of-scratch-area reads/writes during execution phase (pushdown from verification phase).\n#) Make scratch memory disjoint from bytecode memory.\n#) (Our patching strategy) disallow bytecode self-modification by tightening verification phase checks.\n\nIn both cases, CBs must:\n#) Handle dynamic dispatch, complex paths based on input inherent to an interpreter\n#) Handle self-modifying bytecode this implies accurately modeling memory\n\n"
  },
  {
    "path": "corpus/cgc/cotton_swab_arithmetic/lib/cgc_libc.h",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n\n#ifndef LIBC_H\n#define LIBC_H\n\n#include \"libcgc.h\"\n\n#define SUCCESS 0\n#define ERRNO_RECV -63\n#define ERRNO_TRANSMIT -88\n#define ERRNO_INSUFFICIENT_BYTES -32\n#define ERRNO_VFRY_REJECT_OFF -27\n#define ERRNO_INST_DECODE -67\n#define ERRNO_INVALID_OPCODE -62\n\n#define uint8_t unsigned char\n#define uint16_t unsigned short\n#define uint32_t unsigned int \n\n// Fragmentation related\nint cgc_receive_all(int fd, void *buf, cgc_size_t count, cgc_size_t *rx_bytes);\nint cgc_transmit_all(int fd, const void *buf, cgc_size_t count, cgc_size_t *tx_bytes);\n\n////\n// The following is verbatim from EAGLE_00004, but isn't included in the \n// released binary (DEBUG is not defined), so this reuse shouldn't be a concern.\n////\n#ifdef DEBUG\n\n#define _FILE_STATE_OPEN  1\n#define _FILE_STATE_ERROR 2\n#define _FILE_STATE_EOF   4\n#define _FILE_HAVE_LAST   8\n\ntypedef struct _FILE {\n   int fd;\n   int state;\n   int last;\n} FILE;\n\nextern FILE *stdin;\nextern FILE *stdout;\nextern FILE *stderr;\n\nint fprintf(FILE * stream, const char *format, ...);\n\n#endif\n// ^ DEBUG\n\n#endif\n// ^ LIBC_H\n\n"
  },
  {
    "path": "corpus/cgc/cotton_swab_arithmetic/lib/libc.c",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n\n#include \"cgc_libc.h\"\n\n// Address fragmentation issue.\n// Keep looping until we've receive'd count bytes.\n// VERBATIM to JUSTINTIME\nint cgc_receive_all(int fd, void *buf, cgc_size_t count, cgc_size_t *rx_bytes) {\n\n   int ret = SUCCESS;\n   cgc_size_t bytes_left = count;\n   cgc_size_t rx_bytes_local = 0;\n\n   while (bytes_left) {\n\n      rx_bytes_local = 0;\n\n      if (SUCCESS != (ret = cgc_receive(STDIN, buf+(count-bytes_left), bytes_left, &rx_bytes_local))) {\n#ifdef DEBUG\n         fprintf(stderr, \"[E] receive () call within receive_all() failed\\n\");\n#endif\n         goto bail;\n      }\n\n      bytes_left -= rx_bytes_local;\n\n      // Assume EOF if 0-lengthed buffer.\n      if (0 == rx_bytes_local) {\n         if (NULL != rx_bytes) { *rx_bytes = count-bytes_left; }\n         goto bail;\n      }\n   }\n\n   // If we got here, then we got all the bytes.\n   if (NULL != rx_bytes) { *rx_bytes = count; }\n\nbail:\n   return ret;\n}\n\n// Address fragmentation issue.\n// Keep looping until we've transmit'ed count bytes.\n// VERBATIM to JUSTINTIME\nint cgc_transmit_all(int fd, const void *buf, cgc_size_t count, cgc_size_t *tx_bytes) {\n\n   int ret = SUCCESS;\n   cgc_size_t bytes_left = count;\n   cgc_size_t tx_bytes_local = 0;\n\n   while (bytes_left) {\n\n      tx_bytes_local = 0;\n\n      if (SUCCESS != (ret = cgc_transmit(STDOUT, buf, bytes_left, &tx_bytes_local))) {\n#ifdef DEBUG\n         fprintf(stderr, \"[E] transmit () call within transmit_all() failed\\n\");\n#endif\n         goto bail;\n      }\n\n      bytes_left -= tx_bytes_local;\n\n      // Assume EOF if 0-lengthed buffer.\n      if (0 == tx_bytes_local) {\n         if (NULL != tx_bytes) { *tx_bytes = count-bytes_left; }\n         goto bail;\n      }\n   }\n\n   // If we got here, then we got all the bytes.\n   if (NULL != tx_bytes) { *tx_bytes = count; }\n\nbail:\n   return ret;\n}\n\n\n////\n// The following is verbatim from EAGLE_00004, but isn't included in the\n// released binary (DEBUG is not defined), so this reuse shouldn't be a concern.\n////\n#ifdef DEBUG\n\n#ifdef WIN\n#include <stdarg.h>\n#else\ntypedef __builtin_va_list va_list;\n#define va_start(ap, param) __builtin_va_start(ap, param)\n#define va_end(ap) __builtin_va_end(ap)\n#define va_arg(ap, type) __builtin_va_arg(ap, type)\n#endif\n\nstatic FILE std_files[3] = { {0, _FILE_STATE_OPEN}, {1, _FILE_STATE_OPEN}, {2, _FILE_STATE_OPEN} };\n\nFILE *stdin = &std_files[0];\nFILE *stdout = &std_files[1];\nFILE *stderr = &std_files[2];\n\nint vfprintf(FILE *stream, const char *format, va_list ap);\nint vdprintf(int fd, const char *format, va_list ap);\n\n#define IS_DIGIT     1\n#define IS_UPPER     2\n#define IS_LOWER     4\n#define IS_SPACE     8\n#define IS_XDIGIT    16\n#define IS_CTRL      32\n#define IS_BLANK     64\n\n#define IS_ALPHA     (IS_LOWER | IS_UPPER)\n#define IS_ALNUM     (IS_ALPHA | IS_DIGIT)\n\nstatic unsigned char type_flags[256] = {\n     0, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL,\n     IS_CTRL, IS_SPACE | IS_BLANK, IS_SPACE, IS_SPACE, IS_SPACE, IS_SPACE, IS_CTRL, IS_CTRL,\n\n     IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL,\n     IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL, IS_CTRL,\n\n     IS_SPACE | IS_BLANK, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\n     IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT,\n     IS_DIGIT | IS_XDIGIT, IS_DIGIT | IS_XDIGIT, 0, 0, 0, 0, 0, 0,\n\n     0, IS_UPPER | IS_XDIGIT, IS_UPPER | IS_XDIGIT, IS_UPPER | IS_XDIGIT, IS_UPPER | IS_XDIGIT, IS_UPPER | IS_XDIGIT, IS_UPPER | IS_XDIGIT, IS_UPPER,\n     IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER,\n\n     IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER, IS_UPPER,\n     IS_UPPER, IS_UPPER, IS_UPPER, 0, 0, 0, 0, 0,\n\n     0, IS_LOWER | IS_XDIGIT, IS_LOWER | IS_XDIGIT, IS_LOWER | IS_XDIGIT, IS_LOWER | IS_XDIGIT, IS_LOWER | IS_XDIGIT, IS_LOWER | IS_XDIGIT, IS_LOWER,\n     IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER,\n\n     IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER, IS_LOWER,\n     IS_LOWER, IS_LOWER, IS_LOWER, 0, 0, 0, 0, 0,\n};\n\nint isalpha(int c) {\n   return (type_flags[c & 0xff] & IS_ALPHA) != 0;\n}\n\nint isdigit(int c) {\n   return (type_flags[c & 0xff] & IS_DIGIT) != 0;\n}\n\nint isxdigit(int c) {\n   return (type_flags[c & 0xff] & IS_XDIGIT) != 0;\n}\n\nint toupper(int c) {\n   if (isalpha(c)) {\n      return c & ~0x20;\n   }\n   return c;\n}\n\ncgc_size_t cgc_strlen(const char *str) {\n   cgc_size_t res = 0;\n   while (*str++) {res++;}\n   return res;\n}\n\nint vfprintf(FILE * stream, const char *format, va_list ap) {\n   return vdprintf(stream->fd, format, ap);\n}\n\nint fprintf(FILE * stream, const char *format, ...) {\n   va_list va;\n   va_start(va, format);\n   return vfprintf(stream, format, va);\n}\n\nstruct _fd_printer {\n   int fd;\n   int err;\n   unsigned int count;\n};\n\n//if flag != 0 return number of chars output so far\nstatic unsigned int fd_printer(char ch, void *_fp, int flag) {\n   struct _fd_printer *fp = (struct _fd_printer *)_fp;\n   if (flag) {\n      return fp->count;\n   }\n   else {\n      fp->count++;\n      cgc_transmit(fp->fd, &ch, 1, NULL);\n   }\n   return 0;\n}\n\n#define STATE_NORMAL 0\n#define STATE_ESCAPE 1\n#define STATE_PERCENT 2\n#define STATE_OCTAL 3\n#define STATE_HEX 4\n#define STATE_FLAGS 5\n#define STATE_WIDTH 6\n#define STATE_PRECISION 7\n#define STATE_LENGTH 8\n#define STATE_CONVERSION 9\n#define STATE_WIDTH_ARG 10\n#define STATE_WIDTH_VAL 11\n#define STATE_PRECISION_ARG 12\n#define STATE_PRECISION_VAL 13\n#define STATE_NARG 15\n\n#define FLAGS_TICK 1\n#define FLAGS_LEFT 2\n#define FLAGS_SIGN 4\n#define FLAGS_SPACE 8\n#define FLAGS_HASH 16\n#define FLAGS_ZERO 32\n\n#define LENGTH_H 1\n#define LENGTH_HH 2\n#define LENGTH_L 3\n#define LENGTH_J 5\n#define LENGTH_Z 6\n#define LENGTH_T 7\n#define LENGTH_CAPL 8\n\nstatic char *r_utoa(unsigned int val, char *outbuf) {\n   char *p = outbuf;\n   *p = '0';\n   while (val) {\n      *p++ = (val % 10) + '0';\n      val /= 10;\n   }\n   return p != outbuf ? (p - 1) : p;\n}\n\n//outbuf needs to be at least 22 chars\nstatic char *r_llotoa(unsigned long long val, char *outbuf) {\n   char *p = outbuf;\n   *p = '0';\n   while (val) {\n      *p++ = (val & 7) + '0';\n      val >>= 3;\n   }\n   return p != outbuf ? (p - 1) : p;\n}\n\nstatic char *r_otoa(unsigned int val, char *outbuf) {\n   return r_llotoa(val, outbuf);\n}\n\n//outbuf needs to be at least 22 chars\nstatic char *r_llxtoa(unsigned long long val, char *outbuf, int caps) {\n   char *p = outbuf;\n   *p = '0';\n   while (val) {\n      char digit = (char)(val & 0xf);\n      if (digit < 10) {\n         digit += '0';\n      }\n      else {\n         digit = caps ? (digit + 'A' - 10) : (digit + 'a' - 10);\n      }\n      *p++ = digit;\n      val >>= 4;\n   }\n   return p != outbuf ? (p - 1) : p;\n}\n\nstatic char *r_xtoa(unsigned int val, char *outbuf, int caps) {\n   return r_llxtoa(val, outbuf, caps);\n}\n\nstatic int hex_value_of(char ch) {\n   if (isdigit(ch)) {\n      return ch - '0';\n   }\n   else if (isalpha(ch)) {\n      return toupper(ch) - 'A' + 10;\n   }\n   return -1;\n}\n\n//func is responsible for outputing the given character\n//user is a pointer to data required by func\nstatic void printf_core(unsigned int (*func)(char, void *, int), void *user, const char *format, va_list ap) {\n   int state = STATE_NORMAL;\n   int flags;\n   int digit_count = 0;\n   int value = 0;\n   char ch;\n   int arg_count = 0;\n   int width_value;\n   int prec_value;\n   int field_arg;\n   int length;\n   char **args = (char**)ap;\n   for (ch = *format++; ch; ch = *format++) {\n      switch (state) {\n         case STATE_NORMAL:\n            if (ch == '%') {\n               state = STATE_PERCENT;\n            }\n            else if (ch == '\\\\') {\n               state = STATE_ESCAPE;\n            }\n            else {\n               func(ch, user, 0);\n            }\n            break;\n         case STATE_ESCAPE:\n            switch (ch) {\n               case 'n':\n                  func('\\n', user, 0);\n                  break;\n               case 't':\n                  func('\\t', user, 0);\n                  break;\n               case 'r':\n                  func('\\r', user, 0);\n                  break;\n               case 'b':\n                  func('\\b', user, 0);\n                  break;\n               case 'f':\n                  func('\\f', user, 0);\n                  break;\n               case 'v':\n                  func('\\v', user, 0);\n                  break;\n               case '\\\\': case '\\'': case '\"':\n                  func(ch, user, 0);\n                  break;\n               case 'x':\n                  state = STATE_HEX;\n                  digit_count = 0;\n                  value = 0;\n                  break;\n               default:\n                  if (ch > '0' && ch < '8') {\n                     state = STATE_OCTAL;\n                     digit_count = 1;\n                     value = ch - '0';\n                  }\n                  else {\n                     func(*format, user, 0);\n                  }\n                  break;\n            }\n            if (state == STATE_ESCAPE) {\n               state = STATE_NORMAL;\n            }\n            break;\n         case STATE_PERCENT:\n            if (ch == '%') {\n               func(ch, user, 0);\n               state = STATE_NORMAL;\n            }\n            else {\n               state = STATE_NARG;\n               flags = 0;\n               format--;\n            }\n            break;\n         case STATE_OCTAL:\n            if (ch > '0' && ch < '8' && digit_count < 3) {\n               digit_count++;\n               value = value * 8 + (ch - '0');\n               if (digit_count == 3) {\n                  func(value, user, 0);\n                  state = STATE_NORMAL;\n               }\n            }\n            else {\n               func(value, user, 0);\n               state = STATE_NORMAL;\n               format--;\n            }\n            break;\n         case STATE_HEX:\n            if (isxdigit(ch) && digit_count < 2) {\n               digit_count++;\n               value = value * 16 + hex_value_of(ch);\n               if (digit_count == 2) {\n                  func(value, user, 0);\n                  state = STATE_NORMAL;\n               }\n            }\n            else {\n               func(value, user, 0);\n               state = STATE_NORMAL;\n               format--;\n            }\n            break;\n         case STATE_NARG:\n            width_value = -1;\n            prec_value = -1;\n            flags = 0;\n            length = 0;\n            field_arg = -1;\n            if (ch == '0') {\n               format--;\n               state = STATE_FLAGS;\n               break;\n            }\n            if (isdigit(ch)) {\n               //could be width or could be arg specifier or a 0 flag\n               //width and arg values don't start with 0\n               width_value = 0;\n               while (isdigit(ch)) {\n                  width_value = width_value * 10 + (ch - '0');\n                  ch = *format++;\n               }\n               if (ch == '$') {\n                  field_arg = width_value - 1;\n                  width_value = 0;\n                  state = STATE_FLAGS;\n               }\n               else {\n                  //this was a width\n                  format--;\n                  state = STATE_PRECISION;\n               }\n            }\n            else {\n               format--;\n               state = STATE_FLAGS;\n            }\n            break;\n         case STATE_FLAGS:\n            switch (ch) {\n               case '\\'':\n                  flags |= FLAGS_TICK;\n                  break;\n               case '-':\n                  flags |= FLAGS_LEFT;\n                  break;\n               case '+':\n                  flags |= FLAGS_SIGN;\n                  break;\n               case ' ':\n                  flags |= FLAGS_SPACE;\n                  break;\n               case '#':\n                  flags |= FLAGS_HASH;\n                  break;\n               case '0':\n                  flags |= FLAGS_ZERO;\n                  break;\n               default:\n                  format--;\n                  if ((flags & (FLAGS_ZERO | FLAGS_LEFT)) == (FLAGS_ZERO | FLAGS_LEFT)) {\n                     //if both '-' and '0' appear, '0' is ignored\n                     flags &= ~FLAGS_ZERO;\n                  }\n                  state = STATE_WIDTH;\n                  break;\n            }\n            break;\n         case STATE_WIDTH:\n            if (ch == '*') {\n               ch = *format++;\n               int width_arg = 0;\n               if (isdigit(ch)) {\n                  while (isdigit(ch)) {\n                     width_arg = width_arg * 10 + (ch - '0');\n                     ch = *format++;\n                  }\n                  width_arg--;\n                  if (ch != '$') {\n                     //error\n                  }\n               }\n               else {\n                  width_arg = arg_count++;\n                  format--;\n               }\n               width_value = (int)args[width_arg];\n            }\n            else if (isdigit(ch)) {\n               width_value = 0;\n               while (isdigit(ch)) {\n                  width_value = width_value * 10 + (ch - '0');\n                  ch = *format++;\n               }\n               format--;\n            }\n            else {\n               //no width specified\n               format--;\n            }\n            state = STATE_PRECISION;\n            break;\n         case STATE_PRECISION:\n            if (ch == '.') {\n               //have a precision\n               ch = *format++;\n               if (ch == '*') {\n                  ch = *format++;\n                  int prec_arg = 0;\n                  if (isdigit(ch)) {\n                     while (isdigit(ch)) {\n                        prec_arg = prec_arg * 10 + (ch - '0');\n                        ch = *format++;\n                     }\n                     prec_arg--;\n                     if (ch != '$') {\n                        //error\n                     }\n                  }\n                  else {\n                     prec_arg = arg_count++;\n                     format--;\n                  }\n                  prec_value = (int)args[prec_arg];\n               }\n               else if (isdigit(ch)) {\n                  prec_value = 0;\n                  while (isdigit(ch)) {\n                     prec_value = prec_value * 10 + (ch - '0');\n                     ch = *format++;\n                  }\n                  format--;\n               }\n               else {\n                  //no precision specified\n                  format--;\n               }\n            }\n            else {\n               //no precision specified\n               format--;\n            }\n            state = STATE_LENGTH;\n            break;\n         case STATE_LENGTH:\n            switch (ch) {\n               case 'h':\n                  length = LENGTH_H;\n                  if (*format == 'h') {\n                     length++;\n                     format++;\n                  }\n                  break;\n               case 'l':\n                  length = LENGTH_L;\n                  if (*format == 'l') {\n//                     length++;\n                     format++;\n                  }\n                  break;\n               case 'j':\n                  length = LENGTH_J;\n                  break;\n               case 'z':\n                  length = LENGTH_Z;\n                  break;\n               case 't':\n                  length = LENGTH_T;\n                  break;\n               case 'L':\n                  length = LENGTH_CAPL;\n                  break;\n               default:\n                  format--;\n                  break;\n            }\n            state = STATE_CONVERSION;\n            break;\n         case STATE_CONVERSION: {\n            char num_buf[32];\n            char *num_ptr;\n            int use_caps = 1;\n            int sign;\n            int val;\n            long long llval;\n            if (field_arg == -1) {\n               field_arg = arg_count++;\n            }\n            switch (ch) {\n               case 'd': case 'i': {\n                  int len;\n                  switch (length) {\n                     case LENGTH_H:\n                        val = (short)(int)args[field_arg];\n                        sign = val < 0;\n                        if (sign) {\n                           val = -val;\n                        }\n                        num_ptr = r_utoa(val, num_buf);\n                        break;\n                     case LENGTH_HH:\n                        val = (char)(int)args[field_arg];\n                        sign = val < 0;\n                        if (sign) {\n                           val = -val;\n                        }\n                        num_ptr = r_utoa(val, num_buf);\n                        break;\n                     case LENGTH_L:\n                     default:\n                        val = (long)args[field_arg];\n                        sign = val < 0;\n                        if (sign) {\n                           val = -val;\n                        }\n                        num_ptr = r_utoa(val, num_buf);\n                        break;\n                  }\n                  len = num_ptr - num_buf + 1;\n                  if (width_value == -1) {\n                     //by default min length is the entire value\n                     width_value = len;\n                     if (sign || (flags & FLAGS_SIGN)) {\n                        width_value++;\n                     }\n                  }\n                  if (prec_value == -1) {\n                     //by default max is entire value\n                     prec_value = len;\n                     if ((flags & FLAGS_ZERO) != 0 && prec_value < width_value) {\n                        //widen precision if necessary to pad to width with '0'\n                        if (sign || (flags & FLAGS_SIGN)) {\n                           prec_value = width_value - 1;\n                        }\n                        else {\n                           prec_value = width_value;\n                        }\n                     }\n                  }\n                  else {\n                     if (prec_value < len) {\n                        prec_value = len;\n                     }\n                     //number won't need leading zeros\n                     flags &= ~FLAGS_ZERO;\n                  }\n                  if (flags & FLAGS_LEFT) {\n                     if (sign) {\n                        func('-', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     else if ((flags & FLAGS_SIGN) != 0) {\n                        func('+', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (width_value != 0) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                  }\n                  else {\n                     while (width_value > (prec_value + 1)) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     if (sign) {\n                        func('-', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     else if ((flags & FLAGS_SIGN) != 0) {\n                        func('+', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     if (width_value > prec_value) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                     }\n                  }\n                  break;\n               }\n               case 'o': {\n                  int len;\n                  switch (length) {\n                     case LENGTH_H:\n                        num_ptr = r_otoa((unsigned short)(unsigned int)args[field_arg], num_buf);\n                        break;\n                     case LENGTH_HH:\n                        num_ptr = r_otoa((unsigned char)(unsigned int)args[field_arg], num_buf);\n                        break;\n                     case LENGTH_L:\n                     default:\n                        num_ptr = r_otoa((unsigned long)args[field_arg], num_buf);\n                        break;\n                  }\n                  if (flags & FLAGS_HASH) {\n                     if (*num_ptr != '0') {\n                        num_ptr++;\n                        *num_ptr = '0';\n                     }\n                  }\n                  len = num_ptr - num_buf + 1;\n                  if (width_value == -1) {\n                     //by default min length is the entire value\n                     width_value = len;\n                  }\n                  if (prec_value == -1) {\n                     //by default max is entire value\n                     prec_value = len;\n                     if ((flags & FLAGS_ZERO) != 0 && prec_value < width_value) {\n                        //widen precision if necessary to pad to width with '0'\n                        prec_value = width_value;\n                     }\n                  }\n                  else {\n                     if (prec_value < len) {\n                        prec_value = len;\n                     }\n                     flags &= ~FLAGS_ZERO;\n                  }\n                  if (flags & FLAGS_LEFT) {\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (width_value != 0) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                  }\n                  else {\n                     while (width_value > prec_value) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                     }\n                  }\n                  break;\n               }\n               case 'u': {\n                  int len;\n                  switch (length) {\n                     case LENGTH_H:\n                        num_ptr = r_utoa((unsigned short)(unsigned int)args[field_arg], num_buf);\n                        break;\n                     case LENGTH_HH:\n                        num_ptr = r_utoa((unsigned char)(unsigned int)args[field_arg], num_buf);\n                        break;\n                     case LENGTH_L:\n                     default:\n                        num_ptr = r_utoa((unsigned long)args[field_arg], num_buf);\n                        break;\n                  }\n                  len = num_ptr - num_buf + 1;\n                  if (width_value == -1) {\n                     //by default min length is the entire value\n                     width_value = len;\n                  }\n                  if (prec_value == -1) {\n                     //by default max is entire value\n                     prec_value = len;\n                     if ((flags & FLAGS_ZERO) != 0 && prec_value < width_value) {\n                        //widen precision if necessary to pad to width with '0'\n                        prec_value = width_value;\n                     }\n                  }\n                  else {\n                     if (prec_value < len) {\n                        prec_value = len;\n                     }\n                     flags &= ~FLAGS_ZERO;\n                  }\n                  if (flags & FLAGS_LEFT) {\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (width_value != 0) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                  }\n                  else {\n                     while (width_value > prec_value) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                     }\n                  }\n                  break;\n               }\n               case 'x':\n                  use_caps = 0;  //now fall into X case\n               case 'X': {\n                  int len;\n                  switch (length) {\n                     case LENGTH_H:\n                        num_ptr = r_xtoa((unsigned short)(unsigned int)args[field_arg], num_buf, use_caps);\n                        break;\n                     case LENGTH_HH:\n                        num_ptr = r_xtoa((unsigned char)(unsigned int)args[field_arg], num_buf, use_caps);\n                        break;\n                     case LENGTH_L:\n                     default:\n                        num_ptr = r_xtoa((unsigned long)args[field_arg], num_buf, use_caps);\n                        break;\n                  }\n                  len = num_ptr - num_buf + 1;\n                  if (width_value == -1) {\n                     //by default min length is the entire value\n                     width_value = len;\n                  }\n                  if (prec_value == -1) {\n                     //by default max is entire value\n                     prec_value = len;\n                     if ((flags & FLAGS_ZERO) != 0 && prec_value < width_value) {\n                        //widen precision if necessary to pad to width with '0'\n                        prec_value = width_value;\n                     }\n                  }\n                  else {\n                     if (prec_value < len) {\n                        prec_value = len;\n                     }\n                     flags &= ~FLAGS_ZERO;\n                  }\n                  if (flags & FLAGS_LEFT) {\n                     if (flags & FLAGS_HASH && (len != 1 || *num_ptr != '0')) {\n                        func('0', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                        func(use_caps ? 'X' : 'x', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (width_value != 0) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                  }\n                  else {\n                     while (width_value > (prec_value + 2)) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     if (flags & FLAGS_HASH && (len != 1 || *num_ptr != '0')) {\n                        func('0', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                        func(use_caps ? 'X' : 'x', user, 0);\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     else {\n                        while (width_value > prec_value) {\n                           func(' ', user, 0);\n                           width_value--;\n                        }\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                     }\n                  }\n                  break;\n               }\n               case 'f': case 'F':\n                  break;\n               case 'e': case 'E':\n                  break;\n               case 'g': case 'G':\n                  break;\n               case 'a': case 'A':\n                  break;\n               case 'c': {\n                  unsigned char ch = (unsigned char)(unsigned int)args[field_arg];\n                  if (width_value == -1) {\n                     width_value = 1;\n                  }\n                  if (flags & FLAGS_LEFT) {\n                     func((char)ch, user, 0);\n                     if (width_value > 0) {\n                        width_value--;\n                     }\n                     while (width_value != 0) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                  }\n                  else {\n                     while (width_value > 1) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     func(ch, user, 0);\n                  }\n                  break;\n               }\n               case 's': {\n                  const char *s_arg = (const char *)args[field_arg];\n                  int len = cgc_strlen(s_arg);\n                  if (width_value == -1) {\n                     //by default min length is the entire string\n                     width_value = len;\n                  }\n                  if (prec_value == -1 || prec_value > len) {\n                     //by default max is entire string but no less than width\n                     prec_value = len;\n                  }\n                  if (flags & FLAGS_LEFT) {\n                     while (prec_value != 0) {\n                        func(*s_arg++, user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (width_value != 0) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                  }\n                  else {\n                     while (width_value > prec_value) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     while (prec_value != 0) {\n                        func(*s_arg++, user, 0);\n                        prec_value--;\n                     }\n                  }\n                  break;\n               }\n               case 'p': {\n                  int len;\n                  flags |= FLAGS_HASH;\n                  num_ptr = r_xtoa((unsigned int)args[field_arg], num_buf, 0);\n                  len = num_ptr - num_buf + 1;\n                  if (prec_value == -1) {\n                     //by default max is entire value\n                     prec_value = len;\n                  }\n                  else {\n                     if (prec_value < len) {\n                        prec_value = len;\n                     }\n                     flags &= ~FLAGS_ZERO;\n                  }\n                  if (width_value == -1) {\n                     //by default min length is the entire value\n                     width_value = prec_value + 2;\n                  }\n                  if (flags & FLAGS_LEFT) {\n                     func('0', user, 0);\n                     if (width_value > 0) {\n                        width_value--;\n                     }\n                     func('x', user, 0);\n                     if (width_value > 0) {\n                        width_value--;\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                        if (width_value > 0) {\n                           width_value--;\n                        }\n                     }\n                     while (width_value != 0) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                  }\n                  else {\n                     while (width_value > (prec_value + 2)) {\n                        func(' ', user, 0);\n                        width_value--;\n                     }\n                     func('0', user, 0);\n                     if (width_value > 0) {\n                        width_value--;\n                     }\n                     func('x', user, 0);\n                     if (width_value > 0) {\n                        width_value--;\n                     }\n                     while (prec_value > len) {\n                        func('0', user, 0);\n                        prec_value--;\n                     }\n                     while (prec_value != 0) {\n                        func(*num_ptr--, user, 0);\n                        prec_value--;\n                     }\n                  }\n                  break;\n               }\n               case 'n': {\n                  void *np = (void*)args[field_arg];\n                  unsigned int len = func(0, user, 1);\n                  switch (length) {\n                     case LENGTH_HH:\n                        *(unsigned char*)np = (unsigned char)len;\n                        break;\n                     case LENGTH_H:\n                        *(unsigned short*)np = (unsigned short)len;\n                        break;\n                     case LENGTH_L:\n                     default:\n                        *(unsigned int*)np = len;\n                        break;\n                  }\n                  break;\n               }\n               case 'C':\n                  break;\n               case 'S':\n                  break;\n               default:\n                  break;\n            }\n            state = STATE_NORMAL;\n            break;\n         }\n      }\n   }\n}\n\nint vdprintf(int fd, const char *format, va_list ap) {\n   struct _fd_printer fp;\n   fp.fd = fd;\n   fp.err = 0;\n   fp.count = 0;\n   printf_core(fd_printer, &fp, format, ap);\n   return fp.count;\n}\n\n#endif\n"
  },
  {
    "path": "corpus/cgc/cotton_swab_arithmetic/notes.txt",
    "content": "In the compiled cotton_swab_arithmetic.exe executable, the main function is at\noffset 0x1D30 (0x401D30 address).\n"
  },
  {
    "path": "corpus/cgc/cotton_swab_arithmetic/src/cgc_service.h",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n\n#ifndef SERVICE_H\n#define SERVICE_H\n\n#include \"libcgc.h\"\n#include \"cgc_libc.h\"\n\n#define SCRATCH_SZ 2048\n#define BYTECODE_SZ 2048\n\n#define FALSE 0\n#define TRUE 1\n\ntypedef struct instruction {\n\tuint8_t len;\n    uint8_t opcode;\n    uint32_t op1;\n    uint32_t op2;\n} inst_t;\n\nint cgc_bytecode_vrfy(uint8_t *bytecode, uint16_t len);\nint cgc_bytecode_exec(uint8_t *bytes, uint16_t len, uint8_t *scratch, uint32_t *out);\n\n// Bytecode is (single) register-based with memory accesses available.\n// Only a single register is used, which can be thought of as ACC (accumulator).\n// Solutions to arthmetic operands are stored in this register which can be \n// accessed with the appropriate opcodes.\n\n// All arithmetic operations are modulo 0xFFFFFFFF (no special handling for \n// over/underflows, etc).\n\n// Bytecode format:\n// <opcode><operand1><(optional)operand2>\n// 1B: opcode\n// 4B / 2B: offset1 / immediate1\n// 4B / 2B: (optional) offset2 / immediate2\n\n#define INST_OFF_SZ 4\n#define INST_IMM_SZ 2\n\n// NOTE1: even if one operand is ACC, both operands still consume space.  \n// The amount of space consumed is dictated by their immediate / offset status.  \n// The value of the extra operand is ignored.\n\n// NOTE2: This encoding scheme is not space-efficient.  It's designed to be \n// easy to grok.\n\n////\n// Masks\n////\n\n#define INST_MASK_DST 0x01\n// XXXX XX0X: store into ACC\n// XXXX XX1X: store into mem (offset in operand1)\n// NOTE: If we're storing into memory, we've consumed an operand for the memory \n// offset. We arbitrarily choose op1 to hold this offset.  This implies:\n// INST_MASK_ACC - because our arithmetic will involve ACC & op2.\n// INST_MASK_OP1 - because op1 will be interpreted as an offset.\n// If INST_MASK_DST is set and either INST_MASK_ACC or INST_MASK_OP1 is not, \n// the instruction is invalid.\n\n#define INST_MASK_ACC 0x02\n// XXXX XXX0: 2 operands\n// XXXX XXX1: ACC & operand2\n\n#define INST_MASK_OP1 0x04\n// XXXX X0XX: operand1 is immediate\n// XXXX X1XX: operand1 is offset (memory)\n// NOTE: this flag along with op1 value is ignored if INST_MASK_ACC is set.\n\n#define INST_MASK_OP2 0x08\n// XXXX 0XXX: operand2 is immediate\n// XXXX 1XXX: operand2 is offset (memory)\n\n#define INST_MASK_OPCODE 0xF0\n// YYYY XXXX: YYYY is opcode\n\n////\n// Opcodes\n////\n#define OPCODE_ADD 0x00 // 0000: ADD\n#define OPCODE_SUB 0x10 // 0001: SUB\n#define OPCODE_MUL 0x20 // 0010: MUL\n#define OPCODE_DIV 0x30 // 0011: DIV\n#define OPCODE_OUT 0xF0 // 1111: OUT (OUTPUT <- ACC)\n\n#define OUT_DEFAULT 0xDEADBEEF // some probably-incorrect value\n\n#endif\n"
  },
  {
    "path": "corpus/cgc/cotton_swab_arithmetic/src/service.c",
    "content": "/*\n * Copyright (C) Narf Industries <info@narfindustries.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n\n#include \"cgc_service.h\"\n\n// Decode instruction.  \n// Do not access beyond bytecode+len.  \n//      Assumes at least 1 byte is available.\n// If an instruction is INVALID, return non-SUCCESS.  \n//      INVALID inst contents are undefined.\n// IN: pointer to bytes, len (number of bytes left to safely consume)\n// OUT: populated inst struct\n// RET: status\nint cgc_inst_decode(uint8_t *bytes, uint16_t len, inst_t *inst) {\n\n    int ret = SUCCESS;\n    uint32_t cursor = 0;\n    inst->opcode = bytes[cursor];\n    \n    // Determine how long the instruction is.\n    // For each offset, add 2B, for each immediate, add 4B.\n    uint8_t inst_len = 1;\n    if (inst->opcode & INST_MASK_OP1) { inst_len += INST_OFF_SZ; } else { inst_len += INST_IMM_SZ; }\n    if (inst->opcode & INST_MASK_OP2) { inst_len += INST_OFF_SZ; } else { inst_len += INST_IMM_SZ; }\n\n    // If we would cgc_read off the end of the bytecode, bail.\n    if (inst_len > len) {\n#ifdef DEBUG\n        fprintf(stderr, \n            \"[D] decode() | insufficient bytes provided; \"\n            \"required: 0x%02x (%d), available: 0x%02x (%d)\\n\", \n            inst_len, inst_len, len, len);\n#endif\n        ret = ERRNO_INSUFFICIENT_BYTES;\n        goto bail;\n    }\n\n    // We have sufficient space; decode the instruction.\n    inst->len = inst_len;\n    if (inst->opcode & INST_MASK_OP1) { \n        inst->op1 = bytes[cursor+1] << 24 |\n                    bytes[cursor+2] << 16 |\n                    bytes[cursor+3] << 8|\n                    bytes[cursor+4] << 0;  \n#ifdef DEBUG\n        fprintf(stderr, \n            \"[D] decode() | op1 (off) | bytes[cursor+1:cursor+4] = 0x%02x 0x%02x 0x%02x 0x%02x\\n\", \n            bytes[cursor+1], bytes[cursor+2], bytes[cursor+3], bytes[cursor+4]);\n#endif  \n        cursor += 4;  \n    } else { \n        inst->op1 = bytes[cursor+1] << 8 |\n                    bytes[cursor+2] << 0;\n#ifdef DEBUG\n        fprintf(stderr, \n            \"[D] decode() | op1 (imm) | bytes[cursor+1:cursor+2] = 0x%02x 0x%02x\\n\", \n            bytes[cursor+1], bytes[cursor+2]);\n#endif\n        cursor += 2;\n    }\n\n    if (inst->opcode & INST_MASK_OP2) { \n        inst->op2 = bytes[cursor+1] << 24 |\n                    bytes[cursor+2] << 16 |\n                    bytes[cursor+3] << 8|\n                    bytes[cursor+4] << 0;\n#ifdef DEBUG\n        fprintf(stderr, \n            \"[D] decode() | op2 (off) | bytes[cursor+1:cursor+4] = 0x%02x 0x%02x 0x%02x 0x%02x\\n\", \n            bytes[cursor+1], bytes[cursor+2], bytes[cursor+3], bytes[cursor+4]);\n#endif\n    } else { \n        inst->op2 = bytes[cursor+1] << 8 |\n                    bytes[cursor+2] << 0;\n#ifdef DEBUG\n        fprintf(stderr, \n            \"[D] decode() | op2 (imm) | bytes[cursor+1:cursor+2] = 0x%02x 0x%02x\\n\", \n            bytes[cursor+1], bytes[cursor+2]);\n#endif\n    }\n\n#ifdef DEBUG\n    fprintf(stderr, \n        \"[D] decode() | successfully decoded instruction:\\n\"\n        \"    inst->len = %d\\n\"\n        \"    inst->opcode = 0x%02x\\n\"\n        \"    inst->op1 = 0x%08x\\n\"\n        \"    inst->op2 = 0x%08x\\n\",\n        inst->len, inst->opcode, inst->op1, inst->op2);\n#endif\n\nbail:\n    return ret;\n}\n\n\nint cgc_bytecode_vrfy(uint8_t *bytes, uint16_t len) {\n\n    int ret = SUCCESS;\n\n#ifdef DEBUG\n    fprintf(stderr, \"[D] bytecode_vrfy() | init\\n\");\n    uint32_t inst_count = 0;\n#endif\n\n    uint8_t *cursor = bytes;\n    inst_t inst;\n    uint8_t *dst = NULL;\n\n    // Loop over the opcodes, verify offset within each one.\n    while (len) {\n\n#ifdef DEBUG\n        fprintf(stderr, \n            \"\\n[D] bytecode_vrfy() | instruction #%d\\n\", inst_count);\n#endif\n\n        if (SUCCESS != (ret = cgc_inst_decode(cursor, len, &inst))) {\n#ifdef DEBUG\n            fprintf(stderr, \n                \"[D] bytecode_vrfy() | non-SUCCESS from inst_decode' bailing...\\n\");\n#endif\n            ret = ERRNO_INST_DECODE;\n            goto bail;\n        }\n\n        // Verify offsets fall within allowed bounds.\n#ifdef PATCHED\n        if (inst.opcode & INST_MASK_OP1 && (SCRATCH_SZ - sizeof(uint32_t) < inst.op1)) {\n#else\n        if (inst.opcode & INST_MASK_OP1 && (SCRATCH_SZ + BYTECODE_SZ - sizeof(uint32_t) < inst.op1)) {\n#endif\n            ret = ERRNO_VFRY_REJECT_OFF;\n            goto bail;\n        }\n\n#ifdef PATCHED\n        if (inst.opcode & INST_MASK_OP2 && (SCRATCH_SZ - sizeof(uint32_t) < inst.op2)) {\n#else\n        if (inst.opcode & INST_MASK_OP2 && (SCRATCH_SZ + BYTECODE_SZ - sizeof(uint32_t) < inst.op2)) {\n#endif \n            ret = ERRNO_VFRY_REJECT_OFF;\n            goto bail;\n        }\n\n        // These *shouldn't* under/overflow due to (inst_len > len) check in inst_decode().\n        cursor += inst.len;\n        len -= inst.len;\n\n#ifdef DEBUG\n        fprintf(stderr, \"[D] bytecode_vrfy() | len = %d\\n\", len);\n        inst_count++;\n#endif\n    }\n\nbail:\n#ifdef DEBUG\n    if (ERRNO_VFRY_REJECT_OFF == ret) {\n        fprintf(stderr, \n            \"[D] bytecode_vrfy() | REJECT due to offset check\\n\");\n    }\n#endif\n\n    return ret;\n}\n\n\n// We've verified the bytecode for safety, now we execute it.\nint cgc_bytecode_exec(uint8_t *bytes, uint16_t len, uint8_t *scratch, uint32_t *out) {\n\n    int ret = SUCCESS;\n\n#ifdef DEBUG\n    fprintf(stderr, \"[D] bytecode_exec() | init\\n\");\n    uint32_t inst_count = 0;\n#endif\n\n    inst_t inst;\n    uint8_t *cursor = bytes;\n    uint32_t acc = 0;\n    uint32_t op1 = 0;\n    uint32_t op2 = 0;\n    uint32_t *dst = NULL;\n\n    while (len) {\n\n#ifdef DEBUG\n        fprintf(stderr, \n            \"\\n[D] bytecode_exec() | instruction #%d\\n\", inst_count);\n#endif\n\n        if (SUCCESS != (ret = cgc_inst_decode(cursor, len, &inst))) {\n#ifdef DEBUG\n            fprintf(stderr, \n                \"[D] bytecode_exec() | non-SUCCESS from inst_decode; bailing...\\n\");\n#endif\n            ret = ERRNO_INST_DECODE;\n            goto bail;\n        }\n\n        ////\n        // Error Tree\n        ////\n        // INST_MASK_DST\n        //  +- INST_MASK_ACC\n        //      +- INST_MASK_OP1\n        //      +- !INST_MASK_OP1: ERROR\n        //  +- !INST_MASK_ACC: ERROR\n\n        ////\n        // Get dst.\n        ////\n        if (inst.opcode & INST_MASK_DST) {\n            dst = (uint32_t *)(scratch + inst.op1);\n        } else {\n            dst = &acc;\n        }\n\n        ////\n        // Get op1.\n        ////\n        if (inst.opcode & INST_MASK_DST && inst.opcode & INST_MASK_ACC) {\n            // The dst is a memory offset pointed to by op1 (meaning INST_MASK_OP1 must be set).\n            // The arith operands are ACC and op2.\n            if (!(inst.opcode & INST_MASK_OP1)) {\n#ifdef DEBUG\n                fprintf(stderr, \n                \"[D] bytecode_exec() | INVALID opcode: mem dst & immediate op1; bailing...\\n\");\n#endif       \n                ret = ERRNO_INVALID_OPCODE;\n                goto bail;\n            }\n            op1 = acc;\n\n        } else if (inst.opcode & INST_MASK_DST && !(inst.opcode & INST_MASK_ACC)) {\n            // The dst is a memory offset pointed to by op1.\n            // The arith operands are op1 and op2.\n            // This is ILLEGAL; op1 cannot specify both dst offset and operand.\n#ifdef DEBUG\n            fprintf(stderr, \n                \"[D] bytecode_exec() | INVALID opcode: mem dst & not ACC as op1; bailing...\\n\");\n#endif       \n            ret = ERRNO_INVALID_OPCODE;\n            goto bail;\n\n        } else if (!(inst.opcode & INST_MASK_DST) && inst.opcode & INST_MASK_ACC) {\n            // The dst is ACC.\n            // The arith operands are ACC and op2.\n            op1 = acc;\n\n        } else if (!(inst.opcode & INST_MASK_DST) && !(inst.opcode & INST_MASK_ACC)) {\n            // The dst is ACC.\n            // The arith operands are op1 and op2.\n            if (inst.opcode & INST_MASK_OP1) {\n                op1 =   scratch[inst.op1+0] << 0 |\n                        scratch[inst.op1+1] << 8 |\n                        scratch[inst.op1+2] << 16|\n                        scratch[inst.op1+3] << 24;\n#ifdef DEBUG\n                fprintf(stderr, \n                    \"[D] bytecode_exec() | scratch + inst.op1 = 0x%08x; op1 = *(scratch + inst.op1) = 0x%08x\\n\", \n                    scratch + inst.op1, op1);\n#endif  \n            } else {\n                // op1 is an immediate.\n                op1 = inst.op1;\n            }\n        }\n\n        ////\n        // Get op2.\n        ////\n        if (inst.opcode & INST_MASK_OP2) {\n            op2 =   scratch[inst.op2+0] << 0 |\n                    scratch[inst.op2+1] << 8 |\n                    scratch[inst.op2+2] << 16|\n                    scratch[inst.op2+3] << 24;\n#ifdef DEBUG\n            fprintf(stderr, \n                \"[D] bytecode_exec() | scratch + inst.op2 = 0x%08x; op2 = *(scratch + inst.op2) = 0x%08x\\n\", \n                scratch + inst.op2, op2);\n#endif  \n        } else {\n            op2 = inst.op2;\n        }\n\n        ////\n        // Do the operation.\n        ////\n        switch(inst.opcode & INST_MASK_OPCODE) {\n            case OPCODE_ADD: *dst = op1 + op2; break;\n            case OPCODE_SUB: *dst = op1 - op2; break;\n            case OPCODE_MUL: *dst = op1 * op2; break;\n            case OPCODE_DIV: \n                if (0 == op2) { op2 = 0xf000f000; }\n                *dst = op1 / op2; \n                break;\n            // NOTE: that OUT instructions ignore both op1 and op2.\n            case OPCODE_OUT: *out = acc; break;\n            default:\n#ifdef DEBUG\n                fprintf(stderr, \n                    \"[D] bytecode_exec() | INVALID opcode; bailing...\\n\");\n#endif  \n                ret = ERRNO_INVALID_OPCODE;\n                goto bail;\n                break;\n        }\n\n#ifdef DEBUG\n        fprintf(stderr, \n            \"[D] bytecode_exec() | dst = 0x%08x; *dst = 0x%08x\\n\", dst, *dst);\n#endif  \n\n        // These *shouldn't* under/overflow due to (inst_len > len) check in inst_decode().\n        cursor += inst.len;\n        len -= inst.len;\n\n#ifdef DEBUG\n        fprintf(stderr, \"[D] bytecode_exec() | #%04d: acc = 0x%08x\\n\", inst_count++, acc);\n        fprintf(stderr, \"[D] bytecode_exec() | len = %d\\n\", len);\n#endif\n    }\n    \nbail:\n    return ret;\n}\n\n\nint main(int cgc_argc, char *cgc_argv[]) {\n\n    int ret = SUCCESS;\n    cgc_size_t rx_bytes = 0;\n    cgc_size_t tx_bytes = 0;\n\n    // Allocate scratch + bytecode space.\n    // Per man, allocate()d memory is zero-filled.\n    uint8_t *space = NULL;\n    if (SUCCESS != (ret = cgc_allocate(SCRATCH_SZ + BYTECODE_SZ, FALSE, (void **)&space))) {\n#ifdef DEBUG\n        fprintf(stderr, \"[E] allocate()\\n\");\n#endif\n        return ret;\n    }\n#ifdef DEBUG\n        fprintf(stderr, \"[D] allocate() | space = 0x%08x\\n\", space);\n#endif\n\n    // Get length of bytecode (2B).\n    uint16_t bytecode_len = 0;\n    rx_bytes = 0;\n    if (SUCCESS != (ret = cgc_receive_all(STDIN, (void *)&bytecode_len, sizeof(bytecode_len), &rx_bytes))) { \n#ifdef DEBUG\n        fprintf(stderr, \"[E] during receive_all() of bytecode_len\\n\");\n#endif\n        ret = ERRNO_RECV;\n        goto bail;\n    }\n\n    // Verify bytecode_len.\n    // We bail instead of capping bytecode_len to avoid having to flush an \n    // unknown number of bytes from the receive buffer - a time-consuming \n    // process when traffic is fragmented.\n    if (BYTECODE_SZ - sizeof(uint32_t) < bytecode_len) {\n#ifdef DEBUG\n        fprintf(stderr, \"[D] BYTECODE_SZ < bytecode_len; bailing...\\n\");\n#endif\n        goto bail;\n    }\n\n    // Read in the bytecode itself.\n    rx_bytes = 0;\n    if (SUCCESS != (ret = cgc_receive_all(STDIN, (void *)(space+SCRATCH_SZ), bytecode_len, &rx_bytes))) { \n#ifdef DEBUG\n        fprintf(stderr, \"[E] during receive_all() of bytecode\\n\");\n#endif\n        ret = ERRNO_RECV;\n        goto bail;\n    }\n\n    // Verify bytecode.\n    if (SUCCESS != (ret = cgc_bytecode_vrfy(space+SCRATCH_SZ, bytecode_len))) { \n#ifdef DEBUG\n        fprintf(stderr, \"[D] bytecode_vrfy(): REJECT\\n\");\n#endif\n        goto bail;\n    }\n\n#ifdef DEBUG\n    fprintf(stderr, \"[D] bytecode_vrfy(): PASS\\n\");\n#endif\n\n    // Execute bytecode.\n    uint32_t out = OUT_DEFAULT;\n    if (SUCCESS != (ret = cgc_bytecode_exec(space+SCRATCH_SZ, bytecode_len, space, &out))) { \n#ifdef DEBUG\n        fprintf(stderr, \"[D] bytecode execution failed; bailing...\\n\");\n#endif\n        goto bail;\n    }\n\n    // Send answer back to CRS.\n    tx_bytes = 0;\n    if (SUCCESS != (ret = cgc_transmit_all(STDOUT, &out, sizeof(out), &tx_bytes))) { \n#ifdef DEBUG\n        fprintf(stderr, \"[E] transmit_all(answer)\\n\");\n#endif\n        ret = ERRNO_TRANSMIT;\n        goto bail;\n    }\n\nbail:\n    if (space) { cgc_deallocate(space, SCRATCH_SZ + BYTECODE_SZ); }\n    return ret;\n}\n\n"
  },
  {
    "path": "corpus/google/README.md",
    "content": "The fuzzing test corpus in this directory is taken from google's fuzzer test\nsuite, which can be found at https://github.com/google/fuzzer-test-suite.\n"
  },
  {
    "path": "corpus/google/vorbis/build.sh",
    "content": "#!/bin/bash\n# Copyright 2017 Google Inc. All Rights Reserved.\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n\nreadonly INSTALL_DIR=\"$PWD/INSTALL\"\n\nget_git_revision() {\n  GIT_REPO=\"$1\"\n  GIT_REVISION=\"$2\"\n  TO_DIR=\"$3\"\n  [ ! -e $TO_DIR ] && git clone $GIT_REPO $TO_DIR && (cd $TO_DIR && git reset --hard $GIT_REVISION)\n}\n\nbuild_ogg() {\n  rm -rf BUILD/ogg\n  mkdir -p BUILD/ogg $INSTALL_DIR\n  cp -r SRC/ogg/* BUILD/ogg/\n  (cd BUILD/ogg && ./autogen.sh && ./configure \\\n    --prefix=\"$INSTALL_DIR\" \\\n    --enable-static \\\n    --disable-shared \\\n    --disable-crc \\\n    && make clean && make -j $JOBS && make install)\n}\n\nbuild_vorbis() {\n  rm -rf BUILD/vorbis\n  mkdir -p BUILD/vorbis $INSTALL_DIR\n  cp -r SRC/vorbis/* BUILD/vorbis/\n  (cd BUILD/vorbis && ./autogen.sh && ./configure \\\n    --prefix=\"$INSTALL_DIR\" \\\n    --enable-static \\\n    --disable-shared \\\n    && make clean && make -j $JOBS && make install)\n}\n\nget_git_revision https://github.com/xiph/ogg.git \\\n  c8391c2b267a7faf9a09df66b1f7d324e9eb7766 SRC/ogg\nget_git_revision https://github.com/xiph/vorbis.git \\\n  c1c2831fc7306d5fbd7bc800324efd12b28d327f SRC/vorbis\n\nbuild_ogg\nbuild_vorbis\n\nif [[ $CXX == \"\" ]]; then\n  CXX=\"g++\"\nfi\n\n$CXX $CXXFLAGS decode_fuzzer.cc \\\n  -o decode_fuzzer.exe -L\"$INSTALL_DIR/lib\" -I\"$INSTALL_DIR/include\" \\\n  -lvorbisfile  -lvorbis -logg\n"
  },
  {
    "path": "corpus/google/vorbis/decode_fuzzer.cc",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <cstdint>\n#include <vorbis/vorbisfile.h>\n\nstruct vorbis_data {\n  const uint8_t *current;\n  const uint8_t *data;\n  size_t size;\n};\n\nsize_t read_func(void *ptr, size_t size1, size_t size2, void *datasource) {\n  vorbis_data* vd = (vorbis_data *)(datasource);\n  size_t len = size1 * size2;\n  if (vd->current + len > vd->data + vd->size) {\n      len = vd->data + vd->size - vd->current;\n  }\n  memcpy(ptr, vd->current, len);\n  vd->current += len;\n  return len;\n}\n\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {\n  ov_callbacks memory_callbacks = {0};\n  memory_callbacks.read_func = read_func;\n  vorbis_data data_st;\n  data_st.size = Size;\n  data_st.current = Data;\n  data_st.data = Data;\n  OggVorbis_File vf;\n  int result = ov_open_callbacks(&data_st, &vf, NULL, 0, memory_callbacks);\n  if (result < 0) {\n    return 0;\n  }\n  int current_section = 0;\n  int eof = 0;\n  char buf[4096];\n  int read_result;\n  while (!eof) {\n    read_result = ov_read(&vf, buf, sizeof(buf), 0, 2, 1, &current_section);\n    if (read_result != OV_HOLE && read_result <= 0) {\n      eof = 1;\n    }\n  }\n  ov_clear(&vf);\n  return 0;\n}\n\nint main(int argc, char ** argv)\n{\n  FILE * fp = 0;\n  char * filename;\n  uint8_t * data;\n  size_t size;\n  struct stat st;\n\n  if(argc < 2) {\n    printf(\"%s filename\\n\", argv[0]);\n    return 1;\n  }\n  filename = argv[1];\n\n  if(stat(filename, &st)) {\n    printf(\"Could not find file %s\\n\", filename);\n    return 1;\n  }\n\n  data = (uint8_t *)malloc(st.st_size);\n  if(!data) {\n    printf(\"Malloc failed\\n\");\n    return 1;\n  }\n\n  fp = fopen(filename, \"r\");\n  if(!fp) {\n    printf(\"Could not open file %s\\n\", filename);\n    return 1;\n  }\n  size = fread(data, 1, st.st_size, fp);\n  fclose(fp);\n\n  LLVMFuzzerTestOneInput(data, size);\n\n  free(data);\n  return 0;\n}\n\n"
  },
  {
    "path": "corpus/google/vorbis/decode_fuzzer.exe.stackdump",
    "content": "Exception: STATUS_ACCESS_VIOLATION at rip=001004283AA\nrax=4200000042000000 rbx=0000000000000000 rcx=000006FFFFCD0010\nrdx=0000000000002824 rsi=0000000000000004 rdi=00000000FFFFB040\nr8 =0000000000002824 r9 =0000000000002824 r10=0000000000000002\nr11=0000000000000000 r12=0000000000000008 r13=0000000600044F60\nr14=0000000600044A20 r15=0000000000000004\nrbp=00000000FFFFB0C0 rsp=00000000FFFFB020\nprogram=C:\\killerbeez\\src\\killerbeez\\corpus\\google\\vorbis\\decode_fuzzer.exe, pid 4380, thread main\ncs=0033 ds=002B es=002B fs=0053 gs=002B ss=002B\nStack trace:\nFrame        Function    Args\n000FFFFB0C0  001004283AA (000FFFFB250, 000FFFFB370, 00000000530, 00100414BB0)\n000FFFFB4D0  00100429A6D (000FFFFCA00, 000FFFFC730, 00000000000, 0060004105A)\n000FFFFC7D8  00100402618 (001800BAEA3, 000FFFFC750, 000FFFFCAE0, 000FFFFCAE0)\n000FFFFB608  00100402868 (00600043630, 00600000410, 000FFFFCC50, 00100000002)\n000FFFFB740  00100407637 (001800DDD4B, 006000003A0, 000FFFFC9D0, 00000000002)\n000FFFFB740  00100401322 (00000000F96, 00100000001, 001801C31D0, 0008E458768)\n000FFFFCC00  00100401494 (000FFFFCC50, 30001000000FF00, 00180047B51, 00180046B90)\n000FFFFCCB0  00180047BC2 (00000000000, 00000000000, 00000000000, 00000000000)\n00000000000  00180045863 (00000000000, 00000000000, 00000000000, 00000000000)\n000FFFFFFF0  00180045914 (00000000000, 00000000000, 00000000000, 00000000000)\nEnd of stack trace\n"
  },
  {
    "path": "corpus/google/vorbis/notes.txt",
    "content": "See https://github.com/google/fuzzer-test-suite/tree/master/vorbis-2017-12-11\nfor more information.\n\nFuzzing benchmark for Vorbis. Contains CVE-2018-5146 (pwn2own 2018), a buffer\noverflow. Reproducer provided (crash-e86e0482b8d66f924e50e62f5d7cc36a0acb03a7). \nA second buffer overflow is also present. Reproducer provided\n(crash-8c5dea6410b0fb0b21ff968a9966a0bd7956405f). This bug no longer reproduces\nafter the fix for CVE-2018-5146. Also contains a null-dereference. Reproducer\nprovided (crash-23c2d78e497bf4aebe5859e3092657cb0af4c299). This bug also no\nlonger reproduces after the fix for CVE-2018-5146.\n\nIn the included decode_fuzzer.exe, the main function is at offset 0x1363\n(0x401363 address).\n"
  },
  {
    "path": "corpus/hang/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (hang-linux)\n\nadd_executable(hang-linux ${PROJECT_SOURCE_DIR}/hang.c)\n"
  },
  {
    "path": "corpus/hang/hang.c",
    "content": "int main()\n{\n\twhile(1);\n}\n"
  },
  {
    "path": "corpus/libtest/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (libtest)\n\nadd_executable(libtest      ${PROJECT_SOURCE_DIR}/test.c)\nadd_executable(libtest_pie  ${PROJECT_SOURCE_DIR}/test.c)\nadd_library(test1 SHARED ${PROJECT_SOURCE_DIR}/lib1.c)\nadd_library(test2 SHARED ${PROJECT_SOURCE_DIR}/lib2.c)\n\nset_target_properties(libtest PROPERTIES LINK_FLAGS \"-no-pie\")\n\ntarget_link_libraries(libtest     test1 test2)\ntarget_link_libraries(libtest_pie test1 test2)\n"
  },
  {
    "path": "corpus/libtest/lib1.c",
    "content": "#include <stdio.h>\n\nint test_func1(char * buffer)\n{\n  char * nil = NULL;\n\n  if (buffer[0] == 'A')\n  {\n    if (buffer[1] == 'B')\n    {\n      if (buffer[2] == 'C')\n      {\n        if (buffer[3] == 'D')\n        {\n          *nil = 0;\n        }\n        else\n        {\n          puts(\"lib1 Wrong 3\");\n        }\n      }\n      else\n      {\n        puts(\"lib1 Wrong 2\");\n      }\n    }\n    else\n    {\n      puts(\"lib1 Wrong 1\");\n    }\n  }\n  else\n  {\n    puts(\"lib1 Wrong 0\");\n  }\n\n  return 0;\n}\n\n"
  },
  {
    "path": "corpus/libtest/lib2.c",
    "content": "#include <stdio.h>\n\nint test_func2(char * buffer)\n{\n  char * nil = NULL;\n\n  if (buffer[0] == 'E')\n  {\n    if (buffer[1] == 'F')\n    {\n      if (buffer[2] == 'G')\n      {\n        if (buffer[3] == 'H')\n        {\n          *nil = 0;\n        }\n        else\n        {\n          puts(\"lib2 Wrong 3\");\n        }\n      }\n      else\n      {\n        puts(\"lib2 Wrong 2\");\n      }\n    }\n    else\n    {\n      puts(\"lib2 Wrong 1\");\n    }\n  }\n  else\n  {\n    puts(\"lib2 Wrong 0\");\n  }\n\n  return 0;\n}\n\n"
  },
  {
    "path": "corpus/libtest/libs.h",
    "content": "#pragma once\nint test_func1(char * buffer);\nint test_func2(char * buffer);\n"
  },
  {
    "path": "corpus/libtest/test.c",
    "content": "#include \"libs.h\"\n#include <string.h>\n#include <unistd.h>\n\nint main()\n{\n  char buffer[4];\n  memset(buffer, 0, 4);\n  read(0, buffer, sizeof(buffer));\n\n  test_func1(buffer);\n  test_func2(buffer);\n  return 0;\n}\n"
  },
  {
    "path": "corpus/network/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (network-linux)\n\nadd_executable(server-linux ${PROJECT_SOURCE_DIR}/server/server.cpp)\nadd_executable(client-linux ${PROJECT_SOURCE_DIR}/client/client.cpp)\n"
  },
  {
    "path": "corpus/network/client/client.cpp",
    "content": "#ifdef _WIN32\n#define _WINSOCK_DEPRECATED_NO_WARNINGS\n#include <Winsock2.h>\n#include <Windows.h>\n#else\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <netinet/ip.h>\n#include <arpa/inet.h>\n#include <unistd.h>\n#include <errno.h>\n#include <string.h>\n#include <stdlib.h>\n\n#define INVALID_SOCKET -1\n#define SOCKET_ERROR -1\n#endif\n\n#include <stdio.h>\n\n// This program crashes if it receives ABCD on a socket from a server.\n// You can test it by doing: nc -l 4444, ./client.exe in another shell,\n// and typing the input you want to send in the nc window.\n\n// Note that VisualStudio will not overwrite the binaries already \n// included with Killerbeez. (corpus/network/{client,server}.exe)\n// It will instead put newly-compiled binaries in corpus/network/x64.\n\nvoid process_data(char * buffer)\n{\n\tchar * nil = NULL;\n\tif (buffer[0] == 'A')\n\t{\n\t\tif (buffer[1] == 'B')\n\t\t{\n\t\t\tif (buffer[2] == 'C')\n\t\t\t{\n\t\t\t\tif (buffer[3] == 'D')\n\t\t\t\t{\n\t\t\t\t\t*nil = 'E';\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tprintf(\"Wrong 3\\n\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tprintf(\"Wrong 2\\n\");\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tprintf(\"Wrong 1\\n\");\n\t\t}\n\t}\n\telse\n\t{\n\t\tprintf(\"Wrong 0\\n\");\n\t}\n}\n\n\nint main(int argc, char ** argv)\n{\n#ifdef _WIN32\n\tWSADATA wsaData;\n\tSOCKET sock = INVALID_SOCKET;\n#else\n\tint sock = INVALID_SOCKET;\n#endif\n\tstruct sockaddr_in addr;\n\tint result, port;\n\tchar buffer[512];\n\tconst char * ip;\n\n\tif (argc < 3) {\n\t\tprintf(\"Using 127.0.0.1:4444\\n\");\n\t\tip = \"127.0.0.1\";\n\t\tport = 4444;\n\t}\n\telse\n\t{\n\t\tip = argv[1];\n\t\tport = atoi(argv[2]);\n\t}\n\n#ifdef _WIN32\n\tif (WSAStartup(MAKEWORD(2, 2), &wsaData))\n\t{\n\t\tprintf(\"WSAStartup Failed\\n\");\n\t\treturn 1;\n\t}\n#endif\n\n\tsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\n\tif (sock == INVALID_SOCKET)\n\t\treturn -1;\n\n\taddr.sin_family = AF_INET;\n\taddr.sin_addr.s_addr = inet_addr(ip);\n\taddr.sin_port = htons(port);\n\tif (connect(sock, (sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR)\n\t\treturn -1;\n\tprintf(\"Connected.\\n\");\n\n\tresult = recv(sock, buffer, sizeof(buffer) - 1, 0);\n\tif (result > 0)\n\t\tprintf(\"Received: %s\", buffer);\n\n\tprocess_data(buffer);\n\n#ifdef _WIN32\n\t\t\tshutdown(sock, SD_BOTH);\n\t\t\tclosesocket(sock);\n#else\n\t\t\tshutdown(sock, SHUT_RDWR);\n\t\t\tclose(sock);\n#endif\n    return 0;\n}\n\n"
  },
  {
    "path": "corpus/network/client/client.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <VCProjectVersion>15.0</VCProjectVersion>\n    <ProjectGuid>{4B6243FA-0079-4FFC-9100-5CEA5D0F3698}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>client</RootNamespace>\n    <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v141</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v141</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v141</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v141</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LinkIncremental>true</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <LinkIncremental>false</LinkIncremental>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"client.cpp\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "corpus/network/client/client.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"client.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "corpus/network/close.txt",
    "content": "@BCD\n"
  },
  {
    "path": "corpus/network/multipart.txt",
    "content": "[\"::MEM::40424344\",\"::MEM::BBBBBBBB\"]\n"
  },
  {
    "path": "corpus/network/network.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.27428.2002\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"server\", \"server\\server.vcxproj\", \"{8D91B6E4-5A17-4C0A-A5B7-DF5ED80AC9E7}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"client\", \"client\\client.vcxproj\", \"{4B6243FA-0079-4FFC-9100-5CEA5D0F3698}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{8D91B6E4-5A17-4C0A-A5B7-DF5ED80AC9E7}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{8D91B6E4-5A17-4C0A-A5B7-DF5ED80AC9E7}.Debug|x64.Build.0 = Debug|x64\n\t\t{8D91B6E4-5A17-4C0A-A5B7-DF5ED80AC9E7}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{8D91B6E4-5A17-4C0A-A5B7-DF5ED80AC9E7}.Debug|x86.Build.0 = Debug|Win32\n\t\t{8D91B6E4-5A17-4C0A-A5B7-DF5ED80AC9E7}.Release|x64.ActiveCfg = Release|x64\n\t\t{8D91B6E4-5A17-4C0A-A5B7-DF5ED80AC9E7}.Release|x64.Build.0 = Release|x64\n\t\t{8D91B6E4-5A17-4C0A-A5B7-DF5ED80AC9E7}.Release|x86.ActiveCfg = Release|Win32\n\t\t{8D91B6E4-5A17-4C0A-A5B7-DF5ED80AC9E7}.Release|x86.Build.0 = Release|Win32\n\t\t{4B6243FA-0079-4FFC-9100-5CEA5D0F3698}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{4B6243FA-0079-4FFC-9100-5CEA5D0F3698}.Debug|x64.Build.0 = Debug|x64\n\t\t{4B6243FA-0079-4FFC-9100-5CEA5D0F3698}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{4B6243FA-0079-4FFC-9100-5CEA5D0F3698}.Debug|x86.Build.0 = Debug|Win32\n\t\t{4B6243FA-0079-4FFC-9100-5CEA5D0F3698}.Release|x64.ActiveCfg = Release|x64\n\t\t{4B6243FA-0079-4FFC-9100-5CEA5D0F3698}.Release|x64.Build.0 = Release|x64\n\t\t{4B6243FA-0079-4FFC-9100-5CEA5D0F3698}.Release|x86.ActiveCfg = Release|Win32\n\t\t{4B6243FA-0079-4FFC-9100-5CEA5D0F3698}.Release|x86.Build.0 = Release|Win32\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {6BAE5368-94FB-433E-8E4B-B681FD9D2E10}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "corpus/network/server/server.cpp",
    "content": "// linux: compile with gcc -o server-linux server.cpp\n// windows: compile w/ visual studio\n#ifdef _WIN32\n#define _WINSOCK_DEPRECATED_NO_WARNINGS\n#include <Winsock2.h>\n#include <Windows.h>\n#else\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <netinet/ip.h>\n#include <arpa/inet.h>\n#include <unistd.h>\n#include <errno.h>\n#include <string.h>\n#include <stdlib.h>\n\n#define INVALID_SOCKET -1\n#define SOCKET_ERROR -1\n#endif\n\n#include <stdio.h>\n\n#define PORT 4444\n\n// this program will listen on 127.0.0.1:4444 and crash if it receives the\n// input \"ABCD\".\n\n// Note that VisualStudio will not overwrite the binaries already \n// included with Killerbeez. (corpus/network/{client,server}.exe)\n// It will instead put newly-compiled binaries in corpus/network/x64.\n\nvoid process_data(char * buffer)\n{\n\tchar * nil = NULL;\n\tif (buffer[0] == 'A')\n\t{\n\t\tif (buffer[1] == 'B')\n\t\t{\n\t\t\tif (buffer[2] == 'C')\n\t\t\t{\n\t\t\t\tif (buffer[3] == 'D')\n\t\t\t\t{\n\t\t\t\t\t*nil = 'E';\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tprintf(\"Wrong 3\\n\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tprintf(\"Wrong 2\\n\");\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tprintf(\"Wrong 1\\n\");\n\t\t}\n\t}\n\telse\n\t{\n\t\tprintf(\"Wrong 0\\n\");\n\t}\n}\n\n#ifdef _WIN32\nint tcp_listen(SOCKET * sock)\n#else\nint tcp_listen(int * sock)\n#endif\n{\n\tstruct sockaddr_in addr;\n\n\t*sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\n\tif (*sock == INVALID_SOCKET)\n\t\treturn -1;\n#ifndef _WIN32 // linux-only\n\t// https://stackoverflow.com/a/24194999\n\tint enable = 1;\n\tif (setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)\n\t{\n\t\tprintf(\"setsockopt failed.\\n\");\n\t\treturn -1;\n\t}\n#endif\n\n\taddr.sin_family = AF_INET;\n\taddr.sin_addr.s_addr = inet_addr(\"127.0.0.1\");\n\taddr.sin_port = htons(PORT);\n\tif (bind(*sock, (const sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) {\n#ifdef _WIN32\n\t\tprintf(\"bind failed with error: %d\\n\", WSAGetLastError());\n\t\tclosesocket(*sock);\n#else\n\t\tprintf(\"bind failed with error: %d\\n\", errno);\n\t\tclose(*sock);\n#endif\n\t\treturn 1;\n\t}\n\n\tif (listen(*sock, SOMAXCONN) == SOCKET_ERROR) {\n#ifdef _WIN32\n\t\tprintf(\"listen failed with error: %d\\n\", WSAGetLastError());\n\t\tclosesocket(*sock);\n#else\n\t\tprintf(\"listen failed with error: %d\\n\", errno);\n\t\tclose(*sock);\n#endif\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n#ifdef _WIN32\nint udp_listen(SOCKET * sock)\n#else\nint udp_listen(int * sock)\n#endif\n{\n\tstruct sockaddr_in addr;\n\n\t*sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);\n\tif (*sock == INVALID_SOCKET)\n\t\treturn -1;\n\n#ifndef _WIN32 // linux-only\n\t// https://stackoverflow.com/a/24194999\n\tint enable = 1;\n\tif (setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)\n\t{\n\t\tprintf(\"setsockopt failed.\\n\");\n\t\treturn -1;\n\t}\n#endif\n\n\taddr.sin_family = AF_INET;\n\taddr.sin_addr.s_addr = inet_addr(\"127.0.0.1\");\n\taddr.sin_port = htons(PORT);\n\tif (bind(*sock, (const sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) {\n#ifdef _WIN32\n\t\tprintf(\"bind failed with error: %d\\n\", WSAGetLastError());\n\t\tclosesocket(*sock);\n#else\n\t\tprintf(\"bind failed with error: %d\\n\", errno);\n\t\tclose(*sock);\n#endif\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\nint main(int argc, char ** argv)\n{\n#ifdef _WIN32\n\tWSADATA wsaData;\n#endif\n\tint i, done, forever = 0, udp = 0, num_skipped_inputs = 0;\n#ifdef _WIN32\n\tSOCKET server = INVALID_SOCKET, client = INVALID_SOCKET;\n#else\n\tint server = INVALID_SOCKET, client = INVALID_SOCKET;\n#endif\n\tchar buffer[4096];\n\tstruct sockaddr_in addr;\n\tint addrlen = sizeof(addr);\n\t\n\tif (argc > 1 && !strcmp(\"-loop\", argv[1]))\n\t\tforever = 1;\n\tif (argc > 2)\n\t\tnum_skipped_inputs = atoi(argv[2]);\n\tif (argc > 2)\n\t\tudp = strcmp(\"-udp\", argv[3]) == 0;\n\n#ifdef _WIN32\n\tif (WSAStartup(MAKEWORD(2, 2), &wsaData))\n\t{\n\t\tprintf(\"WSAStartup Failed\\n\");\n\t\treturn 1;\n\t}\n#endif\n\n\tif ((!udp && tcp_listen(&server)) || (udp && udp_listen(&server)))\n\t\treturn 1;\n\n\tdone = 0;\n\twhile (!done || forever) {\n\t\tdone = 1;\n\n\t\tif (udp) {\n\t\t\tfor (i = 0; i < num_skipped_inputs; i++)\n#ifdef _WIN32\n\t\t\t\trecvfrom(server, buffer, sizeof(buffer), 0, (sockaddr *)&addr, &addrlen);\n#else\n\t\t\t\trecvfrom(server, buffer, sizeof(buffer), 0, (sockaddr *)&addr, (socklen_t *)&addrlen);\n#endif\n\n#ifdef _WIN32\n\t\t\tif (recvfrom(server, buffer, sizeof(buffer), 0, (sockaddr *)&addr, &addrlen) != SOCKET_ERROR)\n#else\n\t\t\tif (recvfrom(server, buffer, sizeof(buffer), 0, (sockaddr *)&addr, (socklen_t *)&addrlen) != SOCKET_ERROR)\n#endif\n\t\t\t\tprocess_data(buffer);\n\n\t\t} else {\n\t\t\tclient = accept(server, NULL, NULL);\n\t\t\tif (client == INVALID_SOCKET) {\n#ifdef _WIN32\n\t\t\t\tprintf(\"accept failed with error: %d\\n\", WSAGetLastError());\n\t\t\t\tclosesocket(server);\n#else\n\t\t\t\tprintf(\"accept failed with error: %d\\n\", errno);\n\t\t\t\tclose(server);\n#endif\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tfor (i = 0; i < num_skipped_inputs; i++)\n\t\t\t\trecv(client, buffer, sizeof(buffer), 0);\n\n\t\t\tif (recv(client, buffer, sizeof(buffer), 0) > 0)\n\t\t\t\tprocess_data(buffer);\n#ifdef _WIN32\n\t\t\tshutdown(client, SD_BOTH);\n\t\t\tclosesocket(client);\n#else\n\t\t\tshutdown(client, SHUT_RDWR);\n\t\t\tclose(client);\n#endif\n\t\t}\n\t}\n\n#ifdef _WIN32\n\t\t\tclosesocket(server);\n#else\n\t\t\tclose(server);\n#endif\n    return 0;\n}\n\n"
  },
  {
    "path": "corpus/network/server/server.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <VCProjectVersion>15.0</VCProjectVersion>\n    <ProjectGuid>{8D91B6E4-5A17-4C0A-A5B7-DF5ED80AC9E7}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>server</RootNamespace>\n    <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v141</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v141</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v141</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v141</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LinkIncremental>true</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <LinkIncremental>false</LinkIncremental>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"server.cpp\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "corpus/network/server/server.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"server.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "corpus/persist/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (persist)\n\nset(PERSIST_SRC ${PROJECT_SOURCE_DIR}/test.c)\n\nadd_executable(nopersist       ${PERSIST_SRC})\nadd_executable(persist         ${PERSIST_SRC})\nadd_executable(persist_hang    ${PERSIST_SRC})\nadd_executable(deferred        ${PERSIST_SRC})\nadd_executable(deferred_nohook ${PERSIST_SRC})\n\ntarget_compile_definitions(persist         PUBLIC PERSIST)\ntarget_compile_definitions(persist_hang    PUBLIC PERSIST PUBLIC HANG)\ntarget_compile_definitions(deferred        PUBLIC SLOW_STARTUP)\ntarget_compile_definitions(deferred_nohook PUBLIC SLOW_STARTUP PUBLIC DEFERRED_NOHOOK)\n\ntarget_link_libraries(persist         forkserver)\ntarget_link_libraries(persist_hang    forkserver)\ntarget_link_libraries(deferred        forkserver)\ntarget_link_libraries(deferred_nohook forkserver)\n\ninclude_directories(${PROJECT_SOURCE_DIR}/../../instrumentation/)\n"
  },
  {
    "path": "corpus/persist/test.c",
    "content": "#include <string.h>\n#include <stdio.h>\n#include <unistd.h>\n\n#if defined(PERSIST) || defined(DEFERRED_NOHOOK)\n#include <forkserver.h>\n#endif\n\nint test_func()\n{\n  char buffer[4];\n  char * nil = NULL;\n  FILE * fp = stdin;\n  memset(buffer, 0, 4);\n  read(0, buffer, sizeof(buffer));\n\n  if (buffer[0] == 'A')\n  {\n    if (buffer[1] == 'B')\n    {\n      if (buffer[2] == 'C')\n      {\n        if (buffer[3] == 'D')\n        {\n          *nil = 'E';\n        }\n        else\n        {\n          puts(\"Wrong 3\");\n        }\n      }\n      else\n      {\n        puts(\"Wrong 2\");\n      }\n    }\n    else\n    {\n      puts(\"Wrong 1\");\n    }\n  }\n  else\n  {\n    puts(\"Wrong 0\");\n  }\n\n  return 0;\n}\n\n\nint main()\n{\n#ifdef SLOW_STARTUP\n  sleep(5);\n#endif\n\n#ifdef DEFERRED_NOHOOK\n  KILLERBEEZ_INIT();\n#endif\n\n#ifdef PERSIST\n  while(KILLERBEEZ_LOOP()) {\n#endif\n\n#ifdef HANG\n    while(1);\n#endif\n\n    test_func();\n#ifdef PERSIST\n  }\n#endif\n\n  return 0;\n}\n"
  },
  {
    "path": "corpus/test/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (test-linux)\n\nadd_executable(test-linux ${PROJECT_SOURCE_DIR}/test.c)\n"
  },
  {
    "path": "corpus/test/inputs/close.txt",
    "content": "@BCD"
  },
  {
    "path": "corpus/test/inputs/crash.txt",
    "content": "ABCD"
  },
  {
    "path": "corpus/test/inputs/input.txt",
    "content": "AAAA"
  },
  {
    "path": "corpus/test/inputs/multipart.txt",
    "content": "[\"::MEM::41414141414141414141414141414141\",\"::MEM::42424242424242424242424242424242\"]"
  },
  {
    "path": "corpus/test/inputs/telnet_multipart.txt",
    "content": "[\"::MEM::fffb01fffb01fffb01\",\"::MEM::fffb03fffd18fffd1f\",\"::MEM::68656c6c6f20776f726c640a0d\"]"
  },
  {
    "path": "corpus/test/notes.txt",
    "content": "test.c is just a very simple testcase to make sure our instrumentation is\nworking as expected.  It looks at the first 4 characters of input, and takes a\ndifferent one for each character matching \"ABCD\".  If the full string matches\nABCD, then the test program will crash (by writing to NULL).\n\nIn the compiled test.exe executable, the main function is at offset 0x1000\n(0x401000 address).\n"
  },
  {
    "path": "corpus/test/test.c",
    "content": "#include <string.h>\n#include <stdio.h>\n\nint main(int argc, char ** argv)\n{\n\tchar buffer[4];\n\tchar * nil = NULL;\n\tFILE * fp = stdin;\n\n\tif (argc > 1)\n\t{\n\t\tfp = fopen(argv[1], \"rb+\");\n\t\tif (!fp)\n\t\t{\n\t\t\tputs(\"Couldn't open file\\n\");\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\tmemset(buffer, 0, 4);\n\tfread(buffer, 1, 4, fp);\n\tfclose(fp);\n\n\tif (buffer[0] == 'A')\n\t{\n\t\tif (buffer[1] == 'B')\n\t\t{\n\t\t\tif (buffer[2] == 'C')\n\t\t\t{\n\t\t\t\tif (buffer[3] == 'D')\n\t\t\t\t{\n\t\t\t\t\t*nil = 'E';\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tputs(\"Wrong 3\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tputs(\"Wrong 2\");\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tputs(\"Wrong 1\");\n\t\t}\n\t}\n\telse\n\t{\n\t\tputs(\"Wrong 0\");\n\t}\n\n\t//puts(\"Sleeping now\");\n\t//Sleep(1000 * 100);\n\t//while (1) {}\n\n    return 0;\n}\n"
  },
  {
    "path": "docs/AFL.md",
    "content": "# AFL based Instrumentation\n\nThe AFL instrumentation module provides coverage information for the target\nprogram. The AFL instrumentation module utilizes the GCC, LLVM, or QEMU based\ninstrumentation in order to obtain an AFL-style bitmap of the program\ncoverage. The AFL instrumentation is only available on Linux; for WinAFL based\ninstrumentation see the [DynamoRIO documentation](docs/DynamoRIO.md). This\ndocument describes the AFL instrumentation module, how to use it, and the\nchanges that were made from the original\n[AFL implementation](http://lcamtuf.coredump.cx/afl/).\n\n# Background\n\n[AFL](http://lcamtuf.coredump.cx/afl/) is a state-of-the-art fuzzer that can\nemploy several different types of program instrumentation in order to increase\nthe efficiency of the fuzzer by utilizing coverage information. As one of the\nmost popular fuzzers available a large number of developers have contributed\nenhancements and additional features. As such, Killerbeez hopes to build off of\nthese contributions by reusing the instrumentation methods available in AFL. AFL\nsupports instrumentation of source code through the [GCC](https://gcc.gnu.org/)\nand [LLVM](https://llvm.org/) based instrumentation, as well as the binary\ninstrumentation through the use of a modified version of\n[QEMU](https://www.qemu.org/).\n\n# Killerbeez Implementation Differences\n\n### Fork Server Differences\n\nIn order to standardize the fork server protocol between the AFL instrumentation\nand the [IPT instrumentation](docs/IPT.md), the AFL instrumentation has been\nslightly modified. The fork server protocol in Killerbeez is based on 1-byte\ncommands being sent to the fork server and 4-byte responses returning. Five\ncommands are supported:\n1. `EXIT` - kill any child processes and exit\n2. `FORK` - fork a new child, but wait to run the new target executable\n3. `RUN`  - Tell the newly forked child to run target executable\n4. `FORK_RUN` - fork a new child and run the target executable immediately\n5. `GET_STATUS` - Return the status (from `waitpid`) of the last child\nThe GCC, LLVM, and QEMU instrumentation only implements `EXIT`, `FORK_RUN`, and\n`GET_STATUS`, whereas the `LD_PRELOAD` library based fork server used in the\nIPT instrumentation implements all 5 commands.\n\n### QEMU Instrumentation Differences\n\nThe QEMU instrumentation included in Killerbeez has been patched with a number\nof third party patches which fix bugs or add enhancements to it. These patches\nare available in\n[vanhauser-thc's github repo](https://github.com/vanhauser-thc/afl-patches/).\nThe following patches have been included:\n* `afl-qemu-speed.diff` - Updates QEMU to allow caching, ~3 times speed\nimprovement. See [abiondo's AFL repo](https://github.com/abiondo/afl) or this\n[post](https://abiondo.me/2018/09/21/improving-afl-qemu-mode/) describing the\nwork for more details.\n* `afl-qemu-ppc64.diff` - Updates the AFL QEMU instrumentation to work with\nPowerPC\n* `afl_qemu_optimize_map.diff` - Optimizes the AFL log function in the QEMU\ninstrumentation.\n* `afl_qemu_optimize_entrypoint.diff` - Fixes entrypoint detection in QEMU\ninstrumentation on ARM.\n\n# GCC Instrumentation\n\nAs Killerbeez's GCC instrumentation is based off of AFL's GCC instrumentation,\nthe process for instrumenting a target is very similar. As such,\n[the original README](https://github.com/mirrorer/afl/blob/master/docs/README#L84)'s\ninstructions for instrumenting a target may provide helpful information.\n\nFirst, the `afl-gcc` compiler tool needs to be compiled. This tool can be built\nby running the following commands:\n```\n$ cd afl_progs/\n$ make\n```\nThe resulting `afl-gcc` and `afl-g++` tools can then be used in place of the\nregular gcc/g++ compilers to instrument any source code compiled. The correct\nway to compile the target program may vary depending on the specifics of the\nbuild process, but a nearly-universal approach would be:\n```\n$ CC=/path/to/killerbeez/afl_progs/afl-gcc ./configure\n$ make clean all\n```\nFor C++ programs, you'd would also want to set\n`CXX=/path/to/killerbeez/afl_progs/afl-g++`.\n\nOnce the target program has been instrumented, it can be fuzzed using the\n`fuzzer` program.\n```\n$ ./fuzzer stdin afl bit_flip -d '{\"path\":\"/path/to/test/program\"}' -n 10 -sf /path/to/seed/file\n```\n\n# LLVM Instrumentation\n\nAs Killerbeez's LLVM instrumentation is based off of AFL's LLVM instrumentation,\nthe process for instrumenting a target is very similar. As such,\n[the LLVM README](https://github.com/mirrorer/afl/blob/master/llvm_mode/README.llvm)'s\ninstructions for instrumenting a target may provide helpful information.\n\nFirst, the `afl-clang-fast` compiler tool needs to be compiled. This tool can\nbe built by running the following commands:\n```\n$ cd afl_progs/llvm_mode\n$ make\n```\nIf `make` cannot find a version of `llvm-config` in `PATH`, you may need to\nspecify the `LLVM_CONFIG` environment variable. The exact filename of\n`llvm-config` will vary based on your specific distribution. For Ubuntu 16.04.5\nLTS, the make command should be run as follows:\n```\n$ make LLVM_CONFIG=llvm-config-3.8\n```\n\nThe resulting `afl-clang-fast` and `afl-clang-fast++` tools can then be used in\nplace of the regular clang/clang++ compilers to instrument any source code\ncompiled. Thus, you can instrument the target in a way similar to the GCC\ninstrumentation, e.g.:\n```\n$ CC=/path/to/killerbeez/afl_progs/afl-clang-fast ./configure\n$ make clean all\n```\nFor C++ programs, you'd would also want to set\n`CXX=/path/to/killerbeez/afl_progs/afl-clang-fast++`.\n\nOnce the target program has been instrumented, it can be fuzzed using the\n`fuzzer` program.\n```\n$ ./fuzzer stdin afl bit_flip -d '{\"path\":\"/path/to/test/program\"}' -n 10 -sf /path/to/seed/file\n```\n\n### Persistence Mode\n\nThe LLVM based instrumentation supports persistence mode to further increase the\nspeed of fuzzing. Persistence mode involves executing multiple inputs without\nrestarting the target process. While this approach can be much quicker, it can\ncause instabilities in the target process if not setup properly. In order for\npersistence mode to work, the target must reset its state after each test case.\n\nIn LLVM based instrumentation, persistence mode is accomplished by modifying the\nsource code of the target to call the `__AFL_LOOP()` macro.  This macro is used\nto mark the start and stop of the target process testing a single input. An\nideal program for persistence mode is one that has very little global state, or\nthe state can easily be reset. The structure of a persistence mode program, is\nshown below, where the `__AFL_LOOP` macro is used to call the fork server. A\nmore complete example program and Makefile that can be used with LLVM\npersistence mode is available in the corpus/afl_test/ directory of this\nrepository.\n\n```\n  while(__AFL_LOOP()) {\n    // Read input data.\n    // Call library code to be fuzzed.\n    // Reset state.\n  }\n```\n\nOnce a program has been instrumented, persistence mode can be enabled by setting\nthe AFL instrumentation's `persistence_max_cnt` option. The\n`persistence_max_cnt` option defines how many inputs to test in a single process\nbefore restarting the target program. This value can be determined\nexperimentally, but a good starting value is 1000.  An example `fuzzer` command\nthat utilizes persistence mode is shown below:\n```\n$ ./fuzzer stdin afl afl -d '{\"path\":\"/path/to/test/program\"}' -n 5000 -sf /path/to/seed/file -i '{\"persistence_max_cnt\":1000}'\n```\n\n### Deferred Startup Mode\n\nThe AFL instrumentation fork server tries to optimize performance of the target\nprocess by executing the target binary until it reaches the `main` function, and\nthen forking all new processes from the copy stopped at `main`. This ensures all\nof the startup code that is executed prior to the `main` function is only ever\nrun once. However, if a target process has a large startup cost, fuzzing will\nstill be slow. In these cases, it is beneficial to use the fork server's\ndeferred startup mode, to wait until after the process has finished starting up\nto start the fork server.\n\nTo enable the deferred startup mode, find a suitable location in the code where\nthe delayed forking can take place.  Ideally, this location would be after any\nstartup work is performed but before the actual processing of an input begins.\nMore information on the process for determining this location is available in\nthe original AFL's [LLVM instrumentation README](https://github.com/mirrorer/afl/blob/master/llvm_mode/README.llvm#L82).\n\nOnce this location is selected, add the following code to indicate to the start\nthe fork server at this location:\n```\n  __AFL_INIT();\n```\nOnce this code is added, the target program can be compiled with\n`afl-clang-fast` and it can then be used with the `fuzzer`.  To enable the\ndeferred startup mode, the `deferred_startup` option should be passed to the AFL\ninstrumentation module's options. An example `fuzzer` command that utilizes\ndeferred startup mode is shown below:\n```\n$ ./fuzzer stdin afl afl -d '{\"path\":\"/path/to/test/program\"}' -n 5000 -sf /path/to/seed/file -i '{\"deferred_startup\":1}'\n```\n\n# QEMU Instrumentation\n\nIf source code is not available or the target cannot be successfully\ninstrumented via the GCC or LLVM instrumentation described above, AFL's QEMU\ninstrumentation may be the right approach.  AFL's QEMU instrumentation supports\nthe ability to perform on-the-fly instrumentation of black-box binaries through\nits user space emulation mode.  Additionally, this instrumentation can be used\nto fuzz binaries built for a different architecture than the host processor\n(i.e. fuzzing an ARM binary on an x86 computer).\n\nBefore the QEMU instrumentation can be used, the `afl-qemu-trace` binary must be\nbuilt.  The commands below will download the QEMU source code, update the code\nto include the instrumentation, and build the `afl-qemu-trace` binary.  For\nadditional instructions and caveats, see\n[README.qemu_mode](afl_progs/qemu_mode/README.qemu).\n```\n$ cd afl_progs/qemu_mode\n$ ./build_qemu_support.sh\n```\n\nOnce `afl-qemu-trace` is compiled, the target program can be fuzzed with the\n`fuzzer`. To enable the QEMU instrumentation, the `qemu_mode` option should be\npassed to the AFL instrumentation module's options. An example `fuzzer` command\nthat utilizes qemu mode is shown below:\n```\n$ ./fuzzer stdin afl bit_flip -d '{\"path\":\"/path/to/test/program\"}' -n 10 -sf /path/to/seed/file -i '{\"qemu_mode\":1}'\n```\nIf the AFL instrumentation cannot automatically detect the location of the\n`afl-qemu-trace` binary, you will need to specify the path to `afl-qemu-trace`\nwith the `qemu_path` option:\n```\n$ ./fuzzer stdin afl bit_flip -d '{\"path\":\"/path/to/test/program\"}' -n 10 -sf /path/to/seed/file -i '{\"qemu_mode\":1,\"qemu_path\":\"/path/to/afl-qemu-trace\"}'\n```\n"
  },
  {
    "path": "docs/BUILD.md",
    "content": "# Build Instructions\n\nThis document describes the process of compiling Killerbeez on Linux and\nWindows.\n\n## Windows\n\n### Prerequisites\n\nTo build Killerbeez on Windows you will need Microsoft Visual Studio 2017,\nCygwin, Radamsa, and DynamoRIO. Unless otherwise noted, all of the snippets\nbelow use cmd.exe.\n\n### Installation\n1. Install [Visual Studio 2017\nCommunity](https://www.visualstudio.com/downloads/). Version 15.5.7 has\nbeen tested to work with Killerbeez. Anything later should also work.\nEarlier versions which support cmake will likely work but have not been\ntested and may require slight changes to the build settings.\n  + The following workloads/components will be needed to build Killerbeez.\nThey can be added with the Visual Studio Installer.\n      1. Desktop development with C++\n      2. Linux development with C++\n      3. Visual C++ tools for CMake\n      4. Git for Windows\n\n2. Install [Cygwin](https://cygwin.com/install.html) (only required for\nthe radamsa mutator).\n  + Use `C:\\cygwin64` as the installation directory.\n  + Make sure the packages `gcc-core`, `make`, `git`, and `wget` are being\ninstalled.\n  + Add the Cygwin `bin/` (e.g. `C:\\cygwin64\\bin`) to your PATH environment\nvariable.\n\n3. Download the Killerbeez source code\n\n    ```\n    set WORKDIR=C:/\n    :: We'll use forward slashes (Windows doesn't care) to avoid escaping backslashes\n    cd %WORKDIR%\n    git clone https://github.com/grimm-co/killerbeez.git\n    ```\n\n4. Build [Radamsa](https://gitlab.com/akihe/radamsa) (optional).\n  + Clone the Radamsa repository into %WORKDIR% from a Cygwin terminal and\nbuild:\n\n        ```\n        cd /cydrive/c/killerbeez\n        git clone https://gitlab.com/akihe/radamsa.git\n        cd radamsa\n        make\n        ```\n\n5. Install [DynamoRIO](http://dynamorio.org/). Use the [latest build\navailable](https://console.cloud.google.com/storage/browser/chromium-dynamorio/builds).\nA direct link to the latest build as of 3/14/18 can be found\n[here](https://storage.googleapis.com/chromium-dynamorio/builds/DynamoRIO-Windows-6.2.17295-0xa77808f.zip).\n  + Download the zip file and extract it so that the main directory (the\none containing bin32/ and bin64/ directories) is `%WORKDIR%/killerbeez/dynamorio`\n  + *Note:* The reason we have to use the latest build is that [commit\nc575ad](https://github.com/DynamoRIO/dynamorio/commit/c575ad16f8943eb6946e8c875eb248d948390537)\nis needed to support binaries built with VS 2017 on Windows 10. This commit\nis not included in the 7.0.0-RC1 release.\n\n6. Build Killerbeez\n  + Open the repository `killerbeez` within Visual Studio (File -> Open ->\nCMake..) and build it using (CMake -> Build All).  This should build the\nfuzzer and its dependencies from the other repos.  If successful, you'll\nsee an aggregate `build/` directory in the root of your working directory.\nIn it, the compiled executables and libraries from all three projects will\nbe found in folders named after the architecture (e.g. x64) and build type\n(e.g. Debug).\n  + The fuzzer.exe executable can be found at\n`%WORKDIR%/killerbeez/build/x64/Debug/killerbeez/fuzzer.exe`\n\n## Linux and Mac\n\n### Prerequisites\n\nTo build Killerbeez on Linux/Mac you will need a compiler (gcc or clang), make,\nand cmake.  To build the AFL instrumentation with gcc, clang, and qemu, there\nare a few extra packages needed.  The dependency lists below will make sure\nyou can compile everything to get all the cool features.\n\nmacOS (brew)\n```\nbrew install autoconf automake libtool gcc cmake pkg-config\n```\n\nDebian 9 (stretch) / Ubuntu 18.04 (bionic) / Ubuntu 16.04 (xenial):\n```\nsudo apt install llvm clang libtool-bin build-essential cmake automake bison flex libglib2.0-dev libc6-dev-i386 libpixman-1-dev\n```\n\nUbuntu 14.04 (trusty)\n```\nsudo apt install llvm clang libtool build-essential cmake automake bison flex libglib2.0-dev libc6-dev-i386 git\n```\n\nFedora (tested on 29 and 30):\n```\nsudo dnf install llvm clang llvm-devel libtool libstdc++-static cmake bison flex glib2-devel glibc-devel.i686 zlib-devel\n```\n\nNotes:\nUbuntu 12.04 (precise) doesn't have a recent enough version of CMake (it\nhas 2.8.7, but 2.8.8 needed) in the repositories.  It should work if you compile\nCMake 2.8.8 or later yourself, but it is not a tested distribution.\n\nDebian 8 (jessie) fails to build/install due to what looks like a bug in\nCMake, though we did not take the time to figure out the specific error.\n\nDebian 10 (buster) and Ubuntu 18.04 both have versions of clang which do not\ncurrently work with the version of the llvm instrumentation from AFL.  This\nwill be fixed when we replace the standard AFL programs with the ones from\nAFL++.\n\nOn macOS (at least on 10.13.4 (High Sierra)), Apple has reportedly removed the\nability to load dylibs using relative paths.[1]  There are reports that SIP\nneeds to be disabled[2] to fix this, however setting DYLD_LIBRARY_PATH to\npoint to the location of the .dylib files (usually $REPOROOT/build/killerbeez)\nwas sufficient in our tests.  For now, just set this environment variable if\nthere are errors about RPATH or loading .dylibs.  In the long run, we'll be\ninvestigating what other projects have done[3] to work around this issue.\n\n[1] https://github.com/tensorflow/tensorflow/issues/6729#issuecomment-272583349\n[2] https://github.com/BVLC/caffe/issues/3227\n[3] https://github.com/alexgkendall/caffe-segnet/pull/68/commits/f282c0f784e95460d55e18d68933f2ef66bd3b47\n\n### Installation\n\nClone the killerbeez repo\n\n```\n# the --recursive is needed to check out submodules\ngit clone --recursive https://github.com/grimm-co/killerbeez.git\ncd killerbeez\n\n# Make a build directory and compile the code.\nmkdir build; cd build; cmake ..; make radamsa all\n# radamsa isn't in \"all\" by default because of Windows\n```\n\nIf everything compiled, the fuzzer and other Killerbeez\nfiles will be in `build/killerbeez`, and the mutators will be \nunder `build/mutators`.\n\n"
  },
  {
    "path": "docs/CI.md",
    "content": "# Setting Up GitLab CI Runners for Killerbeez\n\nWe use GitLab to develop Killerbeez internally; these are the instructions for\ncreating CI runners that test the build on a number of platforms.\n\n## Prerequisites\n\n* A GitLab server hosting Killerbeez\n* A CI server with the following installed:\n    * Vagrant\n    * VirtualBox\n\n## Instructions\n\n* Clone this repo onto your server\n* `cd vagrant/ci_runner`\n* `cp runner_vars.example runner_vars`\n* Edit `runner_vars` with the parameters of your Gitlab server:\n    * `CI_SERVER_URL` - HTTPS URL to the GitLab server\n    * `REGISTRATION TOKEN` - CI token generated by GitLab (get it from the\n      Settings > CI/CD > Runners page for the Killerbeez project)\n    * `CI_SERVER_TLS_CA_FILE` - If your GitLab server's certificate is signed\n      by a private CA, place the CA certificate in the `vagrant/ci_runner`\n      directory and set this variable. The certificate will be copied to\n      `/killerbeez` in the VM, so if your certificate is named\n      `ca.crt`, set `CI_SERVER_TLS_CA_FILE=/killerbeez/ca.crt`.\n    * Any other settings that gitlab-runner accepts as environment variables.\n      See `gitlab-runner register -h` for more options.\n* `vagrant up`\n\nThis will bring up the runners for a bunch of platforms. If you would like to\nbring up the runners one at a time, first run\n```\nvagrant status\n```\nto see the list of runners available, then run\n```\nvagrant up <vm_name>\n```\nto bring up the specified VM.\n\n## Technical Details\n\nThere are three kinds of runners created by the Vagrantfile:\n\n1. For OSes that are listed as supported by the [official Linux package\n   repositories](https://docs.gitlab.com/runner/install/linux-repository.html)\n   we start up a VM from a Vagrant Box of that OS and install the gitlab-runner\n   package. The runner uses the `shell` executor to run builds.\n2. For all other linux platforms, we prebuild a Docker image of the OS with\n   dependency packages installed. We run gitlab-runner in a docker container\n   and use the `docker` executor to run builds using the prebuilt OS image.\n3. Windows. For these we download the gitlab-runner binary directly and install\n   it as a service.\n\nIn all cases, the `.gitlab-ci.yml` specifies the OSes to build on using tags.\nThe Docker runners are configured with the prebuilt docker image as the default\nso that it does not have to be specified in the job configuration.\n"
  },
  {
    "path": "docs/DynamoRIO.md",
    "content": "# DynamoRIO Persistence Mode\n\nThe DynamoRIO instrumentation module provides coverage information for the\ntarget program.  This module is largely copied from\n[WinAFL](https://github.com/ivanfratric/winafl), and as such has many of the\nsame advantages and disadvantages.  The DynamoRIO instrumentation module\nutilizes persistence mode to greatly increase the speed of fuzzing.  This\ndocument describes how to use persistence mode with the DynamoRIO\ninstrumentation module.\n\n# Background\n\nPersistence mode involves executing multiple inputs without restarting the\nprocess.  While this approach is much quicker, it can cause instabilities in the\ntarget process.  In the DynamoRIO instrumentation module, persistence mode is\naccomplished by selecting a target function to wrap, and re-executing this\nfunction for each input.  The re-execution of this function is done by recording\nthe program counter, the stack address, and the function parameters, and then\nsimply setting the registers and arguments back to the original values when the\nfunction finishes.  As you can imagine, this can cause problems with larger\nprograms that rely on the program's global state.\n\nThe target function must be carefully selected to ensure that it rereads the\ninput to ensure that the new input is processed.  Further, the target function\nmust also finish in order to ensure that the fuzzer can quickly reset and run a\nnew input.\n\n# Options\n\nIn order to enable persistence mode, several options must be passed to the\nDynamoRIO instrumentation.\n\nArguments:\n\n* `-fuzz_iterations` - The number of fuzz inputs to send to a target before\nrestarting the target.  Default is 1 iteration (i.e. persistence mode is\ndisabled).\n* `-coverage_modules` - The modules (i.e. libraries or the main executable) that\nDynamoRIO should track for coverage information.\n* `-per_module_coverage` - Whether each of the tracked modules should be recorded\nindependently (when the option is set to 1) or whether the same coverage map\nshould be used for all modules (when set to 0).  The default option is to record\neach module in the same map.\n* `-client_params` - A string of options that should be passed to the DynamoRIO\nplugin. See the description of these arguments below.\n\nIn addition to the arguments passed to the instrumentation module, there are a\nnumber of options that can be passed to the DynamoRIO plugin that is executed in\nthe target process' address space.  These arguments are passed inside the\n`-client_params` argument.\n\n* `-target_module` - This option specifies which module the target function to\nwrap is in.\n* `-target_offset` - This option specifies the address of the target function to\nwrap.\n* `-target_method` - This option specifies the name of the target function to\nwrap.  In order for this option to be able to lookup the name, the function\nneeds to be exported or the symbols for the target module need to be available.\n* `-nargs` - The number of arguments that the target function takes.  This is used\nto save and restore the arguments between fuzz iterations.\n* `-call_convention` - The target function's calling convention.  The default\ncalling convention is cdecl on 32-bit x86 platforms and Microsoft x64 for\nVisual Studio 64-bit applications. Possible values: fastcall, ms64 for Microsoft\nx64 Visual Studio, stdcall for cdecl or stdcall, and thiscall.\n* `-no_thread_coverage` - With this option enabled, all threads of the target\nprogram will track coverage.  By default, only the thread that hits the target\nfunction will track coverage.\n* `-covtype` - the type of coverage being recorded. Supported options are bb for\nbasic block coverage or edge for edge coverage.  Edge coverage is the default.\n* `-write_log` - A debug option that writes a log file to the current directory\nwith debug information on the DynamoRIO plugin's status.\n\nIn order to run the fuzzer in DynamoRIO's persistence mode, the\n`-fuzz_iterations`, `-coverage_modules`, `-target_module`, and either the\n`-target_method` or `-target_offset` options all need to be setup with values\nspecific to the target being fuzzed.\n\n# Example\n\n```\nfuzzer.exe file dynamorio afl -n 100 -sf C:\\<path to repository>\\killerbeez\\corpus\\test\\inputs\\close.txt -d \"{\\\"path\\\":\\\"C:\\\\<path to repository>\\\\killerbeez\\\\corpus\\\\test\\\\test.exe\\\",\\\"timeout\\\":2,\\\"arguments\\\":\\\"@@\\\"}\" -i \"{\\\"timeout\\\": 3000,\\\"coverage_modules\\\":[\\\"test.exe\\\"], \\\"client_params\\\":\\\"-target_module test.exe -target_offset 0x1000\\\",\\\"fuzz_iterations\\\":50}\" -l \"{\\\"level\\\":0}\"\n```\n\nThis example fuzzes the include test.exe program for 100 iterations, feeding\ninput mutated by the AFL mutator.  The instrumentation arguments are specified\nso that the DynamoRIO instrumentation module will track coverage of the test.exe\nbinary.  The instrumentation will wrap the test's function at offset 0x1000,\nrestarting this function for each input.  It will run 50 iterations of this\nfunction, and then restart the program cleanly for the next iteration.  This\nspecific example will find a crash in the test program at iteration 7.\n\n"
  },
  {
    "path": "docs/IPT.md",
    "content": "# Intel Processor Trace Instrumentation\n\nThe Intel Processor Trace (IPT) instrumentation module provides coverage\ninformation for the target program. The IPT instrumentation module utilizes\nIntel Processor Trace to quickly obtain a set of hashes that represent the\nexecution trace of a program. For the moment, IPT instrumentation is only\navailable on Linux. This document describes the Intel PT instrumentation, how to\nuse it, and the design decisions that lead to its development.\n\n# Background\n\nBeginning with the 5th generation Intel Processors, Intel introduced Intel\nProcessor Trace to provide an efficient way to trace the execution of a\nprocessor. In order to reduce the overhead and increase the speed of tracing,\nIPT records as little information is possible, while still allowing for an exact\ntrace of execution to be obtained.\n\nIPT works by recording packets which detail the execution trace in memory. IPT\ncan be configured to limit packet generation based on the address of the\ninstruction pointer. This allows tracing of specific executables without\ngenerating unnecessary trace information for any libraries used. Each IPT packet\ncontains a different type of information relating to the execution trace,\nhowever the only two packets that Killerbeez uses are:\n\n* TNT packets - which contain the results of conditional branches (i.e. jnz, jz,\nja, etc). These packets contain a set of bits which correspond to whether the\nlast several branches were Taken (T) or Not Taken (NT). Depending on the\nprocessor, IPT may send TNT packets in either the short (maximum 6 TNT bits) or\nlong (maximum 47 TNT bits) form.\n\n* TIP packets - which contain the results of indirect calls/jumps (i.e. call\nrax) and if enabled, the saved instruction pointer of ret instructions.\n\nWith a recording of these two packets for an execution trace, software can\nutilize a disassembler to obtain the exact control flow of an execution. More\ninformation on IPT is available in Chapter 35 of the Intel Architecture\nSoftware Developer's manual.\n\n# Intel PT and Fuzzing\n\nWhile great in theory, IPT is not perfect for fuzzing. It is a step\nforward and can be useful, but there are a few issues that must be accommodated.\n\nIn an ideal implementation, IPT would provide a set of basic block transitions,\nsuch as those obtained in the AFL fuzzer or Killerbeez's DynamoRIO\ninstrumentation. However, IPT only provides the addresses of indirect\njumps/calls and the results of conditional branches. Thus, any attempt to\nobtain basic block transitions must decode the packets, disassemble the traced\nexecutable and libraries, and walk through the execution trace. While IPT's\ntracing is very fast and low overhead compared to other instrumentations, the\nparsing of these traces can be very slow.\n\nOne possible optimization for parsing IPT execution traces, is to obtain a\ncomplete Control Flow Graph (CFG) prior to decoding and utilizing the CFG to\nreplace the disassembling of instructions. However, statically obtaining a\ncomplete CFG of real world programs is a hard problem, and becomes especially\ntroublesome when a target calls a library API with a callback function.\n\nAnother concern is the asynchronous nature and caching of TIP and TNT packets.\nTNT bits can be built up and cached for as long as the processor decides, or may\nbe sent immediately. Further, the number of TNT bits in a TNT packet is\nnon-deterministic and can vary between runs when tracing the same program. As\nsuch, the order of TIP packets is irrelevant to the order of the TNT packets.\nThis prevents parsing approaches which rely on TIP packets to skip to relevant\nportions of the execution trace.\n\n# Killerbeez Implementation\n\nTo compensate for the previously mentioned issues, Killerbeez's implementation\nof IPT-based fuzzing does not attempt to disassemble packets. Rather, Killerbeez\nmaintains a set of hashes which encode the TIP and TNT data in the execution\ntrace. As mentioned above, the order of TIP and TNT packets are not always the\nsame, so each of the two packets are hashed independently. The instruction\npointer address is extracted from the TIP packets and hashed into the trace's\nTIP hash, while the TNT bits are extracted from the TNT packets and hashed into\nthe trace's TNT hash. After the hashes have been generated, a hash table is then\nused to lookup these hashes and determine if an execution trace has been seen\nbefore.\n\nThis approach has the advantage of not requiring disassembling in order to walk\nthe execution trace. Additionally, our IPT packet parser is able to ignore\nirrelevant packets and only focus on TNT and TIP packets. These characteristics\nmake the Killerbeez IPT packet parser very fast. However, this approach does\nhave the disadvantage of requiring IPT instruction pointer address filtering, to\nensure unnecessary libraries are not also traced. This also helps reduce the\nnon-determinism in the execution trace, as some libraries do not always trace\nexactly the same in each execution.\n\n# Execution Traces vs Basic Block Transitions\n\nAs compared to basic block transitions, this implementation may overestimate\nwhich execution traces are consider interesting. For instance, imagine two\nexecutions: run A and run B. If run B's execution trace is a subset of run A's\nexecution trace, our implementation will report it as being interesting, despite\na basic block transition based instrumentation not reporting it as interesting.\nRun B may or may not be interesting depending on the specific code being\nexecuted. For instance, run B doesn't exercise any additional code, so it may\nnot be interesting, however if a bug in the program can only be exercised by not\nexecuting a specific piece of code, or executing it fewer times, run B may be\ninteresting.\n\nIn order to compensate for the differences between execution traces and basic\nblock transitions, the manager will analyze each interesting input generated by\nthe fuzzing clients before adding it to the working input set. For instance,\ndepending on the manager design, it may trace the target program's execution\nwith the interesting input file using another slower instrumentation that is\nable to obtain basic block transitions. With the list of basic block transitions\nfor this input file, the manager can query the database of previously found\nbasic block transitions and make a decision on whether the client reported\ninteresting input file is actually interesting enough to be added to the working\ninput set.\n\n# Comparison of Implementations\n\n## Honggfuzz\n\nHonggfuzz also utilizes Intel PT support to trace userland targets when fuzzing.\nRather than hashing the TIP/TNT packets, honggfuzz utilizes the instruction\npointers in TIP packets as an index into a bitmap which records previously seen\ninstruction pointers. While this approach is quick and can avoid disassembling\nof the target executable and libraries, it disregards the conditional branch\ndecisions recorded in the TNT packets. While our implementation will\noverestimate interesting files, honggfuzz's implementation underestimates\ninteresting files and will not report an input file that only changes a\nconditional branch in the execution of the target program. Honggfuzz's IPT\nimplementation is available in the [honggfuzz repository on github](https://github.com/google/honggfuzz/blob/master/linux/pt.c).\n\n## kAFL\n\nkAFL utilizes Intel PT support to trace execution while fuzzing Operating System\nkernels. Rather than hashing TIP/TNT packets, kAFL utilizes a custom packet\ndecoder that caches disassembly. Similar to Killerbeez, kAFL also ignores\nnon-relevant IPT packets. As described above, the Killerbeez implementation does\nnot a use a disassembler and thus will be faster than kAFL, but is unable to\nobtain the basic block transitions that kAFL can. kAFL's IPT implementation is\navailable in the [kAFL repository on github](https://github.com/RUB-SysSec/kAFL/blob/master/QEMU-PT/pt/).\n\n# Example\n\nIn order to utilize Killerbeez's IPT instrumentation, your processor and Linux\nkernel must support IPT. To check for support, look for the directory\n`/sys/devices/intel_pt/`. Additionally, Killerbeez's IPT instrumentation\nrequires address filtering; the number of address filters supported on your\nsystem is available in the `/sys/devices/intel_pt/caps/num_address_ranges` file.\n\nThe IPT instrumentation can be used as any other instrumentation module would,\ni.e. by specifying the name as the instrumentation type. The TNT and TIP hashes\nare output as DEBUG messages, and can be viewed by increasing the logging level\n(with the option `-l \"{\\\"level\\\":0}\"`).\n\nAn example command illustrating the IPT module's usage is shown below. This\nexample runs 10 iterations of the test-linux binary, mutates the input with the\nbit_flip mutator, and feeds the input over stdin to the target program. This\ncommand will cause a crash in the test-linux binary on the seventh iteration.\nThe IPT instrumentation tracks the TNT and TIP packets that are generated from\nthe main test-linux executable.\n```\n./fuzzer stdin ipt bit_flip -d \"{\\\"path\\\":\\\"$HOME/killerbeez/build/killerbeez/corpus/test-linux\\\"}\" -n 10 -sf $HOME/killerbeez/killerbeez/corpus/test/inputs/close.txt\n```\n\nIf instead of tracking code coverage for the main executable, you wish to track\nthe coverage of a library, then you can use the `coverage_libraries` option.\nThis option specifies an array of libraries for the IPT instrumentation module\nto track coverage information for. The below command illustrates how to use this\noption with the included example program. This command tracks the code coverage\nof libtest1.so and libtest2.so.\n```\n./fuzzer stdin ipt bit_flip -d \"{\\\"path\\\":\\\"$HOME/killerbeez/build/killerbeez/corpus/libtest\\\"}\" -n 10 \\\n  -i \"{\\\"coverage_libraries\\\":[\\\"$HOME/killerbeez/build/killerbeez/corpus/libtest1.so\\\",\\\"$HOME/killerbeez/build/killerbeez/corpus/libtest2.so\\\"]}\" \\\n  -sf $HOME/killerbeez/killerbeez/corpus/test/inputs/close.txt\n```\n\n# Persistence Mode\n\nThe IPT instrumentation module provides the ability to use persistence mode to\nincrease the speed of fuzzing. Persistence mode involves executing multiple\ninputs without restarting the target process. While this approach can be much\nquicker, it can cause instabilities in the target process if not setup\nproperly. The IPT instrumentation module's persistence mode is based off the\npersistence mode available in the [LLVM instrumentation included in\nAFL](https://github.com/mirrorer/afl/tree/master/llvm_mode). As such, it has\nsimilar advantages and disadvantages.\n\nIn the IPT instrumentation module, persistence mode is accomplished by modifying\nthe source code of the target program to repeatedly call the Killerbeez fork\nserver library's `killerbeez_loop` function. This function is used to mark the\nstart and stop of the target process testing a single input. An ideal program\nfor persistence mode is one that has very little global state, or the state can\neasily be reset. The structure of a persistence mode program, is shown below,\nwhere the `KILLERBEEZ_LOOP` macro is used to call the fork server. One thing\nto note is that the target process must reread any input data, to ensure it is\nrunning with the newly mutated input each iteration. In order to compile the\ninstrumented source code, it must include the forkserver.h header file (so that\nthe `KILLERBEEZ_LOOP` macro is defined) and the linker arguments must be\nmodified to link against the fork server library. A more complete example\nprogram and Makefile that can be used with IPT persistence mode is available in\nthe corpus/persist/ directory of this repository.\n\n```\n  while(KILLERBEEZ_LOOP()) {\n    // Read input data.\n    // Call library code to be fuzzed.\n    // Reset state.\n  }\n```\n\nOnce a program has been instrumented, persistence mode can be enabled by setting\nthe IPT instrumentation's `persistence_max_cnt` option. The\n`persistence_max_cnt` option defines how many inputs to test in a single process\nbefore restarting the target program. This value can be determined\nexperimentally, but a good starting value is 1000.\n\nAn example command illustrating the IPT module's usage with persistence mode is\nshown below. This example runs 5000 iterations of the persist binary, mutates\nthe input with the afl mutator, and feeds the input over stdin to the target\nprogram. The IPT module will run 1000 iterations per persist process.\n```\n./fuzzer stdin ipt afl -i \"{\\\"persistence_max_cnt\\\":1000}\" -d \"{\\\"path\\\":\\\"$HOME/killerbeez/build/killerbeez/corpus/persist\\\"}\" -n 5000 -sf $HOME/killerbeez/killerbeez/corpus/test/inputs/close.txt\n```\nFor comparison, a non-persistence mode run with a similar binary can be started\nwith this command:\n```\n./fuzzer stdin ipt afl -d \"{\\\"path\\\":\\\"$HOME/killerbeez/build/killerbeez/corpus/nopersist\\\"}\" -n 5000 -sf $HOME/killerbeez/killerbeez/corpus/test/inputs/close.txt\n```\n\n# Deferred Startup Mode\n\nKillerbeez's fork server tries to optimize performance of the target process by\nexecuting the target binary until it reaches the `main` function, and then\nforking all new processes from the copy stopped at `main`. This ensures all of\nthe startup code that is executed prior to the `main` function is only ever run\nonce. However, if a target process has a large startup cost, fuzzing will still\nbe slow. In these cases, it is beneficial to use the fork server's deferred\nstartup mode, to wait until after the process has finished starting up to start\nthe fork server. Killerbeez's deferred startup mode is based off the deferred\ninstrumentation mode available in the [LLVM instrumentation included in\nAFL](https://github.com/mirrorer/afl/tree/master/llvm_mode). Killerbeez offers\ntwo different techniques for enabling the deferred startup mode. Both techniques\nare configured by modifying the configuration in the forkserver_config.h header\nfile in the instrumentation/ directory of this repository and recompiling\nKillerbeez.\n\n## Function Hooking\n\nBy default, the Killerbeez fork server uses library injection and function\nhooking in order to execute code in a target process. Thus, the Killerbeez\ndeferred startup mode can be enabled by switching which function is hooked.\nThis mode has the advantage that it can still hook functions in target programs\nwhen source code is unavailable.\n\nIn forkserver_config.h, there are 4 preprocessor macros that control the fork\nserver's function hooking behavior:\n* `DISABLE_HOOKING` - This macro disables function hooking. This macro should be\nset to 0 to enable function hooking.\n* `USE_LIBC_START_MAIN` - This macro controls whether the default function\n(`__libc_start_main`) is hooked or not. To customize the hooked function, this\nmust be set to 0.\n* `CUSTOM_FUNCTION_NAME` - This macro should contain the name of the function to\nhook. The name should NOT be placed in quotes.\n* `RUN_BEFORE_CUSTOM_FUNCTION` - This macro determines whether the fork server\nshould startup before or after the hooked function is called. Set it to 0 to\nstart the fork server after the hooked function returns, or 1 to start the fork\nserver before the hooked function is called.\n\nThe deferred executable in the corpus/persist/ directory is an example of a\ntarget where deferred startup mode is advantageous. This target calls sleep at\nthe beginning of the program, which will substantially slowdown fuzzing.\nKillerbeez can be instructed to wait to start the fork server until after the\nsleep call by modifying forkserver_config.h to set the macros as shown below:\n```\n#define DISABLE_HOOKING            0\n#define USE_LIBC_START_MAIN        0\n#define CUSTOM_FUNCTION_NAME       sleep\n#define RUN_BEFORE_CUSTOM_FUNCTION 0\n```\n\n## Source Code Instrumentation\n\nIf source code is available, the target program can be modified to explicitly\nstart the fork server by calling the `KILLERBEEZ_INIT()` macro at the desired\npoint in the target program. In order to compile the instrumented source code,\nit must include the forkserver.h header file (so that the `KILLERBEEZ_INIT`\nmacro is defined) and the linker arguments must be modified to link against the\nfork server library.\n\nOnce the target program's source code is modified, the `DISABLE_HOOKING` macro\nin the forkserver_config.h file should be set to 1. This ensures the forkserver\ndoes not also try to hook a function to startup. The deferred_nohook executable\nin the corpus/persist/ directory shows an example of using source code\ninstrumentation to enable deferred startup mode.\n\n"
  },
  {
    "path": "docs/Server.md",
    "content": "# Client/Server Operation using BOINC\n\n## Installation\n\n### Server (Tested on Ubuntu 16.04)\n1. Install required software\n\n\t```\n    sudo apt update && sudo apt install git m4 pkg-config autoconf libtool \\\n      libssl-dev libmysqlclient-dev libcurl4-openssl-dev python apache2 \\\n      mysql-server python-mysqldb haveged php libapache2-mod-php php-mysql \\\n      php-xml-parser curl python-requests python-virtualenv unzip\n\t```\n\t* You will be asked to set a password for mysql root user\n2. Get code\n\t```\n    sudo mkdir /usr/local/killerbeez\n    sudo chown $USER /usr/local/killerbeez\n    sudo chmod a+rx /usr/local/killerbeez\n    umask 0022\n    cd /usr/local/killerbeez\n    git clone --recursive https://github.com/grimm-co/killerbeez.git\n\t```\n3. Build code\n\t```\n    cd killerbeez/server/boinc\n    ./_autosetup\n    ./configure --disable-client --disable-manager\n    make\n\t```\n4. User permissions\n\t```\n    sudo useradd -m -s /bin/bash boincadm\n    sudo usermod -a -G boincadm www-data\n    sudo -u boincadm sh -c 'echo umask 0007 >> /home/boincadm/.bashrc'\n    sudo sh -c 'echo umask 0007 >> /etc/apache2/envvars'\n    sudo chgrp boincadm /usr/local/killerbeez\n    sudo chmod g+w /usr/local/killerbeez\n\t```\n  * Note: the new user doesn't have sudo access, so continue using your normal\n    account for the remaining instructions except when indicated.\n5. MySQL setup (make sure to select your own password)\n    ```\n    mysql -u root -p\n    mysql> CREATE USER 'killerbeez'@'localhost' IDENTIFIED BY '<password here>';\n    mysql> GRANT ALL ON killerbeez.* to 'killerbeez'@'localhost';\n    ```\n    ```\n    sudo sh -c 'echo sql_mode=\"ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION\" >> /etc/mysql/mysql.conf.d/mysqld.cnf'\n    sudo systemctl restart mysql\n    ```\n6. Apache setup\n    ```\n    sudo a2enmod cgi\n    sudo systemctl restart apache2\n    ```\n7. Project setup (run as the boincadm user)\n    1. First, open a shell as the boincadm user for the rest of this step\n\n        ```\n        sudo -i -u boincadm\n        ```\n    2. Determine a URL that points to this server. If accessed in a browser,\n       this URL should display the default Apache \"It works!\" page. If this\n       will  be a public instance, take a look at\n       [these guidelines](https://boinc.berkeley.edu/trac/wiki/MasterUrl#ChoosingaprojectURL).\n       * `export BOINC_URL=<this url>`\n    3. Create the BOINC project for Killerbeez (using the passord from step 5 above)\n\n        ```\n        cd /usr/local/killerbeez/killerbeez/server/boinc\n        tools/make_project --url_base $BOINC_URL \\\n          --db_user killerbeez --db_pass '<password here>' killerbeez\n        ```\n        * Enter Y at the prompt.\n    4. Set up cron, load platforms into the database, and set a password to\n       access the admin UI (admin username does not need to be boincadm)\n        ```\n        cd ~/projects/killerbeez\n        crontab killerbeez.cronjob\n        bin/xadd\n        htpasswd -c html/ops/.htpasswd <admin username>\n        ```\n    5. Edit `html/project/project.inc` to set PROJECT and COPYRIGHT_HOLDER\n       correctly\n    6. Install killerbeez-specific files:\n        ```\n        cp /usr/local/killerbeez/killerbeez/server/*.py bin\n        cp -r /usr/local/killerbeez/killerbeez/server/skel .\n        ```\n    7. We need the killerbeez binaries to run on the target system. Download the\n       latest [release](https://github.com/grimm-co/killerbeez/releases) for the\n       target platform and place it in the `skel/<platform>` directory\n    8. The Killerbeez fuzzer binary does not use the BOINC API, however BOINC\n       has a wrapper which wraps an executable and deals with all the\n       BOINC-specific stuff.  This allows any application to be leveraged by\n       BOINC. We need this wrapper program for all platforms which we intend to\n       support. Extract the wrapper binary (or see the [build instructions](#wrapper) to\n       build your own copy):\n\n       For 64-bit Windows:\n        ```\n        unzip -j -d skel/windows_x86_64 skel/windows_x86_64/killerbeez-x64.zip \\\n          '*wrapper_26014_windows_x86_64.exe'\n        ```\n       For 64-bit Linux:\n        ```\n        unzip -j -d skel/x86_64-pc-linux-gnu \\\n          skel/x86_64-pc-linux-gnu/killerbeez-Linux.zip */wrapper\n        ```\n    9. If you want to support MacOS, you will need to [build the wrapper\n       yourself](#wrapper), as the versions on the [BOINC\n       wiki](https://boinc.berkeley.edu/trac/wiki/WrapperApp) are too old.\n    10. Enable the project\n        ```\n        bin/start\n        ```\n    11. Done running as boincadm\n\n        ```\n        exit\n        ```\n8. Install Apache config for project\n\n    ```\n    sudo cp /home/boincadm/projects/killerbeez/killerbeez.httpd.conf /etc/apache2/sites-available/killerbeez.conf\n    sudo sed -i -e '/Order /d' -e 's/Deny from all/Require all denied/' \\\n      -e 's/Allow from all/Require all granted/' \\\n      /etc/apache2/sites-available/killerbeez.conf\n    sudo a2ensite killerbeez\n    sudo systemctl reload apache2\n    ```\n\n10. Start the Killerbeez API server\n    ```\n    sudo -i -u boincadm\n    cd /usr/local/killerbeez\n    virtualenv -ppython3 killerbeez-venv\n    source killerbeez-venv/bin/activate\n    cd /usr/local/killerbeez/killerbeez/python/manager\n    pip install -r requirements.txt\n    python server.py -create  # Remove -create if restarting server\n    ```\n    This will start up the server on port 5000. In the instructions below, we\n    will call the URL pointing to this port `$API_URL`.\n    \n### Client\nNext we need to set up at least one client. Follow these instructions first,\nthen the operating system specific instructions below.  If there aren't any\ninstructions for your operating system, you're on your own (when if you figure\nit out, we accept pull requests for improved documentation :-)).\n\n1. Create an account via BOINC webpage (`$BOINC_URL/killerbeez/create_account_form.php`)\n\n#### Linux (Ubuntu)\n1. sudo apt install boinc-client\n2. Get an account key using: `boinccmd --lookup_account $BOINC_URL/killerbeez/ <email address> <password>`\n3. `boinccmd --project_attach $BOINC_URL/killerbeez/ <account key>`\n\n#### Windows\nNote: only Windows 10 x64 is currently supported\n\n1. Log into the BOINC webpage (`$BOINC_URL/killerbeez`)\n2. GUI instructions to add project:\n    1. Go to Project > Join on website\n    2. If client not installed, install it\n    3. Select \"Add project\" in GUI\n    4. Enter project URL from webpage\n    5. Enter email address and password of the account you registered in step 1\n\n## Administration\nAll administration of the BOINC server which is done from the command line\nshould be done as the \"boincadm\" user.  You can use `sudo -i -u boincadm` to\ndrop to an interactive shell with this user.\n\n### Add a target\nKillerbeez jobs have a \"target\", which represents a target program running on a\ncertain platform. BOINC needs to be told about these targets, and the platforms\nthey can run on. The [add_target.py](../server/add_target.py) tool will create a\nBOINC \"app\" for each target/platform combination. These can be customized to\ninstall a new application, but the default configuration will allow fuzzing\nanything that is installed on client machines already, such as Windows Media\nPlayer.\n\n1. Create the target\n\nA list of platforms (operating/cpu architecture) can be found on the [BOINC\nWiki](https://boinc.berkeley.edu/trac/wiki/BoincPlatforms).\n\n    ```\n    cd ~/projects/killerbeez/\n    bin/add_target.py <target> <platform> [<platform> ...]\n    ```\n    * Example: `bin/add_target.py wmp windows_x86_64`\n2. If you need any additional files in this app, put them in the app dir\n   (`apps/<target>_<platform>/1/<platform>`).  At a minimum, you will probably\n   want to put the executable there (unless the assumption is that it is already\n   on the clients' computers).\n3. Add an entry for each added file to the\n   `apps/<target>_<platform>/1/<platform>/version.xml` file, as in the\n   following example:\n\n    ```\n    <file>\n        <physical_name>myfile.exe</physical_name>\n        <logical_name>myfile.exe</logical_name>\n        <copy_file/>\n    </file>\n    ```\n    The physical name is the actual filename you added, while the logical name\n    is the name it will be given on the client system. `<copy_file/>` ensures\n    that the real file is placed at that name rather than a BOINC-specific\n    \"link\" file. See the [BOINC\n    docs](https://boinc.berkeley.edu/trac/wiki/AppVersionNew) for more\n    information on configuring your app.\n4. Finalize the app creation\n\n    ```\n    bin/update_versions\n    ```\n5. If you need to make changes to your app, you can do so by creating a new app\n   version. Keep in mind that BOINC files are immutable, so if you change a file\n   you must also change its filename. The following is a good workflow:\n    1. In the `apps/<target>_<platform>/<version>/<platform>` directory, change\n       whatever files you need to update.\n    2. Add a version number to the names of updated files (e.g. myfile.zip.1 or\n       myfile.1.exe)\n    3. Edit `apps/<target>_<platform>/<version>/<platform>/version.xml` with the\n       new physical names of all files.\n    4. Rename the whole `apps/<target>_<platform>/<version>` directory to\n       `apps/<target>_<platform>/<version+1>`.\n    5. Run `bin/update_versions`.\n\nSupporting a new platform is kind of a big deal.  If you want to take a stab at\nit, take a look at the files in the [skel](../server/skel) directory and the\ncomments in add_target.py to get started.  You will probably want to have the\n[BOINC wiki](https://boinc.berkeley.edu/trac/wiki) loaded up, especially if\nyou're not already familiar with how the implementation details of BOINC.\n\n\n### Submit job\nCustomize the [boinc_submit.py](../server/boinc_submit.py) script for your\ndesired job by changing the constants at the top, and the job parameters in the\nrequests. The constants are:\n* `PROJECT` - The URL for the Killerbeez API (`$API_URL`)\n* `SEED` - A string to be used as the contents of the seed file\n\nRun the script, and it will print out the ID of the submitted job. \n\n### View job results\nThe results of a job can be accessed via the killerbeez API. Let `$JOB_ID`\nbe the ID of the job of interest:\n```\ncurl $API_URL/api/job/$JOB_ID/results\n```\nFor example:\n```\n$ curl http://localhost:5000/api/job/37/results                                                                                       \n[{\"result_type\": \"crash\", \"repro_file\": \"3fb/38D1F16F84B07DBF6B29861BD7464ABA\", \"job_id\": 37, \"result_id\": 1}, {\"result_type\": \"crash\", \"repro_file\": \"235/97A596BE0B77EF1B6899503300B205FE\", \"job_id\": 37, \"result_id\": 2}]\n```\nThe output is a JSON list of all the job's results. Each result is a JSON\nobject, in which the result_type describes why this result is interesting\n(crash? hang? new_path?), and the repro_file is the path of a file with the\ninput that caused the crash, hang, or new path. To retrieve the crashing input:\n```\ncurl $BOINC_URL/killerbeez/download/$repro_file\n```\nFor example:\n```\n$ curl http://localhost:80/killerbeez/download/3fb/38D1F16F84B07DBF6B29861BD7464ABA\n-215005474723783\n```\nYou may be interested to know what seed file these results were mutated from.\nThe path of the seed file is available in the job information:\n```\ncurl $API_URL/api/job/$JOB_ID\n```\nFor example:\n```\n$ curl http://localhost:5000/api/job/37\n{\"mutator\": null, \"end_time\": null, \"status\": \"completed\", \"input_ids\": [], \"instrumentation_type\": null, \"seed_file\": \"ab/jf_2f79d50c5c10004b755b4622555e99f5\", \"job_type\": null, \"mutator_state\": null, \"driver\": null, \"assign_time\": null, \"job_id\": 37}\n```\nWhen jobs are submitted automatically, the seed file may be the result of some\nother job, in which case it's possible to find the job that produced it by\nsearching results by repro_file:\n```\ncurl $API_URL/api/results?repro_file=$repro_file\n```\nFor example:\n```\n$ curl http://localhost:5000/api/results?repro_file=235/97A596BE0B77EF1B6899503300B205FE\n[{\"result_type\": \"crash\", \"repro_file\": \"235/97A596BE0B77EF1B6899503300B205FE\", \"job_id\": 37, \"result_id\": 2}]\n```\nThis gives you the job ID of the job that produced the file, allowing you to\ntrace its ancestry.\n\n### Set up account with administrator access\nThis step is only needed if you are going to create an account that will submit\njobs directly to BOINC (see next section). You do not need administrator access\nto submit jobs via the Killerbeez API server.\n1. Administrator must register an account via BOINC webpage (`$BOINC_URL/killerbeez/create_account_form.php`)\n2. Log into site and go to Project > Account to find User ID\n3. On server:\n\n    ```\n    sudo -i -u boincadm\n    cd ~/projects/killerbeez\n    bin/manage_privileges grant <user id> all`\n    ```\n\n### Set up account with direct BOINC job submission privileges\nYou only need to do this if you want to submit jobs directly to BOINC (most\nlikely for testing). Submitting jobs via the Killerbeez API server does not\nrequire this.\nTo perform these steps you must have administrator access (see previous\nsection). However, as an administrator you can grant job submission privileges\nto any account, administrator or otherwise.\n1. Go to `$BOINC_URL/killerbeez/manage_project.php`\n2. Click name of the user to grant privileges to\n3. Select \"All apps\"\n4. Click \"Ok\".\n\n## Optional build instructions\n\n### Wrapper\nThe BOINC [wrapper](https://boinc.berkeley.edu/trac/wiki/WrapperApp) is an\nadapter that lets programs be run unmodified under the BOINC client. Our usage\nof the wrapper requires features and bugfixes that are more recent than the last\nreleased wrapper binary. Our binary release inlcudes a compiled copy of the\nwrapper, as described above, but you can build your own with the following\nsteps:\n1. On a Windows machine, install [git](https://git-scm.com/downloads) and\n   [Visual Studio Community 2013](https://visualstudio.microsoft.com/vs/older-downloads/)\n2. Start Git Bash and clone the [BOINC repository](https://github.com/BOINC/boinc)\n3. Open `win_build\\boinc_vs2013.sln` from the cloned repo in Visual Studio 2013\n4. Click the `wrapper` project in the Solution Explorer\n5. Select `x64` from the Platforms drop-down in the toolbar, and `Release`\n   from the Configurations drop-down next to it.\n6. From the `BUILD` menu, select `Build wrapper`\n7. The compiled binary should be in\n   `win_build\\Build\\x64\\Release\\wrapper_26014_windows_x86_64.exe`\n8. Drop this binary into the `/home/boincadm/projects/killerbeez/skel/windows_x86_64`\n   directory on your killerbeez server\n"
  },
  {
    "path": "docs/api/Makefile",
    "content": ".PHONY=all clean\nTYPESETTER=pdflatex\n\nall: api.pdf\n\nclean:\n\trm -f *.out *.aux *.toc *.out *.log *.pdf\n\napi.pdf: api.tex defines.tex api_mutator.tex api_driver.tex \\\n\t\tapi_instrumentation.tex coverpage.tex\n\t${TYPESETTER} api.tex # first time for the ToC\n\t${TYPESETTER} api.tex # second time for the real deal\n"
  },
  {
    "path": "docs/api/README.txt",
    "content": "# API Documentation\n\nThis directory contains all the documentation for the KILLERBEEZ API.  This \nmeans it includes the documentation for the mutator API, even though the\nmutators are kept in a separate repository.  Mutator specific documentation,\nhowever, is kept in the mutator's repository.\n\n# Building\n\nThe included Makefile can be used to build the api.pdf documentation by running\nthe command `make` from this directory. The documentation is written in\n[LaTeX](https://www.latex-project.org/) and uses `pdflatex` to compile.\n\nOn Ubuntu a working LaTeX environment can be setup with the following command:\n```\nsudo apt install okular texlive texlive-full texinfo texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended latex2rtf pandoc\n```\n\nOn macOS, a working LaTeX environment can be setup using the\n[MacTeX package](https://tug.org/mactex/mactex-download.html) or via homebrew.\n\nOn Windows, a working LaTeX environment can be setup via the\n[MiKTeX project](https://miktex.org/).\n"
  },
  {
    "path": "docs/api/api.tex",
    "content": "\\documentclass{article}\n\\input{defines}\n\\input{packages}\n\\input{coverpage}\n\n\\title{\\killerbeez{} API}\n\\author{GRIMM}\n\\date{\\apiDate{}}\n\n\\begin{document}\n% Nice cover page\n\\thispagestyle{empty}\n\\maketitle\n\\newpage\n\n% Table of Contents\n\\tableofcontents\n\\newpage\n\n\\section{Overview}\nThis document will cover the version \\apiVersion{} API for each module, along\nwith a quick high-level summary of what it does.\n\n\\par\nThe APIs are all specified in C, as this provides a consistent language and is\nexplicit about data types which means there's no need for a separate Python\nspecification.  The C code is frequently wrapped with Python (via ctypes), but\nmodules are typically written in C code as they run considerably faster when\nit is all native code.\n\n\\section{Manager}\nThe manager is what coordinates a fuzz job.  It decides which seeds to use,\nwhich mutators to run and sends this information to the client, which kicks\noff one or more Main Fuzzers.  The client will then also handle getting the\nresults back to the manager.\n\n\\section{Fuzzer}\nThis will run many iterations of a single seed and a single mutator against a\ntarget program.  For efficiency, this will be run on the same computer (which\nmeans same O/S) as the target binary.  This component will be an executable that\nthe manager executes on each of the target systems.  The arguments for this\nfunction are defined in the usage function of the fuzzer.\n\n\\section{Mutator}\n\\label{mutator}\n\\input{api_mutator}\n\n\\section{Driver}\n\\label{driver}\n\\input{api_driver}\n\n\\section{Instrumentation}\n\\label{instrumentation}\n\\input{api_instrumentation}\n\n\\section{Structures}\n\\label{structures}\n\\input{api_structures}\n\n\\section{Helper Utilities}\n\\label{helpers}\n\\input{helpers}\n\n\n%\\section{Database}\n% TODO: document me!\n\n%\\section{Tracer}\n% TODO: document me!\n\n%\\section{Input Generator}\n% TODO: create me and then document me!\n\n\\end{document}\n\n"
  },
  {
    "path": "docs/api/api_driver.tex",
    "content": "The driver will be the component that runs the program being fuzzed.  The driver\nshould start the program, feed in the input, and determine when the program is\ndone processing the input.  This component may need to be customized per\ntarget application.\n\n\\par\nAnything which is driver specific will only be used within the driver functions.\nAll other components will treat these items as opaque strings/blobs.\n\n\n\\api{void * create(char * options, instrumentation\\_t * instrumentation,\nvoid * instrumentation\\_state, mutator\\_t * mutator, void * mutator\\_state)\n}{\nThis function will allocate and initialize the driver structures.  If the driver\nis going to be testing a long-running process, this function should start that\nprocess.  Anything that needs to be done before a fuzzing run can start should\nbe done here.\n}{\n\\item options - a JSON string that contains the driver specific string of\noptions.\n\\item instrumentation - a pointer to an instrumentation instance that the driver\nwill use to instrument the requested program.  The caller should initialize this\ninstrumentation instance before the create call to the driver, and then free it\nafter cleaning up the driver.  This parameter is optional and can be set to NULL\nif the caller does not wish to use an instrumentation with the driver.\n\\item instrumentation\\_state - a pointer to the instrumentation state for the\npassed in instrumentation.  This parameter is optional and can be set to NULL\nif the caller does not wish to use an instrumentation with the driver.\n\\item mutator - a pointer to a mutator instance that the driver can use to\nobtain the next input (for use in the \\texttt{test\\_next\\_input} function).\nThis parameter is optional and can be set to NULL if the caller does not wish to\nuse a mutator with the driver.  Without this parameter, the\n\\texttt{test\\_next\\_input} and \\texttt{get\\_last\\_input} functions will be\nunavailable.\n\\item mutator\\_state - a pointer to the mutator state for the passed in mutator.\nThis parameter is optional and can be set to NULL if the caller does not wish to\nuse a mutator with the driver.\n\\item return value - a driver specific structure or NULL on failure.  The\nreturned value should not be used for anything other than passing to the various\nDriver API functions.\n}\n\n\\api{void cleanup(void * driver\\_state)\n}{\nThis function will kill any processes created by the driver and clean up\nanything else that was created to help fuzzing.  It will also free the driver\nstate.\n}{\n\\item driver\\_state - a driver specific structure previously created by the\ncreate function.  This structure will be freed and should not be referenced\nafterwards.\n}\n\n\\api{int test\\_input(void * driver\\_state, char * buffer, size\\_t length)\n}{\nThis function will cause the program being fuzzed to be tested against the given\ninput.  This function should block execution until the program being fuzzed has\nfinished processing the given input.\n}{\n\\item driver\\_state - a driver specific structure previously created by the\ncreate function.\n\\item buffer -  the input that should be tested\n\\item length - the length of the buffer argument\n\\item return value - 0 on success, -1 on failure\n}\n\n\\api{int test\\_next\\_input(void * driver\\_state);\n}{\nThis function uses the mutator given during the driver creation to retrieve the\nnext mutated input and test it against the target program.  This function blocks\nexecution until the program being fuzzed has finished processing the mutated\ninput. It will report whether the fuzzed process crashed or hung, or neither.\nThis function is only available if a mutator was given to the driver in the\n\\texttt{create} function.\n}{\n\\item driver\\_state - a driver specific structure previously created by the\ncreate function.\n\\item return value - 0 on success, -1 on failure, or -2 if the mutator has run\nout of inputs to to mutate.\n}\n\n\\api{void * get\\_last\\_input(void * driver\\_state, int * length);\n}{\nThis function retrieves the most recent mutated input that was tested with the\n\\texttt{test\\_next\\_input} function.  This function is only available if a\nmutator was given to the driver in the \\texttt{create} function.\n}{\n\\item driver\\_state - a driver specific structure previously created by the\ncreate function.\n\\item length - a pointer to an integer that will be set to the length of the\nreturned buffer.\n\\item return value - on success this function will return a buffer containing\nthe last input that was tested, or NULL on failure.  This pointer should not be\nfreed by the caller, and is only valid until the next call to\n\\texttt{test\\_next\\_input}.\n}\n\n\n\\api{int help(char ** help\\_str)\n}{\nThis function sets a help message for the driver. This is useful if the driver\ntakes a JSON options string in the create() function.\n}{\n\\item help\\_str - A double pointer that will be updated to point to the new help\nstring.\n\\item return value - 0 on success and -1 on failure\n}\n"
  },
  {
    "path": "docs/api/api_instrumentation.tex",
    "content": "The instrumentation modules are what track the state of a process and\ndetermine if a path through the process is new.  This will include things such\nas QEMU (for Linux), LLVM (for source), PIN, Dynamo-RIO, Dyninst, and Intel PT.\nThey are optionally given some state information.  The state information is\nmodule-specific and is used to tell the instrumentation module which paths have\nbeen previously hit.  Additionally, each instrumentation module will have a\nvariety of configuration options that can be specified that will be\nspecific to that instrumentation module.  These options will be specified as a\nJSON char array.\n\n\\par\nAnything which is instrumentation specific will only be used within the\ninstrumentation functions.  All other components will treat these items as\nopaque strings/blobs.  The typical order of calling instrumentation functions\nis create(), enable(), is_process_done(), get_fuzz_result().\n\n\\par\nAs an implementation note, all of the instrumentation modules can not have\nthe same name for functions like ``create'' or there will be a naming\ncollision. This is currently handled in instrumentation_factory.c by setting\nan instrumentation structure which maps the names listed here to the actual\nfunctions which back them for the selected instrumentation.\n\n\\api{void * create(char * options, char * state)\n}{\nThis function will create and return an instrumentation struct that defines\nthe instrumentation's state.  The state argument will be used to load the\npreviously executed paths through the fuzzed program.\n}{\n\\item options - a JSON string that contains the instrumentation specific options\n\\item state - used to load a previously dumped state (produced by the get\\_state()\nfunction), that defines the current paths seen by the instrumentation.\nAlternatively, NULL can be provided to start an instrumentation without a\npreviously dumped state\n\\item return value - an instrumentation specific structure or NULL on failure.\nThe returned value should not be used for anything other than passing to the\nvarious Instrumentation API functions\n}\n\n\\api{void cleanup(void * instrumentation\\_state)\n}{\nThis function will release any resources that the instrumentation has open and\nfree the instrumentation state.\n}{\n\\item instrumentation\\_state - an instrumentation specific structure previously\ncreated by the create function.  This structure will be freed and should not be\nreferenced afterwards\n}\n\n\\api{char * get\\_state(void * instrumentation\\_state)\n}{\nThis function will return the state information holding the previous execution\npath info.  The returned value can later be passed to the instrumentation\ncreate() function to load the state back into an instrumentation struct.\nIt is the caller's responsibility to free the memory allocated and returned\nhere using the free\\_state() function.\n}{\n\\item instrumentation\\_state - an instrumentation specific structure previously\ncreated by the create function\n\\item return value - a buffer that holds information about the previous\nexecution paths as a JSON char array.\n}\n\n\\api{void free\\_state(char * state)\n}{\nThis function will free a previously dumped state (via the get\\_state()\nfunction) of the instrumentation.\n}{\n\\item state - a previously dumped state buffer obtained by the get\\_state()\nfunction\n}\n\n\\api{int set\\_state(void * instrumentation\\_state, char * state)\n}{\nThis function will set the previous execution paths of the instrumentation.\nThis can be used to restart an instrumentation once it has been created.\n}{\n\\item instrumentation\\_state - an instrumentation specific structure previously\ncreated by the create() function\n\\item state - a previously dumped state buffer obtained by the get\\_state()\nfunction\n\\item return value - 0 on success or non-zero on failure\n}\n\n\\api{void * merge(void * instrumentation\\_state,\nvoid * other\\_instrumentation\\_state)\n}{\nThis function will merge two sets of instrumentation coverage data.  The\nresulting instrumentation state will include the tracked coverage from both\ninstrumentation states.  Both instrumentation states must have the same\ninstrumentation options (what to track coverage of, which modules, etc.)\nspecified, and generally need to be produced by the same instrumentation\nmodule in order for the merge to work correctly.  It's possible that two\ndifferent instrumentation modules may produce state information in the same\nformat, however this is up to them and not something guaranteed by this\nspecification.  Neither argument will be modified nor freed.  It is the caller's\nresponsibility to free the memory allocated and returned here using the\nfree\\_state() function.\n}{\n\\item instrumentation\\_state - an instrumentation specific structure previously\ncreated by the create() function\n\\item other\\_instrumentation\\_state - a second instrumentation specific structure\npreviously created by the create() function that should be merged with the first\n\\item return value - an instrumentation specific structure that combines the\ncoverage information from both of the instrumentation states or NULL on failure\n}\n\n\\api{int enable(void * instrumentation\\_state, void * process, char * cmd\\_line,\nchar * input, size\\_t input\\_length)\n}{\nThis function will enable the instrumentation module for a specific process and\nruns that process.  If the process needs to be restarted, it will be.\n}{\n\\item instrumentation\\_state - an instrumentation specific structure previously\ncreated by the create() function\n\\item process - a pointer to a handle for the process on which the\ninstrumentation was enabled.  On Windows, this is a HANDLE*, on UNIX-based\nsystems it is a pid_t*\n\\item cmd\\_line - the command line of the fuzzed process on which to enable\ninstrumentation\n\\item input - pointer to the buffer containing the input data that should be\nsent to the fuzzed process\n\\item input\\_length - the length of the input parameter\n\\item return value - 0 on success, non-zero on failure\n}\n\n\\api{int is\\_new\\_path(void * instrumentation\\_state)\n}{\nThis function will determine whether the process being instrumented has taken a\nnew path.  It should be called after the process has finished processing the\ntested input. If \\texttt{is\\_new\\_path} is called prior to \\texttt{enable}, it\nwill return failure, as the fuzzing of processes has not been started yet.\n}{\n\\item instrumentation\\_state - an instrumentation specific structure previously\ncreated by the create() function\n\\item return value - 1 if the previously setup process (via the enable()\nfunction) took a new path, 0 if it did not, or -1 on failure\n}\n\n\\api{int get\\_fuzz\\_result(void * instrumentation\\_state)\n}{\nThis function will return the result of the fuzz job. It should be called\nafter the process has finished processing the tested input, i.e. after a\nsuccessful \\texttt{is\\_process\\_done}. If \\texttt{get\\_fuzz\\_result} is called\nprior to \\texttt{enable}, it will return failure, as the fuzzing of processes\nhas not been started yet.  Because this is only called once the fuzzing is\ndone, it will generally clean up resources such as reaping the target process.\n}{\n\\item instrumentation\\_state - an instrumentation specific structure previously\ncreated by the create() function\n\\item return value - either \\texttt{FUZZ\\_NONE}, \\texttt{FUZZ\\_HANG},\n\\texttt{FUZZ\\_CRASH}, or \\texttt{FUZZ\\_ERROR} on error.\n}\n\n\\api{int get\\_module\\_info(void * instrumentation\\_state, int index, int * is\\_new,\nchar ** module\\_name, char **info, int size)\n}{\nThis function is optional and not required for the fuzzer to work.  It\ncan be used to obtain coverage information for each executable/library\nseparately.  This function returns information about each of the separate\nmodules (shared libraries such as .dll, .so, .dynlib). If\n\\texttt{get\\_module\\_info} is called and requests the \\texttt{is\\_new} or\n\\texttt{info} parameters prior to \\texttt{enable} being called, it will return\nfailure, as the fuzzing of processes has not been started yet.\n}{\n\\item instrumentation\\_state - an instrumentation specific structure previously\ncreated by the create() function\n\\item index - an index into the module list for the module about which\ninformation should be retrieved.  The return value will indicate if a module\nexists for this index.  Indices start at 0 and increase from there\n\\item is\\_new - This parameter returns whether or not the last run of the\ninstrumentation returned a new path for the module with the specified index.  In\norder for the information returned in this parameter to be accurate, the\nis\\_new\\_path method should be called first.  This parameter is optional and can\nbe set to NULL, if you do not want this information\n\\item module\\_name - This parameter returns the filename of the module at the\nspecified index.  This parameter is optional and can be set to NULL, if you do\nnot want this information.  This parameter should not be freed by the caller\n\\item info - This parameter returns the per-instrumentation path info for the\nmodule with the specified index.  For example, for the DynamoRIO module, the\nreturned info is an AFL style bitmap of the edges.  This parameter is optional\nand can be set to NULL, if you do not want this information.  This parameter\nshould not be freed by the caller\n\\item size - This parameter returns the size of the per-instrumentation path\ninfo in the returned info parameter.  This parameter is optional and can be set\nto NULL, if you do not want this information\n\\item return value - non-zero if module with the specified index cannot be\nfound, or 0 if it is found\n}\n\n\\api{instrumentation\\_edges\\_t * get\\_edges(void * instrumentation\\_state,\nint index)\n}{\nThis function is optional and not required for the fuzzer to work.  It is used\nby the tracer.  This function returns an array of basic block edges that\noccurred in the most recent run of the instrumentation. If \\texttt{get\\_edges}\nis called prior to \\texttt{enable}, it will return failure, as the fuzzing of\nprocesses has not been started yet.\n}{\n\\item instrumentation\\_state - an instrumentation specific structure previously\ncreated by the create() function.\n\\item index - If per-module instrumentation information is enabled, this\nparameter is an index into the module list for the module about which edges\nshould be retrieved.  The return value will indicate if a module exists for this\nindex.  Indices start at 0 and increase from there.  If per-module\ninstrumentation information is NOT enabled, then this parameter is ignored and\nthe general edges array will be returned.\n\\item return value - NULL if an array of basic block edges was not tracked for\nthe most recent instrumentation run or per-module instrumentation is enabled and\nthe requested index was not found.  Otherwise, an instrumentation\\_edges\\_t pointer\nthat contains an array of basic block edges that were hit in the most recent\ninstrumentation run.  The returned pointer should be freed by the caller.\n}\n\n\\api{int is\\_process\\_done(void * instrumentation\\_state)\n}{\nThis function is used by the driver to determine if an instrumented process has\nfinished being fuzzed. If the process is done being fuzzed, then\n\\texttt{get\\_fuzz\\_result} is ready to be called. If \\texttt{is\\_process\\_done}\nis called prior to \\texttt{enable}, it will return failure, as the fuzzing of\nprocesses has not been started yet.\n}{\n\\item instrumentation\\_state - an instrumentation specific structure previously\ncreated by the create() function.\n\\item return value - 0 if the process has finished being fuzzed, 1 if not, -1\non error.\n}\n\n\n\\api{int help(char ** help\\_str)\n}{\nThis function sets a help message for the instrumentation. This is useful if the\ninstrumentation takes a JSON options string in the create() function.\n}{\n\\item help\\_str - A double pointer that will be updated to point to the new help\nstring.\n\\item return value - 0 on success and -1 on failure\n}\n"
  },
  {
    "path": "docs/api/api_mutator.tex",
    "content": "The mutator modules are what actually mutate the seed buffers.  These would\ninclude things like a bit flipper, byte munger and so forth.  They are given an\ninput buffer and optionally some state information.  The state information is\nmodule-specific and allows the mutator to pick up where it left off.  For\nexample, the bit flipper mutator module, which simply flips one bit in the input\nbuffer, would just need to record what bit to flip as their state.  On the other\nhand, more complicated mutators may need to keep track of more information.\nAdditionally, each mutator will have a variety of mutator specific configuration\noptions that can be specified.  Both the mutator state and options will be\nspecified as JSON char arrays.\n\n\\par\nAnything which is mutator specific will only be used within the mutator\nfunctions.  All other components will treat these items as opaque strings/blobs.\n\n\n\\api{void init(mutator\\_t * m)\n}{\nThis function fills in m with all of the function pointers for this mutator.\n% TODO Put this note in a sidebar\nNote: This function only appears when compiled as a module.  When\nALL\\_MUTATORS\\_IN\\_ONE is defined, this function will not exist, as there would\nbe a name collision with all the other init() functions from other modules and\nthere will not be any need for obtaining this struct, as all the functions will\njust be called directly.  It's just the code which uses modules which will want\nto use this struct.  ALL\\_MUTATORS\\_IN\\_ONE being defined will cause all the\nother functions to have the name of the mutator and an underscore prepended.\nThis means that the create() function will be called bit\\_flip\\_create() in the\nbit flipper mutator.  The name of the mutator is defined by MUTATOR\\_NAME.\n}{\n\\item m - a pointer to a mutator\\_t structure that will be filled in with the\nfunction pointers that define this mutator.\n\\item return value - none\n}\n\n\n\\api{void * create(char * options, char * state, char * input,\nsize\\_t input\\_length)\n}{\nThis function will allocate and initialize the mutator structure.  The allocated\nstructure will exist until the cleanup() function is called.\n}{\n\\item options - a JSON string that contains the mutator specific string of\noptions.\n\\item state - used to load a previously dumped state (produced by the get\\_state()\nfunction), that defines the current iteration of the mutator.  This will be a\nmutator specific JSON string.  Alternatively, NULL can be provided to start a\nmutator without a previously dumped state.\n\\item input - base input string which will be modified to produce mutated inputs\nlater when the mutate() function is called\n\\item input\\_length - the size of the input buffer\n\\item return value - a mutator specific structure or NULL on failure.  The\nreturned value should not be used for anything other than passing to the various\nMutator API functions.\n}\n\n\n\\api{void cleanup(void * mutator\\_state)\n}{\nThis function will release any resources that the mutator has open and free the\nmutator state structure.\n}{\n\\item mutator\\_state - a mutator specific structure previously created by the\ncreate() function.  This structure will be freed and should not be referenced\nafterwards.\n}\n\n\n\\api{\nint mutate(void * mutator\\_state, char * buffer, size\\_t buffer\\_length)\n}{\nThis function will mutate the input given in the create() function and return it\nin the buffer argument.  The size of the buffer will be mutator\nspecific.  For example, some mutators may require this buffer to be larger than\nthe original input (passed to the create() function) as it's going to extend the\noriginal input in some way.  Other mutators will want it to be the same size.\nGuidance on this will be specified by the mutator specific documentation.\n}{\n\\item mutator\\_state - a mutator specific structure previously created by the\ncreate() function.\n\\item buffer - a buffer to which the mutated input will be written\n\\item buffer\\_length - the size of the passed in buffer argument\n\\item return value - the length of the mutated data on success, 0 when the\nmutator is out of mutations, or -1 on error\n}\n\n\\api{\nint mutate\\_extended(void * mutator\\_state, char * buffer, size\\_t buffer\\_length, uint64\\_t flags);\n}{\nThis function is identical to the \\texttt{mutate} function, with the exception\nthat it accepts a flags parameter that specifies how the mutations should be\ndone.\n}{\n\\item mutator\\_state - a mutator specific structure previously created by the\ncreate() function.\n\\item buffer - a buffer to which the mutated input will be written\n\\item buffer\\_length - the size of the passed in buffer argument\n\\item flags - this parameter is a bitfield that specifies how the mutations\nshould be done. Available flags are:\n\\begin{itemize}\n\\item \\texttt{MUTATE\\_THREAD\\_SAFE} - The mutator should ensure that the mutations\nare done in a thread safe way.  If the mutator will be accessed via multiple\nconcurrent threads, this flag should be set.\n\\item \\texttt{MUTATE\\_MULTIPLE\\_INPUTS} - If the mutator will be handling\nindividual input parts, this flag should be used.  For some of the fuzzer\napplications, it may be necessary to split the input up into separate pieces\nthat are mutated independently.  In these cases, the mutator can be given\nmultiple inputs and asked for mutations of the input parts individually.  One\nexample user of this API is the network driver, where each input is a separate\nnetwork packet sent to the target process.  When this flag is set, the index of\nthe input part to mutate should be included in the lowest 16-bits of the flags\nparameter.  For instance, to mutate the fifth input buffer, set flags to \\\\\n\\texttt{(MUTATE\\_MULTIPLE\\_INPUTS | 5)}.\n\\end{itemize}\n\\item return value - the length of the mutated data on success, 0 when the\nmutator is out of mutations, or -1 on error\n}\n\n\\api{char * get\\_state(void * mutator\\_state)\n}{\nThis function will return the state of the mutator.  The returned value can be\nused to restart the mutator at a later time, by passing it to the create() or\nset\\_state() function.  It is the caller's responsibility to free the memory\nallocated here using the free\\_state() function.\n}{\n\\item mutator\\_state - a mutator specific structure previously created by the\ncreate() function.\n\\item return value - a buffer that defines the current state of the mutator.\nThis will be a mutator specific JSON string.\n}\n\n\n\\api{void free\\_state(char * state)}{\nThis function will free a previously dumped state (via the get\\_state()\nfunction) of the mutator.\n}{\n\\item state - a previously dumped state buffer obtained by the get\\_state()\nfunction.\n}\n\n\n\\api{int set\\_state(void * mutator\\_state, char * state)\n}{\nThis function will set the current state of the mutator.  This can be used to\nrestart a mutator once from a previous run.\n}{\n\\item mutator\\_state - a mutator specific structure previously created by the\ncreate() function.\n\\item state - a previously dumped state buffer obtained by the get\\_state()\nfunction.  This will be a mutator specific JSON string.\n\\item return value - 0 on success or non-zero on failure\n}\n\n\n\\api{\nint get\\_current\\_iteration(void * mutator\\_state)\n}{\nThis function will return the current iteration count of the mutator, i.e. how\nmany mutations have been generated with it.\n}{\n\\item mutator\\_state - a mutator specific structure previously created by the\ncreate() function.\n\\item return value - the number of previously generated mutations\n}\n\n\n\\api{int get\\_total\\_iteration\\_count(void * mutator\\_state)\n}{\nThis function will return the total possible number of mutations with this\nmutator.  For some mutators, this value won't be possible to predict or the\nmutator will be capable of an infinite number of mutations.\n}{\n\\item mutator\\_state - a mutator specific structure previously created by the\ncreate() function.\n\\item return value - the number of possible mutations with this mutator.  If\nthis number can't be predicted or is infinite, -1 will be returned.\n}\n\n\n\\api{void get\\_input\\_info(void * mutator\\_state, int * num\\_inputs, size\\_t **input\\_sizes)\n}{\nThis function will retrieve the number of inputs and the size of each input that\nis managed by a mutator.  For most of the simple mutators, they will only be\ngiven a single input.  However, some of the more complicated mutators, such as\nthe manager mutator, will manage several input buffers and mutate them\nindependently with the \\texttt{mutate\\_extended} function.  This function\nwill return the number of inputs that a mutator is mutating and the sizes of\neach of those inputs.\n}{\n\\item mutator\\_state - a mutator specific structure previously created by the\ncreate() function.\n\\item num\\_inputs - a pointer to an integer which will be used to return the\nnumber of inputs that a mutator has.\n\\item input\\_sizes - a pointer to a size\\_t array that will be used to return\nthe size of each of the inputs.\n}\n\n\n\\api{int set\\_input(void * mutator\\_state, char * new\\_input,\nsize\\_t input\\_length)\n}{\nThis function will set the input (saved in the mutator's state) to something new.\nThis can be used to reinitialize a mutator with new data, without reallocating\nthe entire state struct.\n}{\n\\item mutator\\_state - a mutator specific structure previously created by the\ncreate() function.\n\\item new\\_input - The new input used to produce new mutated inputs later when\nthe mutate() function is called\n\\item input\\_length - the size in bytes of the input buffer.\n\\item return value - 0 on success and -1 on failure\n}\n\n\n\\api{int help(char ** help\\_str)\n}{\nThis function sets a help message for the mutator. This is useful if the mutator\ntakes a JSON options string in the create() function.\n}{\n\\item help\\_str - A double pointer that will be updated to point to the new help\nstring.\n\\item return value - 0 on success and -1 on failure\n}\n"
  },
  {
    "path": "docs/api/api_structures.tex",
    "content": "This section describes the structures used throughout the API.  For each of the\ntop level components, there is a structure which defines the available functions\nin that component.  This allows for a common interface among all of the\navailable implementations of a component.\n\n\\vbox{\\lstinputlisting[\n  label={lst:mutatort},\n  caption={\\texttt{mutator\\_t} struct definition},\n  language=C,\n  captionpos=b\n  ]{files/mutator_t.c}\n}\n\nThe \\texttt{mutator\\_t} structure, shown in Listing \\ref{lst:mutatort}, defines\nall of the common interfaces for each mutator.  The definitions of each of the\nfunction pointers in the \\texttt{mutator\\_t} structure is described in Section\n\\ref{mutator}.\n\n\\vbox{\\lstinputlisting[\n  label={lst:drivert},\n  caption={\\texttt{driver\\_t} struct definition},\n  language=C,\n  captionpos=b\n  ]{files/driver_t.c}\n}\n\nThe \\texttt{driver\\_t} structure, shown in Listing \\ref{lst:drivert}, defines\nall of the common interfaces for each driver.  The definitions of each of the\nfunction pointers in the \\texttt{driver\\_t} structure is described in Section\n\\ref{driver}.  The last field in the struct, \\texttt{state} holds a pointer to\nthe implementation specific driver state structure.  This field should only be\nused when calling each of the driver's functions.\n\n\\vbox{\\lstinputlisting[\n  label={lst:instrumentationt},\n  caption={\\texttt{instrumentation\\_t} struct definition},\n  language=C,\n  captionpos=b\n  ]{files/instrumentation_t.c}\n}\n\nThe \\texttt{instrumentation\\_t} structure, shown in Listing\n\\ref{lst:instrumentationt}, defines all of the common interfaces for each\ninstrumentation.  The definitions of each of the function pointers in the\n\\texttt{instrumentation\\_t} structure is described in Section\n\\ref{instrumentation}.\n\n\\vbox{\\lstinputlisting[\n  label={lst:instrumentationedget},\n  caption={\\texttt{instrumentation\\_edge\\_t} struct definition},\n  language=C,\n  captionpos=b\n  ]{files/instrumentation_edge_t.c}\n}\n\nThe \\texttt{instrumentation\\_edge\\_t} structure, shown in Listing\n\\ref{lst:instrumentationedget}, is used to return a list of basic block\naddresses which make up each edge in the fuzzed program's path.  This list is\nreturned from the \\texttt{get\\_edges} method as described in Section\n\\ref{instrumentation}.\n\n"
  },
  {
    "path": "docs/api/coverpage.tex",
    "content": "\\makeatletter         \n\\def\\@maketitle{\n    \\begin{center}\n        {\\Huge \\bfseries \\sffamily \\@title }\\\\[3ex]\n        {\\Large Version \\apiVersion{}}\\\\[3ex]\n        {\\Large \\@date}\\\\[8ex]\n        \\includegraphics{killerbeez-logo.png}\n    \\end{center}\n}\n\\makeatother\n\n"
  },
  {
    "path": "docs/api/defines.tex",
    "content": "% 1 = definition, 2 = description, 3 = args/return value\n\\def\\api#1#2#3{\n\\bigskip\n% Can't make \\texttt bold...\n% Maybe use \\lstinputlisting ?\n\\texttt{#1}\n\\par\n#2\n\\par\n\\begin{itemize}\n#3\n\\end{itemize}\n}\n\n\\def\\killerbeez{Killerbeez}\n\\def\\apiVersion{0.1}\n\\def\\apiDate{2018.07.30}\n"
  },
  {
    "path": "docs/api/files/driver_t.c",
    "content": "struct driver\n{\n  void (*cleanup)(void * driver_state);\n  int (*test_input)(void * driver_state, char * buffer, size_t length);\n  int(*test_next_input)(void * driver_state);\n  void *(*get_last_input)(void * driver_state, int * length);\n  void * state;\n};\ntypedef struct driver driver_t;\n"
  },
  {
    "path": "docs/api/files/instrumentation_edge_t.c",
    "content": "struct instrumentation_edge\n{\n#ifdef _M_X64\n  uint64_t from;\n  uint64_t to;\n#else\n  uint32_t from;\n  uint32_t to;\n#endif\n};\ntypedef struct instrumentation_edge instrumentation_edge_t;\n"
  },
  {
    "path": "docs/api/files/instrumentation_t.c",
    "content": "struct instrumentation\n{\n  void *(*create)(char * options, char * state);\n  void(*cleanup)(void * instrumentation_state);\n  void *(*merge)(void * instrumentation_state,\n    void * other_instrumentation_state);\n  char * (*get_state)(void * instrumentation_state);\n  void(*free_state)(char * state);\n  int(*set_state)(void * instrumentation_state, char * state);\n  int(*enable)(void * instrumentation_state, HANDLE * process,\n  char * cmd_line, char * input, size_t input_length);\n  int(*is_new_path)(void * instrumentation_state, int * process_status);\n\n  //Optional\n  int (*get_module_info)(void * instrumentation_state, int index,\n    int * is_new, char ** module_name, char ** info, int * size);\n  instrumentation_edges_t * (*get_edges)(void * instrumentation_state,\n    int index);\n};\ntypedef struct instrumentation instrumentation_t;\n"
  },
  {
    "path": "docs/api/files/mutator_t.c",
    "content": "typedef struct mutator\n{\n  void * (*create)(char * options, char * state, char * input,\n    size_t input_length);\n  void(*cleanup)(void * mutator_state);\n\n  int(*mutate)(void * mutator_state, char * buffer,\n    size_t buffer_length);\n  int(*mutate_extended)(void * mutator_state, char * buffer,\n    size_t buffer_length, uint64_t flags);\n\n  char * (*get_state)(void * mutator_state);\n  void(*free_state)(char * state);\n  int(*set_state)(void * mutator_state, char * state);\n\n  int(*get_current_iteration)(void * mutator_state);\n  int(*get_total_iteration_count)(void * mutator_state);\n  void(*get_input_info)(void * mutator_state, int * num_inputs,\n    size_t **input_sizes);\n\n  int(*set_input)(void * mutator_state, char * new_input,\n    size_t input_length);\n  int(*help)(char **help_str);\n} mutator_t;\n"
  },
  {
    "path": "docs/api/helpers.tex",
    "content": "In addition to the fuzzer, a few other utilities have been created that help\nwith the fuzzing process.  This section describes these helper utilities and\ntheir role in the \\killerbeez{} architecture.\n\n\\subsection{Merger}\nThe merger combines multiple sets of instrumentation data into one\ninstrumentation state.  The resulting instrumentation state will include the\ntracked coverage from all of the input instrumentation states. This allows\nmultiple instances of the fuzzer to share instrumentation data, and ignore paths\nthat the other fuzzers found.\n\n\\subsection{Picker}\nThe picker helps the user decide which libraries should be instrumented while\nfuzzing.  This is accomplished by running the target program and recording\ncoverage information on each of the loaded libraries. It then analyzes the\ncoverage information for each library to determine which libraries the\ncoverage information varies based on the input file.  These libraries are most\nlikely the ones that process the input file, and thus the most likely targets\nfor fuzzing.\n\n\\subsection{Tracer}\nThe tracer runs a target program in an instrumented state and records the entire\nset of basic block transitions that the process makes.  This process will\ntypically be slower than the instrumentations used during fuzzing.  The full\nlist of basic block transitions that a target process makes when parsing a given\ninput is needed for advanced corpus management techniques.\n"
  },
  {
    "path": "docs/api/packages.tex",
    "content": "\\usepackage{textcomp}\n\\usepackage{listings}\n\\lstset{basicstyle=\\ttfamily\\small,showstringspaces=false,upquote=true}\n\\usepackage{graphicx}\n"
  },
  {
    "path": "docs/paper/Makefile",
    "content": ".PHONY=all clean\nTYPESETTER=pdflatex\n\nall: killerbeez.pdf\n\nclean:\n\trm -f *.out *.aux *.toc *.out *.log *.pdf\n\nkillerbeez.pdf: killerbeez.tex packages.tex introduction.tex references.tex \\\n\t\timplementation.tex overview.tex future_work.tex \\\n\t\tbackground.tex related_work.tex\n\t${TYPESETTER} killerbeez.tex\n\t${TYPESETTER} killerbeez.tex  # do it twice for the bibliography\n"
  },
  {
    "path": "docs/paper/abstract.tex",
    "content": "\\textbf{\\textit{Abstract}}:\nThe trend of people increasingly relying on software has continued for\nseveral decades and shows no sign of abating. Businesses rely on Windows and\nthe applications which run on it, servers are typically some type of UNIX\nsystem, and Apple computers are gaining popularity as of late. The desire\nfor these systems to be stable and resilient to attacks drives the need to find\nsoftware errors which may compromise them. Many improvements have been\nmade in the field of software testing, with one of the popular ones being fuzz\ntesting, or fuzzing for short.  Unfortunately, the implementation details make\nit difficult to compare or combine different methods, while others are only\navailable for specific operating systems, or limited to cases where source\ncode is available.  Killerbeez intends to pull these technologies together\nand allow them to interoperate. It is scalable, supports multiple operating\nsystems, is extensible, and will have support for testing both kernel and\nuser space applications. Killerbeez's goal is to measure the effectiveness\nof various fuzzing techniques in a variety of situations so the optimal\nsolution can be applied. \n"
  },
  {
    "path": "docs/paper/acknowledgments.tex",
    "content": "This research was started through an internal research program funded at GRIMM.\nThe authors would like to thank Brian Schanbacher, Ian Klatzco, and Tommy Chin for their\nsupport and contributions.  Additionally, the authors would like to thank the\nmany security researchers who have open sourced their prior-research, which\neases the integration into Killerbeez.\n"
  },
  {
    "path": "docs/paper/background.tex",
    "content": "There are a huge number of fuzzing tools\\cite{afl,aflosx,winafl,peach22,syzkaller,ossfuzz,driller,radamsa,ni,zzuf,synfuzz,brundlefuzz,honggfuzz,kafl,vuzzer,boofuzz} which are publicly available, many of\nwhich are very useful on real-world binaries.\nHowever, each tool\ntypically only handles one very specific use case or contains other real-world limitations, and most are not designed to scale\nout.  For instance, there are a number of fuzzers targeting kernel system calls\\cite{syzkaller,trinity,kafl,osxfuzz}, others for\nfuzzing \\IOCTLs{}\\cite{ioctlfuzzer,ioctlbf}, and others for fuzzing userland Linux targets that only effectively work with\ncommand line programs written in C-like languages\\cite{afl}.  Some only function with\nsource code, only work on 32-bit Linux\\cite{vuzzer}, or require users to manually specify\nthe data format which the target is\nexpecting.\\cite{peach,boofuzz}  Finally, there is a category of tools which work amazingly well\non tiny example programs but do not work on production software due to bugs or lack of\nsupport for features such as multithreading.\\cite{grimmdriller,angrissues}\n\nLack of compatibility with production software is typically not viewed as an issue in academic work, as the problem to address can be\nscoped based on the tools that are available; one may assume that the problem can\nbe solved in other situations, but leave the proof for future work.  The researchers\nare typically correct in their assumption, however practitioners need tools\nthat work in practice, not theoretical solutions.\n\nIn industry, the situation is dictated by the target software,\nand there is often not a choice as to the implementation's programming language,\nwhether source code is available, what operating system it runs\non, or which CPU architectures it supports. This leaves the security\nprofessional to choose between the limited set of tools that can handle the specific requirements of their target, many of which will\nturn out to be mutually exclusive. This lack of available tools also creates a new problem, as a common\nresponse to this dilemma is to put together a custom tool which meets their\nneeds, and to do so in the shortest amount of time possible.  Furthermore,\nthis results in the same code being re-written for different platforms, or\nsometimes for the same platform, simply because the security professional was\nunaware of existing implementations.  The adapted tool will likely\ncontain some of the same bugs and limitations that were in the initial\nversion of the existing tool, which may or may not get fixed before it is\nabandoned.\n\nIn short, while the state of security research is advancing rapidly, the\ntools to bring their benefits to life are sorely lacking.  Though there are some\nfuzzing projects which come close, such as OSS-Fuzz,\\cite{ossfuzz} there\nare not any fuzzing tools which are freely available, work on closed source applications,\nare easily extendable,\ncan be run in a distributed manner, and run against Windows, Linux, and macOS applications.\n"
  },
  {
    "path": "docs/paper/conclusion.tex",
    "content": "In this paper, we present Killerbeez, a fuzzing framework that integrates many\ndisparate research projects so that they can be used together. This framework\nallows for independent fuzzing improvements to be reused in a distributed,\ncross-platform way that they otherwise would not have been able to. Furthermore,\nKillerbeez allows for each new improvement to be easily evaluated against the\nexisting components, which will expedite the evaluation of new research.  The\nauthors have released Killerbeez as open-source\nsoftware\\footnote{https://github.com/grimm-co/killerbeez} in the hopes that it\nwill allow for the quicker adoption and evaluation of new security research,\nresulting in a more efficient vulnerability detecting system.\n"
  },
  {
    "path": "docs/paper/data/Makefile",
    "content": "\nall: image\n\nimage:\n\tgnuplot < picker.gnuplot\n\nclean:\n\trm -f picker.svg\n"
  },
  {
    "path": "docs/paper/data/picker.gnuplot",
    "content": "set terminal pngcairo  background \"#ffffff\" enhanced fontscale 1.0 dashlength 2\nset output '../picker.png'\n\nset title \"Detected Non-Detemrinistic Basic Block Transitions in\\nWindows Media Player Libraries\"\nset key right center\nset xlabel '{/Helvetica-Oblique Number of Executions}' font 'arial,10'\nset ylabel '{/Helvetica-Oblique Non-deterministic Basic Block Transitions Detected}' font 'arial,10'\n\nset linetype 1 dt 1\nset style line 1 lt 1 lw 2\nset linetype 2 dt 2\nset style line 2 lt 2 lw 2\nset linetype 3 dt 3\nset style line 3 lt 3 lw 3\nset linetype 4 dt 4\nset style line 4 lt 4 lw 2\n\nplot \"data/AudioSes.dll\" title 'AudioSes.dll' with lines ls 2, \\\n\t\t\"data/MFPlat.dll\" title 'MFPlat.dll' with lines ls 1, \\\n\t\t\"data/MSIMG32.dll\" title 'MSIMG32.dll' with lines ls 3, \\\n\t\t\"data/WindowsCodecs.dll\" title 'WindowsCodecs.dll' with lines ls 4\n"
  },
  {
    "path": "docs/paper/future_work.tex",
    "content": "The short-term focus will be to incorporate existing technologies from other\nprojects and get them integrated with Killerbeez and running on all the\nsupported platforms.  There is ample research, tools, and techniques available\nnow which have yet to be applied in different domains. Once the state of the\nart has been incorporated, more automation will be the next priority.\n\nExpanding the portability of the instrumentation modules so they work on more\noperating systems is a high priority. The \\IPT{} module currently only works\non Linux, but should be able to work on Windows now that Windows \\IPT{} driver support has\nimproved. The reverse is true for DynamoRIO, which currently works on Windows\nbut should be able to be ported to run on macOS\\footnote{DynamoRIO's\nsupport for macOS is a work in progress.} and Linux without too much difficulty.\nPulling in more instrumentation technologies such as Intel's Pin,\nand Dyninst~\\cite{dyninst} is also on the list of future work. Wrapping up the\nfuture enhancements to instrumentation is making more instrumentations aware of\nthe non-deterministic portions of code which were identified by the Picker.\nCurrently, only the DynamoRIO instrumentation can use this information, but\nit should be easy to extend this to all of the \\AFL{}-bitmap compatible\ninstrumentation modules.  This includes the \\AFL{} module and the to-be-written\nPin and Dyninst modules.  The \\IPT{} module will not be able to use this data\nbecause it does not actually decode the \\TNT{} and \\TIP{} bitstreams to determine what\ncode is being executed. Adding real-time parsing would slow down the target\nsoftware significantly, however, this would still be considered if the benefit\nof handling non-deterministic code appears to be worth the additional overhead\nwhich would be incurred. Finally, adding in the Linux-only instrumentation\ntechnologies from Honggfuzz~\\cite{honggfuzz} is planned, to get the performance\nboost on software which runs on Linux, especially that which is closed source\nor not written in either C or C++.\n\nExpanding the selection of drivers to include the ability to monitor dialog\nbox pop-ups on Windows is an area of interest. There are already drivers for\nthe more common input methods, such as files, \\stdin{}, and network data, however\nthese should also be expanded to cover kernel functions via syscalls, drivers\nvia \\IOCTLs{}, \\IPC{} messages, etc. This will make Killerbeez a fuzzer\nwhich can handle not only applications on multiple operating systems, but also\nthe kernel of multiple operating systems as well.  Currently, this is only\ntheoretically possible with Killerbeez, which is not much help to researchers\nin the field. Making it supported without any development or modifications\nwill be a big step in helping industry researchers analyze operating system kernels.\n\nThe mutation algorithms from several other projects have already been\nintegrated with Killerbeez, however it is desirable to have the ability\nto write mutators in Python.  This will allow pulling in mutators from\nprojects like BrundleFuzz~\\cite{brundlefuzz} as well as quickly putting\ntogether custom target-specific mutators without needing to learn the Killerbeez\nmutator \\API{}, nor even needing a compiler.\n\nIn addition to the aforementioned modules on the client side, there are a number\nof algorithms to pull in from academic publications.  This includes the seed\nenergy rating and power schedules from AFLFast~\\cite{aflfast} and\nAFLGo.\\cite{aflgo} FairFuzz presents another seed selection algorithm to bias\nseed files toward code segments which are not often executed.\\cite{fairfuzz}\nThe algorithm from PerfFuzz~\\cite{perffuzz} can be incorporated into\nKillerbeez to find algorithmic complexity vulnerabilities. The research on\nusing estimators and extrapolators to determine if a fuzzing campaign should\nbe stopped, or continue running, can be integrated from Pythia.\\cite{pythia}\nInstrumentation modules can be updated to implement the collision resistant\nalgorithm from CollAFL.\\cite{collafl} Angora is also on the list of techniques\nto integrate into Killerbeez, however it is at the end of the queue of\nimprovements due to it needing to be completely re-implemented\non account of the authors never releasing the code.\\cite{angora}\n\nThe need to obtain a wide variety of seed values is a weakness of Killerbeez\nas well as many other fuzzers. The quality of the starting corpus makes a big\ndifference in the efficiency of fuzzing. This issue will be addressed by leveraging\nexisting tools which find new inputs more efficiently, or are able to find\ninputs which reach code that is unlikely to be hit via mutation.\n\nThere are a number of security analysis and fuzzing tools which do not\nfit into mutators, drivers, nor instrumentation modules. This includes input\ngeneration tools, such as Driller~\\cite{driller} and Synfuzz~\\cite{synfuzz}.\nIntegrating Driller can be accomplished by simply scheduling \\BOINC{} jobs\nwhich run Driller instead of the fuzzer component. The input to the process\nis still the executable and the code which has been covered thus far, and the\noutput is still inputs which cause new code to be executed, so this will work\nperfectly with the current system.  This allows the \\BOINC{} code to be\nleveraged to handle things like scheduling tasks, dealing with worker nodes\nwhich time out, and the campaign manager can deal with deciding how much time\nto spend drilling versus fuzzing. Preparing a Driller environment which can\nbe easily deployed will require a bit of work, however this should only need\nto be done one time, not once for each fuzzing target.\n\nPulling in inputs generated with Synfuzz should be even easier, as the only\n\\REST{} \\API{} which should be required is the ability to add files to the corpus.\nSome automation of setting up Synfuzz may also be possible, but it requires an\noracle to determine which inputs are valid or not, which will likely mean it\nwill need to be set up manually, short of new research that allows\nautonomously detecting such oracles and hooking the appropriate functions.\n\nFinally, expanded support for fuzzers other than the Killerbeez fuzzer is planned. With\nthe client/server architecture which was chosen, there is no reason Killerbeez\nhas to be limited to a single fuzzer.  It could easily run Honggfuzz,\n\\AFL{}, WinAFL, or others.  Doing so will require additional configuration in\n\\BOINC{} to ensure the previous state is sent to the \\BOINC{} clients, as well\nas a new \\BOINC{} assimilator to gather the results.\n\n% Not sure if we want to take on the things below or not, but if so they will\n% be in the far future.\n% Unsolved problems:\n\n% How to choose targets\n% Where to get seeds?\n%   Search the web, very ad-hoc and manual process\n% Avoiding the easy-to-find crashes to get to the more interesting ones\n%   Could be done with smarter input generators/mutators & automated static/dynamic analysis\n% Targets which include checksums, compression or encryption\n%   Typical solution, modify the source/executable to remove those checks\n\n\n% Room for improvement:\n\n% Detecting non-crashing errors (especially without source code for the target)\n\n\n"
  },
  {
    "path": "docs/paper/implementation.tex",
    "content": "Killerbeez is an interoperable fuzzing architecture that is\nenvironment- and platform-independent. It consists of driver, instrumentation,\nand mutator modules on the client side, a tracer which obtains accurate code\ncoverage and a picker which determines which code should be instrumented.\nScalability is achieved by using a \\BOINC{} server to allow multiple client\nnodes to fuzz in parallel.  Clients simply obtain work from and return results\nto the server.\n\nWhile there are some novel improvements in Killerbeez,\nthe primary benefit is getting many existing tools to work\ntogether and run on new platforms.  Each tool pulled into Killerbeez was the best in class on its own, but\nwhen combined with others, the value is more than the sum of its parts.\n\n\\subsection{Driver} \\label{Driver}\nDriver modules use a mutator module to mutate an input,\nan instrumentation module to trace the target's execution, and are responsible\nfor getting the input data into the target.  A simple example is a\nfile-based driver, which will create a file containing the mutated input and\nuse the instrumentation module to launch the application in a way that it will\nread this file.  This is typically accomplished by passing a filename on the\ncommand line.  For targets which do not have any way to specify the input\non the command line, a custom driver would be required to use keyboard\nshortcuts, mouse input, or some other method of getting the input into the\nprogram.\n\nThe following drivers have been implemented:\n\\begin{itemize}[noitemsep]\n\\item \\textbf{File} - for programs that read input from a file\n\\item \\textbf{Stdin} - for programs that read input from standard input\n\\item \\textbf{Network Server} - enables fuzzing server programs\n\\item \\textbf{Network Client} - enables fuzzing client programs\n\\item \\textbf{Windows Media Player} - for Windows Media Player\n\\end{itemize}\n\nThe File and Stdin drivers provide feature parity with \\AFL{}, in terms of input\nmethods. There is nothing particularly novel about these drivers, but they are\nan important feature.  Sending malicious files via email is a popular attack\nvector, so there is an interest in proactively finding bugs that can be triggered by loading files.\n\nThe Network Server and Network Client drivers provide feature parity with \\AFL{} when it\nis combined with Preeny,\\cite{preeny} which modifies the behavior of network-based\ntarget programs to accept input via stdin.  Two drivers are needed, one to establish\na connection to a server, and the other to accept a connection from a\nclient. These drivers caused the creation of the multipart mutator,\nwhich is covered in more detail in Section~\\ref{Mutator}.\n\nA Windows Media Player (WMP) driver was created to demonstrate how to deal with\na \\GUI{} application which does not exit without user interaction. Applications\nwith a \\GUI{} are difficult to fuzz and many fuzzers\\cite{afl,honggfuzz,peach,vuzzer,boofuzz} evade this problem by not\nsupporting targets with a \\GUI{}.  The typical recommendation is to fuzz the library\nwhich does the heavy lifting, or modify the application to not load a \\GUI{}.\nThis does not work well when dealing with closed source applications. A test\nharness can be written which calls the undocumented functions in the closed\nsource library, but there is no guarantee that bugs found will also be present\nand reachable in the real application.  This is due to constraints which may\nbe placed on function arguments in the main application, or that functions are\ncalled in a different order.  While writing a custom harness to test a library\nis a good recommendation, it should not be the only option.\nKillerbeez addresses the problem of fuzzing \\GUI{} applications with modular\ndrivers instead of simply avoiding the problem.\n\nThe next issue a driver has to deal with is determining when the target is done\nprocessing the input.\nTypically, a fuzzer mutates the input, feeds it to a\ntarget, and then monitors the target for interesting behavior such as a crash\nor a hang, and if it does not exit after the timeout period, it considers the target to\nbe hung.  This works for command line programs which exit immediately after processing\nthe input, but falls apart when dealing with \\GUI{} applications.\nSetting a timeout which is too low results in stopping before the\nprogram is finished processing the input, while setting it too high means\nwasting time. On top of this, every non-crashing test case is considered\na hang. WinAFL attempts to address these problems by forcing the user to\nreverse engineer the target software to identify the function which reads and\nprocesses input data.  This is time consuming, and if there is one function\nwhich reads the data into memory and another function which parses it, this\nstrategy does not work well. This can sometimes be worked around by going up\na level in the call stack until the function is located which calls both the reading and parsing functions.\nHowever, that function might also be the one which loads the \\GUI{}, which means\nit may never return. This breaks WinAFL's assumption that there is a function\nwhich reads input data, parses it, and returns, which means it will fail in the\nsame way fuzzers intended for command line programs will fail: with every test\ncase being a hang.  The next alternative is to patch the target executable\nto exit after parsing. All of these approaches require reverse engineering,\nand will have varied results depending on the details of the target software.\n\nThe WMP driver, when used with the DynamoRIO\\cite{dynamo} instrumentation, uses the same strategy as WinAFL, where a specific function\nname or offset needs to be specified and the test is ended when that function returns, however\nthis is not the only stopping condition. The driver also checks for sound\nplaying and assumes that if it was able to decode the file and start playing\nsound, that the application has finished parsing the input file.\nThe underlying assumptions are that errors will be in the\ncode which does the parsing, rather than the code which does the playing, and that all\nthe parsing is done up front.  This does mean that bugs which require a\nsignificant number of frames will not be found, as the test will conclude\nearly and kill the application.  This is a conscious trade-off which was made\nto speed up the number of executions per second by terminating much earlier than\nwaiting for the entire clip to\nplay or the timeout to occur.  While this technique is based on fuzzing Windows Media Player,\nit should work on any media playing application. \n\n\\subsection{Mutator} \\label{Mutator}\nThe mutators from Honggfuzz, Radamsa, AFL, and Ni\\cite{ni} are leveraged by wrapping the\ncode from these projects to conform to the Killerbeez mutator \\API{}. By\ndefining an \\API{} for the mutators, researchers can modify other\nfuzzers to conform to the Killerbeez mutator \\API{} and easily swap in the new mutators.\n\nThe following mutators have been implemented:\n\\begin{itemize}[noitemsep]\n\\item \\textbf{arithmetic} - 32-bit arithmetics, both endians. From \\AFL{}\n\\item \\textbf{bit flip} - Flips various number of bits (1-32). From \\AFL{}\n\\item \\textbf{dictionary} - Inserts or replaces values from a dictionary. From \\AFL{}\n\\item \\textbf{havoc} - Runs multiple mutations on a single input. From \\AFL{}\n\\item \\textbf{interesting value} - Inserts values which are more likely to trigger\n                                   integer overflows or off-by-one errors. From\n                                   \\AFL{}\n\\item \\textbf{splice} - Splices two input files together. From \\AFL{}\n\\item \\textbf{afl} - All of the \\AFL{} mutators, run in the same manner as is\n                     done in \\AFL{}\n\\item \\textbf{honggfuzz} - Mutation algorithm from Honggfuzz\\cite{honggfuzz}\n\\item \\textbf{multipart} - Input must be made up of multiple parts, different\n                           mutators are applied to different parts of the\n                           input. Useful for network protocols where there is\n                           a desire to not disrupt the handshake/login\n\\item \\textbf{ni} - Mutation algorithm from Ni\n\\item \\textbf{nop} - Mutator which does not mutate anything, useful for\n                     testing and when combined with the multipart mutator\n\\item \\textbf{radamsa} - Mutator which wraps the Radamsa\\cite{radamsa} executable\n\\item \\textbf{zzuf} - Mutation algorithm from zzuf\\cite{zzuf}\n\\end{itemize}\n\nAs indicated in the list above, several of the mutators were taken from \\AFL{}\nand adapted to the Killerbeez mutator \\API{}. These have proven to be effective algorithms\nand were a solid starting point.\n\nHonggfuzz has a different set of mutators, some of which are similar to those\nfrom \\AFL{}, such as Honggfuzz's magic value mutator and \\AFL{}'s interesting value mutator, however there are slight variations which work better\nagainst some targets than others.  Honggfuzz is the only fuzzer to have found a\ncritical vulnerability in OpenSSL to date,\\cite{honggfuzz} so clearly it does\nsomething different than the other fuzzers.  Again, the approach was one of pragmatism:\ntaking the existing techniques and bringing them to new\nenvironments, such as Windows with code coverage capabilities.\n\nThe multipart mutator's development was driven by the network drivers and the desire to have\nthe handshake or authentication section of the input not be mutated, as this\nwould prevent much of the target's code from being reached.  The input is\ndivided into parts and a mutator is run on each part. For any parts which\nshould not be modified, the ``nop'' mutator, which is described below, is\nselected. This allows different mutators to be used on different segments of\nthe input and the ones which perform the best can be selected more often by the\ncampaign manager.  The multipart mutator could also be used with a file-based\ndriver which is multipart aware, allowing different segments of input files to\nbe defined.  This would enable things such as ensuring a file's magic bytes are\nnever modified by using the ``nop'' mutator on the first segment.\n\nAki Helin, the author of Radamsa, also wrote a mutation algorithm called Ni.\nThis code was adopted with minimal changes to provide more diversity in\nmutation methods, and based on Aki's reputation for having novel ideas on how\nto mutate inputs.\n\nDuring development, it quickly became clear that having a mutator which does\nnot do any mutation would be handy when debugging issues.  This is how the nop\nmutator was born. It was later used when the multipart mutator was developed.\n\nRadamsa is a general purpose fuzzer, written in Lisp, which came from the\nOulu University Secure Programming Group (OUSPG) Protos Genome Project.\\cite{genome} It works well against a variety of network\nprotocols and file formats, and has found dozens of vulnerabilities.\\cite{radamsaresults} The\nradamsa mutator module in Killerbeez is a simple wrapper which feeds data\nto the Radamsa executable.  The strategy of using an external process was chosen\nto allow the process to be long lived, so Radamsa's internal state can be\nupdated over the course of many inputs.  The alternative approach, which\nother fuzzing projects have taken when adopting Radamsa, is to pull in the \\texttt{main()}\nfunction from the C code (which is generated by the Radamsa Lisp code) and\nexecute \\texttt{main()} once per input.\\cite{radamsatob}  This is much faster\nin terms of execution time, because the function is executed within the context of the\nfuzzer process.  This means data does not need to be piped from one process\nto another and then back again, however it loses a key value of Radamsa, which\nis that it keeps state and tends to get better as it sees more data.\\cite{radamsagrrproblems} While the implementation\nin Killerbeez is slower, and this reflects poorly on the metric of executions\nof the target application per second, it is arguably higher quality mutations\nin the long run.  There was an effort to get Radamsa compiled on Windows as a\nlibrary, which was painstakingly implemented, only to find that it was about twice\nas slow as using an external process. The cause of this was not immediately\napparent, and the effort was abandoned in favor of developing other features.\n\nFinally there is zzuf, which is yet another application fuzzer, that\nprimarily targets media players, image viewers, and web browsers.  As with\nother mutators which were pulled in from other projects, it has found bugs in\nproduction code ranging from audio and video codecs to objdump~\\cite{binutils} and nm~\\cite{binutils}.\n\nEach of the mutators brings diversity to Killerbeez.  Different authors are\ngoing to frequently have different approaches, and even when the algorithms\nare similar, there are frequently implementation details which will vary in\nways which are sometimes important.  Different mutation algorithms will\nperform differently on various targets.  The benefit of being able to switch from one to another easily\nenables Killerbeez to measure which ones are finding\nmore inputs which trigger new code execution on different targets and at different points in\nthe fuzzing process.  A mutator which performs poorly with the initial corpus\nof inputs may be the best later when a different section of code is unearthed.\n\n\\subsection{Instrumentation} \\label{Instrumentation}\nKillerbeez uses an instrumentation abstraction, to implement the\nfeedback-based portion of the fuzzer. Instrumentation monitors code coverage of\nthe target binary. Feedback-based fuzzing helps expand code\ncoverage by reducing the input set to only those that reach new code.\nThis reduces that the likelihood that multiple inputs will be tested that result\nin the same code coverage.\n\nThe following instrumentation modules have been implemented:\n\\begin{itemize}[noitemsep]\n\\item \\textbf{Debug} - A na\\\"ive Windows-only instrumentation that determines the\n\tresult of a round of fuzzing via the Windows Debug \\API{}.\\cite{windebugapi}\n\\item \\textbf{Return Code} - A Linux-only equivalent to the debug instrumentation that\n\tuses the \\texttt{waitpid()} system call to determine the result of a fuzz round.\n\\item \\textbf{DynamoRIO} - An instrumentation that uses the DynamoRIO project\\cite{dynamo} to\n\tdetermine new code paths discovered in a binary.\n\\item \\textbf{Intel PT} - An instrumentation that uses Hardware-level ``Process Tracing''\n\\item \\textbf{AFL} - An instrumentation injected by a modified version of AFL's compilers (afl-gcc or\n\tafl-clang-fast), or via running the executable under a modified version of QEMU\\cite{qemu}\n\\end{itemize}\n\nThe instrumentation modules monitor, at a minimum, whether a process crashed,\nexited cleanly, or timed out. More advanced instrumentation modules, such as\nDynamoRIO, monitors basic block coverage and can inform the fuzzer of new code paths\ntaken in a binary.  Instrumentation developers decide what options their\nmodule has and whether they will implement optional features. For example, a\nmodule can do only lightweight tracking, as is done in \\AFL{}, or it can\noptionally support tracking every\nbasic block executed and each transition.  If it can do the slower, more\naccurate tracing, it is considered to be not only an instrumentation module,\nbut also a tracer.  How tracers are used is covered more in section\n\\ref{Tracer}.\n\nThe Debug instrumentation is currently a Windows-only instrumentation which\nattaches to the target process using the debugging interface and monitors the\nprocess for a crash or clean exit.  It does not track code coverage, which is\ncommonly referred to as ``black box'' fuzzing.  The driving force behind this module was\nthat there is no reliable way to determine if a process crashed or exited normally\non Windows without debugging it.  Unlike Unix, the return code does not contain this information,\nso there is no way to tell the difference between a program that decided to\nexit with a non-zero status code to indicate an error, and a crash.\n\nThe Return Code instrumentation module is similar to the Debug instrumentation\nin that it does not track code coverage. On \\POSIX{} operating systems, the return\ncode of a process is a 32-bit integer.  Only the eight least significant bits\nare provided to the shell, but the full value is available from the\n\\texttt{waitpid()} function and macros such as WIFEXITED and WIFSIGNALED can be used to\ndiscern between a clean exit with a non-zero exit code and an actual crash.\n\nThe DynamoRIO instrumentation module is a modified version of the\ninstrumentation in WinAFL. It requires the user to specify a function which\nis responsible for loading and processing the input data. At the end of the\ntarget function, DynamoRIO will kill the process. Alternatively, this instrumentation supports\npersistence mode, which allows for multiple inputs to tested without restarting a\nprocess.  This mode reduces the overhead of restarting the process, and thus\nincreases the number of tests that can be conducted per second.  Persistence\nmode in the DynamoRIO instrumentation is accomplished by resetting the stack and\njumping to the beginning of the function again, which may work in\ntest applications, but does not tend to work in real-world software.  \nThe typical result is a crash due to global state which is never reset.\nThis includes things like open file handles, allocated memory, application specific state\ninformation, etc. The target function must be identified outside of\nKillerbeez and is typically done manually. By default, an \\AFL{}-style bitmap\nis generated to track code coverage. The module takes options which allow this\nto be changed to obtain a full trace (see section \\ref{Tracer} for details on\nthis feature). Other options include a list of libraries which should be\ncovered by instrumentation. This allows things like tracking code coverage in acrord32.dll\nwhen fuzzing Adobe Reader~\\cite{adobereader}.  Tracking code coverage in modules is an important\nfeature, because the majority of the input parsing code is encapsulated in a\nlibrary and recompiling is not an option.\n\nThe Intel PT module uses \\IPT{} to gather trace information for CPUs which\nsupport \\IPT{}. This requires a kernel component to manage \\IPT{}, but\nthe tracing itself is done in hardware with a modest performance overhead\\cite{iptoverhead,harnessingipt}. The\ncurrent implementation of this instrumentation module~\\cite{killerbeezipt} only works on Linux, via\nthe ``perf'' subsystem. Expanding this to support the \\IPT{} driver in Windows\nis planned in the future. Regardless of operating system,\nthe output of \\IPT{} relevant for tracing execution in fuzzing are the \\TNT{} and\n\\TIP{} packets.  The former tracks ``the direction of direct control branches,''\nwhile the latter records ``the target \\IP{} of indirect branches, exceptions,\ninterrupts and other branches or events.''\\cite{intelptmanual}\n\nThe \\TNT{} packets form a bit stream, while the \\TIP{} packets contain a series of\ninstruction pointer addresses, which may be compressed if the \\IP{}'s upper bits match\nthe previous \\IP{} value. However, these two packet types are not synchronized. For example, if there are four\nconditional branches, an indirect jump, and then four more conditional branches, \\IPT{} will generate\na \\TIP{} packet and one byte of \\TNT{} packet data with no\ninformation about the order in which the \\TIP{} and \\TNT{} events occurred.  To make sense of\nthis data, the executable must be analyzed to determine the order in which to\npull information from the \\TNT{} and \\TIP{} queues. As this disassembly adds to the performance\noverhead, the Intel PT instrumentation module does not do it. Instead it\ntakes a hash of the entire \\TNT{} bit stream and the entire set of \\IP{} addresses in the \\TIP{} packets.\nThis does not identify what code was executed, but it does determine if a\ndifferent code path was taken, as a different code path would result in\ndifferent packet data, and thus a different hash. Because the packet order is\nnot synchronized between the \\TNT{} and \\TIP{} streams, hashes are taken of each\nstream separately and the pair of hashes are used to identify a particular code path.\n\nThe \\IPT{} instrumentation also supports persistence mode.  Persistence mode in the\n\\IPT{} instrumentation is accomplished by modifying the target to repeatedly\naccept a new input from the fuzzer, call the code to be fuzzed, and reset the\ntarget state.  While persistence mode in the \\IPT{} instrumentation requires\nsource code and manual modifications to the target software, it is much more\nlikely to work properly as compared to the DynamoRIO instrumentation persistence\nmode.\n\nThe only other public fuzzers known to implement Intel PT based tracing are\nHonggfuzz\\cite{honggfuzz}, Richard Johnson's modified version\\cite{winaflintelpt} of\nWinAFL, and kAFL\\cite{kafl}. Honggfuzz does full packet decoding using the\nIntel's processor trace decoder library\\cite{libipt} which incurs a much\nhigher overhead than the Killerbeez implementation.  Richard's fork of WinAFL\ndid full packet decoding at one point, but does not seem to use the trace data\nat all with the latest commit.\\cite{winaflcommit} Instead, there is a comment which says\n``FIXME winipt'' and the calls to \\texttt{PtTraceProcessStart()} and\n\\texttt{PtTraceProcessStop()} have been commented out, which implies this is still a\nwork in progress. kAFL utilizes a custom packet decoder built specifically to\nallow efficient parsing of the \\IPT{} packets and disassembly of the target\nexecutable.  As such, kAFL's \\IPT{} parser is faster than the Intel processor trace\ndecoder library,\\cite{harnessingipt} but is slower than the approach taken in Killerbeez which\nrefrains from analyzing the target executable.\n\nFinally, we have the \\AFL{} instrumentation module, which is based around the\ninstrumentation injected at compile time by afl-gcc or the \\AFL{}\nllvm module. Much of the code was taken directly from \\AFL{} and adapted to\nconform to the Killerbeez instrumentation \\API{}. This module has been tested\nwith Linux and macOS, but should work on any \\POSIX{} operating system.\nThe injected fork server is a slightly modified version of the\nimplementation in the \\AFL{} project. The forkserver is also used by the\nIntel PT module, which splits the ``fork'' and ``run'' actions, as \\IPT{} needs\nto be initialized between these two steps.  The original AFL implementation\ncombined these two actions, as they did not have any use case that required\nthem to be separate.  The \\AFL{} instrumentation modules also\nimplements the persistence mode feature\nincluded in \\AFL{}.  The \\AFL{} instrumentation persistence mode is implemented\nsimilarly to the \\IPT{} instrumentation persistence mode and has similar\nadvantages and disadvantages. \\AFL{}'s QEMU user mode tracing is also included in Killerbeez,\nhowever this mode only works on Linux as QEMU user mode is only\navailable there.  QEMU chain caching, which is disabled in \\AFL{},\nhas been enabled in the Killerbeez implementation via the patch made by Andrea Biondo.\\cite{qemuspeedup} This patch\nto QEMU ensures chains are properly tracked and results in a 3-4x improvement\nin performance.\n\nThis puts the Killerbeez implementation of the source-based \\AFL{}-style\ninstrumentation equivalent with the original implementation and the QEMU\nfeature significantly faster, showing the advantages of combining the\ninnovations of different authors.\n\n\\subsection{Tracer} \\label{Tracer}\nA tracer is an instrumentation module which captures detailed trace\ninformation about exactly which basic blocks were executed, along with the\ntransitions between them and implements some optional functions in the Killerbeez instrumentation \\API{}\nwhich return this information.  This coverage information is commonly referred\nto as nodes and edges.\n\nThe DynamoRIO instrumentation module is an example of both a normal\ninstrumentation module and a tracer. By default, it does lightweight tracing to\nobtain the \\AFL{}-style bitmap coverage information and returns an error if it\nis asked for nodes and edges. The ``edges'' option can be enabled to\nswitch the module to capture full trace information.\nEnabling the more accurate tracing mode has a larger overhead, so it is not\nused for every iteration of fuzzing.\n\nAs a counterexample, the Intel PT instrumentation module is currently not a\ntracer.  Without full \\IPT{} packet decoding, it is not possible for this\nmodule to obtain such detailed information.\n\nAny time trace information is found, the assimilator stores it in the manager's\ndatabase in a standard format.  This is possible because the Killerbeez instrumentation \\APIs{} which get\nnodes and edges require the data to be in a specific format.  Any other trace\ndata is allowed to be in any format, as it is passed around as an opaque blob\nand not consumed by anything other than the instrumentation module which\ncreated it.  Trace data is accessible via the manager's \\REST{} \\API{}.\n\nThe trace data can later be used to reduce the set of seeds to only include the minimum\nnumber of files, or the minimum file size, which hits the maximum amount of\ncode. The concept of minimizing test corpora while maintaining the maximum code\ncoverage dates back to at least October of 2008, when Peach Fuzzer version 2.2\nwas released, which included the minset tool.\\cite{peach22}  There are a number\nof different algorithms which could be chosen, which is why this is handled by\nan optional add-in which can be swapped out at will, as shown in Figure\n\\ref{fig:Killerbeez-integrations}.\n\nThis granular code coverage data can also be used for weighting seeds based on\nvarious algorithms, such as attempting to get to code which is less frequently\ncovered, or targeting a particular piece of code such as a parser which was\nmanually identified or a new piece of code which was identified using automated\npatch analysis. This would be implemented by the seed selector module from the\ncampaign manager.  The most basic seed selection algorithm would weigh\nall of the seeds equally and go through them in a round-robin fashion.\n\nDetermining how often to use the tracer is the responsibility of the job\ntype selector in the campaign manager.  This module has the ability, but\nnot the obligation, to take node and edge coverage into account.\nThe decision of when to run the tracer is\nmade based on whether the trace data is necessary for the configured Killerbeez\ncomponents and how much of a performance impact the tracer will have (as\ncompared to scheduling fuzzing jobs during the same time period).\nThe simplest\nalgorithm would never enable the tracer, which would inhibit all other\ncomponents from using trace data.\n\n\\subsection{Picker} \\label{Picker}\nInstrumenting all libraries for a real application using a dynamic\ninstrumentation technology is prohibitively slow. Even when using more\nefficient instrumentation methods, there is a desire to minimize the amount of\noverhead in instrumentation so more effort can be spent finding bugs instead of\nperforming bookkeeping operations.  The Picker automatically determines which\nlibraries should be instrumented so the fuzzer can limit instrumentation to\nwhat is interesting, and omit all the other libraries. For deterministic\ncode, this comes with a level of certainty that what is instrumented is, in\nfact, all of the code which handles the input the fuzzer is sending it. This\nstep is taken when configuring a target, before any fuzzing begins.\n\nThe Picker determines the library to instrument by running through all seed values and instrumenting each\nlibrary separately. If the code is never executed, or the coverage is the\nsame for every input, it implies the library is not important in parsing the\ninput.  It is possible that the library handles some aspect of the\nprotocol which was simply never executed by any of the seed inputs, however,\nwith a diverse set of starting inputs, there can be some confidence that\nnothing is omitted for the list of modules to instrument.\n\nCode which is non-deterministic causes problems with the algorithm above.\nTracking down each source of non-determinism and attempting to eliminate it\nwould be a very tedious task. An example of one source of non-determinism was a\ncall to a graphics libraries failing to allocate a surface object. It is\ndifficult to know how to remove this type of non-determinism. Every system call\nwhich fails on a regular basis would have to be analyzed, and a decision made\non what to do about it.  Making it always fail may cut off code paths later\nwhich trigger a bug which would be reachable in the program in practice.\nRepeatedly making the call until it succeeded may also eliminate code paths\nlater, plus makes execution slower at best and an infinite loop at worst.\n\nInstead of trying to force the non-deterministic program to behave in a\ndeterministic fashion, the Picker accepts that the code in question is\ngoing to behave erratically and ignores the execution data related to those\nsections of code.  This is done by running the same input through the target\n\\textit{N} times and finding all of the bytes in the coverage info which\nvary. By default, \\textit{N} is 10, however it should be large enough that a\nsignificant number of executions do not identify any more bytes where the\nexecution varied. The correct value for N will vary from one target to another.\nThe data for Windows Media Player, shown in Figure \\ref{fig:picker}, indicates\nnew non-deterministic code was being found at 325 executions. However, after\n10 executions, more than half of the non-deterministic transitions were\nidentified for each of the four libraries.\n\nChoosing the number of executions is a trade-off between spending time up front\nto get more efficient fuzzing, and getting started more quickly but being less\nefficient.  In addition to determining which libraries to instrument, the\nidentified non-deterministic transitions can be used by some instrumentation\nmodules in determining if an input caused new code paths to be found.  This is\ncurrently only implemented in the DynamoRIO instrumentation module, but will\nlikely be implemented in the several of the instrumentation modules listed in\nthe \\nameref{Future Work} section.\n\n\\begin{figure}[htb]\n\\centering\n\\includegraphics[width=3.5in]{picker.png}\n\\caption{Total Non-deterministic Basic Block Transitions Detected per Execution In Windows Media Player Libraries}\n\\label{fig:picker}\n\\end{figure}\n\nThe algorithm the Picker uses is not effective with all instrumentation\nmodules. The Picker uses the instrumentation module which will be used in\npractice, and uses the same options for that module. It then operates on\nthe opaque blob which represents the code coverage information.  It does\nthis without any knowledge of the internal format.  Anything which uses the\n\\AFL{}-style bitmap will work fine.  This would include the DynamoRIO and\n\\AFL{} instrumentation modules. The \\IPT{} instrumentation output is the hashes\nof the \\TNT{} and \\TIP{} packets, so any non-determinism will change every byte of\nthe instrumentation data.  This will cause the Picker to mask out all bytes of\nthe coverage data, which is not useful. If the Intel PT\ninstrumentation was also a tracer, it would be capable of using an internal\nformat which is compatible with the Picker.\n"
  },
  {
    "path": "docs/paper/introduction.tex",
    "content": "Over the past few years, coverage-guided fuzzing has become a popular way to\nfind software and hardware vulnerabilities due to advances in publicly\navailable tools such as \\AFL{}\\cite{afl} and its derivatives.\\cite{vanhauser} Many\nfuzzers have ``trophy cases'' consisting of a list of bugs known to be found with that tool to\ndemonstrate their effectiveness against real-world applications.\\cite{rustfuzztrophy}\\cite{honggfuzz}\\cite{afl}  However, most\ntools are primarily focused on finding bugs in open source, command line Linux\nsoftware which reads input from files or standard input. While there has been some\nexploration to get \\AFL{} working on other operating\nsystems\\cite{aflosx,winafl} as well as supporting network\ninput,\\cite{netafl,preeny} these features are often omitted.\n\nMost of the published improvements over the original version of \\AFL{} are\nimplemented as forks of\n\\AFL{}.\\cite{aflfast,aflgo,fairfuzz,perffuzz,pythia,collafl}\nThus the enhancements are mutually exclusive, short of embarking on a\ndevelopment effort to review the modifications and merge the forks back\ntogether, manually resolving any conflicts and incompatibilities.  The issue\nof incompatibility is not limited to projects which are modified versions of\n\\AFL{}. Mixing and matching features from various tools requires a significant\namount of effort. It involves setting up a build environment, which in itself\ncan be a challenge, as well as merging together different code bases.  Often\ntimes the code bases will be written in different programming languages, which\nmeans they need to be integrated in some way.\nUsing a tool against a type of software it has never been\nused against before, such as using a Linux kernel fuzzer against another\noperating system, can find a large number of bugs\\cite{anton}.  However, in practice, security\nprofessionals rarely have the amount of time to invest to get the tools working\ntogether, or working in other contexts.\n\nWe present Killerbeez, a fuzzing framework which brings together many of the\nvarious security analysis tools so they can be used together.  Killerbeez\nsupports multiple operating systems, can handle target applications with or\nwithout source code, and software with a \\GUI{}.\nFurthermore, the input mutation algorithms, instrumentation, seed selection\nalgorithms, and methods for feeding input data to the target are all easily\ninterchangeable via modular components.  This modularity enables two\nproperties (1) easily mixing and matching\ntactics from different researchers and (2) implementing new algorithms easily.\nFinally, Killerbeez is scalable, using \\BOINC{}\\cite{boinc} to distribute work\nto multiple nodes from a central server.\n\nOur contributions include:\n\\begin{enumerate}[noitemsep]\n\\item An \\API{} combining the different components of a fuzzer in a pluggable (modular) way to allow for extensibility\n\\item A collection of existing fuzzers modified to use the \\API{}\n\\item A method for automatically determining which libraries are likely to\n\tcause a crash, so those can be targeted while fuzzing\n\\item A technique for quickly utilizing \\IPT{} trace information to identify unique code traces while fuzzing\n\\item Ability to automatically filter out trace data related to non-deterministic code\n\\end{enumerate}\n\nSection \\ref{Background} covers background information, section\n\\ref{Killerbeez Overview} provides an overview, the implementation is covered\nin section \\ref{Implementation}, and sections \\ref{Related Work},\n\\ref{Future Work} and \\ref{Conclusion} cover related work, future, work and\nconclusion, respectively.\n"
  },
  {
    "path": "docs/paper/killerbeez.tex",
    "content": "\\documentclass[twocolumn]{article}\n\\input{packages}\n\n\\title{Killerbeez: Fuzzing Framework to Bring Together the State of the Art}\n\\author{Adam Nichols, Ian Bridges, Benjamin Lipton, Jeff Stewart, Tomas Tillery \\\\\nGRIMM\\\\\n\\{adam,ben,jeffball,tomas\\}@grimm-co.com icb@rice.edu\\footnote{Research was done while at GRIMM}\\\\\n}\n\\date{Published: 18 OCT 2019}\n\n\n% Ensure all acronyms we use are expanded on first use\n\\def\\AFL{\\renewcommand\\AFL{AFL}American Fuzzy Lop (AFL)}\n\\def\\COM{\\renewcommand\\COM{COM}Common Object Model (COM)}\n\\def\\BOINC{\\renewcommand\\BOINC{BOINC}Berkeley Open Infrastructure for Network Computing (BOINC)}\n\\def\\BTS{\\renewcommand\\BTS{BTS}Branch Trace Store (BTS)}\n\\def\\GUI{\\renewcommand\\GUI{GUI}Graphical User Interface (GUI)}\n\\def\\IOCTLs{\\renewcommand\\IOCTLs{IOCTLs}Input/Output Controls (IOCTLs)}\n\\def\\IPC{\\renewcommand\\IPC{IPC}Interprocess Comunication (IPC)}\n\\def\\IPT{\\renewcommand\\IPT{IPT}Intel Processor Trace (IPT)}\n\\def\\stdin{\\renewcommand\\stdin{stdin}standard input (stdin)}\n\\def\\TNT{\\renewcommand\\TNT{TNT}Taken Not Taken (TNT)}\n\\def\\TIP{\\renewcommand\\TIP{TIP}Target IP (TIP)}\n\\def\\IP{\\renewcommand\\IP{IP}Instruction Pointer (IP)}\n\\def\\API{% Whether we use API or APIs first, we want to redefine both\n\\renewcommand\\API{API}%\n\\renewcommand\\APIs{APIs}%\nApplication Programming Interface (API)%\n}\n\\def\\APIs{% It would look silly to spell out API and APIs both\n\\renewcommand\\API{API}%\n\\renewcommand\\APIs{APIs}%\nApplication Programming Interfaces (APIs)%\n}\n\\def\\REST{\\renewcommand\\REST{REST}Representational State Transfer (REST)}\n\\def\\POSIX{\\renewcommand\\POSIX{POSIX}Portable Operating System Interface (POSIX)}\n\n\\begin{document}\n% Heading for the first page has the title, author(s) and date\n\\maketitle\n\n\n\\input{abstract}\n\n\\section{Introduction} \\label{Introduction}\n\\input{introduction}\n\n\\section{Background} \\label{Background}\n\\input{background}\n\n% The overview describes what components exist (driver, mutator, manager, etc.)\n% and why. Examples are provided as needed, but just enough to cover the\n% concepts.\n\\section{Killerbeez Overview} \\label{Killerbeez Overview}\n\\input{overview}\n\n% The implementation goes over each component in detail to showcase what we\n% have available so far.\n\\section{Implementation} \\label{Implementation}\n\\input{implementation}\n\n%\\section{Evaluation} \\label{Evaluation}\n\n\\section{Related Work} \\label{Related Work}\n\\input{related_work}\n\n% This is where we cover planned expansions, both in terms of additional things\n% to pull in, such as grammars which generate test files, Driller style\n% integration of symbolic execution, and additional modules for the existing\n% components (drivers, instrumentation, etc.).\n\\section{Future Work} \\label{Future Work}\n\\input{future_work}\n\n\\section{Conclusion} \\label{Conclusion}\n\\input{conclusion}\n\n\\section{Acknowledgments} \\label{Acknowledgments}\n\\input{acknowledgments}\n\n\\section{References} \\label{References}\n\\renewcommand{\\section}[2]{}  % Removes the title thebibliography wants to add\n\\input{references}\n\n\\end{document}\n"
  },
  {
    "path": "docs/paper/overview.tex",
    "content": "The core components of Killerbeez can be split into two logical categories\nof orchestration and handling interactions with the target\\footnote{Software under test is referred to as the ``target.''}\nprogram.  The former refers to decisions such as what\ninputs to use as seed data,\\footnote{Initial inputs which will be modified\nare referred to as ``seeds,'' and the set of initial inputs used is referred to as the ``seed corpus.``} which mutation algorithms to use, how to minimize\nthe input corpus and other decisions which are best left to a central\ncontroller.  The latter category contains actions such as launching the target;\nfeeding the target input data; tracking code coverage; determining when the target is\ndone processing the input; and reporting whether the target crashed, froze due\nto something like an infinite loop, or executed new portions of code.\n\n\\subsection{Orchestration}\nKillerbeez coordinates the entire distributed fuzzing\ncampaign. The orchestration tasks are handled by the Killerbeez ``manager,''\nwhich runs on a central server. After some initial configuration to specify\ntargets and strategies, the manager decides what jobs to schedule next.\nIt tracks targets available for fuzzing, selects which tools to\nuse and how to configure them, manages the corpus of inputs by removing\nless interesting ones, and dispatches jobs to worker nodes to be executed.  It also\nprovides a \\REST{} \\API{} that allows a researcher to trigger actions and\nextract results manually, or to integrate an external system that\ndoes so autonomously. The components of the manager are depicted in Figure\n\\ref{fig:Killerbeez-server}.\n\n\\begin{figure*}[!ht]\n\\centering\n\\includegraphics[width=\\textwidth]{KILLERBEEZ_Server_Architecture.png}\n\\caption{Killerbeez Server Architecture}\n\\label{fig:Killerbeez-server}\n\\end{figure*}\n\n\\subsubsection{Work Distribution}\nThe most basic role of the manager is to provide an interface for queuing tasks\nto be executed on worker nodes and processing the results. A \\BOINC{} server is\nused to transmit the work to nodes and receive results. The manager provides a\nlayer on top of \\BOINC{} that understands Killerbeez-specific parameters such as\nthe mutator and instrumentation to use, making it simple to submit jobs to\n\\BOINC{} that run the fuzzer with an appropriate command line. Jobs\nsubmitted via the manager also automatically set up Killerbeez and the target\nsoftware, so the worker nodes are not required to have any special software\ninstalled besides the off-the-shelf \\BOINC{} client.\n\nWhen jobs complete, the manager uses the \\BOINC{} ``assimilator'' interface to\ncollect the results and update the manager's database. The information inserted\nincludes not only the direct output of the fuzzer (new inputs that cause new\npaths in the binary to be hit) but metadata about the job as well. This metadata\ncould include the average execution time of the binary (to help choose\nparameters that execute faster), the final instrumentation state from fuzzing\n(to help the next job find fewer duplicate paths), and various other statistics.\n\nBecause the manager is not responsible for running the target application, it\ndoes not need to run on the same platform as the target.  Thus, it can run on Linux while\nserving work to be executed by Windows or macOS machines.\n\n\\subsubsection{Integration}\nThe manager provides a \\REST{} \\API{}, which allows clients\nto access and configure seed data, fuzzing targets, and low-level metadata\nproduced during fuzzing.\nThis will enable future enhancements to be made by taking advantage of\nexternal tools, such as\nusing a test case generator to produce new seed data. Another planned integration\nis to use Driller\\cite{driller} to generate program inputs which reach\ncode that has not yet been reached by mutation.\n\nThe \\REST{} \\API{} is also used for some of the manager's built-in\nfunctionality. The campaign manager, the component that plans new jobs to\nexecute, gathers data using the \\REST{} \\API{}, analyzes the data to determine the\nnext job to create, and then submits the resulting job via the \\REST{} \\API{}.\nThe corpus minimization uses the \\REST{} \\API{} to obtain execution traces and\nmodify the working set of seed values. Accessing data via the \\REST{} \\API{}\nallows these components to be less coupled with the internals of the manager,\nenabling them to run as standalone processes. Figure\n\\ref{fig:Killerbeez-integrations} shows how the \\REST{} \\API{} enables\nintegration with various tools.\n\n\\begin{figure*}[!ht]\n\\centering\n\\includegraphics[width=\\textwidth]{KILLERBEEZ_Integrations.png}\n\\caption{Killerbeez Integration with External Tools}\n\\label{fig:Killerbeez-integrations}\n\\end{figure*}\n\n\n\\subsubsection{Tracing and Corpus Minimization} \\label{Corpus Minimization}\nKillerbeez also introduces the idea of obtaining detailed code coverage information about\nexecution for each input which has a unique code path.  This is typically\nnot done by other fuzzers, as obtaining a full execution trace is significantly more overhead than\nthe lightweight instrumentation that \\AFL{} or Honggfuzz\\cite{honggfuzz} use.\\cite{collafl} During\nnormal fuzzing, Killerbeez will generally use lightweight methods of tracking\nexecution. However, having a full trace is useful when minimizing the seed corpus\nand determining which seeds should be weighted more heavily. Reducing the\nnumber of files in the corpus helps fuzzers to more efficiently test targets\nby eliminating inputs which result in the same target functionality being\ntested.\\cite{fileformatfuzzing,softwaredumber} This concept has\nbeen encapsulated in the tracer module.\n\nEach time an input\nis found which hits a new code path, a tracer job can be added via the manager.\nThe new tracer job will be executed by a \\BOINC{} client, just like any other fuzzing job.\nThe results will include full trace data, which will be stored in the manager's\ndatabase.  The data can be retrieved via the \\REST{} \\API{}, enabling a ``corpus\nminimizer'' tool to explore the paths covered by the current input corpus and\nremove inputs that are redundant. More\ninformation about the tracer and corpus minimizer can be found in section\n\\ref{Tracer}.\n\n\\subsubsection{Work Generation}\nThe manager is also responsible for deciding what work should be performed next.\nThe component that does this is called the ``campaign manager,'' and it consists\nof several pluggable modules that work together to generate jobs. For\njobs that run the Killerbeez fuzzer, the seed selector module specifies an\nalgorithm for choosing the most interesting input to use as a starting point for\nfuzzing, while the job parameter selector module determines parameters like the\nmutator to use for the job or the instrumentation options. It is also possible\nto integrate tools besides the fuzzer into the job system, such as Driller or\nthe tracer. The job type selector module is responsible for choosing which of\nthese tools is currently needed most. The modules can use the \\REST{} \\API{} to\nquery any of the metadata recorded in the database to make their decisions.\n\n\\subsubsection{Scalability}\nThe manager can choose the amount of work done per job by specifying things like the\nnumber of fuzz iterations. By scheduling larger jobs, the manager can scale up to a very large number\nof clients, allowing a substantial amount of\nwork to get done with a minimal amount of coordination and network overhead.\nHowever, if the manager becomes a bottleneck due to the number of workers or\nthe number of API requests, several components could be scaled\nout. The \\BOINC{} server could be moved to its own machine, or even scaled out\nto a cluster.\\cite{boincmultihost} The manager database could also be moved to\nits own machine. The \\REST{} \\API{} server is stateless, so it could be scaled\nfairly easily to run on multiple machines, and components that interact via the\n\\REST{} \\API{}, such as input generators and the campaign manager, can also be\nmoved to run on their own hardware.\n\nIf performance is still a problem even with\nall components scaled up as much as possible, multiple manager servers could be\nset up to run parallel fuzzing campaigns, using the \\REST{} \\API{} to share\nresults between them. In this mode, each manager would act as an input generator\nfor the others.\n\n\\subsection{Preparation}  \\label{Preparation Overview}\nThere is a preparation step in fuzzing workflows which is often overlooked or\ndismissed, that includes setting up the target software and deciding specific\nfuzzing parameters. This occurs before any real fuzzing begins and includes\nthings such as compiling the target, possibly with a specific compiler or\ncompiler flags, determining what options should be enabled in the target\nsoftware, deciding which portions of the code should be tracked for code\ncoverage, and specifying how to deal with non-deterministic code.\n\nThe compilation step is driven by the type of instrumentation chosen,\nwhich is typically just a matter of selecting the option with the lowest\nperformance penalty. Instrumentation does not need to be added at compile\ntime, but it is added here when possible, as it reduces the overhead at runtime.\nWhat options to enable in the target software is target specific and\nsubjective.  It depends on the higher level goals.  If the goal is to find a\nvulnerability with wide applicability, choose default options. If it is to test\nout a specific feature, disable everything except that option. If it is just to\nfind any bug in any configuration, enable everything.  While these are\nimportant questions, the most interesting decision is what to track in terms of\ncode coverage, and how to deal with non-deterministic code.\n\nThe solution \\AFL{} uses is to require the user to manually determine which code\nin the target to instrument. \\AFL{} requires the user to compile the target library\nor executable with a special instrumenting compiler. Alternatively, \\AFL{} can\nuse a modified version of QEMU while fuzzing to instrument all of the libraries\nused by a target at run-time.  As expected, instrumenting all of the libraries\nhas a higher overhead than only instrumenting a few specific modules. Killerbeez\nimproves on this by including a tool\ncalled the ``Picker'' which automatically determines which libraries should be\ninstrumented.  The algorithm for doing so is described in section \\ref{Picker}.\n\nOne important detail is that the picker can not operate effectively when the\ntarget does not have deterministic execution.  If feeding the same file into\nthe application multiple times results in different code being executed, this\nis a problem, not only for the Picker, but also for code coverage in general.\nNon-deterministic code causes new code paths to be taken, making it appear as\nif the input file was the reason new code was executed.  This results in\nerroneously keeping inputs which are not actually valuable.\n\\AFL{} does not deal with this problem directly, but it does alert the user to\nthe fact that the target is non-deterministic. The user can then do things like\nhijack calls to functions such as \\texttt{srand()} which intentionally introduces\nrandomness and non-determinism. This is often done for applications which employ cryptography for\ninitialization vectors and nonces. Under command line Linux applications, hijacking non-determinism introducing functions\nworks fairly well.  On GUI applications in Windows, it does not work as well.\nThere are system calls in Windows which occasionally fail for no apparent reason. This\nshould not be a problem for the target software, as it should be checking the return code to\ndetect and handle this appropriately.  However, when these failures happens it has the\nside effect of making the fuzzer misinterpret the new code coverage to think an uninteresting input was interesting.\nThe details of how non-determinism is handled in Killerbeez are also described in\nsection \\ref{Picker}.\n\n\\subsection{Execution}\nExecution is handled by the client fuzzer program, which is aptly named ``fuzzer.''\nThis can be run manually from the command line, however it is typically run by\nthe manager, via a \\BOINC{} client.  In either case, the fuzzer is responsible\nfor running the target, feeding it input data, tracking code\ncoverage, detecting crashes, and dealing with user interaction such as dialog\nboxes.\n\n\\begin{figure*}[!ht]\n\\centering\n\\includegraphics[width=\\textwidth]{killerbeez-high-level-block-diagrams.png}\n\\caption{Killerbeez Fuzzer Overview}\n\\label{fig:Killerbeez-fuzzer-overview}\n\\end{figure*}\n\nThe fuzzer consists of glue code that combines together various\nmodules, which is where all the interesting things occur. The purpose of\nthe Driver, Mutator and Instrumentation modules used in the fuzzer are covered in sections\n\\ref{Driver Overview}, \\ref{Mutator Overview}, and\n\\ref{Instrumentation Overview}, respectively.  The relationships between these components are depicted in Figure \\ref{fig:Killerbeez-fuzzer-overview}. The modules which currently\nexist and how they work are covered in the \\nameref{Implementation}\nsection.\n\nThe same code base is used on Windows, Linux, and macOS to enable as much code\nre-use as possible.  Most of the mutators are shared among all platforms.\nOnly the Radamsa mutator, which runs as a separate process, has platform specific code.\nSome of the instrumentation and driver\\footnote{\n``driver'' refers to driver modules, not operating system drivers.}\nmodules, such as the \\IPT{} instrumentation and WMP driver, contain platform specific and sometimes target specific code.\n\n\\subsubsection{Driver} \\label{Driver Overview}\nKillerbeez offers drivers, which are target-specific wrappers that abstract\naway the concept of loading data into a target and enable finer\ndefinition of the failure modes of a particular piece of software. While\ntypical fuzzers look for crashes and hangs, specifically-written drivers can\nhave more context about a given fuzz target.  Better understanding of the fuzz\ntarget's behavior means that Killerbeez can make better-informed decisions\nabout the status of a target after a particular input, and it can terminate or\nclassify the result of a particular input more quickly than waiting for a\ntimeout.\n\nFirst, the driver module is responsible for feeding inputs to a target.  This\nis a departure from most fuzzers, which only work for one type of input.  In\nthe case of AFL, the input is a file (or \\stdin{}, which is also a file under\nUNIX).  Syzkaller\\cite{syzkaller}, on the other hand, uses only system calls.\nEach tool then has to implement their own mutation algorithms, code coverage,\nresults collection and so forth. Drivers enable Killerbeez to reuse all of\nthese components and select how to interact with the target by simply selecting\nthe appropriate driver.  Abstracting this away allows for more exotic use\ncases, such as fuzzing \\IOCTLs{}, network servers, network clients, \\IPC{} such as\nMach Messages, XPC, Distributed Objects, \\COM{}, and others, all with minimal\neffort.\n\nThe second thing drivers are responsible for is dealing with any target\nspecific issues, such as handling GUI interactions.  For example, if a PDF file\nwith a malformed header is given to a PDF reader application, it typically will\npop up a dialog box indicating that the file is corrupt. Fuzzers such as\nHonggfuzz or WinAFL\\cite{winafl} would wait until a timeout expires.\\footnote{WinAFL can\nexit at the end of a function, but dialog boxes tend to prevent that function\nfrom returning in practice.} This results in all executions which hit this code\npath to appear as a hung process.  In Killerbeez, a driver could be written for\nthe specific PDF reader which monitors the application for dialog boxes,\ndetects when dialog boxes appear, analyzes the text of the dialog box and\ndetermines that the status is a clean exit rather than a hang.  This would allow\nthe fuzzer to move on to the next input more quickly, as it would know the\ninput is done being processed and would not need to wait for the full timeout\nperiod.  It also helps discern between a hang, which may indicate a denial of\nservice vulnerability such as an infinite loop, and an error which is handled\nin the expected manner. For another example, see the Windows Media Player\ndriver in section \\ref{Driver}.\n\nMany of the drivers work on many fuzzing targets in a particular category.\nTargets which accept input from the network are handled by the Network Server\ndriver module, programs which open a file are generally handled by the file\ndriver and so forth.  Other drivers can be written to handle things which are\nspecific to particular pieces of software.  Some targets will handle opening files\ndifferently if opened via double clicking an icon as compared to using the open\noption from the file menu. Other examples include error message analysis to\ndetermine if the system should move on to the next input, or if it should click\n``OK'' and continue (e.g. in the event of a warning message).\n\n\\subsubsection{Mutator} \\label{Mutator Overview}\nKillerbeez also implements ``mutators,'' which are abstractions on modifying\nprogram input. They decide where to modify bytes in the input data, and how\nto modify them.\n\nKillerbeez uses a selection of user-selectable mutators. Parameters are passed\nto the mutator module via the driver, which control the operation of the\nmutator. For example, the bit flip mutator flips a parametrized number of bits\nthroughout the entire input, one at a time.\n\nModular mutators also enable trivial combination of different approaches. Using\nthe multipart mutator, different mutators can be applied to different parts of\nthe input. This is required for efficiently fuzzing network protocols, as it is\noften desirable to not mutate the initial packets as they may include a handshake or\nauthentication.  Any mutation to this section would prevent the majority of code from being\nexecuted, as the target software would execute an error path instead. It can\nalso be used to ensure that the first few bytes in a file are not modified so\nthe file will still be recognized as being the correct file type.\n\n\n\\subsubsection{Instrumentation} \\label{Instrumentation Overview}\nInstrumentation modules are responsible for tracking program execution and\ndetermining if an input has caused the target program to execute new code. How it does this,\nand what level of granularity is used, are questions left to the module author.\nThere is an \\IPT{} instrumentation module which is very high resolution.\nIf a loop somewhere in the target is executed 178 times instead of 177\ntimes, it will detect this as a new code path, as the state explored is\ndifferent than what was seen before.  The \\AFL{} instrumentation module, on the\nother hand, would not consider this to be an input which causes the execution of new code.\nThe \\AFL{} instrumentation module uses a bucketing system that groups executions of the same\ncode and considers anything which executes a portion of code 128-255 times to\nbe equivalent.\\cite{aflbucketing}\n\nSometimes instrumentation modules need to interface with kernel drivers, which are\nimplemented differently on different operating systems. For instance, the \\IPT{}\ninstrumentation module uses the perf subsystem on Linux, which is not available\non macOS or Windows. Other instrumentation technologies, such as Intel's\nPin~\\cite{pin}, have a very similar interface across different operating\nsystems, which means more of the code in the instrumentation module can be\nre-used, simply using \\#ifdef directives if there are portions which are\nspecific to a particular operating system.\n"
  },
  {
    "path": "docs/paper/packages.tex",
    "content": "\\usepackage{enumitem}\n\\usepackage[margin=0.75in]{geometry}\n\\usepackage{graphicx}\n% Allow breaking urls at hyphens (https://tex.stackexchange.com/a/3034)\n\\PassOptionsToPackage{hyphens}{url}\n\\usepackage[hidelinks]{hyperref}\n\\usepackage{multicol}\n"
  },
  {
    "path": "docs/paper/references.tex",
    "content": "\\begin{thebibliography}{99} % two-digit numbers, max\n\n\\bibitem{afl}\n  Michal Zalewski. % Author\n  \\textit{American Fuzzy Lop}. % Title\n  \\url{http://lcamtuf.coredump.cx/afl/}. % URL\n\n\\bibitem{vanhauser}\n  Marc ``van Hauser'' Heuse.\n  \\textit{Collection of Patches to AFL}.\n  \\url{https://github.com/vanhauser-thc/afl-patches/}.\n\n\\bibitem{aflosx}\n  Ben Nagy.\n  \\textit{AFL on OSX}.\n  \\url{https://github.com/bnagy/osx-afl-llvm}.\n\n\\bibitem{winafl}\n  Ivan Fratric.\n  \\textit{WinAFL - Fork of AFL for Windows}.\n  \\url{https://github.com/ivanfratric/winafl}\n\n\\bibitem{netafl}\n  Maksim Shudrak.\n  \\textit{winAFL patch to enable network-based apps fuzzing}.\n  \\url{https://github.com/mxmssh/netafl}\n\n\\bibitem{preeny}\n  Yan Shoshitaishvili.\n  \\textit{Preeny: preload libraries for pwning stuff}.\n  \\url{https://github.com/zardus/preeny}\n\n\\bibitem{boinc}\n  University of California.\n  \\textit{Berkeley Open Infrastructure for Network Computing}.\n  \\url{https://boinc.berkeley.edu/}.\n\n\\bibitem{peach22}\n  Michael Eddington.\n  \\textit{Peach Fuzzer version 2.2}.\n  \\url{https://sourceforge.net/projects/peachfuzz/files/Peach/2.2/}.\n\n\\bibitem{aflfast}\n  Marcel B\\\"ohme, Van-Thuan Pham, Abhik Roychoudhury.\n  \\textit{Coverage-based Greybox Fuzzing as Markov Chain}.\n  \\url{https://www.comp.nus.edu.sg/~mboehme/paper/CCS16.pdf}.\n\n\\bibitem{aflgo}\n  Marcel B\\\"ohme, Van-Thuan Pham, Manh-Dung Nguyen, Abhik Roychoudhury.\n  \\textit{Directed Greybox Fuzzing}.\n  \\url{https://mboehme.github.io/paper/CCS17.pdf}.\n\n\\bibitem{fairfuzz}\n  Caroline Lemieux, Koushik Sen.\n  \\textit{FairFuzz: Targeting Rare Branches to Rapidly Increase Greybox Fuzz Testing Coverage}.\n  \\url{https://arxiv.org/pdf/1709.07101.pdf}.\n\n\\bibitem{perffuzz}\n  Caroline Lemieux, Rohan Padhye, Koushik Sen, Dawn Song.\n  \\textit{PerfFuzz: automatically generating pathological inputs}.\n  \\url{https://dl.acm.org/citation.cfm?doid=3213846.3213874}.\n\n\\bibitem{pythia}\n  Marcel B\\\"ohme.\n  \\textit{STADS: Software Testing as Species Discovery}.\n  \\url{https://mboehme.github.io/paper/TOSEM18.pdf}.\n\n\\bibitem{collafl}\n  Shuitao Gan, Chao Zhang, Xiaojun Qin, Xuwen Tu, Kang Li, Zhongyu Pei, Zuoning Chen.\n  \\textit{CollAFL: Path Sensitive Fuzzing}.\n  \\url{http://chao.100871.net/papers/oakland18.pdf}.\n\n\\bibitem{syzkaller}\n  Google.\n  \\textit{syzkaller - kernel fuzzer}.\n  \\url{https://github.com/google/syzkaller}.\n\n\\bibitem{trinity}\n  kernelslacker.\n  \\textit{Trinity - Linux system call fuzzer}.\n  \\url{https://github.com/kernelslacker/trinity}.\n\n\\bibitem{osxfuzz}\n  MWR Labs.\n  \\textit{macOS Kernel Fuzzer}.\n  \\url{https://github.com/mwrlabs/OSXFuzz}.\n\n\\bibitem{ioctlfuzzer}\n  eSage Lab.\n  \\textit{IOCTL Fuzzer}.\n  \\url{https://github.com/Cr4sh/ioctlfuzzer}.\n\n\\bibitem{ioctlbf}\n  Jeremy Brun.\n  \\textit{Windows Kernel Drivers fuzzer}.\n  \\url{https://github.com/koutto/ioctlbf}.\n\n\\bibitem{ossfuzz}\n  Google.\n  \\textit{OSS-Fuzz - Continuous Fuzzing for Open Source Software}.\n  \\url{https://github.com/google/oss-fuzz}.\n\n\\bibitem{driller}\n  Nick Stephens, John Grosen, Christopher Salls, Audrey Dutcher, Ruoyu Wang,\n  Jacopo Corbetta, Yan Shoshitaishvili, Christopher Kruegel, Giovanni Vigna.\n  \\textit{Driller: Augmenting Fuzzing Through Selective Symbolic Execution}.\n  \\url{http://www.cs.ucsb.edu/~chris/research/doc/ndss16_driller.pdf}.\n\n\\bibitem{boincmultihost}\n  BOINC.\n  \\textit{Increasing Server Capacity}.\n  \\url{https://boinc.berkeley.edu/trac/wiki/MultiHost}.\n\n\\bibitem{pin}\n  Intel Corporation.\n  \\textit{Pin - A Dynamic Binary Instrumentation Tool}.\n  \\url{https://software.intel.com/en-us/articles/pin-a-dynamic-binary-instrumentation-tool}.\n\n\\bibitem{ni}\n  Aki Helin.\n  \\textit{Ni mutator}.\n  \\url{https://github.com/aoh/ni}.\n\n\\bibitem{radamsa}\n  Aki Helin.\n  \\textit{Radamsa - a general-purpose fuzzer}.\n  \\url{https://gitlab.com/akihe/radamsa}.\n\n\\bibitem{radamsaresults}\n  Aki Helin.\n  \\textit{Radamsa - Some Known Results}.\n  \\url{https://gitlab.com/akihe/radamsa/blob/master/README.md#some-known-results}.\n\n\\bibitem{radamsatob}\n  Trail of Bits.\n  \\textit{Grr Radamsa Modifications}.\n  \\url{https://github.com/trailofbits/grr/tree/master/third_party/radamsa}.\n\n\\bibitem{radamsagrrproblems}\n  Aki Helin.\n  \\textit{Grr Radamsa Modifications Comments}.\n  \\url{https://gitlab.com/akihe/radamsa/issues/28#note_77242061}.\n\n\\bibitem{zzuf}\n  Sam Hocevar.\n  \\textit{zzuf - general purpose fuzzer}.\n  \\url{https://github.com/samhocevar/zzuf}.\n\n\\bibitem{synfuzz}\n  Joe Rozner.\n  \\textit{Synfuzz - re-targetable grammar based test case generation}.\n  \\url{https://github.com/jrozner/synfuzz}.\n\n\\bibitem{dyninst}\n  The University of Wisconsin, University of Maryland.\n  \\textit{DyninstAPI: Tools for binary instrumentation, analysis, and modification}.\n  \\url{https://dyninst.org/}.\n\n\\bibitem{brundlefuzz}\n  Carlos Garcia Prado.\n  \\textit{BrundleFuzz - a distributed fuzzer for Windows and Linux using dynamic binary instrumentation}.\n  \\url{https://github.com/carlosgprado/BrundleFuzz}.\n\n\\bibitem{angora}\n  Peng Chen, Hao Chen.\n  \\textit{Angora: Efficient Fuzzing by Principled Search}.\n  \\url{https://angorafuzzer.github.io/}.\n\n\\bibitem{intelptmanual}\n  Intel Corporation.\n  \\textit{Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3C: System Programming Guide, Part 3, p248}.\n  \\url{https://software.intel.com/en-us/download/intel-64-and-ia-32-architectures-sdm-volume-3c-system-programming-guide-part-3}.\n\n\\bibitem{libipt}\n  Intel Corporation.\n  \\textit{libipt - an Intel(R) Processor Trace decoder library }.\n  \\url{https://github.com/01org/processor-trace}.\n\n\\bibitem{winaflintelpt}\n  Ivan Fratric, Richard Johnson.\n  \\textit{Fork of WinAFL}.\n  \\url{https://github.com/intelpt/winafl-intelpt/}.\n\n\\bibitem{winaflcommit}\n  Richard Johnson.\n  \\textit{Commit which appears to have removed IPT support}.\n  \\url{https://github.com/intelpt/winafl-intelpt/commit/d1e9e560bbaf4e56f6d6bd48672bf691097e86fa}.\n\n\\bibitem{killerbeezipt}\n  GRIMM.\n  \\textit{Killerbeez IPT Documentation}.\n  \\url{https://github.com/grimm-co/killerbeez/blob/master/docs/IPT.md}.\n\n\\bibitem{qemuspeedup}\n  Andrea Biondo.\n  \\textit{Improving AFL's QEMU mode performance}.\n  \\url{https://abiondo.me/2018/09/21/improving-afl-qemu-mode/}.\n\n\\bibitem{qemu}\n  \\textit{QEMU}.\n  \\url{https://www.qemu.org/}.\n\n\\bibitem{peach}\n  Peach Tech.\n  \\textit{Peach Fuzzer}.\n  \\url{https://www.peach.tech/}.\n\n\\bibitem{honggfuzz}\n  Google.\n  \\textit{Honggfuzz - A security oriented, feedback-driven, evolutionary, easy-to-use fuzzer with interesting analysis options}.\n  \\url{http://honggfuzz.com/}.\n\n\\bibitem{honggfuzzgrimm}\n  GRIMM.\n  \\textit{Modified version of Honggfuzz which enables it to use Killerbeez mutator modules}.\n  \\url{https://github.com/grimm-co/honggfuzz}.\n\n\\bibitem{anton}\n  Anton Lindqvist.\n  \\textit{Fuzzing the OpenBSD kernel}.\n  \\url{https://www.openbsd.org/papers/fuzz-slides.pdf}.\n\n\\bibitem{genome}\n  Oulu University Secure Programming Group.\n  \\textit{PROTOS Protocol Genome Project}.\n  \\url{https://www.ee.oulu.fi/roles/ouspg/genome}.\n\n\\bibitem{dynamo}\n  \\textit{DynamoRIO}.\n  \\url{http://www.dynamorio.org/}.\n\n\\bibitem{kafl}\n  Schumilo, Sergej and Aschermann, Cornelius and Gawlik, Robert and Schinzel, Sebastian and Holz, Thorsten.\n  \\textit{kAFL: Hardware-Assisted Feedback Fuzzing for OS Kernels}.\n  \\url{https://github.com/RUB-SysSec/kAFL}.\n\n\\bibitem{vuzzer}\n  Sanjay Rawat et al.\n  \\textit{VUzzer: Application-aware Evolutionary Fuzzing}.\n  \\url{https://www.ndss-symposium.org/ndss2017/ndss-2017-programme/vuzzer-application-aware-evolutionary-fuzzing/}.\n\n\\bibitem{boofuzz}\n  Joshua Pereyda.\n  \\textit{boofuzz: Network Protocol Fuzzing for Humans}.\n  \\url{https://github.com/jtpereyda/boofuzz}.\n\n\\bibitem{grimmdriller}\n  GRIMM.\n  \\textit{Guided Fuzzing with Driller}.\n  \\url{https://blog.grimm-co.com/post/guided-fuzzing-with-driller/}.\n\n\\bibitem{angrissues}\n  Audrey Dutcher.\n  \\textit{Angr Real World Program Issue}.\n  \\url{https://github.com/shellphish/driller/issues/25#issuecomment-288253948}.\n\n\\bibitem{fileformatfuzzing}\n  Mateusz \"j00ru\" Jurczyk.\n  \\textit{Effective File Format Fuzzing}.\n  \\url{https://www.blackhat.com/docs/eu-16/materials/eu-16-Jurczyk-Effective-File-Format-Fuzzing-Thoughts-Techniques-And-Results.pdf}.\n\n\\bibitem{softwaredumber}\n  Tavis Ormandy.\n  \\textit{Making Software Dumber}.\n  \\url{http://taviso.decsystem.org/making_software_dumber.pdf}.\n\n\\bibitem{aflbucketing}\n  Michal Zalewski.\n  \\textit{Technical Whitepaper for afl-fuzz}.\n  \\url{http://lcamtuf.coredump.cx/afl/technical_details.txt}.\n\n\\bibitem{iptoverhead}\n  James Reinders.\n  \\textit{Processor Tracing}.\n  \\url{https://software.intel.com/en-us/blogs/2013/09/18/processor-tracing}.\n\n\\bibitem{harnessingipt}\n  Andrea Allievi and Richard Johnson.\n  \\textit{Harnessing Intel Processor Trace on Windows for Vulnerability Discovery}.\n  \\url{https://conference.hitb.org/hitbsecconf2017ams/materials/D1T1%20-%20Richard%20Johnson%20-%20Harnessing%20Intel%20Processor%20Trace%20on%20Windows%20for%20Vulnerability%20Discovery.pdf}.\n\n\\bibitem{binutils}\n  Free Software Foundation.\n  \\textit{GNU Binutils}.\n  \\url{https://www.gnu.org/software/binutils/}.\n\n\\bibitem{windebugapi}\n  Microsoft.\n  \\textit{Debugging Functions}.\n  \\url{https://docs.microsoft.com/en-us/windows/desktop/debug/debugging-functions}.\n\n\\bibitem{adobereader}\n  Adobe.\n  \\textit{Adobe Acrobat Reader DC}.\n  \\url{https://get.adobe.com/reader/}.\n\n\\bibitem{rustfuzztrophy}\n  Sergey ``Shnatsel'' Davidoff.\n  \\textit{Collection of bugs uncovered by fuzzing Rust code}.\n  \\url{https://github.com/rust-fuzz/trophy-case}.\n\n\\bibitem{clusterfuzzrelease}\n  Google.\n  \\textit{Open sourcing ClusterFuzz}.\n  \\url{https://opensource.googleblog.com/2019/02/open-sourcing-clusterfuzz.html}.\n\n%\\bibitem{}\n%  .\n%  \\textit{}.\n%  \\url{}.\n\n\\end{thebibliography}\n"
  },
  {
    "path": "docs/paper/related_work.tex",
    "content": "There are projects which have addressed some of the aspects covered by Killerbeez\nsuch as platform independence, distributed fuzzing, leveraging existing tools,\nand so forth.\n\nGoogle's OSS-Fuzz\\cite{ossfuzz} addresses scalability by running many fuzzers\nin parallel, as well as re-using existing code by leveraging tools like\nHonggfuzz to handle the actual fuzzing. The core fuzzing component of OSS-Fuzz,\nCluserFuzz, was unpublished and therefore unavailable to anyone outside of\nGoogle for the first eight years.  On February 7, 2019, ClusterFuzz was released\nunder the Apache Licence (v2).\\cite{clusterfuzzrelease}  Differences which still\nremain between OSS-Fuzz and Killerbeez include OSS-Fuzz requiring source code for the\ntarget software, and requiring that tests be written to integrate it\ninto the overall system. This adds efficiency, as the test cases can eliminate\ncode like GUI libraries, which is not the real target of the fuzzing, however\nit is unable to test closed source software.  Had Clusterfuzz been open source\nin 2017, the authors likely would have attempted to extend OSS-Fuzz to also be\nable to fuzz closed source software and run on computers the user controls\ninstead of using Google's cloud service.\n\n\\AFL{}\\cite{afl} is an open source fuzzer that uses coverage data and genetic\nalgorithms to automatically discover interesting test cases in a target.  \\AFL{}\nwas designed to be practical; it has a low overhead, is easy to use, and works\nagainst real-world software. As such, \\AFL{} has become one of the most popular\nfuzzers and many research projects investigate how to improve \\AFL{}. Killerbeez\nborrows many features from \\AFL{}, such as the compiler and QEMU\ninstrumentations. While Killerbeez has also borrowed \\AFL{}'s mutation strategy,\nit does not currently include \\AFL{}'s mutations which mutate based on coverage\ndata. Coverage data is used to avoid wasting time mutating portions of the input\nthat the target does not process. These mutations will be incorporated into\nKillerbeez in the future.  While \\AFL{} is a great local fuzzer, it is not\neasily distributed and cannot easily manage the fuzzing of more complex targets.\n\\AFL{} does not support applications on Windows, and the \\AFL{} fork which does\nsupport Windows, WinAFL, lacks many of the features of \\AFL{}.\n\nPeach Fuzzer\\cite{peach} now supports distributed fuzzing, modular mutators, and\nmodules for launching apps, is able to do both file and network-based fuzzing,\nand does work on closed source applications.  However, the distributed aspect\nis only available in the proprietary version of the fuzzer; it does not exist\nin the community edition, which is open source. There is also no feedback loop\nfor code coverage in either edition.  Instead, the input format needs to be\nmanually described in XML files, as does the model for the program state. To\nalleviate this problem, the company behind Peach Fuzzer is willing to sell\naccess to the definitions they have created.\n\nHonggfuzz\\cite{honggfuzz} is an open source fuzzer which runs on Windows, Linux,\nmacOS, Android, FreeBSD and NetBSD, all using a single code base. It can handle\nclosed source applications, long-running applications such as servers, and will\nautomatically use multiple CPU cores to do fuzzing in parallel. Modularity is\nachieved by allowing an external program to do the mutation of inputs. While\nHonggfuzz scales nicely on a single machine, it does not have any built in\nmechanism to utilize multiple machines.  Using Honggfuzz in a larger framework\nsuch as OSS-Fuzz takes care of this limitation.  In fact, Honggfuzz is a fuzzer\nwhich will be likely integrated into Killerbeez in the future, as described in\nsection \\ref{Future Work}. Honggfuzz has more types of instrumentation than any\nother fuzzer, including Killerbeez at the time of writing, however none of\nthese work on Windows. The \\BTS{} and \\IPT{} instrumentations are only for\nLinux, as is the hardware-based counters instrumentation which tracks the\nnumber of instructions and branches which were executed. There is also compile time\ninstrumentation, but this is only helpful in the case where source code is\navailable, and it can be compiled by GCC or LLVM.  It is possible to compile\nsome C/C++ code for windows using LLVM, but anything which requires Microsoft\nVisual Studio to be compiled will not have any instrumentation.  Supporting\nWindows does not seem to be a priority for Honggfuzz, as it cannot be compiled\nnatively, but only via Cygwin.\n\nHonggfuzz is a great tool, which is why a modified version of it was created\nwhich can use all of the Killerbeez modules.\\cite{honggfuzzgrimm} Section\n\\ref{Future Work} describes the Linux instrumentation technologies from\nHonggfuzz planned for integration with Killerbeez.\nIf it is feasible to add the ability to use\nKillerbeez instrumentation modules, that is another contribution which will be\nmade to the Honggfuzz project.\n"
  },
  {
    "path": "driver/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (driver)\n\nSET(DRIVER_SRC\n\t${PROJECT_SOURCE_DIR}/driver.c\n\t${PROJECT_SOURCE_DIR}/driver_factory.c\n\t${PROJECT_SOURCE_DIR}/file_driver.c\n\t${PROJECT_SOURCE_DIR}/stdin_driver.c\n\t${PROJECT_SOURCE_DIR}/network_server_driver.c\n\t${PROJECT_SOURCE_DIR}/network_client_driver.c\n)\n\nif (WIN32)\n\tset(DRIVER_SRC\n\t\t${DRIVER_SRC}\n\t\t${PROJECT_SOURCE_DIR}/wmp_driver.cpp\n\t)\nendif(WIN32)\n\nsource_group(\"Library Sources\" FILES ${DRIVER_SRC})\n\nadd_library(driver OBJECT ${DRIVER_SRC})\ntarget_compile_definitions(driver PUBLIC DRIVER_NO_IMPORT)\ntarget_include_directories(driver PUBLIC ${PROJECT_SOURCE_DIR}/../instrumentation/)\n\n"
  },
  {
    "path": "driver/driver.c",
    "content": "#include <jansson.h>\n#include <jansson_helper.h>\n#include <global_types.h>\n#include <utils.h>\n#include <instrumentation.h>\n#include \"driver.h\"\n\n#include <time.h>\n\n#ifndef _WIN32\n#include <unistd.h>\n#include <errno.h>\n#include <sys/types.h>\n#include <sys/socket.h>\n#endif\n\n/**\n * Waits for a fuzzed process to be finished processing the input, either via timing out or the\n * process exiting.\n * @param process - a HANDLE to the fuzzed process\n * @param timeout - The maximum number of seconds to wait before declaring the process done\n * @param instrumentation - used to access `is_process_done` and `get_fuzz_result`\n * @param instrumentation_state - arguments for `is_process_done` and `get_fuzz_result`\n * @return - FUZZ_HANG or FUZZ_ result (from get_fuzz_result)\n */\n#ifdef _WIN32\nint generic_wait_for_process_completion(HANDLE process, int timeout, instrumentation_t * instrumentation, void * instrumentation_state)\n#else\nint generic_wait_for_process_completion(pid_t process, int timeout, instrumentation_t * instrumentation, void * instrumentation_state)\n#endif\n{\n\ttime_t start_time = time(NULL);\n\tint process_done = 0;\n\n\twhile(1)\n\t{\n\t\tprocess_done = instrumentation->is_process_done(instrumentation_state);\n\t\tif (process_done == 1)\n\t\t\treturn instrumentation->get_fuzz_result(instrumentation_state);\n\t\telse if (process_done == -1)\n\t\t\treturn FUZZ_ERROR;\n\t\t// if it's zero, the process is not done, so keep looping\n\n\t\t// timeout\n\t\tif (time(NULL) - start_time > timeout)\n\t\t\treturn FUZZ_HANG;\n\n\t\t// FUZZ_HANG isn't ever set in the instrumentation, which isn't great.\n\t\t// could be solved by adding a set_fuzz_result function to the API. I\n\t\t// am unaware of any API constraints that require it at this time. A\n\t\t// potential issue I forsee is that a second get_fuzz_result would\n\t\t// incorrectly report FUZZ_RUNNING.\n\n\t\t#ifdef _WIN32\n\t\tSleep(5);\n\t\t#else\n\t\tusleep(5*1000);\n\t\t#endif\n\t}\n}\n\n/**\n * This function will call mutate on the given mutator state to modify the mutator buffer\n * and then, if the mutation succeeds, call the given test_input function with the mutated\n * buffer\n * @param state - a driver specific structure previously created by the driver's create function\n * @param mutator - the mutator to call to obtain a mutated input buffer\n * @param mutator_state - the state of the mutator given in the mutator parameter\n * @param buffer - the buffer to write the mutated input to\n * @param buffer_length - the length of the buffer parameter\n * @param test_input_func - the test_input function to call after mutating the input buffer\n * @param mutate_last_size - this parameter is used to return the size of the mutated input buffer\n * @return - FUZZ_CRASH, FUZZ_HANG, or FUZZ_NONE on success, FUZZ_ERROR on error, -2 if the mutator has finished generating inputs\n */\nint generic_test_next_input(void * state, mutator_t * mutator, void * mutator_state, char * buffer, size_t buffer_length,\n\tint (*test_input_func)(void * driver_state, char * buffer, size_t length), int * mutate_last_size)\n{\n\tif (!mutator) {\n\t\tERROR_MSG(\"Mutator module missing!\");\n\t\treturn -1;\n\t}\n\tDEBUG_MSG(\"Mutating input...\");\n\t*mutate_last_size = mutator->mutate(mutator_state, buffer, buffer_length);\n\tif (*mutate_last_size < 0)\n\t\treturn -1;\n\telse if (*mutate_last_size == 0)\n\t\treturn -2;\n\treturn test_input_func(state, buffer, *mutate_last_size);\n}\n\n/**\n * This function allocates a buffer to be used for holding the mutated input that a driver will\n * to the target program.\n * @param ratio - The desired ratio of mutate buffer size to input size.\n * @param input_length - The size of the input buffer\n * @param buffer - a pointer to a buffer pointer, used to return the allocated buffer\n * @param length - a pointer to a size_t variable, used to return the allocated buffer's length\n * @return - zero on success, non-zero on failure\n */\nint setup_mutate_buffer(double ratio, size_t input_length, char ** buffer, size_t * length)\n{\n\tsize_t output_size;\n\tchar * output_buffer;\n\n\toutput_size = (size_t)(input_length * ratio);\n\tif (!output_size)\n\t\treturn 1;\n\n\toutput_buffer = malloc(output_size);\n\tif (!output_buffer)\n\t\treturn 1;\n\n\t*buffer = output_buffer;\n\t*length = output_size;\n\treturn 0;\n}\n\n/**\n* This function sends the provided buffer on the already connected TCP socket\n* @param sock - a pointer to a connected TCP SOCKET to send the buffer on\n* @param buffer - the buffer to send\n* @param length - the length of the buffer parameter\n* @return - non-zero on error, zero on success\n*/\n#ifdef _WIN32\nint send_tcp_input(SOCKET * sock, char * buffer, size_t length)\n#else\nint send_tcp_input(int * sock, char * buffer, size_t length)\n#endif\n{\n\tint result;\n\tsize_t total_read = 0;\n\n\tresult = 1;\n\twhile (total_read < length && result > 0)\n\t{\n\t\tresult = send(*sock, buffer + total_read, length - total_read, 0);\n\n\t\tif (result > 0)\n\t\t\ttotal_read += result;\n\t\telse if (result < 0) //Error, then break\n\t\t{\n#ifdef _WIN32\n\t\t\t// Here in the network drivers, we have a little bit more\n\t\t\t// information than you'd get in a stdin/file driver.\n\t\t\t// We want to pass up information that we terminated after n packets.\n\n\t\t\t// We have a few possible send() results inside this loop.\n\t\t\t// send tells us ERROR and\n\t\t\t//  - we retry\n\t\t\t//  - it counts as success, do not retry\n\t\t\t//  - it is a proper error, stop\n\n\t\t\tint error_code = WSAGetLastError();\n\t\t\tERROR_MSG(\"send() failed with error: %d\", error_code);\n\n\t\t\t// (10053) the client unexpectedly terminated\n\t\t\tif (error_code == 10053)\n\t\t\t\treturn -2;\n\t\t\t// TODO: this -2 should be #define FUZZ_UNUSED_PART or something similar\n\t\t\t// Currently this is checked in network_client_run()\n#else\n\t\t\tERROR_MSG(\"send() failed with error: %d\", errno);\n\t\t\t// TODO: Write error-checks\n#endif\n\t\t}\n\t}\n\n\t// This currently assumes that failing to write all our input is an\n\t// error, which may not always be the case.\n\treturn total_read != length; \n}\n\n"
  },
  {
    "path": "driver/driver.h",
    "content": "#pragma once\n\n#ifdef _WIN32\n#include <Windows.h>\n#else\n#include <sys/types.h> // pid_t\n#endif\n\n#include <global_types.h>\n#include <instrumentation.h>\n\n#ifdef DRIVER_EXPORTS\n#define DRIVER_API __declspec(dllexport)\n#elif defined(DRIVER_NO_IMPORT)\n#define DRIVER_API\n#else\n#define DRIVER_API __declspec(dllimport)\n#endif\n\n#ifdef __cplusplus\n#define FUNC_PREFIX extern \"C\"\n#else\n#define FUNC_PREFIX\n#endif\n\nstruct driver\n{\n\tvoid (*cleanup)(void * driver_state);\n\tint (*test_input)(void * driver_state, char * buffer, size_t length);\n\tint (*test_next_input)(void * driver_state);\n\tchar *(*get_last_input)(void * driver_state, int * length);\n\tvoid * state;\n};\ntypedef struct driver driver_t;\n\n#ifdef _WIN32\nFUNC_PREFIX int generic_wait_for_process_completion(HANDLE process, int timeout, instrumentation_t * instrumentation, void * instrumentation_state);\n#else\nFUNC_PREFIX int generic_wait_for_process_completion(pid_t process, int timeout, instrumentation_t * instrumentation, void * instrumentation_state);\n#endif\nFUNC_PREFIX int generic_test_next_input(void * state, mutator_t * mutator, void * mutator_state, char * buffer, size_t buffer_length,\n\tint(*test_input_func)(void * driver_state, char * buffer, size_t length), int * mutate_last_size);\nFUNC_PREFIX int setup_mutate_buffer(double ratio, size_t input_length, char ** buffer, size_t * length);\n#ifdef _WIN32\nFUNC_PREFIX int send_tcp_input(SOCKET * sock, char * buffer, size_t length);\n#else\nFUNC_PREFIX int send_tcp_input(int * sock, char * buffer, size_t length);\n#endif\n"
  },
  {
    "path": "driver/driver_factory.c",
    "content": "#include <string.h>\n#include <stdlib.h>\n#include <stdio.h>\n\n#include \"instrumentation.h\"\n#include \"driver_factory.h\"\n#include \"driver.h\"  // for driver_t\n\n#include \"file_driver.h\"\n#include \"stdin_driver.h\"\n#include \"network_server_driver.h\"\n#include \"network_client_driver.h\"\n#ifdef _WIN32\n#include \"wmp_driver.h\"\n#endif\n\n\n#define FACTORY_ERROR()  { free(ret); return NULL; }\n\n/**\n * This function obtains a driver_t object by calling the driver specified by driver_type's create method.\n * @param driver_type - the name of the driver that should be created.\n * @param options - a JSON string that contains the driver specific string of options\n * @return - a driver_t object of the specified type on success or NULL on failure\n */\nDRIVER_API driver_t * driver_factory(char * driver_type, char * options)\n{\n\treturn driver_all_factory(driver_type, options, NULL, NULL, NULL, NULL);\n}\n\n/**\n * This function obtains a driver_t object by calling the driver specified by driver_type's create method.\n * @param driver_type - the name of the driver that should be created.\n * @param options - a JSON string that contains the driver specific string of options\n * @param instrumentation - optionally, a pointer to an instrumentation instance that the driver will use\n * to instrument the requested program.  This instrumentation instance should already be initialized.\n * @param instrumentation_state - a pointer to the instrumentation state for the passed in instrumentation\n * @return - a driver_t object of the specified type on success or NULL on failure\n */\nDRIVER_API driver_t * driver_instrumentation_factory(char * driver_type, char * options, instrumentation_t * instrumentation, \n\tvoid * instrumentation_state)\n{\n\treturn driver_all_factory(driver_type, options, instrumentation, instrumentation_state, NULL, NULL);\n}\n\n/**\n * This function obtains a driver_t object by calling the driver specified by driver_type's create method.\n * @param driver_type - the name of the driver that should be created.\n * @param options - a JSON string that contains the driver specific string of options\n * @param mutator - optionally, a pointer to a mutator instance that the driver will use\n * to obtain input when fuzzing the requested program.  This mutator instance should already be initialized.\n * @param mutator_state - a pointer to the mutator state for the passed in mutator\n * @return - a driver_t object of the specified type on success or NULL on failure\n */\nDRIVER_API driver_t * driver_mutator_factory(char * driver_type, char * options, mutator_t * mutator, void * mutator_state)\n{\n\treturn driver_all_factory(driver_type, options, NULL, NULL, mutator, mutator_state);\n}\n\n/**\n * This function obtains a driver_t object by calling the driver specified by driver_type's create method.\n * @param driver_type - the name of the driver that should be created.\n * @param options - a JSON string that contains the driver specific string of options\n * @param instrumentation - optionally, a pointer to an instrumentation instance that the driver will use\n * to instrument the requested program.  This instrumentation instance should already be initialized.\n * @param instrumentation_state - a pointer to the instrumentation state for the passed in instrumentation\n * @param mutator - optionally, a pointer to a mutator instance that the driver will use\n * to obtain input when fuzzing the requested program.  This mutator instance should already be initialized.\n * @param mutator_state - a pointer to the mutator state for the passed in mutator\n * @return - a driver_t object of the specified type on success or NULL on failure\n */\nDRIVER_API driver_t * driver_all_factory(char * driver_type, char * options, instrumentation_t * instrumentation, void * instrumentation_state,\n\tmutator_t * mutator, void * mutator_state)\n{\n\tdriver_t * ret = (driver_t *)malloc(sizeof(driver_t));\n\tif (!strcmp(driver_type, \"file\"))\n\t{\n\t\tret->state = file_create(options, instrumentation, instrumentation_state, mutator, mutator_state);\n\t\tif (!ret->state)\n\t\t\tFACTORY_ERROR();\n\t\tret->cleanup = file_cleanup;\n\t\tret->test_input = file_test_input;\n\t\tret->test_next_input = file_test_next_input;\n\t\tret->get_last_input = file_get_last_input;\n\t}\n\telse if (!strcmp(driver_type, \"stdin\"))\n\t{\n\t\tret->state = stdin_create(options, instrumentation, instrumentation_state, mutator, mutator_state);\n\t\tif (!ret->state)\n\t\t\tFACTORY_ERROR();\n\t\tret->cleanup = stdin_cleanup;\n\t\tret->test_input = stdin_test_input;\n\t\tret->test_next_input = stdin_test_next_input;\n\t\tret->get_last_input = stdin_get_last_input;\n\t}\n\telse if (!strcmp(driver_type, \"network_server\"))\n\t{\n\t\tret->state = network_server_create(options, instrumentation, instrumentation_state, mutator, mutator_state);\n\t\tif (!ret->state)\n\t\t\tFACTORY_ERROR();\n\t\tret->cleanup = network_server_cleanup;\n\t\tret->test_input = network_server_test_input;\n\t\tret->test_next_input = network_server_test_next_input;\n\t\tret->get_last_input = network_server_get_last_input;\n\t}\n\telse if (!strcmp(driver_type, \"network_client\"))\n\t{\n\t\tret->state = network_client_create(options, instrumentation, instrumentation_state, mutator, mutator_state);\n\t\tif (!ret->state) {\n\t\t\tputs(\"Factory Error\");\n\t\t\tFACTORY_ERROR();\n\t\t\t}\n\t\tret->cleanup = network_client_cleanup;\n\t\tret->test_input = network_client_test_input;\n\t\tret->test_next_input = network_client_test_next_input;\n\t\tret->get_last_input = network_client_get_last_input;\n\t}\n\t#ifdef _WIN32\n\telse if (!strcmp(driver_type, \"wmp\"))\n\t{\n\t\tret->state = wmp_create(options, instrumentation, instrumentation_state, mutator, mutator_state);\n\t\tif (!ret->state)\n\t\t\tFACTORY_ERROR();\n\t\tret->cleanup = wmp_cleanup;\n\t\tret->test_input = wmp_test_input;\n\t\tret->test_next_input = wmp_test_next_input;\n\t\tret->get_last_input = wmp_get_last_input;\n\t}\n\t#endif\n\telse\n\t\tFACTORY_ERROR();\n\treturn ret;\n}\n\n#define APPEND_HELP(text, new_text, func)                               \\\n  if(!func(&new_text)) {                                                \\\n    text = (char *)realloc(text, strlen(text) + strlen(new_text) + 1);  \\\n    strcat(text, new_text);                                             \\\n    free(new_text);                                                     \\\n  }\n\n/**\n * This function returns help text for all available drivers.  This help text will describe the drivers and any options\n * that can be passed to their create functions.\n * @return - a newly allocated string containing the help text.\n */\nDRIVER_API char * driver_help(void)\n{\n\tchar * text, *new_text;\n\ttext = strdup(\"Driver Options:\\n\\n\");\n\tAPPEND_HELP(text, new_text, file_help);\n\tAPPEND_HELP(text, new_text, stdin_help);\n\tAPPEND_HELP(text, new_text, network_server_help);\n\tAPPEND_HELP(text, new_text, network_client_help);\n\t#ifdef _WIN32\n\tAPPEND_HELP(text, new_text, wmp_help);\n\t#endif\n\treturn text;\n}\n\n"
  },
  {
    "path": "driver/driver_factory.h",
    "content": "#pragma once\n#include \"driver.h\"\n#include <instrumentation.h>\n#include <global_types.h>\n\nDRIVER_API driver_t * driver_factory(char * driver_type, char * options);\nDRIVER_API driver_t * driver_instrumentation_factory(char * driver_type, char * options, instrumentation_t * instrumentation,\n\tvoid * instrumentation_state);\nDRIVER_API driver_t * driver_mutator_factory(char * driver_type, char * options, mutator_t * mutator, void * mutator_state);\nDRIVER_API driver_t * driver_all_factory(char * driver_type, char * options, instrumentation_t * instrumentation, void * instrumentation_state,\n\tmutator_t * mutator, void * mutator_state);\nDRIVER_API char * driver_help(void);\n"
  },
  {
    "path": "driver/file_driver.c",
    "content": "#include \"file_driver.h\"\n\n#include <utils.h>\n#include <jansson_helper.h>\n#include <instrumentation.h>\n#include \"driver.h\" // IWYU pragma: keep\n\n//c headers\n#include <stdio.h>\n#include <stdlib.h>\n\n#ifdef _WIN32\n#include <Shlwapi.h>\n#include <process.h>\n#else\n#include <string.h> // memset\n#include <unistd.h> // unlink\n#endif\n\n/**\n * This function creates a file_state_t object based on the given options.\n * @param options - A JSON string of the options to set in the new file_state_t. See the\n * help function for more information on the specific options available.\n * @return - the file_state_t generated from the options in the JSON options string, or NULL on failure\n */\nstatic file_state_t * setup_options(char * options)\n{\n\tfile_state_t * state;\n\tsize_t cmd_length;\n\n\tstate = (file_state_t *)malloc(sizeof(file_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(file_state_t));\n\n\t//Setup defaults\n\tstate->timeout = 2;\n\tstate->extension = strdup(\".dat\");\n\tstate->input_ratio = 2.0;\n\n\t//Parse the options\n\tPARSE_OPTION_STRING(state, options, path, \"path\", file_cleanup);\n\tPARSE_OPTION_STRING(state, options, test_filename, \"filename\", file_cleanup);\n\tPARSE_OPTION_STRING(state, options, arguments, \"arguments\", file_cleanup);\n\tPARSE_OPTION_STRING(state, options, extension, \"extension\", file_cleanup);\n\tPARSE_OPTION_INT(state, options, timeout, \"timeout\", file_cleanup);\n\tPARSE_OPTION_DOUBLE(state, options, input_ratio, \"ratio\", file_cleanup);\n\n\tif (!state->path || !file_exists(state->path) || state->input_ratio <= 0)\n\t{\n\t\tif(!state->path)\n\t\t{\n\t\t\tFATAL_MSG(\"Failed to load file driver: path to executable missing\");\n\t\t}\n\t\tfile_cleanup(state);\n\t\treturn NULL;\n\t}\n\n\t//If the user didn't specify a test filename to\n\tif(!state->test_filename) {//write the fuzz data to, generate a test filename now\n\t\tif(!state->arguments || !strstr(state->arguments, \"@@\")) {\n\t\t\tERROR_MSG(\"Test filename not specified and the target program's arguments do not include the test filename \"\n\t\t\t\t\"symbol (\\\"@@\\\"). The target program will not be able to receive the mutated input data.\");\n\t\t\tERROR_MSG(\"Use the \\\"arguments\\\" or \\\"filename\\\" options to pass the mutated input to the target program\");\n\t\t\tfile_cleanup(state);\n\t\t\treturn NULL;\n\t\t}\n\t\tstate->test_filename = get_temp_filename(state->extension);\n\t}\n\n\tif (state->arguments)\n\t{\n\t\tint filename_length = strlen(state->test_filename);\n\t\tchar * new_arguments, *pos, *temp;\n\n\t\tpos = new_arguments = state->arguments;\n\t\twhile (*pos != 0)\n\t\t{\n\t\t\t// replace the \"@@\" in the arguments with the temp filename\n\t\t\tif (*pos == '@' && *(pos + 1) == '@')\n\t\t\t{\n\t\t\t\tint index = pos - new_arguments;\n\t\t\t\tsize_t temp_size = (filename_length - 2) + strlen(new_arguments) + 1;\n\n\t\t\t\ttemp = (char *)malloc(temp_size);\n\t\t\t\tmemset(temp, 0, temp_size);\n\t\t\t\tmemcpy(temp, new_arguments, index);\n\t\t\t\tmemcpy(temp + index, state->test_filename, filename_length);\n\t\t\t\tmemcpy(temp + index + filename_length, pos + 2, strlen(new_arguments) - (index + 2));\n\n\t\t\t\tfree(new_arguments);\n\t\t\t\tnew_arguments = temp;\n\t\t\t\tpos = new_arguments + index + filename_length;\n\t\t\t}\n\t\t\telse\n\t\t\t\tpos++;\n\t\t}\n\t\tstate->arguments = new_arguments;\n\t}\n\n\tcmd_length = (state->path ? strlen(state->path) : 0) + (state->arguments ? strlen(state->arguments) : 0) + 2;\n\tstate->cmd_line = (char *)malloc(cmd_length);\n\tif (!state->cmd_line)\n\t{\n\t\tfile_cleanup(state);\n\t\treturn NULL;\n\t}\n\tsnprintf(state->cmd_line, cmd_length, \"%s %s\", state->path, state->arguments ? state->arguments : \"\");\n\n\treturn state;\n}\n\n/**\n * This function allocates and initializes a new driver specific state object based on the given options.\n * @param options - a JSON string that contains the driver specific string of options\n * @param instrumentation - a pointer to an instrumentation instance that the driver will use\n * to instrument the requested program.  This instrumentation instance should already be initialized.\n * @param instrumentation_state - a pointer to the instrumentation state for the passed in instrumentation\n * @return - a driver specific state object on success or NULL on failure\n */\nvoid * file_create(char * options, instrumentation_t * instrumentation, void * instrumentation_state,\n\tmutator_t * mutator, void * mutator_state)\n{\n\tfile_state_t * state;\n\tint num_inputs;\n\tsize_t *input_sizes;\n\n\t//This driver requires at least the path to the program to run. Make sure we either have both a mutator and state\n\tif (!options || !strlen(options) || (mutator && !mutator_state) || (!mutator && mutator_state)) //or neither\n\t{\n\t\tif (!options)\n\t\t{\n\t\t\tFATAL_MSG(\"Options are required for the file driver\");\n\t\t}\n\t\treturn NULL;\n\t}\n\n\tstate = setup_options(options);\n\tif (!state)\n\t\treturn NULL;\n\n\tif (mutator)\n\t{\n\t\tmutator->get_input_info(mutator_state, &num_inputs, &input_sizes);\n\t\tif (num_inputs != 1\n\t\t\t|| setup_mutate_buffer(state->input_ratio, input_sizes[0], &state->mutate_buffer, &state->mutate_buffer_length))\n\t\t{\n\t\t\tfree(input_sizes);\n\t\t\tfile_cleanup(state);\n\t\t\treturn NULL;\n\t\t}\n\t\tfree(input_sizes);\n\t}\n\n\tstate->mutator = mutator;\n\tstate->mutator_state = mutator_state;\n\tstate->mutate_last_size = -1;\n\tstate->instrumentation = instrumentation;\n\tstate->instrumentation_state = instrumentation_state;\n\treturn state;\n}\n\n/**\n * This function cleans up all resources with the passed in driver state.\n * @param driver_state - a driver specific state object previously created by the file_create function\n * This state object should not be referenced after this function returns.\n */\nvoid file_cleanup(void * driver_state)\n{\n\tfile_state_t * state = (file_state_t *)driver_state;\n\n\tfree(state->mutate_buffer);\n\n\tfree(state->path);\n\tfree(state->extension);\n\tfree(state->arguments);\n\tfree(state->cmd_line);\n\tif (state->test_filename)\n\t{\n\t\tunlink(state->test_filename);\n\t\tfree(state->test_filename);\n\t}\n\tfree(state);\n}\n\n/**\n * This function will run the fuzzed program and test it with the given input. This function\n * blocks until the program has finished processing the input.\n * @param driver_state - a driver specific structure previously created by the file_create function\n * @param input - the input that should be tested\n * @param length - the length of the input parameter\n * @return - FUZZ_ result on success or FUZZ_ERROR on failure\n */\nint file_test_input(void * driver_state, char * input, size_t length)\n{\n\tfile_state_t * state = (file_state_t *)driver_state;\n\n\t//Write the input to disk\n\tDEBUG_MSG(\"Writing input to disk...\");\n\twrite_buffer_to_file(state->test_filename, input, length);\n\n\t//Start the process and give it our input\n\tDEBUG_MSG(\"Enabling instrumentation module...\");\n\tif(state->instrumentation->enable(state->instrumentation_state, &state->process, state->cmd_line, NULL, 0))\n\t\treturn FUZZ_ERROR;\n\n\t//Wait for it to be done, return the termination termination status\n\treturn generic_wait_for_process_completion(state->process, state->timeout,\n\t\tstate->instrumentation, state->instrumentation_state);\n}\n\n/**\n * This function will run the fuzzed program with the output of the mutator given during driver\n * creation.  This function blocks until the program has finished processing the input.\n * @param driver_state - a driver specific structure previously created by the file_create function\n * @return - FUZZ_ result on success, FUZZ_ERROR on error, -2 if the mutator has finished generating inputs\n */\nint file_test_next_input(void * driver_state)\n{\n\tfile_state_t * state = (file_state_t *)driver_state;\n\treturn generic_test_next_input(state, state->mutator, state->mutator_state, state->mutate_buffer,\n\t\tstate->mutate_buffer_length, file_test_input, &state->mutate_last_size);\n}\n\n/**\n * When this driver is using a mutator given to it during driver creation, this function retrieves\n * the last input that was tested with the file_test_next_input function.\n * @param driver_state - a driver specific structure previously created by the file_create function\n * @param length - a pointer to an integer used to return the length of the input that was last tested.\n * @return - NULL on error or if the driver doesn't have a mutator, or a buffer containing the last input\n * that was tested by the driver with the file_test_next_input function.  This buffer should be freed\n * by the caller.\n */\nchar * file_get_last_input(void * driver_state, int * length)\n{\n\tfile_state_t * state = (file_state_t *)driver_state;\n\tif (!state->mutator || state->mutate_last_size <= 0)\n\t\treturn NULL;\n\t*length = state->mutate_last_size;\n\treturn memdup(state->mutate_buffer, state->mutate_last_size);\n}\n\n/**\n * This function returns help text for this driver.  This help text will describe the driver and any options\n * that can be passed to file_create.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nint file_help(char ** help_str)\n{\n\t*help_str = strdup(\n\"file - Writes mutated input to a file, that the target process uses\\n\"\n\"Required Options:\\n\"\n\"  path                  The path to the target process\\n\"\n\"Optional Options:\\n\"\n\"  arguments             Arguments to pass to the target process, with the\\n\"\n\"                          target filename specified as @@\\n\"\n\"  extension             The file extension to give the test file\\n\"\n\"  filename              The filename to give the test file\\n\"\n\"  ratio                 The ratio of mutation buffer size to input size when\\n\"\n\"                          given a mutator\\n\"\n\"  timeout               The maximum number of seconds to wait for the target\\n\"\n\"                          process to finish\\n\"\n\"\\n\"\n\t);\n\tif (*help_str == NULL)\n\t\treturn -1;\n\treturn 0;\n}\n"
  },
  {
    "path": "driver/file_driver.h",
    "content": "#pragma once\n#include \"instrumentation.h\"\n#include <sys/types.h>        // for pid_t\n#include \"global_types.h\"     // for mutator_t\n\nvoid * file_create(char * options, instrumentation_t * instrumentation, void * instrumentation_state,\n\tmutator_t * mutator, void * mutator_state);\nvoid file_cleanup(void * driver_state);\nint file_test_input(void * driver_state, char * buffer, size_t length);\nint file_test_next_input(void * driver_state);\nchar * file_get_last_input(void * driver_state, int * length);\nint file_help(char ** help_str);\n\nstruct file_state\n{\n\t//Options\n\tchar * path;          //The path to the fuzzed executable\n\tchar * arguments;     //Arguments to give the binary\n\tchar * extension;     //The file extension of the input files to the fuzzed process\n\tint timeout;          //Maximum number of seconds to allow the executable to run\n\tchar * test_filename; //The filename that we're going to write our test input to\n\tdouble input_ratio;   //the ratio of the maximum input size\n\n\t//The handle to the fuzzed process instance\n\t#ifdef _WIN32\n\tHANDLE process;\n\t#else\n\tpid_t process;\n\t#endif\n\n\t//command line of the fuzzed process\n\tchar * cmd_line;\n\n\t//The instrumentation module\n\tinstrumentation_t * instrumentation;\n\n\t//The instrumentation's state\n\tvoid * instrumentation_state;\n\n\tmutator_t * mutator;\n\tvoid * mutator_state;\n\tchar * mutate_buffer;\n\tsize_t mutate_buffer_length;\n\tint mutate_last_size;\n};\ntypedef struct file_state file_state_t;\n"
  },
  {
    "path": "driver/network_client_driver.c",
    "content": "#include \"network_client_driver.h\"\n\n#include <utils.h>\n#include <jansson_helper.h>\n#include <instrumentation.h>\n#include \"driver.h\"\n\n//c headers\n#include <stdio.h>\n#include <stdlib.h>\n#include <time.h>\n\n\n#ifdef _WIN32\n#include <Shlwapi.h>\n#include <iphlpapi.h>\n#include <process.h>\n#else\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <netinet/ip.h>\n#include <arpa/inet.h>\n#include <unistd.h>\n\n#include <errno.h>\n#include <string.h>\n#include <stdlib.h>\n\n#define INVALID_SOCKET -1\n#define SOCKET_ERROR -1\n#endif\n\n/**\n * This function creates a network_client_state_t object based on the given options.\n * @param options - A JSON string of the options to set in the new network_client_state_t. See the\n * help function for more information on the specific options available.\n * @return - the network_client_state_t generated from the options in the JSON options string, or NULL on failure\n */\nstatic network_client_state_t * setup_options(char * options)\n{\n\tnetwork_client_state_t * state;\n\tsize_t cmd_length;\n\n\tstate = (network_client_state_t *)malloc(sizeof(network_client_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(network_client_state_t));\n\n\t//Setup defaults\n\tstate->timeout = 2;\n\tstate->input_ratio = 2.0;\n\tstate->lport = 9999;\n\tstate->target_ip = strdup(\"127.0.0.1\");\n\n\t//Parse the options\n\tPARSE_OPTION_STRING(state, options, path, \"path\", network_client_cleanup);\n\tPARSE_OPTION_STRING(state, options, arguments, \"arguments\", network_client_cleanup);\n\tPARSE_OPTION_INT(state, options, timeout, \"timeout\", network_client_cleanup);\n\tPARSE_OPTION_INT(state, options, lport, \"port\", network_client_cleanup);\n\tPARSE_OPTION_STRING(state, options, target_ip, \"ip\", network_client_cleanup);\n\tPARSE_OPTION_DOUBLE(state, options, input_ratio, \"ratio\", network_client_cleanup);\n\tPARSE_OPTION_INT_ARRAY(state, options, sleeps, sleeps_count, \"sleeps\", network_client_cleanup);\n\t\n\tcmd_length = (state->path ? strlen(state->path) : 0) + (state->arguments ? strlen(state->arguments) : 0) + 4;\n\tstate->cmd_line = (char *)malloc(cmd_length);\n\tmemset(state->cmd_line, 0, cmd_length);\n\n\tif (!state->path || !state->cmd_line || !file_exists(state->path)\n\t\t|| !state->target_ip || !state->lport || state->input_ratio <= 0)\n\t{\n\t\tnetwork_client_cleanup(state);\n\t\treturn NULL;\n\t}\n\t//Build the cmd line\n\tsnprintf(state->cmd_line, cmd_length, \"\\\"%s\\\" %s\", state->path, state->arguments ? state->arguments : \"\");\n\n\treturn state;\n}\n\n/**\n * This function allocates and initializes a new driver specific state object based on the given options.\n * @param options - a JSON string that contains the driver specific string of options\n * @param instrumentation - a pointer to an instrumentation instance that the driver will use\n * to instrument the requested program.  This instrumentation instance should already be initialized.\n * @param instrumentation_state - a pointer to the instrumentation state for the passed in instrumentation\n * @return - a driver specific state object on success or NULL on failure\n */\nvoid * network_client_create(char * options, instrumentation_t * instrumentation, void * instrumentation_state,\n\tmutator_t * mutator, void * mutator_state)\n{\n#ifdef _WIN32\n\tWSADATA wsaData;\n#endif\n\tnetwork_client_state_t * state;\n\tint i;\n\n\t//Make sure we either have both a mutator and state\n\tif (!options || !strlen(options) || (mutator && !mutator_state) || (!mutator && mutator_state))\n\t{ //or neither\n\t\tFATAL_MSG(\"ERROR: Missing driver options\");\n\t\treturn NULL;\n\t}\n\n#ifdef _WIN32\n\t// Startup because we're going to use the winsock DLL\n\tif (WSAStartup(MAKEWORD(2, 2), &wsaData)) {\n\t\tERROR_MSG(\"WSAStartup Failed\");\n\t\treturn NULL;\n\t}\n#endif\n\n\tstate = setup_options(options);\n\tif (!state)\n\t\treturn NULL;\n\tif (mutator)\n\t{\n\t\tmutator->get_input_info(mutator_state, &state->num_inputs, &state->mutate_buffer_lengths);\n\t\t\n\t\t//size of sleeps array and inputs must be equal\n\t\tif (state->sleeps && state->num_inputs != state->sleeps_count)\n\t\t{\n\t\t\tnetwork_client_cleanup(state);\n\t\t\treturn NULL;\n\t\t}\n\n\t\t//Setup the mutate buffers\n\t\t//allocate space for the array of mutate buffers\n\t\tstate->mutate_buffers = malloc(sizeof(char *) * state->num_inputs);\n\t\tif (!state->mutate_buffers)\n\t\t{\n\t\t\tnetwork_client_cleanup(state);\n\t\t\treturn NULL;\n\t\t}\n\t\tmemset(state->mutate_buffers, 0, sizeof(char *) * state->num_inputs);\n\n\t\t//Allocate space for the array containing the sizes the mutate buffers\n\t\tstate->mutate_last_sizes = malloc(sizeof(size_t) * state->num_inputs);\n\t\tif (!state->mutate_last_sizes)\n\t\t{\n\t\t\tnetwork_client_cleanup(state);\n\t\t\treturn NULL;\n\t\t}\n\t\tmemset(state->mutate_last_sizes, 0, sizeof(char *) * state->num_inputs);\n\n\t\t//populate the array of mutate buffers\n\t\tfor (i = 0; i < state->num_inputs; i++)\n\t\t{\n\t\t\tif (setup_mutate_buffer(state->input_ratio, state->mutate_buffer_lengths[i], &state->mutate_buffers[i],\n\t\t\t\t&state->mutate_buffer_lengths[i]))\n\t\t\t{\n\t\t\t\tnetwork_client_cleanup(state);\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t}\n\n\t\tstate->mutator = mutator;\n\t\tstate->mutator_state = mutator_state;\n\t}\n\n\tstate->instrumentation = instrumentation;\n\tstate->instrumentation_state = instrumentation_state;\n\treturn state;\n}\n\n/**\n * This function cleans up all resources with the passed in driver state.\n * @param driver_state - a driver specific state object previously created by the network_client_create function\n * This state object should not be referenced after this function returns.\n */\nvoid network_client_cleanup(void * driver_state)\n{\n\tnetwork_client_state_t * state = (network_client_state_t *)driver_state;\n\tint i;\n\n\t//Cleanup mutator stuff\n\tfor (i = 0; state->mutate_buffers && i < state->num_inputs; i++)\n\t\tfree(state->mutate_buffers[i]);\n\tfree(state->mutate_buffers);\n\tfree(state->mutate_buffer_lengths);\n\tfree(state->mutate_last_sizes);\n\n\t//Clean up driver specific options\n\tfree(state->path);\n\tfree(state->arguments);\n\tfree(state->cmd_line);\n\tfree(state->target_ip);\n\tfree(state->sleeps);\n\n\t//Clean up the struct holding it all\n\tfree(state);\n}\n\n/**\n * This function creates a socket and waits for a client to connect.\n * @param state - the network_client_state_t object that represents the current state of the driver\n * @param sock - a pointer to a SOCKET used to return the created socket\n * @return - FUZZ_ERROR error, zero on success\n */\n#ifdef _WIN32\nstatic int start_listener(network_client_state_t * state, SOCKET * sock)\n#else\nstatic int start_listener(network_client_state_t * state, int * sock)\n#endif\n{\n\tstruct sockaddr_in addr;\n\tint iResult = 0;\n\t*sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\n\tif (*sock == INVALID_SOCKET)\n\t{\n#ifdef _WIN32\n\t\tERROR_MSG(\"socket function failed with error: %ld\", WSAGetLastError());\n#else\n\t\tERROR_MSG(\"socket function failed with error: %d\", errno);\n#endif\n\t\treturn FUZZ_ERROR;\n\t}\n\n#ifndef _WIN32 // Linux\n\t// Set SO_REUSEADDR so you reuse the address instead of waiting for a minute.\n\t// https://stackoverflow.com/a/24194999\n\tint enable = 1;\n\tif (setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)\n\t\tFATAL_MSG(\"setsockopt failed.\\n\");\n#endif\n\n\t//Create socket (TCP Only right now)\n\taddr.sin_family = AF_INET;\n\taddr.sin_addr.s_addr = inet_addr(state->target_ip);\n\taddr.sin_port = htons(state->lport);\n\n\t//Now bind to the socket\n\tiResult = bind(*sock, (const struct sockaddr *)& addr, sizeof(addr));\n\n\tif (iResult == SOCKET_ERROR)\n\t{\n#ifdef _WIN32\n\t\tERROR_MSG(\"Socket failed to bind to port. Error code: %d\", WSAGetLastError());\n\t\tiResult = closesocket(*sock);\n\t\tif (iResult == SOCKET_ERROR)\n\t\t\tERROR_MSG(\"closesocket function failed with error %d\", WSAGetLastError());\n#else\n\t\tERROR_MSG(\"Socket failed to bind to port. Error code: %d\", errno);\n\t\tiResult = close(*sock);\n\t\tif (iResult == SOCKET_ERROR)\n\t\t\tERROR_MSG(\"closesocket function failed with error %d\", errno);\n#endif\n\t\treturn FUZZ_ERROR;\n\t}\n\n\t//Now put the socket into LISTEN state\n\tif (listen(*sock, SOMAXCONN) == SOCKET_ERROR)\n\t{\n#ifdef _WIN32\n\t\tERROR_MSG(\"listen function failed with error: %d\", WSAGetLastError());\n\t\treturn FUZZ_ERROR;\n#else\n\t\tERROR_MSG(\"listen function failed with error: %d\", errno);\n\t\treturn FUZZ_ERROR;\n#endif\n\t}\n\n\treturn FUZZ_NONE;\n}\n\n/**\n * This function will run the fuzzed program and test it with the given inputs. This function\n * blocks until the program has finished processing the input.\n * @param state - the network_client_state_t object that represents the current state of the driver\n * @param inputs - an array of inputs to send to the program\n * @param lengths - an array of lengths for the buffers in the inputs parameter\n * @param inputs_count - the number of buffers in the inputs parameter\n * @return - FUZZ_NONE, FUZZ_HANG, FUZZ_CRASH on success or FUZZ_ERROR on failure\n */\nstatic int network_client_run(network_client_state_t * state, char ** inputs, size_t * lengths, size_t inputs_count)\n{\n#ifdef _WIN32\n\tSOCKET serverSock;\n\tSOCKET clientSock;\n#else\n\tint serverSock;\n\tint clientSock;\n#endif\n\tsize_t i;\n\tint sock_ret;\n\n\t//Start the server socket so the client can connect below:\n\tif (start_listener(state, &serverSock))\n\t{\n\t\treturn FUZZ_ERROR;\n\t}\n\n\t//Have the instrumentation start the new process, since it needs to do so in a custom environment\n\tstate->instrumentation->enable(state->instrumentation_state, &state->process, state->cmd_line, NULL, 0);\n\n\t//Now accept the client connection\n\tclientSock = accept(serverSock, NULL, NULL);\n\n\tif (clientSock == INVALID_SOCKET)\n\t{\n#ifdef _WIN32\n\t\tFATAL_MSG(\"accept() failed with error: %d\\n\", WSAGetLastError());\n#else\n\t\tFATAL_MSG(\"accept() failed with error: %d\\n\", errno);\n#endif\n\t\treturn FUZZ_ERROR;\n\t}\n\n#ifdef _WIN32\n\tclosesocket(serverSock);\n#else\n\tclose(serverSock);\n#endif\n\n\tfor (i = 0; i < inputs_count; i++)\n\t{\n\t\tif (state->sleeps && state->sleeps[i] != 0)\n#ifdef _WIN32\n\t\t\tSleep(state->sleeps[i]);\n#else\n\t\t\tusleep(1000*state->sleeps[i]);\n#endif\n\t\tsock_ret = send_tcp_input(&clientSock, inputs[i], lengths[i]);\n\t\tif (sock_ret)\n\t\t{\n\t\t\tif (sock_ret == -2)\n\t\t\t{\n\t\t\t\tWARNING_MSG(\"Client terminated connection before all packets \"\n\t\t\t\t\t\"were sent, %d of %d packets sent\", i, inputs_count);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn FUZZ_ERROR;\n\t\t}\n\t}\n#ifdef _WIN32\n\tclosesocket(clientSock);\n#else\n\tclose(clientSock);\n#endif\n\t\n\t//Wait for it to be done\n\treturn generic_wait_for_process_completion(state->process, state->timeout, \n\t\tstate->instrumentation, state->instrumentation_state);\n}\n/**\n * This function will run the fuzzed program and test it with the given input.\n * This function blocks until the program has finished processing the input.\n * @param driver_state - a driver specific structure previously created by the\n * \t\tnetwork_client_create function\n * @param input - the input that should be tested\n * @param length - the length of the input parameter\n * @return - FUZZ_NONE, FUZZ_HANG, FUZZ_CRASH on success or FUZZ_ERROR on failure\n */\nint network_client_test_input(void * driver_state, char * input, size_t length)\n{\n\tnetwork_client_state_t * state = (network_client_state_t *)driver_state;\n\tchar ** inputs;\n\tsize_t * input_lengths;\n\tsize_t i, inputs_count;\n\tint ret = FUZZ_ERROR;\n\n\tif (decode_mem_array(input, &inputs, &input_lengths, &inputs_count) == 0)\n\t{\n\t\tif (inputs_count)\n\t\t\tret = network_client_run(state, inputs, input_lengths, inputs_count);\n\t\t\n\t\t//clean up time\n\t\tfor (i = 0; i < inputs_count; i++)\n\t\t\tfree(inputs[i]);\n\n\t\tfree(inputs);\n\t\tfree(input_lengths);\n\t}\n\treturn ret;\n}\n\n/**\n * This function will run the fuzzed program with the output of the mutator given during driver\n * creation.  This function blocks until the program has finished processing the input.\n * @param driver_state - a driver specific structure previously created by the network_client_create function\n * @return - FUZZ_NONE, FUZZ_HANG, FUZZ_CRASH on success, FUZZ_ERROR on error, or -2 if the mutator has \n * finished generating inputs\n */\nint network_client_test_next_input(void * driver_state)\n{\n\tnetwork_client_state_t * state = (network_client_state_t *)driver_state;\n\tint i, ret;\n\n\tif (!state->mutator)\n\t\treturn FUZZ_ERROR;\n\n\tmemset(state->mutate_last_sizes, 0, sizeof(int) * state->num_inputs);\n\tfor (i = 0; i < state->num_inputs; i++)\n\t{\n\t\tret = state->mutator->mutate_extended(state->mutator_state,\n\t\t\tstate->mutate_buffers[i], state->mutate_buffer_lengths[i], MUTATE_MULTIPLE_INPUTS | i);\n\t\tif (ret < 0)\n\t\t\treturn FUZZ_ERROR;\n\t\tif (ret == 0)\n\t\t\treturn -2;\n\t\tstate->mutate_last_sizes[i] = (size_t)ret;\n\t}\n\treturn network_client_run(state, state->mutate_buffers, state->mutate_last_sizes, state->num_inputs);\n}\n\n/**\n * When this driver is using a mutator given to it during driver creation, this function retrieves\n * the last input that was tested with the network_client_test_next_input function.\n * @param driver_state - a driver specific structure previously created by the network_client_create function\n * @param length - a pointer to an integer used to return the length of the input that was last tested.\n * @return - NULL on error or if the driver doesn't have a mutator, or a buffer containing the last input\n * that was tested by the driver with the network_client_test_next_input function.  This buffer should be freed\n * by the caller.\n */\nchar * network_client_get_last_input(void * driver_state, int * length)\n{\n\tnetwork_client_state_t * state = (network_client_state_t *)driver_state;\n\tint i;\n\n\tif (!state->mutate_buffers)\n\t\treturn NULL;\n\tfor (i = 0; i < state->num_inputs; i++)\n\t{\n\t\t// If network_client_test_next_input has not been called or failed to mutate the\n\t\t// input, there could be no input to return\n\n\t\t// Assumption: mutate_last_size should never be set to 0 in correct\n\t\t// operation, only if it wasn't proper loaded with the mutate array\n\t\t// sizes.\n\t\tif (state->mutate_last_sizes[i] == 0)\n\t\t\treturn NULL;\n\t}\n\treturn encode_mem_array(state->mutate_buffers, \n\t\tstate->mutate_last_sizes, state->num_inputs, length);\n}\n\n/**\n * This function returns help text for this driver.  This help text will describe the driver and any options\n * that can be passed to network_client_create.\n * @return - a newly allocated string containing the help text.\n */\nint network_client_help(char ** help_str)\n{\n\t*help_str = strdup(\n\"network_client - fuzzes clients by acting as a server\\n\"\n\"Required Options:\\n\"\n\"  path                  The path to the exe\\n\"\n\"  arguments             Arguments to pass to the target process\\n\"\n\"Optional Options:\\n\"\n\"  timeout               The maximum number of seconds to wait\\n\"\n\"                          for the target process to finish\\n\"\n\"  ratio                 The ratio of mutation buffer size to\\n\"\n\"                          input size when given a mutator\\n\"\n\"  ip                    The target IP to connect to\\n\"\n\"  port                  The target port to connect to\\n\"\n\"  ratio                 The ratio of mutation buffer size to input\\n\"\n\"                          size when given a mutator\\n\"\n\"  sleeps                An array of milliseconds to wait between each\\n\"\n\"                          input being sent to the target program\\n\"\n\"\\n\"\n\t);\n\n\tif (*help_str == NULL)\n\t\treturn -1;\n\treturn 0;\n}\n"
  },
  {
    "path": "driver/network_client_driver.h",
    "content": "#pragma once\n#include \"driver.h\"\n#include \"instrumentation.h\"\n#include <global_types.h>\n\n#ifndef _WIN32 // Linux\n#include <sys/types.h> // pid_t\n#endif\n\nvoid * network_client_create(char * options, instrumentation_t * instrumentation, void * instrumentation_state,\n\tmutator_t * mutator, void * mutator_state);\nvoid network_client_cleanup(void * driver_state);\nint network_client_test_input(void * driver_state, char * buffer, size_t length);\nint network_client_test_next_input(void * driver_state);\nchar * network_client_get_last_input(void * driver_state, int * length);\nint network_client_help(char ** help_str);\n\nstruct network_client_state\n{\n\t//Options\n\tchar * path;            //The path to the fuzzed executable\n\tchar * arguments;       //Arguments to give the binary\n\tint timeout;            //Maximum number of seconds to allow the executable to run\n\tchar * target_ip;       //The IP address to send the fuzzed data to\n\tint lport;        //The port to send the fuzzed data to\n\tdouble input_ratio;     //the ratio of the maximum input size\n\tint * sleeps;           //How many milliseconds to sleep between inputs\n\tint sleeps_count;       //The number of items in the sleeps array\n\n\t//The handle to the fuzzed process instance\n\t#ifdef _WIN32\n\tHANDLE process;\n\t#else\n\tpid_t process;\n\t#endif\n\n\t//command line of the fuzzed process\n\tchar * cmd_line;\n\n\t//The instrumentation module\n\tinstrumentation_t * instrumentation;\n\n\t//The instrumentation's state\n\tvoid * instrumentation_state;\n\n\tmutator_t * mutator;\n\tvoid * mutator_state;\n\n\t// it'd be nice if this could be size_t, but mutator function\n\t// get_input_info requires ints.\n\tint num_inputs;\n\tchar ** mutate_buffers;\n\tsize_t * mutate_buffer_lengths;\n\tsize_t * mutate_last_sizes;\n};\ntypedef struct network_client_state network_client_state_t;\n"
  },
  {
    "path": "driver/network_server_driver.c",
    "content": "#include \"network_server_driver.h\"\n\n#include <utils.h>\n#include <jansson_helper.h>\n#include <instrumentation.h>\n#include \"driver.h\"\n\n//c headers\n#include <stdio.h>\n#include <stdlib.h>\n#include <time.h>\n#include <string.h>\n\n#ifdef _WIN32\n#include <Shlwapi.h>\n#include <iphlpapi.h>\n#include <process.h>\n#else\n#include <netinet/in.h>\n#include <arpa/inet.h>\n#include <unistd.h>\n#if __APPLE__\n#include <sys/sysctl.h>\n#include <sys/socketvar.h>\n#include <netinet/tcp_var.h>\n#include <netinet/tcp_fsm.h>\n#else\n#include <sys/socket.h>\n#include <netinet/ip.h>\n#endif // __APPLE__\n#endif\n\n/**\n * This function creates a network_server_state_t object based on the given options.\n * @param options - A JSON string of the options to set in the new network_server_state_t. See the\n * help function for more information on the specific options available.\n * @return - the network_server_state_t generated from the options in the JSON options string, or NULL on failure\n */\nstatic network_server_state_t * setup_options(char * options)\n{\n\tnetwork_server_state_t * state;\n\tsize_t cmd_length;\n\n\tstate = (network_server_state_t *)malloc(sizeof(network_server_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(network_server_state_t));\n\n\t//Setup defaults\n\tstate->timeout = 2;\n\tstate->input_ratio = 2.0;\n\n\t//Parse the options\n\tPARSE_OPTION_STRING(state, options, path, \"path\", network_server_cleanup);\n\tPARSE_OPTION_STRING(state, options, arguments, \"arguments\", network_server_cleanup);\n\tPARSE_OPTION_INT(state, options, timeout, \"timeout\", network_server_cleanup);\n\tPARSE_OPTION_INT(state, options, target_port, \"port\", network_server_cleanup);\n\tPARSE_OPTION_STRING(state, options, target_ip, \"ip\", network_server_cleanup);\n\tPARSE_OPTION_INT(state, options, target_udp, \"udp\", network_server_cleanup);\n\tPARSE_OPTION_INT(state, options, skip_network_check, \"skip_network_check\", network_server_cleanup);\n\tPARSE_OPTION_DOUBLE(state, options, input_ratio, \"ratio\", network_server_cleanup);\n\tPARSE_OPTION_INT_ARRAY(state, options, sleeps, sleeps_count, \"sleeps\", network_server_cleanup);\n\n\tcmd_length = (state->path ? strlen(state->path) : 0) + (state->arguments ? strlen(state->arguments) : 0) + 2;\n\tstate->cmd_line = (char *)malloc(cmd_length);\n\n\tif (!state->path || !state->cmd_line || !file_exists(state->path) || !state->target_ip || !state->target_port || state->input_ratio <= 0)\n\t{\n\t\tnetwork_server_cleanup(state);\n\t\treturn NULL;\n\t}\n\n\tsnprintf(state->cmd_line, cmd_length, \"%s %s\", state->path, state->arguments ? state->arguments : \"\");\n\n\treturn state;\n}\n\n/**\n * This function cleans up all resources with the passed in driver state.\n * @param driver_state - a driver specific state object previously created by the network_server_create function\n * This state object should not be referenced after this function returns.\n */\nvoid network_server_cleanup(void * driver_state)\n{\n\tnetwork_server_state_t * state = (network_server_state_t *)driver_state;\n\tint i;\n\n\t//Cleanup mutator stuff\n\tfor(i = 0; state->mutate_buffers && i < state->num_inputs; i++)\n\t\tfree(state->mutate_buffers[i]);\n\tfree(state->mutate_buffers);\n\tfree(state->mutate_buffer_lengths);\n\tfree(state->mutate_last_sizes);\n\t\n\t//Clean up driver specific options\n\tfree(state->path);\n\tfree(state->arguments);\n\tfree(state->cmd_line);\n\tfree(state->target_ip);\n\tfree(state->sleeps);\n\n\t//Clean up the struct holding it all\n\tfree(state);\n}\n\n/**\n * This function allocates and initializes a new driver specific state object based on the given options.\n * @param options - a JSON string that contains the driver specific string of options\n * @param instrumentation - a pointer to an instrumentation instance that the driver will use\n * to instrument the requested program.  This instrumentation instance should already be initialized.\n * @param instrumentation_state - a pointer to the instrumentation state for the passed in instrumentation\n * @return - a driver specific state object on success or NULL on failure\n */\nvoid * network_server_create(char * options, instrumentation_t * instrumentation, void * instrumentation_state,\n\tmutator_t * mutator, void * mutator_state)\n{\n#ifdef _WIN32\n\tWSADATA wsaData;\n#endif\n\tnetwork_server_state_t * state;\n\tsize_t i;\n\n\t//This driver requires at least the path to the program to run. Make sure we either have both a mutator and state\n\tif (!options || !strlen(options) || (mutator && !mutator_state) || (!mutator && mutator_state)) //or neither\n\t\treturn NULL;\n\n#ifdef _WIN32\n\tif (WSAStartup(MAKEWORD(2, 2), &wsaData)) {\n\t\tERROR_MSG(\"WSAStartup Failed\\n\");\n\t\treturn NULL;\n\t}\n#endif\n\t\n\tstate = setup_options(options);\n\tif (!state)\n\t\treturn NULL;\n\n\tif (mutator)\n\t{\n\t\tmutator->get_input_info(mutator_state, &state->num_inputs, &state->mutate_buffer_lengths);\n\t\tif (state->sleeps && state->num_inputs != state->sleeps_count)\n\t\t{\n\t\t\tnetwork_server_cleanup(state);\n\t\t\treturn NULL;\n\t\t}\n\n\t\tstate->mutate_buffers = malloc(sizeof(char *) * state->num_inputs);\n\t\tif (!state->mutate_buffers) {\n\t\t\tnetwork_server_cleanup(state);\n\t\t\treturn NULL;\n\t\t}\n\n\t\t//Setup the mutate buffers\n\t\tstate->mutate_buffers = malloc(sizeof(char *) * state->num_inputs);\n\t\tstate->mutate_last_sizes = malloc(sizeof(size_t) * state->num_inputs);\n\t\tmemset(state->mutate_buffers, 0, sizeof(char *) * state->num_inputs);\n\t\tmemset(state->mutate_last_sizes, 0, sizeof(size_t) * state->num_inputs);\n\t\tfor (i = 0; i < state->num_inputs; i++)\n\t\t{\n\t\t\tif(setup_mutate_buffer(state->input_ratio, state->mutate_buffer_lengths[i], &state->mutate_buffers[i],\n\t\t\t\t&state->mutate_buffer_lengths[i]))\n\t\t\t{\n\t\t\t\tnetwork_server_cleanup(state);\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t}\n\n\t\tstate->mutator = mutator;\n\t\tstate->mutator_state = mutator_state;\n\t}\n\n\tstate->instrumentation = instrumentation;\n\tstate->instrumentation_state = instrumentation_state;\n\treturn state;\n}\n\n/**\n * This function creates a socket and (when using TCP) connects it to the fuzzed program.\n * @param state - the network_server_state_t object that represents the current state of the driver\n * @param sock - a pointer to a SOCKET used to return the created socket\n * @return - non-zero on error, zero on success\n */\n#ifdef _WIN32\nstatic int connect_to_target(network_server_state_t * state, SOCKET * sock)\n#else\nstatic int connect_to_target(network_server_state_t * state, int * sock)\n#endif\n{\n\tstruct sockaddr_in addr;\n\n\tif(state->target_udp)\n\t\t*sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);\n\telse\n\t\t*sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\n#ifdef _WIN32\n\tif (*sock == INVALID_SOCKET)\n#else\n\tif (*sock == -1)\n#endif\n\t\treturn 1;\n\n\tif (!state->target_udp)\n\t{\n\t\taddr.sin_family = AF_INET;\n\t\taddr.sin_addr.s_addr = inet_addr(state->target_ip);\n\t\taddr.sin_port = htons(state->target_port);\n#ifdef _WIN32\n\t\tif (connect(*sock, (const struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) {\n\t\t\tclosesocket(*sock);\n#else\n\t\tif (connect(*sock, (const struct sockaddr *)&addr, sizeof(addr)) == -1) {\n\t\t\tclose(*sock);\n#endif\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n/**\n * This function sends the provided buffer on the UDP socket\n * @param state - the network_server_state_t object that represents the current state of the driver\n * @param sock - a pointer to a UDP SOCKET to send the buffer on\n * @param buffer - the buffer to send\n * @param length - the length of the buffer parameter\n * @return - non-zero on error, zero on success\n */\n#ifdef _WIN32\nstatic int send_udp_input(network_server_state_t * state, SOCKET * sock, char * buffer, size_t length)\n#else\nstatic int send_udp_input(network_server_state_t * state, int * sock, char * buffer, size_t length)\n#endif\n{\n\tstruct sockaddr_in addr;\n\taddr.sin_family = AF_INET;\n\taddr.sin_addr.s_addr = inet_addr(state->target_ip);\n\taddr.sin_port = htons(state->target_port);\n#ifdef _WIN32\n\tif (sendto(*sock, buffer, length, 0, (const struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR)\n#else\n\tif (sendto(*sock, buffer, length, 0, (const struct sockaddr *)&addr, sizeof(addr)) == -1)\n#endif\n\t\treturn 1;\n\treturn 0;\n}\n\n/**\n * This function determines if there is a program listening on the specified port on the local computer\n * @param port - the port number to check\n * @param udp - whether the specified port is udp (1) or tcp (0)\n * @return - 1 if the port is listening, 0 if the port is not listening, or -1 on error\n */\nstatic int is_port_listening(int port, int udp)\n{\n#ifdef _WIN32\n\tMIB_TCPTABLE * tcp_table;\n\tMIB_UDPTABLE * udp_table;\n\tDWORD i, size = 0;\n\n\tif (udp) {\n\t\tif (GetUdpTable(NULL, &size, TRUE) != ERROR_INSUFFICIENT_BUFFER)\n\t\t\treturn -1;\n\t\tudp_table = malloc(size);\n\t\tif (!udp_table)\n\t\t\treturn -1;\n\t\tif (GetUdpTable(udp_table, &size, TRUE) != NO_ERROR) {\n\t\t\tfree(udp_table);\n\t\t\treturn -1;\n\t\t}\n\t\tfor (i = 0; i < udp_table->dwNumEntries; i++) {\n\t\t\tif (udp_table->table[i].dwLocalPort == htons(port))\n\t\t\t{\n\t\t\t\tfree(udp_table);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\tfree(udp_table);\n\n\t} else {\n\t\tif (GetTcpTable(NULL, &size, TRUE) != ERROR_INSUFFICIENT_BUFFER)\n\t\t\treturn -1;\n\t\ttcp_table = malloc(size);\n\t\tif (!tcp_table)\n\t\t\treturn -1;\n\t\tif (GetTcpTable(tcp_table, &size, TRUE) != NO_ERROR) {\n\t\t\tfree(tcp_table);\n\t\t\treturn -1;\n\t\t}\n\t\tfor (i = 0; i < tcp_table->dwNumEntries; i++) {\n\t\t\tif (tcp_table->table[i].dwState == MIB_TCP_STATE_LISTEN && tcp_table->table[i].dwLocalPort == htons(port))\n\t\t\t{\n\t\t\t\tfree(tcp_table);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\tfree(tcp_table);\n\t}\n#elif __APPLE__\n\tchar ctl[] = \"net.inet.tcp.pcblist\";\n\tchar *buf, *entry;\n\tstruct xtcpcb *tcp_entry;\n\tsize_t len;\n\tuint32_t port_n = htons(port);\n\n\tif (sysctlbyname(ctl, NULL, &len, NULL, 0) == -1) // check to get length of data\n\t{\n\t\tperror(\"sysctlbyname failed to get length\");\n\t\treturn -1;\n\t}\n\tbuf = malloc(len);  // malloc some space for it\n\tif (buf == NULL) {\n\t\tperror(\"malloc\");\n\t\treturn -1;\n\t}\n\tif (sysctlbyname(ctl, buf, &len, NULL, 0) == -1)\n\t{\n\t\tperror(\"sysctlbyname\");\n\t\tfree(buf);\n\t\treturn -1;\n\t}\n\n#define ENTRY_LEN(entry) (((struct xtcpcb *)(entry))->xt_len)\n\n\t// buf is an array of length-prepended table entries, potentially of different kinds\n\tentry = buf;\n\t// skip first entry, it defines generation rather than a connection\n\tentry += ENTRY_LEN(entry);\n\twhile (ENTRY_LEN(entry) == sizeof(struct xtcpcb)) {\n\t\ttcp_entry = (struct xtcpcb *)entry;\n\n\t\tif (tcp_entry->xt_socket.xso_protocol == IPPROTO_TCP &&\n\t\t\t\ttcp_entry->xt_tp.t_state == TCPS_LISTEN &&\n\t\t\t\ttcp_entry->xt_inp.inp_lport == port_n)\n\t\t{\n\t\t\tfree(buf);\n\t\t\treturn 1;\n\t\t}\n\n\t\tentry += ENTRY_LEN(entry);\n\t}\n\tfree(buf);\n\n#undef ENTRY_LEN\n\n#else // Linux\n\tchar line[250];\n\tFILE * tcp_info = fopen(\"/proc/net/tcp\",\"r\");\n\tint num, port_from_proc;\n\n\tif (tcp_info == NULL)\n\t\tFATAL_MSG(\"Failed to open /proc/net/tcp\");\n\n\t// Would it be faster to directly fscanf here, instead of reading output\n\t// into a buffer and then scanf'ing that?\n\twhile(fgets(line, 250, tcp_info))\n\t{\n\t\t// skip header line\n        if(!strncmp(line, \"  sl\", 4) != 0)\n            continue;\n\n\t\t// read in: #: (ip in hex):(port), ignore the rest\n\t\t// throw away the (ip in hex) since we don't need it\n\t\tsscanf(line, \"%d: %*[A-Fa-f0-9]:%X\", &num, &port_from_proc);\n\n\t\tif (port == port_from_proc)\n\t\t\treturn 1;\t\n\t}\n\n\tfclose(tcp_info);\n#endif\n\treturn 0;\n}\n\n/**\n * This function will run the fuzzed program and test it with the given inputs. This function\n * blocks until the program has finished processing the input.\n * @param state - the network_server_state_t object that represents the current state of the driver\n * @param inputs - an array of inputs to send to the program\n * @param lengths - an array of lengths for the buffers in the inputs parameter\n * @param inputs_count - the number of buffers in the inputs parameter\n * @return - FUZZ_ result on success or FUZZ_ERROR on failure\n */\nstatic int network_server_run(network_server_state_t * state, char ** inputs, size_t * lengths, size_t inputs_count)\n{\n\n#ifdef _WIN32\n\tSOCKET sock;\n#else\n\tint sock;\n#endif\n\tsize_t i;\n\tint listening = 0;\n\n\t//Start the process and give it our input\n\tif(state->instrumentation->enable(state->instrumentation_state, &state->process, state->cmd_line, NULL, 0))\n\t\treturn FUZZ_ERROR;\n\n\t//Wait for the port to be listening\n\twhile (!state->skip_network_check && listening == 0) {\n\t\tlistening = is_port_listening(state->target_port, state->target_udp);\n\t\tif(listening == 0)\n#ifdef _WIN32\n\t\t\tSleep(5);\n#else\n\t\t\tusleep(5*1000);\n#endif\n\t}\n\tif(listening < 0)\n\t\treturn FUZZ_ERROR;\n\n\tif (connect_to_target(state, &sock)) // opens socket\n\t\treturn FUZZ_ERROR;\n\tfor (i = 0; i < inputs_count; i++)\n\t{\n\t\tif (state->sleeps && state->sleeps[i] != 0)\n#ifdef _WIN32\n\t\t\tSleep(state->sleeps[i]);\n#else\n\t\t\tusleep(1000*state->sleeps[i]);\n#endif\n\t\tif ((state->target_udp && send_udp_input(state, &sock, inputs[i], lengths[i]))\n\t\t\t|| (!state->target_udp && send_tcp_input(&sock, inputs[i], lengths[i])))\n\t\t{\n#ifdef _WIN32\n\t\t\tclosesocket(sock);\n#else\n\t\t\tclose(sock);\n#endif\n\t\t\treturn FUZZ_ERROR;\n\t\t}\n\t}\n#ifdef _WIN32\n\tclosesocket(sock);\n#else\n\tclose(sock);\n#endif\n\n\t//Wait for it to be done and return FUZZ_ result\n\treturn generic_wait_for_process_completion(state->process, state->timeout,\n\t\tstate->instrumentation, state->instrumentation_state);\n}\n\nstatic void network_server_test_input_cleanup(char ** inputs, size_t inputs_count, size_t * input_lengths)\n{\n\tfor (size_t i = 0; i < inputs_count; i++)\n\t\tfree(inputs[i]);\n\tfree(inputs);\n\tfree(input_lengths);\n}\n\n/**\n * This function will run the fuzzed program and test it with the given input. This function\n * blocks until the program has finished processing the input.\n * @param driver_state - a driver specific structure previously created by the network_server_create function\n * @param input - the input that should be tested\n * @param length - the length of the input parameter\n * @return - FUZZ_ result on success or FUZZ_ERROR on failure\n */\nint network_server_test_input(void * driver_state, char * input, size_t length)\n{\n\tnetwork_server_state_t * state = (network_server_state_t *)driver_state;\n\tchar ** inputs;\n\tsize_t * input_lengths;\n\tsize_t inputs_count;\n\tint network_server_run_result = FUZZ_ERROR;\n\n\tif (decode_mem_array(input, &inputs, &input_lengths, &inputs_count))\n\t\treturn FUZZ_ERROR;\n\tif (inputs_count)\n\t{\n\t\tnetwork_server_run_result = network_server_run(state, inputs, input_lengths, inputs_count);\n\t\tif (network_server_run_result == FUZZ_ERROR)\n\t\t{\n\t\t\tnetwork_server_test_input_cleanup(inputs, inputs_count, input_lengths);\n\t\t\treturn FUZZ_ERROR;\n\t\t}\n\t}\n\tnetwork_server_test_input_cleanup(inputs, inputs_count, input_lengths);\n\n\treturn network_server_run_result;\n}\n\n\n/**\n * This function will run the fuzzed program with the output of the mutator given during driver\n * creation.  This function blocks until the program has finished processing the input.\n * @param driver_state - a driver specific structure previously created by the network_server_create function\n * @return - FUZZ_ result on success, FUZZ_ERROR on error, -2 if the mutator has finished generating inputs\n */\nint network_server_test_next_input(void * driver_state)\n{\n\tnetwork_server_state_t * state = (network_server_state_t *)driver_state;\n\tint i, ret;\n\tint network_server_run_result = FUZZ_ERROR;\n\n\tif (!state->mutator)\n\t\treturn FUZZ_ERROR;\n\t\n\tmemset(state->mutate_last_sizes, 0, sizeof(int) * state->num_inputs);\n\tfor (i = 0; i < state->num_inputs; i++)\n\t{\n\t\tret = state->mutator->mutate_extended(state->mutator_state,\n\t\t\tstate->mutate_buffers[i], state->mutate_buffer_lengths[i], MUTATE_MULTIPLE_INPUTS | i);\n\t\tif (ret < 0)\n\t\t\treturn FUZZ_ERROR;\n\t\telse if (ret == 0)\n\t\t\treturn -2;\n\t\tstate->mutate_last_sizes[i] = (size_t)ret;\n\t}\n\n\tnetwork_server_run_result = network_server_run(state, state->mutate_buffers, state->mutate_last_sizes, state->num_inputs);\n\n\treturn network_server_run_result;\n}\n\n/**\n * When this driver is using a mutator given to it during driver creation, this function retrieves\n * the last input that was tested with the network_server_test_next_input function.\n * @param driver_state - a driver specific structure previously created by the network_server_create function\n * @param length - a pointer to an integer used to return the length of the input that was last tested.\n * @return - NULL on error or if the driver doesn't have a mutator, or a buffer containing the last input\n * that was tested by the driver with the network_server_test_next_input function.  This buffer should be freed\n * by the caller.\n */\nchar * network_server_get_last_input(void * driver_state, int * length)\n{\n\tnetwork_server_state_t * state = (network_server_state_t *)driver_state;\n\tint i;\n\n\tif (!state->mutate_buffers)\n\t\treturn NULL;\n\tfor (i = 0; i < state->num_inputs; i++)\n\t{\n\t\t// If network_server_test_next_input has not been called or failed to mutate the\n\t\t// input, there could be no input to return\n\n\t\t// Assumption: mutate_last_size should never be set to 0 in correct\n\t\t// operation, only if it wasn't proper loaded with the mutate array\n\t\t// sizes.\n\t\tif (state->mutate_last_sizes[i] == 0)\n\t\t\treturn NULL;\n\t}\n\treturn encode_mem_array(state->mutate_buffers, state->mutate_last_sizes, state->num_inputs, length);\n}\n\n/**\n * This function returns help text for this driver.  This help text will describe the driver and any options\n * that can be passed to network_server_create.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nint network_server_help(char ** help_str)\n{\n\t*help_str = strdup(\n\"network_server - Fuzzes server-like applications by sending input over the network\\n\"\n\"Required Options:\\n\"\n\"  ip                    The target IP to connect to\\n\"\n\"  path                  The path to the target process\\n\"\n\"  port                  The target port to connect to\\n\"\n\"Optional Options:\\n\"\n\"  arguments             Arguments to pass to the target process\\n\"\n\"  timeout               The maximum number of seconds to wait for the target\\n\"\n\"                          process to finish\\n\"\n\"  ratio                 The ratio of mutation buffer size to input size when\\n\"\n\"                          given a mutator\\n\"\n\"  skip_network_check    Whether or not to wait for the specified port to be\\n\"\n\"                          listening on the localhost prior to connecting to\\n\"\n\"                          the target program\\n\"\n\"  sleeps                An array of milliseconds to wait between each input\\n\"\n\"                          being sent to the target program\\n\"\n\"  udp                   Whether the fuzzed input should be sent to the target\\n\"\n\"                          program on UDP (1) or TCP (0)\\n\"\n\"\\n\"\n\t);\n\tif (*help_str == NULL)\n\t\treturn -1;\n\treturn 0;\n}\n"
  },
  {
    "path": "driver/network_server_driver.h",
    "content": "#pragma once\n#include \"driver.h\"\n#include <instrumentation.h>\n#include <global_types.h>\n\n#ifndef _WIN32 // Linux\n#include <sys/types.h> // pid_t\n#endif\n\nvoid * network_server_create(char * options, instrumentation_t * instrumentation, void * instrumentation_state,\n\tmutator_t * mutator, void * mutator_state);\nvoid network_server_cleanup(void * driver_state);\nint network_server_test_input(void * driver_state, char * buffer, size_t length);\nint network_server_test_next_input(void * driver_state);\nchar * network_server_get_last_input(void * driver_state, int * length);\nint network_server_help(char ** help_str);\n\nstruct network_server_state\n{\n\t//Options\n\tchar * path;            //The path to the fuzzed executable\n\tchar * arguments;       //Arguments to give the binary\n\tint timeout;            //Maximum number of seconds to allow the executable to run\n\tchar * target_ip;       //The IP address to send the fuzzed data to\n\tint target_port;        //The port to send the fuzzed data to\n\tint target_udp;         //Is the driver hitting a udp port (1) or tcp port (0)\n\tint skip_network_check; //Don't wait for the target_port to be listening\n\tdouble input_ratio;     //the ratio of the maximum input size\n\tint * sleeps;           //How many milliseconds to sleep between inputs\n\tint sleeps_count;       //The number of items in the sleeps array\n\n\t//The handle to the fuzzed process instance\n\t#ifdef _WIN32\n\tHANDLE process;\n\t#else\n\tpid_t process;\n\t#endif\n\n\t//command line of the fuzzed process\n\tchar * cmd_line;\n\n\t//The instrumentation module\n\tinstrumentation_t * instrumentation;\n\n\t//The instrumentation's state\n\tvoid * instrumentation_state;\n\n\tmutator_t * mutator;\n\tvoid * mutator_state;\n\n// it'd be nice if this could be size_t, but mutator function\n// get_input_info requires ints.\n\tint num_inputs; \n\n\tchar ** mutate_buffers;\n\tsize_t * mutate_buffer_lengths;\n\tsize_t * mutate_last_sizes;\n};\ntypedef struct network_server_state network_server_state_t;\n"
  },
  {
    "path": "driver/stdin_driver.c",
    "content": "#include \"stdin_driver.h\"\n\n#include <global_types.h>     // for mutator_t\n#include <utils.h>\n#include <jansson_helper.h>\n#include <instrumentation.h>\n#include \"driver.h\" // IWYU pragma: keep\n\n//c headers\n#include <stdio.h>\n#include <stdlib.h>\n\n#ifdef _WIN32\n//Windows API\n#include <Shlwapi.h>\n#include <process.h>\n#else // linux\n#include <string.h>    // memset, strlen\n#endif\n\n/**\n * This function creates a stdin_state_t object based on the given options.\n * @param options - A JSON string of the options to set in the new stdin_state_t. See the\n * help function for more information on the specific options available.\n * @return - the stdin_state_t generated from the options in the JSON options string, or NULL on failure\n */\nstatic stdin_state_t * setup_options(char * options)\n{\n\tstdin_state_t * state;\n\tsize_t cmd_length;\n\n\tstate = (stdin_state_t *)malloc(sizeof(stdin_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(stdin_state_t));\n\n\t//Setup defaults\n\tstate->timeout = 2;\n\tstate->input_ratio = 2.0;\n\n\t//Parse the options\n\tPARSE_OPTION_STRING(state, options, path, \"path\", stdin_cleanup);\n\tPARSE_OPTION_STRING(state, options, arguments, \"arguments\", stdin_cleanup);\n\tPARSE_OPTION_INT(state, options, timeout, \"timeout\", stdin_cleanup);\n\tPARSE_OPTION_DOUBLE(state, options, input_ratio, \"ratio\", stdin_cleanup);\n\n\tcmd_length = (state->path ? strlen(state->path) : 0) + (state->arguments ? strlen(state->arguments) : 0) + 2;\n\tstate->cmd_line = (char *)malloc(cmd_length);\n\n\t//Validate the options\n\tif (!state->path || !state->cmd_line || !file_exists(state->path) || state->input_ratio <= 0)\n\t{\n\t\tstdin_cleanup(state);\n\t\treturn NULL;\n\t}\n\n\tsnprintf(state->cmd_line, cmd_length, \"%s %s\", state->path, state->arguments ? state->arguments : \"\");\n\n\treturn state;\n}\n\n/**\n * This function allocates and initializes a new driver specific state object based on the given options.\n * @param options - a JSON string that contains the driver specific string of options\n * @param instrumentation - a pointer to an instrumentation instance that the driver will use\n * to instrument the requested program.  This instrumentation instance should already be initialized.\n * @param instrumentation_state - a pointer to the instrumentation state for the passed in instrumentation\n * @return - a driver specific state object on success or NULL on failure\n */\nvoid * stdin_create(char * options, instrumentation_t * instrumentation, void * instrumentation_state,\n\tmutator_t * mutator, void * mutator_state)\n{\n\tstdin_state_t * state;\n\tint num_inputs;\n\tsize_t *input_sizes;\n\n\t//This driver requires at least the path to the program to run. Make sure we either have both a mutator and state\n\tif (!options || !strlen(options) || (mutator && !mutator_state) || (!mutator && mutator_state)) //or neither\n\t\treturn NULL;\n\n\tstate = setup_options(options);\n\tif (!state)\n\t\treturn NULL;\n\n\tif (mutator)\n\t{\n\t\tmutator->get_input_info(mutator_state, &num_inputs, &input_sizes);\n\t\tif (num_inputs != 1\n\t\t\t|| setup_mutate_buffer(state->input_ratio, input_sizes[0], &state->mutate_buffer, &state->mutate_buffer_length))\n\t\t{\n\t\t\tfree(input_sizes);\n\t\t\tstdin_cleanup(state);\n\t\t\treturn NULL;\n\t\t}\n\t\tfree(input_sizes);\n\t}\n\n\tstate->mutator = mutator;\n\tstate->mutator_state = mutator_state;\n\tstate->mutate_last_size = -1;\n\tstate->instrumentation = instrumentation;\n\tstate->instrumentation_state = instrumentation_state;\n\treturn state;\n}\n\n/**\n * This function cleans up all resources with the passed in driver state.\n * @param driver_state - a driver specific state object previously created by the stdin_create function\n * This state object should not be referenced after this function returns.\n */\nvoid stdin_cleanup(void * driver_state)\n{\n\tstdin_state_t * state = (stdin_state_t *)driver_state;\n\n\tfree(state->mutate_buffer);\n\tfree(state->path);\n\tfree(state->arguments);\n\tfree(state->cmd_line);\n\tfree(state);\n}\n\n/**\n * This function will run the fuzzed program and test it with the given input. This function\n * blocks until the program has finished processing the input.\n * @param driver_state - a driver specific structure previously created by the stdin_create function\n * @param input - the input that should be tested\n * @param length - the length of the input parameter\n * @return - FUZZ_ on success or FUZZ_ERROR on failure\n */\nint stdin_test_input(void * driver_state, char * input, size_t length)\n{\n\tstdin_state_t * state = (stdin_state_t *)driver_state;\n\n\t//Start the process and give it our input\n\tif(state->instrumentation->enable(state->instrumentation_state, &state->process, state->cmd_line, input, length))\n\t\treturn FUZZ_ERROR;\n\n\t//Wait for it to be done\n\treturn generic_wait_for_process_completion(state->process, state->timeout,\n\t\tstate->instrumentation, state->instrumentation_state);\n}\n\n/**\n * This function will run the fuzzed program with the output of the mutator given during driver\n * creation.  This function blocks until the program has finished processing the input.\n * @param driver_state - a driver specific structure previously created by the stdin_create function\n * @return - FUZZ_ result on success, FUZZ_ERROR on error, -2 if the mutator has finished generating inputs\n */\nint stdin_test_next_input(void * driver_state)\n{\n\tstdin_state_t * state = (stdin_state_t *)driver_state;\n\treturn generic_test_next_input(state, state->mutator, state->mutator_state, state->mutate_buffer,\n\t\tstate->mutate_buffer_length, stdin_test_input, &state->mutate_last_size);\n}\n\n/**\n * When this driver is using a mutator given to it during driver creation, this function retrieves\n * the last input that was tested with the stdin_test_next_input function.\n * @param driver_state - a driver specific structure previously created by the stdin_create function\n * @param length - a pointer to an integer used to return the length of the input that was last tested.\n * @return - NULL on error or if the driver doesn't have a mutator, or a buffer containing the last input\n * that was tested by the driver with the stdin_test_next_input function.  This buffer should be freed\n * by the caller.\n */\nchar * stdin_get_last_input(void * driver_state, int * length)\n{\n\tstdin_state_t * state = (stdin_state_t *)driver_state;\n\tif (!state->mutator || state->mutate_last_size <= 0)\n\t\treturn NULL;\n\t*length = state->mutate_last_size;\n\treturn memdup(state->mutate_buffer, state->mutate_last_size);\n}\n\n/**\n * This function returns help text for this driver.  This help text will describe the driver and any options\n * that can be passed to stdin_create.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nint stdin_help(char ** help_str)\n{\n\t*help_str = strdup(\n\"stdin - Sends mutated input to the STDIN of the target process\\n\"\n\"Required Options:\\n\"\n\"  path                  The path to the target process\\n\"\n\"Optional Options:\\n\"\n\"  arguments             Arguments to pass to the target process\\n\"\n\"  ratio                 The ratio of mutation buffer size to input size when\\n\"\"                          given a mutator\\n\"\n\"  timeout               The maximum number of seconds to wait for the target\\n\"\n\"                          process to finish\\n\"\n\"\\n\"\n\t);\n\tif (*help_str == NULL)\n\t\treturn -1;\n\treturn 0;\n}\n\n"
  },
  {
    "path": "driver/stdin_driver.h",
    "content": "#pragma once\n#include \"instrumentation.h\"\n#include <global_types.h>\n#include <sys/types.h>        // for pid_t\n\n\nvoid * stdin_create(char * options, instrumentation_t * instrumentation, void * instrumentation_state,\n\tmutator_t * mutator, void * mutator_state);\nvoid stdin_cleanup(void * driver_state);\nint stdin_test_input(void * driver_state, char * buffer, size_t length);\nint stdin_test_next_input(void * driver_state);\nchar * stdin_get_last_input(void * driver_state, int * length);\nint stdin_help(char ** help_str);\n\nstruct stdin_state\n{\n\t//Options\n\tchar * path;         //The path to the fuzzed executable\n\tchar * arguments;    //Arguments to give the binary\n\tint timeout;         //Maximum number of seconds to allow the executable to run\n\tdouble input_ratio;  //the ratio of the maximum input size\n\n\t//The handle to the fuzzed process instance\n\t#ifdef _WIN32\n\tHANDLE process;\n\t#else\n\tpid_t process;\n\t#endif\n\n\t//command line of the fuzzed process\n\tchar * cmd_line;\n\n\t//The instrumentation module\n\tinstrumentation_t * instrumentation;\n\n\t//The instrumentation's state\n\tvoid * instrumentation_state;\n\n\tmutator_t * mutator;\n\tvoid * mutator_state;\n\tchar * mutate_buffer;\n\tsize_t mutate_buffer_length;\n\tint mutate_last_size;\n};\ntypedef struct stdin_state stdin_state_t;\n"
  },
  {
    "path": "driver/wmp_driver.cpp",
    "content": "#include \"wmp_driver.h\"\n\n#include <jansson_helper.h>\n#include <utils.h>\n#include <instrumentation.h>\n#include \"driver.h\"\n#include <wingui.h>\n\n//c headers\n#include <stdio.h>\n#include <stdlib.h>\n#include <time.h>\n\n//Windows API\n#include <process.h>\n#include <Mmdeviceapi.h>\n#include <mmdeviceapi.h>\n#include <endpointvolume.h>\n\nstatic int is_playing_sound();\n\n/**\n * This function creates a wmp_state_t object based on the given options.\n * @param options - A JSON string of the options to set in the new wmp_state_t. See the\n * help function for more information on the specific options available.\n * @return - the wmp_state_t generated from the options in the JSON options string, or NULL on failure\n */\nstatic wmp_state_t * setup_options(char * options)\n{\n\twmp_state_t * state;\n\tsize_t cmd_length;\n\n\tstate = (wmp_state_t *)malloc(sizeof(wmp_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(wmp_state_t));\n\n\n\t//Setup defaults\n\tstate->extension = strdup(\".aac\"); //strdup'd so we can uniformly free it later\n\tstate->path = strdup(\"C:\\\\Program Files (x86)\\\\Windows Media Player\\\\wmplayer.exe\"); //strdup'd so we can uniformly free it later\n\tstate->timeout = 2;\n\tstate->input_ratio = 2.0;\n\n\tif (options && strlen(options))\n\t{\n\t\tPARSE_OPTION_STRING(state, options, path, \"path\", wmp_cleanup);\n\t\tPARSE_OPTION_STRING(state, options, extension, \"extension\", wmp_cleanup);\n\t\tPARSE_OPTION_INT(state, options, timeout, \"timeout\", wmp_cleanup);\n\t\tPARSE_OPTION_DOUBLE(state, options, input_ratio, \"ratio\", wmp_cleanup);\n\t}\n\n\t//Create a test filename to write the fuzz file to\n\tstate->test_filename = get_temp_filename(state->extension);\n\n\tcmd_length = strlen(state->path) + strlen(state->test_filename) + 10;\n\tstate->cmd_line = (char *)malloc(cmd_length);\n\tif (!state->cmd_line) {\n\t\twmp_cleanup(state);\n\t\treturn NULL;\n\t}\n\tsnprintf(state->cmd_line, cmd_length, \"\\\"%s\\\" /play %s\", state->path, state->test_filename);\n\n\treturn state;\n}\n\n/**\n * This function allocates and initializes a new driver specific state object based on the given options.\n * @param options - a JSON string that contains the driver specific string of options\n * @param instrumentation - a pointer to an instrumentation instance that the driver will use\n * to instrument the requested program.  This instrumentation instance should already be initialized.\n * @param instrumentation_state - a pointer to the instrumentation state for the passed in instrumentation\n * @return - A driver specific state object on success or NULL on failure\n */\nvoid * wmp_create(char * options, instrumentation_t * instrumentation, void * instrumentation_state,\n\tmutator_t * mutator, void * mutator_state)\n{\n\twmp_state_t * state;\n\tint num_inputs;\n\tsize_t *input_sizes;\n\n\tstate = setup_options(options);\n\tif (!state)\n\t\treturn NULL;\n\n\t//We need to call this before we make WINAPI calls to get the audio device below\n\tCoInitialize(NULL);\n\n\tif (mutator)\n\t{\n\t\tmutator->get_input_info(mutator_state, &num_inputs, &input_sizes);\n\t\tif (num_inputs != 1\n\t\t\t|| setup_mutate_buffer(state->input_ratio, input_sizes[0], &state->mutate_buffer, &state->mutate_buffer_length))\n\t\t{\n\t\t\tfree(input_sizes);\n\t\t\twmp_cleanup(state);\n\t\t\treturn NULL;\n\t\t}\n\t\tfree(input_sizes);\n\t}\n\n\tstate->mutator = mutator;\n\tstate->mutator_state = mutator_state;\n\tstate->mutate_last_size = -1;\n\tstate->instrumentation = instrumentation;\n\tstate->instrumentation_state = instrumentation_state;\n\treturn state;\n}\n\n/**\n * This function cleans up all resources with the passed in driver state.\n * @param driver_state - a driver specific state object previously created by the wmp_create function\n * This state object should not be referenced after this function returns.\n */\nvoid wmp_cleanup(void * driver_state)\n{\n\twmp_state_t * state = (wmp_state_t *)driver_state;\n\n\tfree(state->mutate_buffer);\n\n\tfree(state->path);\n\tfree(state->extension);\n\tfree(state->cmd_line);\n\tif (state->test_filename)\n\t{\n\t\tunlink(state->test_filename);\n\t\tfree(state->test_filename);\n\t}\n\tfree(state);\n}\n\n/**\n * This function will run wmplayer.exe and test it with the given input. This function\n * blocks until the wmplayer.exe has finished processing the input.\n * @param driver_state - a driver specific structure previously created by the wmp_create function\n * @param input - the input that should be tested\n * @param length - the length of the input parameter\n * @return - FUZZ_ result on success or FUZZ_ERROR on failure\n */\nint wmp_test_input(void * driver_state, char * input, size_t length)\n{\n\twmp_state_t * state = (wmp_state_t *)driver_state;\n\n\t//Write the input to disk\n\twrite_buffer_to_file(state->test_filename, input, length);\n\n\t//Start the process and give it our input\n\tif(state->instrumentation->enable(state->instrumentation_state, &state->process, state->cmd_line, NULL, 0))\n\t\treturn FUZZ_ERROR;\n\n\ttime_t start_time = time(NULL);\n\tint tmp_result = FUZZ_ERROR;\n\n\t// This is reimplementing the loop in generic_wait_for_process\n\t// completion, because we want to do an additional check:\n\t// `is_playing_sound`, which can end early.\n\t//\n\t// We assume that if WMP is playing sound, it has successfully\n\t// processed input, which means that we won't get a crash.\n\twhile (1)\n\t{\n\t\ttmp_result = state->instrumentation->is_process_done(state->instrumentation_state);\n\n\t\tif (tmp_result == 1) // process is done, it crashed or exited cleanly\n\t\t{\n\t\t\t// so fetch the result from the instrumentation\n\t\t\treturn state->instrumentation->get_fuzz_result(state->instrumentation_state);\n\t\t}\n\t\telse if (tmp_result == -1)\n\t\t{\n\t\t\treturn FUZZ_ERROR;\n\t\t} // else it's still running, so do our other checks\n\n\t\t// WMP is playing sound, so we don't expect a crash and can end\n\t\t// this fuzz round.\n\t\tif (is_playing_sound())\n\t\t\treturn FUZZ_NONE;\n\t\t\n\t\tif (time(NULL) - start_time > state->timeout)\n\t\t\treturn FUZZ_HANG;\n\t\t\n\t\t// If we're stuck in a modal dialog we're \"hung\". Works for debug, but not dynamorio\n\t\tif (IsProcessInModalDialog(GetProcessId(state->process)))\n\t\t\treturn FUZZ_HANG;\n\t\t\n\t\tSleep(50);\n\t}\n\n\t// We should never get here, because we should take one of the return\n\t// statements in the above loop.\n\treturn FUZZ_ERROR;\n}\n\n/**\n * This function will run the fuzzed program with the output of the mutator given during driver\n * creation.  This function blocks until the program has finished processing the input.\n * @param driver_state - a driver specific structure previously created by the wmp_create function\n * @return - FUZZ_ result on success, FUZZ_ERROR on error, -2 if the mutator has finished generating inputs\n */\nint wmp_test_next_input(void * driver_state)\n{\n\twmp_state_t * state = (wmp_state_t *)driver_state;\n\treturn generic_test_next_input(state, state->mutator, state->mutator_state, state->mutate_buffer,\n\t\tstate->mutate_buffer_length, wmp_test_input, &state->mutate_last_size);\n}\n\n/**\n * When this driver is using a mutator given to it during driver creation, this function retrieves\n * the last input that was tested with the wmp_test_next_input function.\n * @param driver_state - a driver specific structure previously created by the wmp_create function\n * @param length - a pointer to an integer used to return the length of the input that was last tested.\n * @return - NULL on error or if the driver doesn't have a mutator, or a buffer containing the last input\n * that was tested by the driver with the wmp_test_next_input function.  This buffer should be freed\n * by the caller.\n */\nchar * wmp_get_last_input(void * driver_state, int * length)\n{\n\twmp_state_t * state = (wmp_state_t *)driver_state;\n\tif (!state->mutator || state->mutate_last_size <= 0)\n\t\treturn NULL;\n\t*length = state->mutate_last_size;\n\treturn (char *)memdup(state->mutate_buffer, state->mutate_last_size);\n}\n\n#define EXIT_ON_ERROR(hres)  \\\n              if (FAILED(hres)) { goto done; }\n#define SAFE_RELEASE(punk)  \\\n              if ((punk) != NULL)  \\\n                { (punk)->Release(); (punk) = NULL; }\n\n/**\n * This function determines if any sound is currently being played out the speakers.  This is used to\n * determine if the wmplayer.exe process has finished parsing the fuzzed file and now trying to play it.\n * @return - 1 if sound is being played, 0 if sound is not being played, and -1 if an error occurs.\n */\nstatic int is_playing_sound()\n{\n\tHRESULT hr = S_OK;\n\tIMMDeviceEnumerator *pEnumerator = NULL;\n\tIMMDevice *pDevice = NULL;\n\tIAudioMeterInformation *pMeterInfo = NULL;\n\tHWND hPeakMeter = NULL;\n\tfloat peak = 0;\n\tint ret = -1;\n\n\thr = CoCreateInstance(\n\t\t__uuidof(MMDeviceEnumerator), NULL,\n\t\tCLSCTX_ALL, __uuidof(IMMDeviceEnumerator),\n\t\t(void**)&pEnumerator);\n\tEXIT_ON_ERROR(hr);\n\n\thr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);\n\tEXIT_ON_ERROR(hr);\n\n\thr = pDevice->Activate(__uuidof(IAudioMeterInformation), CLSCTX_ALL, NULL, (void**)&pMeterInfo);\n\tEXIT_ON_ERROR(hr);\n\n\thr = pMeterInfo->GetPeakValue(&peak);\n\tEXIT_ON_ERROR(hr);\n\tret = peak > 0;\n\ndone:\n\tSAFE_RELEASE(pEnumerator);\n\tSAFE_RELEASE(pDevice);\n\tSAFE_RELEASE(pMeterInfo)\n\treturn ret;\n}\n\n/**\n * This function returns help text for this driver.  This help text will describe the driver and any options\n * that can be passed to wmp_create.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nint wmp_help(char ** help_str)\n{\n\t*help_str = strdup(\n\"wmp - Windows Media Player driver (Fuzzes wmplayer.exe)\\n\"\n\"Optional Arguments:\\n\"\n\"  extension             The file extension of the input files to\\n\"\n\"                          wmplayer.exe\\n\"\n\"  path                  The path to the wmplayer.exe\\n\"\n\"  ratio                 The ratio of mutation buffer size to input size\\n\"\n\"                          when given a mutator\\n\"\n\"  timeout               The maximum number of seconds to wait for the\\n\"\n\"                          target process to finish\\n\"\n\"\\n\"\n\t);\n\tif (*help_str == NULL)\n\t\treturn -1;\n\treturn 0;\n}\n\n"
  },
  {
    "path": "driver/wmp_driver.h",
    "content": "#pragma once\n#include \"driver.h\"\n\n#include <instrumentation.h>\n\n#ifdef __cplusplus\n#define FUNC_PREFIX extern \"C\"\n#else\n#define FUNC_PREFIX\n#endif\n\nFUNC_PREFIX void * wmp_create(char * options, instrumentation_t * instrumentation, void * instrumentation_state,\n\tmutator_t * mutator, void * mutator_state);\nFUNC_PREFIX void wmp_cleanup(void * driver_state);\nFUNC_PREFIX int wmp_test_input(void * driver_state, char * buffer, size_t length);\nFUNC_PREFIX int wmp_test_next_input(void * driver_state);\nFUNC_PREFIX char * wmp_get_last_input(void * driver_state, int * length);\nFUNC_PREFIX int wmp_help(char ** help_str);\n\nstruct wmp_state\n{\n\t//Options\n\tchar * path;          //The path to wmplayer.exe\n\tchar * extension;     //The file extension of the input files to wmplayer.exe\n\tint timeout;          //Maximum number of seconds to allow wmplayer.exe to run\n\tchar * test_filename; //The filename that we're going to write our test input to\n\tdouble input_ratio;   //the ratio of the maximum input size\n\n\t//The handle to the wmplayer.exe instance\n\tHANDLE process;\n\n\t//command line of the fuzzed process\n\tchar * cmd_line;\n\n\t//The instrumentation module\n\tinstrumentation_t * instrumentation;\n\n\t//The instrumentation's state\n\tvoid * instrumentation_state;\n\n\tmutator_t * mutator;\n\tvoid * mutator_state;\n\tchar * mutate_buffer;\n\tsize_t mutate_buffer_length;\n\tint mutate_last_size;\n};\ntypedef struct wmp_state wmp_state_t;\n"
  },
  {
    "path": "fuzzer/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (fuzzer)\n\ninclude_directories (${CMAKE_SOURCE_DIR}/driver/)\ninclude_directories (${CMAKE_SOURCE_DIR}/instrumentation/)\ninclude_directories (${CMAKE_SOURCE_DIR}/mutator/)\ninclude_directories (${CMAKE_SOURCE_DIR}/utils/)\n\nadd_library(utils ${CMAKE_SOURCE_DIR}/utils/utils.c ${CMAKE_SOURCE_DIR}/utils/mutator_factory.c)\n# Utils requires -ldl (on UNIX) and -lpthread\nif (UNIX)\n  target_link_libraries(utils dl)\nendif (UNIX)\nif (WIN32)\n  add_library(xgetopt ${CMAKE_SOURCE_DIR}/utils/XGetopt.c)\nendif (WIN32)\n\nfind_package(Threads REQUIRED)\nif(THREADS_HAVE_PTHREAD_ARG)\n  set_property(TARGET utils PROPERTY COMPILE_OPTIONS \"-pthread\")\n  set_property(TARGET utils PROPERTY INTERFACE_COMPILE_OPTIONS \"-pthread\")\nendif()\nif(CMAKE_THREAD_LIBS_INIT)\n  target_link_libraries(utils \"${CMAKE_THREAD_LIBS_INIT}\")\nendif()\n\nset(FUZZER_SRC ${PROJECT_SOURCE_DIR}/main.c)\nsource_group(\"Executable Sources\" FILES ${FUZZER_SRC})\n\nadd_executable(fuzzer ${FUZZER_SRC} $<TARGET_OBJECTS:driver>\n\t$<TARGET_OBJECTS:instrumentation>)\n\ntarget_compile_definitions(fuzzer PUBLIC DRIVER_NO_IMPORT)\ntarget_compile_definitions(fuzzer PUBLIC INSTRUMENTATION_NO_IMPORT)\ntarget_compile_definitions(fuzzer PUBLIC MUTATOR_NO_IMPORT)\n\nif (UNIX)\n  target_link_libraries(fuzzer dl)\nendif (UNIX)\ntarget_link_libraries(fuzzer utils)\ntarget_link_libraries(fuzzer jansson)\nif (WIN32)\n  target_link_libraries(fuzzer Shlwapi)  # utils needs Shlwapi\n  target_link_libraries(fuzzer ws2_32)   # network driver needs ws2_32\n  target_link_libraries(fuzzer iphlpapi) # network driver needs iphlpapi\n  target_link_libraries(fuzzer xgetopt) # CLI parsing\nendif (WIN32)\n"
  },
  {
    "path": "fuzzer/main.c",
    "content": "#include <global_types.h>\n#include <driver.h>\n#include <driver_factory.h>\n#include <mutator_factory.h>\n#include <instrumentation.h>\n#include <instrumentation_factory.h>\n#include <utils.h>\n\n#ifdef _WIN32\n#include <io.h>\n#include <Shlwapi.h>\n#define F_OK 00     // for checking if a file is open/writable\n#define W_OK 02\n#include \"XGetopt.h\"\n#else\n#include <libgen.h>     // dirname\n#include <unistd.h>     // access, F_OK, W_OK, getopt\n#include <sys/stat.h>   // mkdir\n#include <errno.h>      // output directory creation\n#endif\n\n#include <signal.h>\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <time.h>\n\n/**\n * This function prints out the usage information for the fuzzer and each of the individual components\n * @param program_name - the name of the program currently being run (for use in the outputted message)\n * @param mutator_directory - the directory to look for mutators in, when printing out the mutator help information\n */\nvoid usage(char * program_name, char * mutator_directory)\n{\n\tprintf(\n\"\\n\"\n\"Usage: %s\\n\"\n\"         [options] driver_name instrumentation_name mutator_name\\n\"\n\"\\n\"\n\"Options:\\n\"\n\"  -d driver_options              JSON filename with options for the driver\\n\"\n\"  -hd                            Get help text about drivers\\n\"\n\"  -hi                            Get help text about instrumentation\\n\"\n\"  -hl                            Get help text about logging\\n\"\n\"  -hm                            Get help text about mutators\\n\"\n\"  -i instrumentation_options     JSON filename with options for the instrumentation\\n\"\n\"  -j instrumentation_state_file  Set the file that the instrumentation state should dump to\\n\"\n\"  -k instrumentation_state_file  Set the file that the instrumentation state should load from\\n\"\n\"  -l logging_options             JSON filename with options for logging\\n\"\n\"  -m mutator_options             JSON filename with options for the mutator\\n\"\n\"  -n num_iterations              Limit the number of iterations to run\\n\"\n\"                                   (optional, infinite by default)\\n\"\n\"  -o output_directory            The directory to write files which cause a\\n\"\n\"                                   crash or hang\\n\"\n\"  -p mutator_directory           The directory to look for mutator DLLs in\\n\"\n\"                                   (must be specified to view help for\\n\"\n\"                                   specific mutators)\\n\"\n\"  -r mutator_state               Set the state that the mutator should load\\n\"\n\"  -s seed                        The seed file to use\\n\"\n\"  -t mutator_state_file          Set the file that the mutator state should dump to\\n\"\n\"  -u mutator_state_file          Set the file that the mutator state should load from\\n\"\n\"\\n\\n\",\n\t\tprogram_name\n\t);\n\n\texit(1);\n}\n\n//The global module state objects\nstatic driver_t * driver = NULL;\nstatic mutator_t * mutator = NULL;\nstatic void * mutator_state = NULL;\nstatic instrumentation_t * instrumentation = NULL;\nstatic void * instrumentation_state = NULL;\n\nstatic void cleanup_modules(void)\n{\n\tif(driver)\n\t\tdriver->cleanup(driver->state);\n\tif(instrumentation && instrumentation_state)\n\t\tinstrumentation->cleanup(instrumentation_state);\n\tif(mutator && mutator_state)\n\t\tmutator->cleanup(mutator_state);\n\tfree(driver);\n\tfree(instrumentation);\n\tfree(mutator);\n}\n\nstatic void sigint_handler(int sig)\n{\n\tCRITICAL_MSG(\"CTRL-c detected, exiting\\n\");\n\tcleanup_modules();\n\texit(0);\n}\n\n#define NUM_ITERATIONS_INFINITE -1\n\n#define PRINT_HELP(x) \\\n\t\tputs(x);      \\\n\t\tfree(x);\n\nint main(int argc, char ** argv)\n{\n\tchar *driver_name, *driver_options = NULL,\n\t\t*mutator_name, *mutator_options = NULL, *mutator_saved_state = NULL,\n\t\t*mutation_state_dump_file = NULL, *mutation_state_load_file = NULL,\n\t\t*mutate_buffer = NULL, *mutator_directory = NULL, *mutator_directory_cli = NULL,\n\t\t*logging_options = NULL,\n\t\t*seed_file = NULL, *seed_buffer = NULL,\n\t\t*instrumentation_name = NULL, *instrumentation_options = NULL, \n\t\t*instrumentation_state_string = NULL, *instrumentation_state_load_file = NULL,\n\t\t*instrumentation_state_dump_file = NULL;\n\tint seed_length = 0, mutate_length = 0, instrumentation_length = 0, mutator_state_length;\n\ttime_t fuzz_begin_time;\n\tint i = 0, iteration = 0, fuzz_result = FUZZ_NONE, new_path = 0;\n\tchar filename[MAX_PATH];\n\tchar filehash[256];\n\tchar c;\n\tchar * directory;\n\n\t//Default options\n\tint num_iterations = NUM_ITERATIONS_INFINITE; //default to infinite\n\tchar * output_directory = \"output\";\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Mutator Setup /////////////////////////////////////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\tif (!mutator_directory)\n\t{\n\t\tchar * mutator_repo_dir = getenv(\"KILLERBEEZ_MUTATORS\");\n\t\t//If the environment variable KILLERBEEZ_MUTATORS is set, try to autodetect the directory based on the repo build path\n\t\tif (mutator_repo_dir) \n\t\t{\n\t\t\tmutator_directory = (char *)malloc(MAX_PATH + 1);\n\t\t\tif (!mutator_directory)\n\t\t\t{\n\t\t\t\tprintf(\"Couldn't get memory for default mutator_directory\");\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tmemset(mutator_directory, 0, MAX_PATH + 1);\n#ifdef _WIN32\n\n#if defined(_M_X64) || defined(__x86_64__)\n#ifdef _DEBUG\n\t\t\tsnprintf(mutator_directory, MAX_PATH, \"%s\\\\..\\\\build\\\\x64\\\\Debug\\\\mutators\\\\\", mutator_repo_dir);\n#else\n\t\t\tsnprintf(mutator_directory, MAX_PATH, \"%s\\\\..\\\\build\\\\x64\\\\Release\\\\mutators\\\\\", mutator_repo_dir);\n#endif\n#else\n#ifdef _DEBUG\n\t\t\tsnprintf(mutator_directory, MAX_PATH, \"%s\\\\..\\\\build\\\\X86\\\\Debug\\\\mutators\\\\\", mutator_repo_dir);\n#else\n\t\t\tsnprintf(mutator_directory, MAX_PATH, \"%s\\\\..\\\\build\\\\X86\\\\Release\\\\mutators\\\\\", mutator_repo_dir);\n#endif\n#endif\n\n#else\n\t\t\tsnprintf(mutator_directory, MAX_PATH, \"%s/../build/mutators/\", mutator_repo_dir);\n#endif\n\t\t}\n\t\telse\n\t\t{\n#ifdef _WIN32\n\t\t\tmutator_directory = filename_relative_to_binary_dir(\"..\\\\mutators\\\\\");\n#else // LINUX and APPLE\n\t\t\tmutator_directory = filename_relative_to_binary_dir(\"../mutators\");\n#endif\n\t\t}\n\t}\n\t\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Parse Arguments ///////////////////////////////////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\twhile ((c = getopt(argc, argv, \"d:h:i:j:k:l:m:n:o:p:r:s:t:u:\")) != -1)\n\t{\n\t\tswitch (c)\n\t\t{\n\t\t\tcase 'd':\n\t\t\t\tread_file(optarg, &driver_options);\n\t\t\t\tbreak;\n\t\t\tcase 'h':\n\t\t\t\tif (optarg == NULL) {\n\t\t\t\t\tusage(argv[0], mutator_directory);\n\t\t\t\t} else if (strcmp(optarg, \"l\") == 0) {\n\t\t\t\t\tPRINT_HELP(logging_help());\n\t\t\t\t} else if (strcmp(optarg, \"d\") == 0) {\n\t\t\t\t\tPRINT_HELP(driver_help());\n\t\t\t\t} else if (strcmp(optarg, \"i\") == 0) {\n\t\t\t\t\tPRINT_HELP(instrumentation_help());\n\t\t\t\t} else if (strcmp(optarg, \"m\") == 0) {\n\t\t\t\t\tPRINT_HELP(mutator_help(mutator_directory));\n\t\t\t\t}\n\t\t\t\texit(1);\n\t\t\tcase 'i':\n\t\t\t\tread_file(optarg, &instrumentation_options);\n\t\t\t\tbreak;\n\t\t\tcase 'j':\n\t\t\t\tinstrumentation_state_dump_file = optarg;\n\t\t\t\tbreak;\n\t\t\tcase 'k':\n\t\t\t\tinstrumentation_state_load_file = optarg;\n\t\t\t\tbreak;\n\t\t\tcase 'l':\n\t\t\t\tread_file(optarg, &logging_options);\n\t\t\t\tbreak;\n\t\t\tcase 'm':\n\t\t\t\tread_file(optarg, &mutator_options);\n\t\t\t\tbreak;\n\t\t\tcase 'n':\n\t\t\t\tnum_iterations = atoi(optarg);\n\t\t\t\tbreak;\n\t\t\tcase 'o':\n\t\t\t\toutput_directory = optarg;\n\t\t\t\tbreak;\n\t\t\tcase 'p':\n\t\t\t\tmutator_directory_cli = optarg;\n\t\t\t\tbreak;\n\t\t\tcase 'r':\n\t\t\t\tmutator_saved_state = optarg;\n\t\t\t\tbreak;\n\t\t\tcase 's':\n\t\t\t\tseed_file = optarg;\n\t\t\t\tbreak;\n\t\t\tcase 't':\n\t\t\t\tmutation_state_dump_file = optarg;\n\t\t\t\tbreak;\n\t\t\tcase 'u':\n\t\t\t\tmutation_state_load_file = optarg;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Make sure we have enough positional arguments\n\tif (argc-optind < 3)\n\t{\n\t\tusage(argv[0], mutator_directory);\n\t}\n\tdriver_name = argv[optind];\n\tinstrumentation_name = argv[optind+1];\n\tmutator_name = argv[optind+2];\n\n\tif (setup_logging(logging_options))\n\t{\n\t\tprintf(\"Failed setting up logging, exiting\\n\");\n\t\treturn 1;\n\t}\n\n\tsignal(SIGINT, sigint_handler);\n\n\t//Check number of iterations for valid number of rounds\n\tif (num_iterations != NUM_ITERATIONS_INFINITE && num_iterations <= 0)\n\t\tFATAL_MSG(\"Invalid number of iterations %d\", num_iterations);\n\n\tif (mutator_directory_cli) \n\t{ \n\t\tfree(mutator_directory);\n\t\tmutator_directory = strdup(mutator_directory_cli); \n\t\tmutator_directory_cli = NULL;\n\t}\n\tif (!mutator_directory)\n\t\tFATAL_MSG(\"Mutator directory was not found in default location. You may need to pass the -md flag.\");\n\n\tif (instrumentation_state_dump_file) {\n\t\tstrncpy(filename, instrumentation_state_dump_file, sizeof(filename));\n\n\t\t#ifdef _WIN32\n\t\tPathRemoveFileSpec(filename);\n\t\t#else\n\t\tdirname(filename);\n\t\t#endif\n\n\t\tif (access(filename, W_OK))\n\t\t\tFATAL_MSG(\"The provided instrumentation_state_dump_file filename (%s) is not writeable\", instrumentation_state_dump_file);\n\t}\n\tif (mutation_state_dump_file) {\n\t\tstrncpy(filename, mutation_state_dump_file, sizeof(filename));\n\n\t\t#ifdef _WIN32\n\t\tPathRemoveFileSpec(filename);\n\t\t#else\n\t\tdirname(filename);\n\t\t#endif\n\n\t\tif (access(filename, W_OK))\n\t\t\tFATAL_MSG(\"The provided mutation_state_dump_file filename (%s) is not writeable\", mutation_state_dump_file);\n\t}\n\n#ifdef _WIN32\n\t#define create_output_directory(name)                                                \\\n\t\tsnprintf(filename, sizeof(filename), \"%s\" name, output_directory);               \\\n\t\tif(!CreateDirectory(filename, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) { \\\n\t\t\tFATAL_MSG(\"Unable to create directory %s\", filename);                        \\\n\t\t}\n#else\n\t#define create_output_directory(name)                                                \\\n\t\tsnprintf(filename, sizeof(filename), \"%s\" name, output_directory);               \\\n\t\tif (mkdir(filename, 0775) == -1) {                                               \\\n\t\t\tif (errno != EEXIST)                                                         \\\n\t\t\t\tFATAL_MSG(\"Unable to create directory %s\", filename);                    \\\n\t\t} // otherwise, it already exists and we don't need to do anything\n#endif\n\n\t//Setup the output directory\n\tcreate_output_directory(\"\");\t\t\t// creates ./output\n\tcreate_output_directory(\"/crashes\");\t// creates ./output/crashes and so on\n\tcreate_output_directory(\"/hangs\");\n\tcreate_output_directory(\"/new_paths\");\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Ojbect Setup //////////////////////////////////////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\t//Load the instrumentation state from disk (if specified, and create the instrumentation\n\tif (instrumentation_state_load_file)\n\t{\n\t\tinstrumentation_length = read_file(instrumentation_state_load_file, &instrumentation_state_string);\n\t\tif (instrumentation_length <= 0)\n\t\t\tFATAL_MSG(\"Could not read instrumentation file or empty instrumentation file: %s\", instrumentation_state_load_file);\n\t}\n\n\t// NULL means instrumentation failed to initialize.\n\tinstrumentation = instrumentation_factory(instrumentation_name);\n\tif (!instrumentation)\n\t{\n\t\tfree(instrumentation_state_string);\n\t\tFATAL_MSG(\"Unknown instrumentation '%s'\", instrumentation_name);\n\t}\n\n\tinstrumentation_state = instrumentation->create(instrumentation_options, instrumentation_state_string);\n\tif (!instrumentation_state)\n\t{\n\t\tfree(instrumentation_state_string);\n\t\tFATAL_MSG(\"Bad options/state for instrumentation %s\", instrumentation_name);\n\t}\n\n\tfree(instrumentation_state_string);\n\n\t//Load the seed buffer from a file\n\tif (seed_file)\n\t{\n\t\tseed_length = read_file(seed_file, &seed_buffer);\n\t\tif (seed_length <= 0)\n\t\t\tFATAL_MSG(\"Could not read seed file or empty seed file: %s\", seed_file);\n\t}\n\n\tif (!seed_buffer)\n\t\tFATAL_MSG(\"No seed file or seed id specified.\");\n\n\tif (mutation_state_load_file)\n\t{\n\t\tfree(mutator_saved_state);\n\t\tmutator_state_length = read_file(mutation_state_load_file, &mutator_saved_state);\n\t\tif (mutator_state_length <= 0)\n\t\t\tFATAL_MSG(\"Could not read mutator saved state from file: %s\", mutation_state_load_file);\n\t}\n\n\t//Create the mutator\n\tmutator = mutator_factory_directory(mutator_directory, mutator_name);\n\tif (!mutator)\n\t\tFATAL_MSG(\"Unknown mutator (%s)\", mutator_name);\n\tfree(mutator_directory);\n\tmutator_state = mutator->create(mutator_options, mutator_saved_state, seed_buffer, seed_length);\n\tif (!mutator_state)\n\t\tFATAL_MSG(\"Bad mutator options or saved state for mutator %s\", mutator_name);\n\tfree(mutator_saved_state);\n\tfree(seed_buffer);\n\n\t//Create the driver\n\tdriver = driver_all_factory(driver_name, driver_options, instrumentation, instrumentation_state, mutator, mutator_state);\n\tif (!driver)\n\t{\n\t\tFATAL_MSG(\"Unknown driver '%s' or bad options: \\n\\n\\tdriver options: %s\\n\\n\"\\\n\t\t\t\"\\tmutator options: %s\\n\\n\\tPass %s -hd for help.\\n\", driver_name,\n\t\t\tdriver_options, mutator_options, argv[0]);\n\t}\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Main Fuzz Loop ////////////////////////////////////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\tfuzz_begin_time = time(NULL);\n\n\t//Copy the input, mutate it, and run the fuzzed program\n\tfor (iteration = 0; num_iterations == NUM_ITERATIONS_INFINITE || iteration < num_iterations; iteration++)\n\t{\n\t\tDEBUG_MSG(\"Fuzzing the %d iteration\", iteration);\n\n\t\tfuzz_result = driver->test_next_input(driver->state);\n\n\t\tif (fuzz_result < 0)\n\t\t{\n\t\t\tif(fuzz_result == -2)\n\t\t\t\tWARNING_MSG(\"The mutator has run out of mutations to test after %d iterations\", iteration);\n\t\t\telse\n\t\t\t\tERROR_MSG(\"The driver failed to test the target program, fuzz_result was %d\",fuzz_result);\n\t\t\tbreak;\n\t\t}\n\n\t\tnew_path = instrumentation->is_new_path(instrumentation_state);\n\t\tif (new_path < 0)\n\t\t{\n\t\t\tERROR_MSG(\"The instrumentation failed to determine the fuzzed process's fuzz_result\");\n\t\t\tbreak;\n\t\t}\n\n\t\tdirectory = NULL;\n\t\tif (fuzz_result == FUZZ_CRASH) {\n\t\t\tdirectory = \"crashes\";\n\t\t\tCRITICAL_MSG(\"Found %s\", directory);\n\t\t} else if (fuzz_result == FUZZ_HANG) {\n\t\t\tdirectory = \"hangs\";\n\t\t\tERROR_MSG(\"Found %s\", directory);\n\t\t} else if (new_path > 0) {\n\t\t\tdirectory = \"new_paths\";\n\t\t\tINFO_MSG(\"Found %s\", directory);\n\t\t}\n\n\t\tif (directory != NULL) {\n\t\t\tmutate_buffer = driver->get_last_input(driver->state, &mutate_length);\n\t\t\tif (!mutate_buffer) {\n\t\t\t\tERROR_MSG(\"Unable to dump mutate buffer\\n\");\n\t\t\t} else {\n\t\t\t\tif (output_directory) {\n\t\t\t\t\tmd5((uint8_t *)mutate_buffer, mutate_length, filehash, sizeof(filehash));\n\t\t\t\t\tsnprintf(filename, MAX_PATH, \"%s/%s/%s\", output_directory, directory, filehash);\n\t\t\t\t\tif (!file_exists(filename)) //If the file already exists, there's no reason to write it again\n\t\t\t\t\t\twrite_buffer_to_file(filename, mutate_buffer, mutate_length);\n\t\t\t\t}\n\t\t\t\tfree(mutate_buffer);\n\t\t\t}\n\t\t}\n\t}\n\n\tINFO_MSG(\"Ran %ld iterations in %lld seconds\", iteration, time(NULL) - fuzz_begin_time);\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Cleanup ///////////////////////////////////////////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\tif (instrumentation_state_dump_file)\n\t{\n\t\tinstrumentation_state_string = instrumentation->get_state(instrumentation_state);\n\t\tif (instrumentation_state_string)\n\t\t{\n\t\t\twrite_buffer_to_file(instrumentation_state_dump_file, instrumentation_state_string, strlen(instrumentation_state_string));\n\t\t\tinstrumentation->free_state(instrumentation_state_string);\n\t\t}\n\t\telse\n\t\t\tWARNING_MSG(\"Couldn't dump instrumentation state to file %s\", instrumentation_state_dump_file);\n\t}\n\tif (mutation_state_dump_file)\n\t{\n\t\tmutator_saved_state = mutator->get_state(mutator_state);\n\t\tif (mutator_saved_state)\n\t\t{\n\t\t\twrite_buffer_to_file(mutation_state_dump_file, mutator_saved_state, strlen(mutator_saved_state));\n\t\t\tmutator->free_state(mutator_saved_state);\n\t\t}\n\t\telse\n\t\t\tWARNING_MSG(\"Couldn't dump mutator state to file %s\", mutation_state_dump_file);\n\t}\n\n\t//Cleanup everything and exit\n\tcleanup_modules();\n\treturn 0;\n}\n"
  },
  {
    "path": "instrumentation/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (instrumentation)\n\nset(INSTRUMENTATION_SRC\n\t${PROJECT_SOURCE_DIR}/instrumentation.c\n\t${PROJECT_SOURCE_DIR}/instrumentation_factory.c\n)\n\nif (WIN32)\n\tset(INSTRUMENTATION_SRC\n\t\t${INSTRUMENTATION_SRC}\n\t\t${PROJECT_SOURCE_DIR}/debug_instrumentation.c\n\t\t${PROJECT_SOURCE_DIR}/dynamorio_instrumentation.c\n\t\t${PROJECT_SOURCE_DIR}/wingui.c\n\t)\nelse ()\n\tset(INSTRUMENTATION_SRC\n\t\t${INSTRUMENTATION_SRC}\n\t\t${PROJECT_SOURCE_DIR}/return_code_instrumentation.c\n\t\t${PROJECT_SOURCE_DIR}/afl_instrumentation.c\n\t)\n\n\tif (NOT APPLE)\n\t\tset(INSTRUMENTATION_SRC\n\t\t\t${INSTRUMENTATION_SRC}\n\t\t\t${PROJECT_SOURCE_DIR}/linux_ipt_instrumentation.c\n\t\t)\n\n\t\tset(FORKSERVER_SRC\n\t\t\t${PROJECT_SOURCE_DIR}/forkserver.c\n\t\t\t${PROJECT_SOURCE_DIR}/forkserver_hooking.c\n\t\t)\n\n\t\tadd_library(forkserver SHARED ${FORKSERVER_SRC})\n\t\ttarget_link_libraries(forkserver dl)\n\tendif ()\nendif ()\n\nsource_group(\"Library Sources\" FILES ${INSTRUMENTATION_SRC})\n\nadd_library(instrumentation OBJECT ${INSTRUMENTATION_SRC})\ntarget_compile_definitions(instrumentation PUBLIC INSTRUMENTATION_NO_IMPORT)\n"
  },
  {
    "path": "instrumentation/afl_instrumentation.c",
    "content": "#include <fcntl.h>\n#include <stddef.h>  // for NULL\n#include <sys/shm.h> // for shm functions\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <unistd.h>  // for lseek, write, ftruncate\n\n#include <utils.h>   // for FUZZ_* return values\n\n#include <jansson_helper.h>  // for PARSE_OPTION_*\n\n#include \"afl_instrumentation.h\"\n\n/**\n * This function allocates and initializes a new instrumentation specific state\n * object based on the given options.\n * @param options - a JSON string that contains the instrumentation specific\n *                  string of options\n * @param state - an instrumentation specific JSON string previously returned\n *                from afl_get_state that should be loaded\n * @return - An instrumentation specific state object on success or NULL on failure\n */\nvoid * afl_create(char *options, char *state) {\n\tafl_state_t *afl_state = setup_options(options);\n\tif(!afl_state)\n\t\treturn NULL;\n\n\tif(state && afl_set_state(afl_state, state)) {\n\t\tDEBUG_MSG(\"Unable to set state for afl instrumentation\");\n\t\treturn NULL;\n\t}\n\n\treturn afl_state;\n}\n\n/**\n * This function cleans up all resources with the passed in instrumentation state.\n * @param instrumentation_state - an instrumentation specific state object\n *                                previously created by the afl_create function\n *                                This state object should not be referenced after\n *                                this function returns.\n */\nvoid afl_cleanup(void *instrumentation_state) {\n\tafl_state_t * state = (afl_state_t *)instrumentation_state;\n\n\t//Cleanup the SHM region\n\tshmctl(state->shm_id, IPC_RMID, NULL);\n\n\t//Kill any remaining target processes\n\tdestroy_target_process(state, 1);\n\n\t// Cleanup the fork server if necessary\n\tif(state->fork_server_setup) {\n\t\tfork_server_exit(&state->fs);\n\t\tstate->fork_server_setup = 0;\n\t}\n\n\tfree(state->target_path);\n\tfree(state->qemu_path);\n}\n\nchar * afl_get_state(void *instrumentation_state) {\n\tafl_state_t * state = (afl_state_t *)instrumentation_state;\n\tjson_t *state_obj, *temp;\n\tchar * ret;\n\n\tstate_obj = json_object();\n\tif (!state_obj)\n\t\treturn NULL;\n\n\t//Add the virgin_bits, virgin_tmout, and virgin_crash bitmaps\n\tADD_MEM(temp, (const char *)state->virgin_bits, MAP_SIZE, state_obj, \"virgin_bits\");\n\tADD_MEM(temp, (const char *)state->virgin_tmout, MAP_SIZE, state_obj, \"virgin_tmout\");\n\tADD_MEM(temp, (const char *)state->virgin_crash, MAP_SIZE, state_obj, \"virgin_crash\");\n\n\tret = json_dumps(state_obj, 0);\n\tjson_decref(state_obj);\n\treturn ret;\n}\n\n/**\n * This function frees an instrumentation state previously obtained via afl_get_state.\n * @param state - the instrumentation state to free\n */\nvoid afl_free_state(char *state) {\n\tfree(state);\n}\n\n\n#define get_bits(name, dest)                      \\\n\tGET_MEM(tempstr, state, tempstr, name, result); \\\n\tmemcpy(dest, tempstr, MAP_SIZE);                \\\n\tfree(tempstr);\n\nint afl_set_state(void *instrumentation_state, char *state) {\n\tint result;\n\tchar * tempstr;\n\tafl_state_t * afl_state = (afl_state_t *)instrumentation_state;\n\n\tif(!state || !instrumentation_state)\n\t\treturn 1;\n\n\tafl_state->loaded_state = 1;\n\tget_bits(\"virgin_bits\", afl_state->virgin_bits);\n\tget_bits(\"virgin_tmout\", afl_state->virgin_tmout);\n\tget_bits(\"virgin_crash\", afl_state->virgin_crash);\n\n\treturn 0;\n}\n\n/**\n * This function merges the bitmap in src into the bitmap in dest\n * @param dest - the bitmap that will be combined with the src bitmap.\n * @param src - the bitmap that will be added to the dest bitmap\n */\nvoid merge_bitmaps(u8 * dest, const u8 * src)\n{\n\tsize_t i;\n\tfor (i = 0; i < MAP_SIZE; i++)\n\t\tdest[i] &= src[i];\n}\n\nvoid * afl_merge(void *instrumentation_state, void *other_instrumentation_state) {\n\tafl_state_t * first = (afl_state_t *)instrumentation_state;\n\tafl_state_t * second = (afl_state_t *)other_instrumentation_state;\n\tafl_state_t * ret;\n\n\tret = (afl_state_t *)malloc(sizeof(afl_state_t));\n\tif(!ret)\n\t\treturn NULL;\n\tmemset(ret, 0, sizeof(afl_state_t));\n\n\tmemcpy(ret->virgin_bits, first->virgin_bits, MAP_SIZE);\n\tmerge_bitmaps(ret->virgin_bits, second->virgin_bits);\n\tmemcpy(ret->virgin_tmout, first->virgin_tmout, MAP_SIZE);\n\tmerge_bitmaps(ret->virgin_tmout, second->virgin_tmout);\n\tmemcpy(ret->virgin_crash, first->virgin_crash, MAP_SIZE);\n\tmerge_bitmaps(ret->virgin_crash, second->virgin_crash);\n\treturn ret;\n}\n\n/**\n * This function enables the instrumentation and runs the fuzzed process.\n * @param instrumentation_state - an instrumentation specific state object\n *                                previously created by the afl_create function\n * @process - a pointer to return a pid_t to the process that the\n *            instrumentation was enabled on\n * @cmd_line - the command line of the fuzzed process to enable instrumentation on\n * @input - a buffer to the input that should be sent to the fuzzed process\n * @input_length - the length of the input parameter\n * returns 0 on success, -1 on failure\n */\nint afl_enable(void *instrumentation_state, pid_t *process, char *cmd_line,\n\t\tchar *input, size_t input_length) {\n\tafl_state_t * state = (afl_state_t *)instrumentation_state;\n\tchar ** argv;\n\n\t// If there's already a child process, get rid of it\n\tif(state->child_pid) {\n\t\tdestroy_target_process(state, 0);\n\t}\n\n\t// Set up shared memory\n\tif(setup_shm(state))\n\t\treturn -1;\n\n\t/* After this memset, trace_bits[] are effectively volatile, so we\n\t\t\tmust prevent any earlier operations from venturing into that\n\t\t\tterritory. */\n\tmemset(state->trace_bits, 0, MAP_SIZE);\n\tMEM_BARRIER();\n\n\tif(create_target_process(state, cmd_line, input, input_length))\n\t\treturn -1;\n\tstate->process_finished = 0;\n\tstate->fuzz_results_set = 0;\n\n\t*process = state->child_pid;\n\treturn 0;\n}\n\n/**\n * This function determines if a new path was covered\n * @param instrumentation_state - an instrumentation specific state object\n *                                previously created by the afl_create function\n * @return - 1 if the previously setup process (via the enable function) took a\n *           new path, 0 if it did not, or -1 on failure.\n */\nint afl_is_new_path(void *instrumentation_state) {\n\tafl_state_t * state = (afl_state_t *)instrumentation_state;\n\n\t// If we haven't set the fuzz results, do that and return the result\n\tif(!state->fuzz_results_set)\n\t\tfinish_fuzz_round(state);\n\tif(state->last_is_new_path)\n\t\treturn 1;\n\treturn 0;\n}\n\n/**\n * This function will return the result of the fuzz job. It should be called\n * after the process has finished processing the tested input.  The target\n * process will also be cleaned up in the process.\n * @param instrumentation_state - an instrumentation specific structure\n *                                previously created by the afl_create function\n * @return - either FUZZ_NONE, FUZZ_HANG, FUZZ_CRASH, or -1 on error.\n */\nint afl_get_fuzz_result(void *instrumentation_state) {\n\tafl_state_t * state = (afl_state_t *)instrumentation_state;\n\n\t// If we haven't set the fuzz results, do that and return the result\n\tif(!state->fuzz_results_set)\n\t\treturn finish_fuzz_round(state);\n\n\t// otherwise we can just return the result\n\treturn state->last_fuzz_result;\n}\n\n/**\n * This function determines if the target process CRASHED, HUNG or EXITED\n * NORMALLY, cleans up the process, and checks to see if any new code was\n * executed.  The assumption is that if you are calling this function,\n * you're sick of waiting for the child, so if it is still executing by the\n * time we get here, we're calling it a HANG.  This is implemented as an\n * internal function so we can use it when the caller calls any of the post-\n * fuzzing functions, such as get_fuzz_result or is_new_path().\n *\n * @param state - The AFL specific state structure\n * @return - either FUZZ_NONE, FUZZ_HANG, FUZZ_CRASH, or -1 on error.\n */\nstatic int finish_fuzz_round(afl_state_t *state) {\n\tint status, rc;\n\n\t// if our process is still running, then it was a hang\n\tif(!afl_is_process_done(state)) {\n\t\tdestroy_target_process(state, 1);\n\t\tstate->last_fuzz_result = FUZZ_HANG;\n#ifdef __x86_64__\n\t\tsimplify_trace((uint64_t*)state->trace_bits);\n#else\n\t\tsimplify_trace((uint32_t*)state->trace_bits);\n#endif /* ^__x86_64__ */\n\t\tstate->last_is_new_path = has_new_bits(state->virgin_tmout, state->trace_bits);\n\t\tDEBUG_MSG(\"Process hung, has_new_bits = %d\", state->last_is_new_path);\n\t\tstate->fuzz_results_set = 1;\n\n\t} else if(WIFEXITED(state->last_status)) {\n\t\t/* Any subsequent operations on trace_bits must not be moved by the\n\t\t\t compiler below this point. Past this location, trace_bits[] behave\n\t\t\t very normally and do not have to be treated as volatile. */\n\t\tMEM_BARRIER();\n\t\tstate->last_is_new_path = has_new_bits(state->virgin_bits, state->trace_bits);\n\t\tstate->last_fuzz_result = FUZZ_NONE;  // process exited normally\n\t\tDEBUG_MSG(\"Process exited normally, has_new_bits = %d\", state->last_is_new_path);\n\t\tstate->fuzz_results_set = 1;\n\n\t} else if(WIFSIGNALED(state->last_status)) {\n\t\t// process was terminated by a signal.  We look for signals which\n\t\t// indicate non-crashing conditions (e.g. SIGPIPE)\n\t\tif(WTERMSIG(state->last_status) == SIGPIPE) {\n\t\t\tstate->last_is_new_path = has_new_bits(state->virgin_bits, state->trace_bits);\n\t\t\tstate->last_fuzz_result = FUZZ_NONE;  // we'll say the process exited normally\n\t\t\tDEBUG_MSG(\"Process exited due to SIGPIPE, has_new_bits = %d\", state->last_is_new_path);\n\t\t\tstate->fuzz_results_set = 1;\n\t\t} else {\n\t\t\tstate->last_fuzz_result = FUZZ_CRASH;\n#ifdef __x86_64__\n\t\t\tsimplify_trace((uint64_t*)state->trace_bits);\n#else\n\t\t\tsimplify_trace((uint32_t*)state->trace_bits);\n#endif /* ^__x86_64__ */\n\t\t\tstate->last_is_new_path = has_new_bits(state->virgin_crash, state->trace_bits);\n\t\t\tDEBUG_MSG(\"Process crashed, has_new_bits = %d\", state->last_is_new_path);\n\t\t\tstate->fuzz_results_set = 1;\n\t\t}\n\t} else {\n\t\t// if it didn't exit normally, nor get interrupted by a signal...\n\t\t// I'm not sure what happened!\n\t\treturn FUZZ_ERROR;\n\t}\n\treturn state->last_fuzz_result;\n}\n\n/**\n * Checks if the target process is done fuzzing the inputs yet.\n * @param instrumentation_state - The afl_state_t object containing this\n *                                instrumentation's state\n * @return - 0 if the process is not done testing the fuzzed input,\n *           non-zero if the process is done.\n */\nint afl_is_process_done(void *instrumentation_state) {\n\tint status, rc;\n\tafl_state_t * state = (afl_state_t *)instrumentation_state;\n\n\t// If the state says we're done, our job is easy!\n\tif(state->process_finished)\n\t\treturn 1;\n\n\tif(state->use_fork_server) {\n\t\tstatus = fork_server_get_status(&state->fs, 0);\n\t\t// if it's still alive or an error occurred and we can't tell\n\t\tif(status < 0 || status == FORKSERVER_NO_RESULTS_READY)\n\t\t\treturn 0;\n\t\tstate->last_status = status;\n\t\tstate->process_finished = 1;\n\t\treturn 1;\n\t} else {\n\t\t// We just need to check to see if the process is still alive\n\t\trc = waitpid(state->child_pid, &status, WNOHANG);\n\t\tif(rc == 0)  // child did not change state\n\t\t\treturn 0;\n\t\tif(rc == state->child_pid) {\n\t\t\t// our child changed state (exited, received a signal, etc.)\n\t\t\tstate->last_status = status;  // Record it\n\t\t\tstate->child_pid = 0;         // We no longer have a child process\n\t\t\tstate->process_finished = 1;  // Mark that we're done\n\t\t\treturn 1;\n\t\t}\n\t\tif(rc == -1) // waitpid failed\n\t\t\treturn -1;\n\t\tERROR_MSG(\"waitpid() said pid %d changed state but our child was %d\",\n\t\t\trc, state->child_pid);\n\t\treturn -1;  // Some other child process changed state?\n\t}\n\n\tERROR_MSG(\"Fell through to end of afl_is_process_done().\");\n\treturn -1;\n}\n\nint afl_help(char **help_str) {\n\t*help_str = strdup(\n\t\t\"afl - AFL-based instrumentation\\n\"\n\t\t\"Options:\\n\"\n\t\t\"  use_fork_server      Whether to use a fork server; 1=yes, 0=no (default=1)\\n\"\n\t\t\"  persistence_max_cnt  The number of executions to run in one process while\\n\"\n\t\t\"                         fuzzing in persistence mode (default=1)\\n\"\n\t\t\"  qemu_mode            Whether to use qemu mode; 1=yes, 0=no (default=0)\\n\"\n\t\t\"  qemu_path            The path to afl-qemu-trace (including executable name)\\n\"\n\t\t\"  deferred_startup     Whether to use deferred startup mode; 1=yes, 0=no (default=0)\\n\"\n\t\t\"\\n\"\n\t);\n\tif (*help_str == NULL)\n\t\treturn -1;\n\treturn 0;\n}\n\n/**\n * This function creates a afl_state_t object based on the given options.\n * @param options - A JSON string of the options to set in the new\n *                  afl_state_t. See the help function for more information on\n *                  the specific options available.\n * @return the afl_state_t generated from the options in the JSON options\n *         string, or NULL on failure\n */\nstatic afl_state_t * setup_options(char *options) {\n\tafl_state_t * state;\n\tchar buffer[PATH_MAX];\n\tchar *pos;\n\tint fd, error = 0;\n\n\tstate = malloc(sizeof(afl_state_t));\n\tif(!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(afl_state_t));\n\tstate->use_fork_server = 1;  // default to use the fork server\n\n\tif(options) {\n\t\tDEBUG_MSG(\"JSON options = %s\", options);\n\t\tPARSE_OPTION_INT(state, options, use_fork_server,\n\t\t\t\t\"use_fork_server\", afl_cleanup);\n\t\tPARSE_OPTION_INT(state, options, persistence_max_cnt,\n\t\t\t\t\"persistence_max_cnt\", afl_cleanup);\n\t\tPARSE_OPTION_INT(state, options, deferred_startup,\n\t\t\t\t\"deferred_startup\", afl_cleanup);\n\t\tPARSE_OPTION_INT(state, options, qemu_mode,\n\t\t\t\t\"qemu_mode\", afl_cleanup);\n\t\tPARSE_OPTION_STRING(state, options, qemu_path,\n\t\t\t\t\"qemu_path\", afl_cleanup);\n\t}\n\n\tif(state->persistence_max_cnt && !state->use_fork_server) {\n\t\tERROR_MSG(\"Cannot use persistence mode without the fork server\");\n\t\terror = 1;\n\t} else if(state->deferred_startup && !state->use_fork_server) {\n\t\tERROR_MSG(\"Cannot use deferred startup mode without the fork server\");\n\t\terror = 1;\n\t} else if(state->qemu_mode && !state->use_fork_server) {\n\t\tERROR_MSG(\"Cannot use qemu mode without the fork server\");\n\t\terror = 1;\n\t} else if(state->qemu_mode && state->persistence_max_cnt) {\n\t\tERROR_MSG(\"Cannot use qemu mode and persistence mode (yet).\");\n\t\terror = 1;\n\t}\n\n\tif(error) {\n\t\tafl_cleanup(state);\n\t\treturn NULL;\n\t}\n\n\tif(state->qemu_mode && !state->qemu_path) {\n\t\t//Try to autodetect afl-qemu-trace\n\t\tif(file_exists(\"../../killerbeez/afl_progs/afl-qemu-trace\")) { //try looking in the source directory\n\t\t\tstate->qemu_path = realpath(\"../../killerbeez/afl_progs/afl-qemu-trace\", NULL);\n\t\t} else { //check $PATH\n\t\t\tsystem(\"which afl-qemu-trace > /tmp/which-afl-qemu-trace\");\n\t\t\tfd = open(\"/tmp/which-afl-qemu-trace\", O_RDONLY);\n\t\t\tif(fd >= 0) {\n\t\t\t\tmemset(buffer, 0, sizeof(buffer));\n\t\t\t\tif(read(fd, buffer, sizeof(buffer)-1) > 0) {\n\t\t\t\t\t//Trim newlines\n\t\t\t\t\tif ((pos = strchr(buffer, '\\n')) != NULL)\n\t\t\t\t\t\t*pos = 0;\n\t\t\t\t\tif ((pos = strchr(buffer, '\\r')) != NULL)\n\t\t\t\t\t\t*pos = 0;\n\t\t\t\t\t//If we read a valid path, use that\n\t\t\t\t\tif(file_exists(buffer))\n\t\t\t\t\t\tstate->qemu_path = strdup(buffer);\n\t\t\t\t}\n\t\t\t\tclose(fd);\n\t\t\t}\n\t\t\tunlink(\"/tmp/which-afl-qemu-trace\");\n\t\t}\n\n\t\tif(!state->qemu_path) {\n\t\t\tERROR_MSG(\"Cannot find afl-qemu-trace for use with qemu mode, please specify the path with the qemu_path option\");\n\t\t\tafl_cleanup(state);\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\treturn state;\n}\n\n/**\n * This function starts the fuzzed process\n * @param state - The afl_state_t object containing this instrumentation's state\n * @param cmd_line - the command line of the fuzzed process to start\n * @param input - a buffer to the input that should be sent to the fuzzed process\n * @param input_length - the length of the input parameter\n * @return - zero on success, non-zero on failure.\n */\nstatic int create_target_process(afl_state_t * state, char* cmd_line,\n\t\t\tchar * input, size_t input_length) {\n\tchar ** argv;\n\tchar qemu_command_line[4096];\n\tint i;\n\n\tif(state->use_fork_server) {\n\t\tif(!state->fork_server_setup) {\n\t\t\tDEBUG_MSG(\"Using fork server...\");\n\t\t\tif(state->qemu_mode) {\n\t\t\t\t//prepend the command with the path of afl-qemu-trace\n\t\t\t\tsnprintf(qemu_command_line, sizeof(qemu_command_line), \"%s %s\", state->qemu_path, cmd_line);\n\t\t\t\tcmd_line = qemu_command_line;\n\t\t\t}\n\n\t\t\t//Split the command line into the executable and arguments\n\t\t\tif(split_command_line(cmd_line, &state->target_path, &argv))\n\t\t\t\treturn -1;\n\n\t\t\tif(state->deferred_startup) {\n\t\t\t\t//set the deferred environment variable to let the forkserver know it\n\t\t\t\tsetenv(DEFER_ENV_VAR, \"1\", 1); //shouldn't do the startup right away\n\t\t\t}\n\n\t\t\t//Start the fork server\n\t\t\tfork_server_init(&state->fs, state->target_path, argv, 0,\n\t\t\t\t\tstate->persistence_max_cnt, input_length != 0);\n\t\t\tstate->fork_server_setup = 1;\n\n\t\t\t//Free the split arguments\n\t\t\tfor(i = 0; argv[i]; i++)\n\t\t\t\tfree(argv[i]);\n\t\t\tfree(argv);\n\t\t}\n\n\t\tif(state->fs.target_stdin != -1) {\n\t\t\t//Take care of the stdin input, write over the file, then truncate it accordingly\n\t\t\tlseek(state->fs.target_stdin, 0, SEEK_SET);\n\t\t\tif(input != NULL && input_length != 0) {\n\t\t\t\tif(write(state->fs.target_stdin, input, input_length) != input_length)\n\t\t\t\t\tFATAL_MSG(\"Short write to target's stdin file\");\n\t\t\t}\n\t\t\tif(ftruncate(state->fs.target_stdin, input_length))\n\t\t\t\tFATAL_MSG(\"ftruncate() failed\");\n\t\t\tlseek(state->fs.target_stdin, 0, SEEK_SET);\n\t\t}\n\n\t\t//Start the new child and tell it to go\n\t\tstate->child_pid = fork_server_fork_run(&state->fs);\n\t\tif(state->child_pid < 0) {\n\t\t\tERROR_MSG(\"Fork server failed to fork a new child\\n\");\n\t\t\treturn -1;\n\t\t}\n\t} else {\n\t\tDEBUG_MSG(\"Not using fork server, executing %s\", cmd_line);\n\t\tif (start_process_and_write_to_stdin(cmd_line, input, input_length, &state->child_pid)) {\n\t\t\tstate->child_pid = 0;\n\t\t\tERROR_MSG(\"Failed to create process with command line: %s\\n\", cmd_line);\n\t\t\treturn -1;\n\t\t}\n\t}\n\tDEBUG_MSG(\"Child process ID = %d\", state->child_pid);\n\n\treturn 0;\n}\n\n/**\n * This function terminates the fuzzed process.\n * @param state - The afl_state_t object containing this instrumentation's state\n */\nstatic void destroy_target_process(afl_state_t * state, int force) {\n\tif(state->child_pid && state->child_pid != -1) {\n\t\tDEBUG_MSG(\"Cleaning up old child process (pid=%d)\", state->child_pid);\n\t\tif(!state->persistence_max_cnt || force) {\n\t\t\tkill(state->child_pid, SIGKILL);\n\t\t\tstate->child_pid = 0;\n\t\t}\n\t\tif(state->use_fork_server) {\n\t\t\tstate->last_status = fork_server_get_status(&state->fs, 1);\n\t\t}\n\t}\n}\n\n/**\n * This sets up the shared memory between our fuzzer and the target process\n * being fuzzed.  The target process will write to this as it executes and\n * we will read it once the fuzzing is complete (crash, hang, or normal exit)\n * @param instrumentation_state - The afl_state_t object containing this\n *                                instrumentation's state\n * @returns zero on success, non-zero on error\n */\nint setup_shm(void *instrumentation_state) {\n\t/*\n\tThis function is based on the AFL setup_shm function present in afl-fuzz.c,\n\tavailable at this URL:\n\thttps://github.com/mirrorer/afl/blob/master/afl-fuzz.c#L1968.\n\tAFL's license is as shown below:\n\n\tamerican fuzzy lop - fuzzer code\n\t--------------------------------\n\tWritten and maintained by Michal Zalewski <lcamtuf@google.com>\n\n\tForkserver design by Jann Horn <jannhorn@googlemail.com>\n\n\tCopyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved.\n\n\tLicensed under the Apache License, Version 2.0 (the \"License\");\n\tyou may not use this file except in compliance with the License.\n\tYou may obtain a copy of the License at:\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\t*/\n \n\tchar* shm_str;\n\tafl_state_t * state = (afl_state_t *)instrumentation_state;\n\n\tif(state->trace_bits) // if trace_bits already points at the shm\n\t\treturn 0;     // region, we've already run this function!\n\n\t// If we loaded a saved input bitmap, do not overwrite the\n\t// map showing what was fuzzed showing everything as untouched\n\tif(!state->loaded_state) {\n\t\tmemset(state->virgin_bits, 255, MAP_SIZE);\n\t\tmemset(state->virgin_tmout, 255, MAP_SIZE);\n\t\tmemset(state->virgin_crash, 255, MAP_SIZE);\n\t}\n\n\t// Allocate shared memory; shm_id must be module level or global so\n\t// the atexit function has access to it (as we can not pass arguments\n\t// to the callback function)\n\tstate->shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600);\n\tif(state->shm_id < 0) {\n\t\tERROR_MSG(\"shmget() failed\");\n\t\treturn 1;\n\t}\n\tshm_str = alloc_printf(\"%d\", state->shm_id);\n\n\t// set the environment variable so the instrumented binary knows which\n\t// shared memory ID to attach to when it goes to write the bitmap\n\tsetenv(SHM_ENV_VAR, shm_str, 1);\n\tck_free(shm_str);\n\n\t// Attach to shared memory region\n\tstate->trace_bits = shmat(state->shm_id, NULL, 0);\n\tif(!state->trace_bits) {\n\t\tERROR_MSG(\"shmat() failed\");\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n/**\n * Check if the current execution path brings anything new to the table.\n * Update virgin bits to reflect the new paths found, so subsequent calls will\n * always return 0.\n *\n * This function is called after every exec() on a fairly large buffer, so\n * it needs to be fast. We do this in 32-bit and 64-bit flavors.\n *\n * @param virgin_map - The map we should compare against, which will be\n *                     virgin_{bits,tmout,crash} in practice.\n * @param trace_bits - The trace for this particular run\n * @returns - 1 if the only change is the hit-count for a particular tuple;\n *            2 if there are new tuples seen, 0 if it is not a new path\n **/\nstatic inline uint8_t has_new_bits(uint8_t* virgin_map, uint8_t *trace_bits) {\n\t/*\n\tThis function is based on the AFL has_new_bits function present in afl-fuzz.c,\n\tavailable at this URL:\n\thttps://github.com/mirrorer/afl/blob/master/afl-fuzz.c#L1968.\n\tAFL's license is as shown below:\n\n\tamerican fuzzy lop - fuzzer code\n\t--------------------------------\n\tWritten and maintained by Michal Zalewski <lcamtuf@google.com>\n\n\tForkserver design by Jann Horn <jannhorn@googlemail.com>\n\n\tCopyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved.\n\n\tLicensed under the Apache License, Version 2.0 (the \"License\");\n\tyou may not use this file except in compliance with the License.\n\tYou may obtain a copy of the License at:\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\t*/\n\n#ifdef __x86_64__\n  uint64_t* current = (uint64_t*)trace_bits;\n  uint64_t* virgin  = (uint64_t*)virgin_map;\n  uint32_t  i = (MAP_SIZE >> 3);\n#else\n  uint32_t* current = (uint32_t*)trace_bits;\n  uint32_t* virgin  = (uint32_t*)virgin_map;\n  uint32_t  i = (MAP_SIZE >> 2);\n#endif /* ^__x86_64__ */\n\n  uint8_t   ret = 0;\n  while (i--) {\n    /* Optimize for (*current & *virgin) == 0 - i.e., no bits in current bitmap\n       that have not been already cleared from the virgin map - since this will\n       almost always be the case. */\n    if (unlikely(*current) && unlikely(*current & *virgin)) {\n      if (likely(ret < 2)) {\n        uint8_t* cur = (uint8_t*)current;\n        uint8_t* vir = (uint8_t*)virgin;\n\n        /* Looks like we have not found any new bytes yet; see if any non-zero\n           bytes in current[] are pristine in virgin[]. */\n#ifdef __x86_64__\n        if ((cur[0] && vir[0] == 0xff) || (cur[1] && vir[1] == 0xff) ||\n            (cur[2] && vir[2] == 0xff) || (cur[3] && vir[3] == 0xff) ||\n            (cur[4] && vir[4] == 0xff) || (cur[5] && vir[5] == 0xff) ||\n            (cur[6] && vir[6] == 0xff) || (cur[7] && vir[7] == 0xff)) ret = 2;\n        else ret = 1;\n#else\n        if ((cur[0] && vir[0] == 0xff) || (cur[1] && vir[1] == 0xff) ||\n            (cur[2] && vir[2] == 0xff) || (cur[3] && vir[3] == 0xff)) ret = 2;\n        else ret = 1;\n#endif /* ^__x86_64__ */\n      }\n      *virgin &= ~*current;\n    }\n    current++;\n    virgin++;\n  }\n  return ret;\n}\n\n/* Destructively simplify trace by eliminating hit count information\n   and replacing it with 0x80 or 0x01 depending on whether the tuple\n   is hit or not. Called on every new crash or timeout, should be\n   reasonably fast. */\nstatic const uint8_t simplify_lookup[256] = {\n  [0]         = 1,\n  [1 ... 255] = 128\n};\n\n#ifdef __x86_64__\nstatic void simplify_trace(uint64_t* mem) {\n  uint32_t i = MAP_SIZE >> 3;\n  while (i--) {\n    /* Optimize for sparse bitmaps. */\n    if (unlikely(*mem)) {\n      uint8_t* mem8 = (uint8_t*)mem;\n      mem8[0] = simplify_lookup[mem8[0]];\n      mem8[1] = simplify_lookup[mem8[1]];\n      mem8[2] = simplify_lookup[mem8[2]];\n      mem8[3] = simplify_lookup[mem8[3]];\n      mem8[4] = simplify_lookup[mem8[4]];\n      mem8[5] = simplify_lookup[mem8[5]];\n      mem8[6] = simplify_lookup[mem8[6]];\n      mem8[7] = simplify_lookup[mem8[7]];\n    } else *mem = 0x0101010101010101ULL;\n    mem++;\n  }\n}\n#else\nstatic void simplify_trace(uint32_t* mem) {\n  uint32_t i = MAP_SIZE >> 2;\n  while (i--) {\n    /* Optimize for sparse bitmaps. */\n    if (unlikely(*mem)) {\n      uint8_t* mem8 = (uint8_t*)mem;\n      mem8[0] = simplify_lookup[mem8[0]];\n      mem8[1] = simplify_lookup[mem8[1]];\n      mem8[2] = simplify_lookup[mem8[2]];\n      mem8[3] = simplify_lookup[mem8[3]];\n    } else *mem = 0x01010101;\n    mem++;\n  }\n}\n#endif /* ^__x86_64__ */\n"
  },
  {
    "path": "instrumentation/afl_instrumentation.h",
    "content": "#include <stdio.h>     // fprintf\n#include <signal.h>    // for pid_t\n#include <stdint.h>    // uint*_t\n#include <string.h>  // for memset, strdup\n#include <sys/wait.h>  // for waitpid\n\n#include \"forkserver_internal.h\"\n\n#include \"../afl_progs/config.h\"\n#include \"../afl_progs/alloc-inl.h\"\n\nstruct afl_state {\n\tint shm_id;\n\tchar *qemu_path;\n\tchar *target_path;\n\tpid_t child_pid;\n\tforkserver_t fs;\n\tint process_finished;\n\tint last_fuzz_result;\n\tint fuzz_results_set;  // have we set the fuzz results?\n\tint last_status;  // the last input did what? (CRASH, HANG, NONE, etc.)\n\tint last_is_new_path;  // did the last input hit a new code path?\n\tint use_fork_server;\n\tint fork_server_setup;\n\tint persistence_max_cnt;\n\tint qemu_mode;\n\tint deferred_startup;\n\tint loaded_state;\n\tuint8_t virgin_bits[MAP_SIZE];  // Regions yet untouched by fuzzing\n\tuint8_t virgin_tmout[MAP_SIZE]; // Bits we haven't seen in tmouts\n\tuint8_t virgin_crash[MAP_SIZE]; // Bits we haven't seen in crashes\n\tuint8_t *trace_bits;            // SHM with instrumentation bitmap\n};\ntypedef struct afl_state afl_state_t;\n\nvoid * afl_create(char *options, char *state);\nvoid afl_cleanup(void *instrumentation_state);\nchar * afl_get_state(void *instrumentation_state);\nvoid afl_free_state(char *state);\nint afl_set_state(void *instrumentation_state, char *state);\nvoid * afl_merge(void *instrumentation_state, void *other_instrumentation_state);\nint afl_enable(void *instrumentation_state, pid_t *process, char *cmd_line,\n\t\tchar *input, size_t input_length);\nint afl_is_new_path(void *instrumentation_state);\nint afl_get_fuzz_result(void *instrumentation_state);\nint afl_is_process_done(void *instrumentation_state);\nint afl_help(char **help_str);\n\nstatic afl_state_t * setup_options(char *options);\nstatic void destroy_target_process(afl_state_t * state, int force);\nstatic int create_target_process(afl_state_t * state, char* cmd_line,\n\t\t\tchar * input, size_t input_length);\nint setup_shm(void *instrumentation_state);\nstatic void remove_shm();\n#ifdef __x86_64__\nstatic void simplify_trace(uint64_t* mem);\n#else\nstatic void simplify_trace(uint32_t* mem);\n#endif /* ^__x86_64__ */\nstatic inline uint8_t has_new_bits(uint8_t* virgin_map, uint8_t *trace_bits);\nstatic int finish_fuzz_round(afl_state_t *state);\n"
  },
  {
    "path": "instrumentation/debug_instrumentation.c",
    "content": "#include <windows.h>\n#include <stdlib.h>\n#include <ntstatus.h>\n\n#include \"instrumentation.h\"\n#include \"debug_instrumentation.h\"\n\n#include <utils.h>\n#include <jansson_helper.h>\n\n/**\n * This function creates the target process and debugs it.  This function runs in\n * a separate thread, releasing the process_creation_semaphore once it has created\n * the target process.  This function then runs the debug loop on the target, setting\n * state->last_status when the process crashes, hangs, or exits normally.\n * @param args - A thread_arguments_t object with the thread's arguments in it\n * @return - zero on success, non-zero on failure\n*/\nstatic int debugging_thread(debug_state_t * state)\n{\n\tDEBUG_EVENT de;\n\tDWORD cont, child_pid;\n\n\twhile (1)\n\t{\n\t\t//Wait for the main thread to tell us to go\n\t\ttake_semaphore(state->fuzz_round_semaphore);\n\n\t\t//Create the child process, mark it as running, and let the main thread know we're done\n\t\tif (start_process_and_write_to_stdin_flags(state->thread_args.cmd_line, state->thread_args.stdin_input,\n\t\t\t\tstate->thread_args.stdin_length, &state->child_handle, DEBUG_ONLY_THIS_PROCESS)) {\n\t\t\trelease_semaphore(state->process_creation_semaphore);\n\t\t\tstate->child_handle = NULL;\n\t\t\tERROR_MSG(\"Failed to create process with command line: %s\\n\", state->thread_args.cmd_line);\n\t\t\treturn 1;\n\t\t}\n\t\tstate->process_running = 1;\n\n\t\t//Let the main thread know we've created the process\n\t\trelease_semaphore(state->process_creation_semaphore);\n\n\t\t//Loop while debugging and look for process exits and exceptions\n\t\tchild_pid = GetProcessId(state->child_handle);\n\t\tstate->last_status = FUZZ_RUNNING;\n\t\tmemset(&de, 0, sizeof(DEBUG_EVENT));\n\t\twhile (state->process_running && WaitForDebugEvent(&de, INFINITE))\n\t\t{\n\t\t\tcont = DBG_CONTINUE;\n\t\t\tif (de.dwProcessId == child_pid && state->process_running) {\n\t\t\t\tif (de.dwDebugEventCode == EXCEPTION_DEBUG_EVENT)\n\t\t\t\t{\n\t\t\t\t\t// Not all exceptions are real crashes - we ignore breakpoints being hit and\n\t\t\t\t\t// exceptions that are encountered multiple times\n\t\t\t\t\tif (!de.u.Exception.dwFirstChance || // if the debugger has not encountered this exception before\n\t\t\t\t\t\t(de.u.Exception.ExceptionRecord.ExceptionCode != EXCEPTION_BREAKPOINT &&\n\t\t\t\t\t\t de.u.Exception.ExceptionRecord.ExceptionCode != STATUS_WX86_BREAKPOINT)) {\n\t\t\t\t\t\tstate->last_status = FUZZ_CRASH;\n\t\t\t\t\t\tcont = DBG_EXCEPTION_NOT_HANDLED;\n\t\t\t\t\t\tstate->process_running = 0;\n\n\t\t\t\t\t\t//Once we know the result, kill the process to speed things up\n\t\t\t\t\t\tTerminateProcess(state->child_handle, 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (de.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)\n\t\t\t\t{\n\t\t\t\t\tstate->last_status = FUZZ_NONE;\n\t\t\t\t\tstate->process_running = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!ContinueDebugEvent(de.dwProcessId, de.dwThreadId, cont)) {\n\t\t\t\tERROR_MSG(\"ContinueDebugEvent: Failed to check child process health\");\n\t\t\t\tstate->last_status = -1;\n\t\t\t\trelease_semaphore(state->results_ready_semaphore);\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tmemset(&de, 0, sizeof(DEBUG_EVENT));\n\t\t}\n\n\t\t//Let the main thread know we've finished looking at the current fuzzed process' debug events\n\t\trelease_semaphore(state->results_ready_semaphore);\n\t}\n\n\treturn 0;\n}\n\n/**\n * This function terminates the fuzzed process.\n * @param state - The debug_state_t object containing this instrumentation's state\n */\nstatic void destroy_target_process(debug_state_t * state) {\n\tif (state->child_handle) {\n\t\tstate->last_child_hung = get_process_status(state->child_handle);\n\t\t//If the process hung, then make sure the debug thread finishes its debug loop\n\t\tif(state->last_child_hung)//otherwise we'll be waiting for it forever\n\t\t\tstate->process_running = 0;\n\n\t\tTerminateProcess(state->child_handle, 0);\n\t\tCloseHandle(state->child_handle);\n\t\tstate->child_handle = NULL;\n\n\t\t//Wait for the debug thread to be done with the child.  We need to wait\n\t\t//here, since we don't want the results_ready_semaphore to becoming stale\n\t\t//because the debug instrumentation user did not read the results of a previous\n\t\t//fuzzed process\n\t\ttake_semaphore(state->results_ready_semaphore);\n\t}\n}\n\n/**\n * This function starts the fuzzed process\n * @param state - The debug_state_t object containing this instrumentation's state\n * @param cmd_line - the command line of the fuzzed process to start\n * @param stdin_input - the input to pass to the fuzzed process's stdin\n * @param stdin_length - the length of the stdin_input parameter\n * @return - zero on success, non-zero on failure.\n */\nstatic int create_target_process(debug_state_t * state, char* cmd_line, char * stdin_input, size_t stdin_length) {\n\n\t//Reset the state for this fuzz process\n\tstate->finished_last_run = 0;\n\tstate->last_child_hung = 0;\n\tstate->last_status = FUZZ_RUNNING;\n\n\t//Tell the debug thread to start a new process\n\tstate->thread_args.cmd_line = cmd_line;\n\tstate->thread_args.stdin_input = stdin_input;\n\tstate->thread_args.stdin_length = stdin_length;\n\trelease_semaphore(state->fuzz_round_semaphore);\n\n\t//Wait for the debug thread to finish creating the new process\n\tif (take_semaphore(state->process_creation_semaphore) || !state->child_handle)\n\t\treturn 1;\n\treturn 0;\n}\n\n/**\n * This function ends the fuzzed process (if it wasn't previously ended).\n * @param state - The debug_state_t object containing this instrumentation's state\n * @return - returns 0 on success or -1 on error\n */\nstatic int finish_fuzz_round(debug_state_t * state) {\n\tif (!state->finished_last_run) {\n\t\tdestroy_target_process(state);\n\t\tstate->finished_last_run = 1;\n\t}\n\tif (state->last_status < 0)\n\t\treturn -1;\n\n\tif(state->last_child_hung)\n\t\tstate->last_status = FUZZ_HANG;\n\t// else leave it as whatever it was\n\n\treturn 0;\n}\n\n////////////////////////////////////////////////////////////////\n// Instrumentation methods /////////////////////////////////////\n////////////////////////////////////////////////////////////////\n\n/**\n * This function allocates and initializes a new instrumentation specific state object based on the given options.\n * @param options - a JSON string that contains the instrumentation specific string of options\n * @param state - an instrumentation specific JSON string previously returned from debug_get_state that should be loaded\n * @return - An instrumentation specific state object on success or NULL on failure\n */\nvoid * debug_create(char * options, char * state)\n{\n\tdebug_state_t * debug_state;\n\tdebug_state = malloc(sizeof(debug_state_t));\n\tif (!debug_state)\n\t\treturn NULL;\n\tmemset(debug_state, 0, sizeof(debug_state_t));\n\n\tdebug_state->fuzz_round_semaphore = create_semaphore(0, 1);\n\tdebug_state->process_creation_semaphore = create_semaphore(0, 1);\n\tdebug_state->results_ready_semaphore = create_semaphore(0, 1);\n\tif (!debug_state->fuzz_round_semaphore || !debug_state->process_creation_semaphore || !debug_state->results_ready_semaphore) {\n\t\tdebug_cleanup(debug_state);\n\t\treturn NULL;\n\t}\n\n\tif (state && debug_set_state(debug_state, state))\n\t{\n\t\tdebug_cleanup(debug_state);\n\t\treturn NULL;\n\t}\n\n\tdebug_state->debug_thread_handle = CreateThread(\n\t\tNULL,           // default security attributes\n\t\t0,              // default stack size\n\t\t(LPTHREAD_START_ROUTINE)debugging_thread, // thread function\n\t\tdebug_state,     // thread argument\n\t\t0,              // default creation flags\n\t\tNULL            // record the thread handle\n\t);\n\tif (!debug_state->debug_thread_handle) {\n\t\tdebug_cleanup(debug_state);\n\t\treturn NULL;\n\t}\n\n\treturn debug_state;\n}\n\n/**\n * This function cleans up all resources with the passed in instrumentation state.\n * @param instrumentation_state - an instrumentation specific state object previously created by the debug_create function\n * This state object should not be referenced after this function returns.\n */\nvoid debug_cleanup(void * instrumentation_state)\n{\n\tdebug_state_t * state = (debug_state_t *)instrumentation_state;\n\n\tdestroy_target_process(state);\n\tif (state->debug_thread_handle) {\n\t\tTerminateThread(state->debug_thread_handle, 0);\n\t\tCloseHandle(state->debug_thread_handle);\n\t\tstate->debug_thread_handle = NULL;\n\t}\n\n\tif(state->fuzz_round_semaphore)\n\t\tdestroy_semaphore(state->fuzz_round_semaphore);\n\tif (state->process_creation_semaphore)\n\t\tdestroy_semaphore(state->process_creation_semaphore);\n\tif (state->results_ready_semaphore)\n\t\tdestroy_semaphore(state->results_ready_semaphore);\n\tfree(state);\n}\n\n/**\n * This function merges the coverage information from two instrumentation states.  This will always fail for the\n * debug instrumentation, since it does not record instrumentation data.\n * @param instrumentation_state - an instrumentation specific state object previously created by the debug_create function\n * @param other_instrumentation_state - an instrumentation specific state object previously created by the debug_create function\n * @return - An instrumentation specific state object that contains the combination of both of the passed in instrumentation states\n * on success, or NULL on failure\n */\nvoid * debug_merge(void * instrumentation_state, void * other_instrumentation_state)\n{\n\treturn NULL; //No instrumentation data, so we can't ever merge\n}\n\n/**\n * This function returns the state information holding the previous execution path info.  The returned value can later be passed to\n * debug_create or debug_set_state to load the state.\n * @param instrumentation_state - an instrumentation specific state object previously created by the debug_create function\n * @return - A JSON string that holds the instrumentation specific state object information on success, or NULL on failure\n */\nchar * debug_get_state(void * instrumentation_state)\n{\n\tdebug_state_t * state = (debug_state_t *)instrumentation_state;\n\tjson_t *state_obj, *temp;\n\tchar * ret;\n\n\tstate_obj = json_object();\n\tADD_INT(temp, state->last_status, state_obj, \"last_status\");\n\tret = json_dumps(state_obj, 0);\n\tjson_decref(state_obj);\n\treturn ret;\n}\n\n/**\n * This function frees an instrumentation state previously obtained via debug_get_state.\n * @param state - the instrumentation state to free\n */\nvoid debug_free_state(char * state)\n{\n\tfree(state);\n}\n\n/**\n * This function sets the instrumentation state to the passed in state previously obtained via debug_get_state.\n * @param instrumentation_state - an instrumentation specific state object previously created by the debug_create function\n * @param state - an instrumentation state previously obtained via debug_get_state\n * @return - 0 on success, non-zero on failure.\n */\nint debug_set_state(void * instrumentation_state, char * state)\n{\n\tdebug_state_t * current_state = (debug_state_t *)instrumentation_state;\n\tint result, temp_int;\n\tif (!state)\n\t\treturn 1;\n\n\t//If a child process is running when the state is being set\n\tdestroy_target_process(current_state);//kill it so we don't orphan it\n\n\tGET_INT(temp_int, state, current_state->last_status, \"last_status\", result);\n\tcurrent_state->finished_last_run = 1;\n\n\treturn 0; //No state to set, so just return success\n}\n\n/**\n * This function enables the instrumentation and runs the fuzzed process.  If the process needs to be restarted, it will be.\n * @param instrumentation_state - an instrumentation specific state object previously created by the debug_create function\n * @process - a pointer to return a handle to the process that instrumentation was enabled on\n * @cmd_line - the command line of the fuzzed process to enable instrumentation on\n * @input - a buffer to the input that should be sent to the fuzzed process on stdin\n * @input_length - the length of the input parameter\n * returns 0 on success, -1 on failure\n */\nint debug_enable(void * instrumentation_state, HANDLE * process, char * cmd_line, char * input, size_t input_length)\n{\n\tdebug_state_t * state = (debug_state_t *)instrumentation_state;\n\tif(state->child_handle)\n\t\tdestroy_target_process(state);\n\tif (create_target_process(state, cmd_line, input, input_length))\n\t\treturn -1;\n\t*process = state->child_handle;\n\tstate->enable_called = 1;\n\treturn 0;\n}\n\n/**\n * This function determines whether the process being instrumented has taken a new path.  The debug instrumentation does\n * not track the fuzzed process's path, so it is unable to determine if the process took a new path.\n * @param instrumentation_state - an instrumentation specific state object previously created by the debug_create function\n * @return - 0 when a new path wasn't detected (as it always won't be with the debug instrumentation), or -1 on failure.\n */\nint debug_is_new_path(void * instrumentation_state)\n{\n\tdebug_state_t * state = (debug_state_t *)instrumentation_state;\n\tif (!state->enable_called)\n\t\treturn -1;\n\treturn 0; //We don't gather instrumentation data, so we can't ever tell if we hit a new path.\n}\n\n/**\n * This function will return the result of the fuzz job. It should be called\n * after the process has finished processing the tested input.\n * @param instrumentation_state - an instrumentation specific structure previously created by the create() function\n * @return - either FUZZ_NONE, FUZZ_HANG, FUZZ_CRASH, or -1 on error.\n */\nint debug_get_fuzz_result(void * instrumentation_state)\n{\n\tdebug_state_t * state = (debug_state_t *)instrumentation_state;\n\tif (!state->enable_called)\n\t\treturn -1;\n\tfinish_fuzz_round(state);\n\treturn state->last_status;\n}\n\n/**\n * Checks if the target process is done fuzzing the inputs yet.  If it has finished, it will have\n * written last_status, the result of the fuzz job.\n *\n * @param state - The debug_state_t object containing this instrumentation's state\n * @return - 0 if the process has not finished testing the fuzzed input, 1 if the process is done,\n * or -1 on error.\n */\nint debug_is_process_done(void * instrumentation_state)\n{\n\tdebug_state_t * state = (debug_state_t *)instrumentation_state;\n\n\tif (!state->enable_called)\n\t\treturn -1;\n\tif (state->process_running)\n\t\treturn 0;\n\telse\n\t\treturn 1;\n\t// we don't need to setup for get_fuzz_result, it should be handled by the debug thread.\n}\n\n/**\n * This function returns help text for this instrumentation.  This help text will describe the instrumentation and any options\n * that can be passed to debug_create.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nint debug_help(char ** help_str)\n{\n\t*help_str = strdup(\n\t\t\"debug - Windows debug thread \\\"instrumentation\\\", only detects crashes\\n\"\n\t\t\"Options:\\n\"\n\t\t\"\\tNone\\n\"\n\t\t\"\\n\"\n\t);\n\tif (*help_str == NULL)\n\t\treturn -1;\n\treturn 0;\n}\n"
  },
  {
    "path": "instrumentation/debug_instrumentation.h",
    "content": "#pragma once\n#include <utils.h>\n\n#ifdef _WIN32\n#include <Windows.h> // HANDLE (winnt.h might work instead)\n#else\n#include <sys/types.h> // pid_t\n#endif\n\nvoid * debug_create(char * options, char * state);\nvoid debug_cleanup(void * instrumentation_state);\nvoid * debug_merge(void * instrumentation_state, void * other_instrumentation_state);\nchar * debug_get_state(void * instrumentation_state);\nvoid debug_free_state(char * state);\nint debug_set_state(void * instrumentation_state, char * state);\n\n#ifdef _WIN32\nint debug_enable(void * instrumentation_state, HANDLE * process, char * cmd_line, char * input, size_t input_length);\n#else\nint debug_enable(void * instrumentation_state, pid_t * process, char * cmd_line, char * input, size_t input_length);\n#endif\n\nint debug_is_new_path(void * instrumentation_state);\nint debug_get_fuzz_result(void * instrumentation_state);\nint debug_is_process_done(void * instrumentation_state);\nint debug_help(char ** help_str);\n\ntypedef struct\n{\n\tchar * cmd_line; //the command line of the target process to start\n\tchar * stdin_input; //input to the STDIN of the target process\n\tsize_t stdin_length; //the length of the input to write stdin\n} thread_args_t;\n\nstruct debug_state\n{\n\t#ifdef _WIN32\n\tHANDLE child_handle;\n\tHANDLE debug_thread_handle;\n\t#else\n\tpid_t child_handle;\n\t#endif\n\tint process_running;\n\n\t//This semaphore is used to make the debug thread wait until the main\n\t//thread wants it to start a new process and begin debugging it.\n\tsemaphore_t fuzz_round_semaphore;\n\n\t//This semaphore is used by the main thread to wait until the debug\n\t//thread has created the fuzzed process.\n\tsemaphore_t process_creation_semaphore;\n\n\t//This semaphore is used by the main thread to wait until the debug\n\t//thread has finished debugging the fuzzed process and the results can\n\t//now be viewed (in last_status).\n\tsemaphore_t results_ready_semaphore;\n\n\tint finished_last_run;\n\tint last_status;\n\tint last_child_hung;\n\tint enable_called;\n\n\t//This struct is used to pass arguments to the debugging thread.  It\n\t//should only be accessed while in the create_thread_process function,\n\t//as they will point to memory that is out of scope afterwards.  The\n\t//strings in the thread_args should not be freed.\n\tthread_args_t thread_args;\n};\ntypedef struct debug_state debug_state_t;\n"
  },
  {
    "path": "instrumentation/dynamorio_instrumentation.c",
    "content": "#define _CRT_RAND_S\n#include <windows.h>\n#include <Shlwapi.h>\n#include <io.h>\n#include <stdlib.h> \n\n#include \"instrumentation.h\"\n#include \"dynamorio_instrumentation.h\"\n\n#include <utils.h>\n#include <jansson_helper.h>\n\n//AFL headers\n#include \"winafl_config.h\"\n#include \"winafl_hash.h\"\n#include \"winafl_types.h\"\n#include \"winafl_alloc_inl.h\"\n\n//#define DEBUG_TRACE_BITS\n\nstatic BOOL connect_to_pipe(HANDLE pipe, char * pipe_name, DWORD timeout);\nstatic HANDLE create_pipe(char * pipe_name, DWORD timeout);\nstatic void cleanup_pipe(HANDLE * pipe);\nstatic int has_new_coverage_per_module(dynamorio_state_t * state);\nstatic int has_new_coverage(u8 * trace_bits, u8 * virgin_bits, u8 * ignore_bytes, u32 * last_shm_hash, char * dump_map_dir);\n\n////////////////////////////////////////////////////////////////\n// SHM Memory Analysis and Misc Functions //////////////////////\n////////////////////////////////////////////////////////////////\n\n/*\n   The code in this section (SHM Memory Analysis and Misc Functions) was taken\n   from WinAFL and falls under the following license:\n\n   Original AFL code written by Michal Zalewski <lcamtuf@google.com>\n\n   Windows fork written and maintained by Ivan Fratric <ifratric@google.com>\n\n   Copyright 2016 Google Inc. All Rights Reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n   The code in this section has been modified from the original to suit the\n   purposes of this project.\n\n*/\n\n\n/**\n * Allocates a string and formats it based on the passed arguments.\n * @param format_string - the printf-style format string to format the allocated string with\n * @return - the newly allocated string, that should be freed with ck_free, containing the\n * formatted text.\n */\nchar *alloc_printf(const char *format_string, ...) {\n\tva_list argptr;\n\tchar* _tmp;\n\ts32 _len;\n\n\tva_start(argptr, format_string);\n\t_len = vsnprintf(NULL, 0, format_string, argptr);\n\tif (_len < 0) FATAL_MSG(\"Whoa, snprintf() fails?!\");\n\t_tmp = (char *)ck_alloc(_len + 1);\n\tvsnprintf(_tmp, _len + 1, format_string, argptr);\n\tva_end(argptr);\n\treturn _tmp;\n}\n\n#define FFL(_b) (0xffULL << ((_b) << 3))\n#define FF(_b)  (0xff << ((_b) << 3))\n\n/**\n * Check if the current execution path brings anything new to the table.\n * Update virgin bits to reflect the finds. Returns 1 if the only change is\n * the hit-count for a particular tuple; 2 if there are new tuples seen.\n * Updates the map, so subsequent calls will always return 0.\n * \n * This function is called after every exec() on a fairly large buffer, so\n * it needs to be fast. We do this in 32-bit and 64-bit flavors.\n *\n * @param trace_bits - the bitmap representing the edges hit in the last run\n * @param virgin_map - the bitmap representing the edges that have been hit so far\n * @return - 1 if the only change is hit-count, 2 if there are new edges, 0 otherwise\n */\nstatic inline u8 has_new_bits(u8*trace_bits, u8* virgin_map) {\n\n#ifdef __x86_64__\n\n\tu64* current = (u64*)trace_bits;\n\tu64* virgin = (u64*)virgin_map;\n\n\tu32  i = (MAP_SIZE >> 3);\n\n#else\n\n\tu32* current = (u32*)trace_bits;\n\tu32* virgin = (u32*)virgin_map;\n\n\tu32  i = (MAP_SIZE >> 2);\n\n#endif /* ^__x86_64__ */\n\n\tu8   ret = 0;\n\n\twhile (i--) {\n\n#ifdef __x86_64__\n\n\t\tu64 cur = *current;\n\t\tu64 vir = *virgin;\n\n#else\n\n\t\tu32 cur = *current;\n\t\tu32 vir = *virgin;\n\n#endif /* ^__x86_64__ */\n\n\t\t/* Optimize for *current == ~*virgin, since this will almost always be the\n\t\tcase. */\n\n\t\tif (cur & vir) {\n\n\t\t\tif (ret < 2) {\n\n\t\t\t\t/* This trace did not have any new bytes yet; see if there's any\n\t\t\t\tcurrent[] byte that is non-zero when virgin[] is 0xff. */\n\n#ifdef __x86_64__\n\n\t\t\t\tif (((cur & FFL(0)) && (vir & FFL(0)) == FFL(0)) ||\n\t\t\t\t\t((cur & FFL(1)) && (vir & FFL(1)) == FFL(1)) ||\n\t\t\t\t\t((cur & FFL(2)) && (vir & FFL(2)) == FFL(2)) ||\n\t\t\t\t\t((cur & FFL(3)) && (vir & FFL(3)) == FFL(3)) ||\n\t\t\t\t\t((cur & FFL(4)) && (vir & FFL(4)) == FFL(4)) ||\n\t\t\t\t\t((cur & FFL(5)) && (vir & FFL(5)) == FFL(5)) ||\n\t\t\t\t\t((cur & FFL(6)) && (vir & FFL(6)) == FFL(6)) ||\n\t\t\t\t\t((cur & FFL(7)) && (vir & FFL(7)) == FFL(7))) ret = 2;\n\t\t\t\telse ret = 1;\n\n#else\n\n\t\t\t\tif (((cur & FF(0)) && (vir & FF(0)) == FF(0)) ||\n\t\t\t\t\t((cur & FF(1)) && (vir & FF(1)) == FF(1)) ||\n\t\t\t\t\t((cur & FF(2)) && (vir & FF(2)) == FF(2)) ||\n\t\t\t\t\t((cur & FF(3)) && (vir & FF(3)) == FF(3))) ret = 2;\n\t\t\t\telse ret = 1;\n\n#endif /* ^__x86_64__ */\n\n\t\t\t}\n\n\t\t\t*virgin = vir & ~cur;\n\n\t\t}\n\n\t\tcurrent++;\n\t\tvirgin++;\n\n\t}\n\n\treturn ret;\n\n}\n\n#ifdef DEBUG_TRACE_BITS\nstatic int first_run = 1;\n#endif\n/**\n * Check if the current execution path brings anything new to the table.\n * Update virgin bits to reflect the finds. Returns 1 if the only change is\n * the hit-count for a particular tuple; 2 if there are new tuples seen.\n * Updates the map, so subsequent calls will always return 0.\n *\n * This function is called after every exec() on a fairly large buffer, so\n * it needs to be fast. We do this in 32-bit and 64-bit flavors.\n *\n * This function is identical to has_new_bits, but takes an ignore_bytes bitmap\n * that lists bits that should be ignored when determining if a new edge has been found\n *\n * @param trace_bits - the bitmap representing the edges hit in the last run\n * @param virgin_map - the bitmap representing the edges that have been hit so far\n * @param ignore_bytes - a bitmap representing the edges that should be ignored when reporting\n * new edges\n * @return - 1 if the only change is hit-count, 2 if there are new edges, 0 otherwise\n */\nstatic inline u8 has_new_bits_with_ignore(u8*trace_bits, u8* virgin_map, u8* ignore_bytes) {\n\n\tu8 ret = 0;\n\tu32  i = 0;\n\n\tu8 trace, virgin, ignore;\n\twhile (i < MAP_SIZE) {\n\t\ttrace = *trace_bits;\n\t\tvirgin = *virgin_map;\n\t\tignore = *ignore_bytes;\n\n\t\t/* Optimize for *current == ~*virgin, since this will almost always be the\n\t\tcase. */\n\t\tif (!ignore && (trace & virgin)) {\n\t\t\tif (ret < 2) {\n\t\t\t\t/* This trace did not have any new bytes yet; see if there's any\n\t\t\t\tcurrent[] byte that is non-zero when virgin[] is 0xff. */\n\t\t\t\tif (trace & FFL(0) && (virgin & FFL(0)) == FFL(0))\n\t\t\t\t\tret = 2;\n\t\t\t\telse\n\t\t\t\t\tret = 1;\n\t\t\t}\n#ifdef DEBUG_TRACE_BITS\n\t\t\tif (!first_run && (trace & FFL(0) && (virgin & FFL(0)) == FFL(0)))\n\t\t\t\tprintf(\"diff byte %d\\n\", i);\n#endif\n\n\t\t\t*virgin_map = virgin & ~trace;\n\t\t}\n\n\t\ttrace_bits++;\n\t\tvirgin_map++;\n\t\tignore_bytes++;\n\t\ti++;\n\t}\n#ifdef DEBUG_TRACE_BITS\n\tfirst_run = 0;\n#endif\n\treturn ret;\n\n}\n\n#define AREP4(_sym)   (_sym), (_sym), (_sym), (_sym)\n#define AREP8(_sym)   AREP4(_sym), AREP4(_sym)\n#define AREP16(_sym)  AREP8(_sym), AREP8(_sym)\n#define AREP32(_sym)  AREP16(_sym), AREP16(_sym)\n#define AREP64(_sym)  AREP32(_sym), AREP32(_sym)\n#define AREP128(_sym) AREP64(_sym), AREP64(_sym)\n\nstatic u8 count_class_lookup[256] = {\n\n\t/* 0 - 3:       4 */ 0, 1, 2, 4,\n\t/* 4 - 7:      +4 */ AREP4(8),\n\t/* 8 - 15:     +8 */ AREP8(16),\n\t/* 16 - 31:   +16 */ AREP16(32),\n\t/* 32 - 127:  +96 */ AREP64(64), AREP32(64),\n\t/* 128+:     +128 */ AREP128(128)\n\n};\n\n#ifdef __x86_64__\n\n/**\n * Destructively classify execution counts in a trace. This is used as a\n * preprocessing step for any newly acquired traces. Called on every exec,\n * must be fast.\n * @param mem - the bitmap which defines the edges that have been hit by a trace\n */\nstatic inline void classify_counts(u64* mem) {\n\n\tu32 i = MAP_SIZE >> 3;\n\n\twhile (i--) {\n\n\t\t/* Optimize for sparse bitmaps. */\n\n\t\tif (*mem) {\n\n\t\t\tu8* mem8 = (u8*)mem;\n\n\t\t\tmem8[0] = count_class_lookup[mem8[0]];\n\t\t\tmem8[1] = count_class_lookup[mem8[1]];\n\t\t\tmem8[2] = count_class_lookup[mem8[2]];\n\t\t\tmem8[3] = count_class_lookup[mem8[3]];\n\t\t\tmem8[4] = count_class_lookup[mem8[4]];\n\t\t\tmem8[5] = count_class_lookup[mem8[5]];\n\t\t\tmem8[6] = count_class_lookup[mem8[6]];\n\t\t\tmem8[7] = count_class_lookup[mem8[7]];\n\n\t\t}\n\n\t\tmem++;\n\n\t}\n\n}\n\n#else\n\n/**\n* Destructively classify execution counts in a trace. This is used as a\n* preprocessing step for any newly acquired traces. Called on every exec,\n* must be fast.\n* @param mem - the bitmap which defines the edges that have been hit by a trace\n*/\nstatic inline void classify_counts(u32* mem) {\n\n\tu32 i = MAP_SIZE >> 2;\n\n\twhile (i--) {\n\n\t\t/* Optimize for sparse bitmaps. */\n\n\t\tif (*mem) {\n\n\t\t\tu8* mem8 = (u8*)mem;\n\n\t\t\tmem8[0] = count_class_lookup[mem8[0]];\n\t\t\tmem8[1] = count_class_lookup[mem8[1]];\n\t\t\tmem8[2] = count_class_lookup[mem8[2]];\n\t\t\tmem8[3] = count_class_lookup[mem8[3]];\n\n\t\t}\n\n\t\tmem++;\n\n\t}\n\n}\n\n#endif /* ^__x86_64__ */\n\n/**\n * This function merges the bitmap in src into the bitmap in dest\n * @param dest - the bitmap that will be combined with the src bitmap.\n * @param src - the bitmap that will be added to the dest bitmap\n */\nvoid merge_bitmaps(u8 * dest, const u8 * src)\n{\n\tsize_t i;\n\tfor (i = 0; i < MAP_SIZE; i++)\n\t\tdest[i] &= src[i];\n}\n\n////////////////////////////////////////////////////////////////\n// Process and SHM Management //////////////////////////////////\n////////////////////////////////////////////////////////////////\n\n/**\n * This function cleans up the shared memory.\n * @param trace_bits - a pointer to the mapped shared memory region\n * @param shm_handle - a Windows handle to the shared memory region\n */\nstatic void remove_shm(u8 * trace_bits, HANDLE shm_handle)\n{\n\tif (trace_bits)\n\t\tUnmapViewOfFile(trace_bits);\n\tif (shm_handle)\n\t\tCloseHandle(shm_handle);\n}\n\n/**\n * This function creates and maps a shared memory region.\n * @param fuzzer_id - the id associated with this shared memory region\n * @param index - the index of the target module that this shared memory region will be associated with.\n * If this shared memory region isn't associated with a target module, -1 should be passed in.\n * @param out_trace_bits - A pointer to a pointer of memory that will be assigned to a mapped view of\n * the shared memory region\n * @param for_edges - whether the shm region is for the full edge recording or not\n * @return - a Windows handle to the shared memory region on success, or NULL on failure\n */\nstatic HANDLE setup_shm_region(char * fuzzer_id, int index, u8 ** out_trace_bits, int for_edges)\n{\n\tchar* shm_str;\n\tHANDLE shm_handle;\n\tDWORD size;\n\n\tif (for_edges)\n\t\tsize = EDGES_SHM_SIZE;\n\telse\n\t\tsize = MAP_SIZE;\n\n\tif (index < 0)\n\t\tshm_str = (char *)alloc_printf(\"afl_shm_%s\", fuzzer_id);\n\telse\n\t\tshm_str = (char *)alloc_printf(\"afl_shm_%s_%d\", fuzzer_id, index);\n\tDEBUG_MSG(\"Setting up shm region: %s\", shm_str);\n\n\tshm_handle = CreateFileMapping(\n\t\tINVALID_HANDLE_VALUE,    // use paging file\n\t\tNULL,                    // default security\n\t\tPAGE_READWRITE,          // read/write access\n\t\t0,                       // maximum object size (high-order DWORD)\n\t\tsize,                    // maximum object size (low-order DWORD)\n\t\tshm_str);                // name of mapping object\n\tck_free(shm_str);\n\n\tif (shm_handle == NULL) {\n\t\tif (GetLastError() != ERROR_ALREADY_EXISTS)\n\t\t\tFATAL_MSG(\"CreateFileMapping failed\");\n\t\treturn NULL;\n\t}\n\n\t*out_trace_bits = (u8 *)MapViewOfFile(\n\t\tshm_handle,          // handle to map object\n\t\tFILE_MAP_ALL_ACCESS, // read/write permission\n\t\t0,\n\t\t0,\n\t\tsize\n\t);\n\tif (!*out_trace_bits)\n\t\tFATAL_MSG(\"MapViewOfFile() failed\");\n\t\n\treturn shm_handle;\n}\n\n/**\n * This function generates a fuzzer_id for use with mapping of shared memory regions and assigns\n * the fuzzer_id to state->fuzzer_id (first freeing the previous state->fuzzer_id if set).\n * @param state - The dynamorio_state_t object containing this instrumentation's state\n */\nvoid generate_fuzzer_id(dynamorio_state_t * state)\n{\n\tunsigned int seeds[2];\n\n\tif (state->fuzzer_id != NULL) {\n\t\tck_free(state->fuzzer_id);\n\t\tstate->fuzzer_id = NULL;\n\t}\n\n\trand_s(&seeds[0]);\n\trand_s(&seeds[1]);\n\tstate->fuzzer_id = (char *)alloc_printf(\"%I32x%I32x\", seeds[0], seeds[1]);\n}\n\n/**\n * This function configures shared memory and virgin_bits.\n * @param state - The dynamorio_state_t object containing this instrumentation's state\n * @param reset_virgin_bits - Whether the virgin bits (that define which edges have already been \n * seen), should be reset\n */\nstatic void setup_shm_and_pick_fuzzer_id(dynamorio_state_t * state, int reset_virgin_bits) {\n\n\tu8 attempts = 0;\n\ttarget_module_t * target_module;\n\n\tif (state->per_module_coverage)\n\t{\n\t\t//First pick a fuzzer id by trying to create the first shm region\n\t\ttarget_module = state->modules;\n\t\twhile (attempts < 5 && !target_module->shm_handle) {\n\t\t\tattempts++;\n\t\t\tgenerate_fuzzer_id(state);\n\t\t\tif(state->edges)\n\t\t\t\ttarget_module->shm_handle = setup_shm_region(state->fuzzer_id, target_module->index, (u8**)&target_module->edges_memory, 1);\n\t\t\telse\n\t\t\t\ttarget_module->shm_handle = setup_shm_region(state->fuzzer_id, target_module->index, &target_module->trace_bits, 0);\n\t\t}\n\t\tif (!target_module->shm_handle) {\n\t\t\tPFATAL(\"Couldn't create shm region for %s module\\n\", state->module_names[target_module->index]);\n\t\t}\n\t\tif(reset_virgin_bits)\n\t\t\tmemset(target_module->virgin_bits, 0xFF, MAP_SIZE);\n\t\tif (state->edges)\n\t\t\tmemset(target_module->edges_memory, 0, EDGES_SHM_SIZE);\n\n\t\t//Next create the rest of them with that fuzzer id\n\t\ttarget_module = target_module->next;\n\t\twhile (target_module)\n\t\t{\n\t\t\tif (state->edges)\n\t\t\t\ttarget_module->shm_handle = setup_shm_region(state->fuzzer_id, target_module->index, (u8**)&target_module->edges_memory, 1);\n\t\t\telse\n\t\t\t\ttarget_module->shm_handle = setup_shm_region(state->fuzzer_id, target_module->index, &target_module->trace_bits, 0);\n\t\t\tif (!target_module->shm_handle)\n\t\t\t\tFATAL_MSG(\"Couldn't create shm region for %s module\", state->module_names[target_module->index]);\n\n\t\t\tif (reset_virgin_bits)\n\t\t\t\tmemset(target_module->virgin_bits, 0xFF, MAP_SIZE);\n\t\t\tif (state->edges)\n\t\t\t\tmemset(target_module->edges_memory, 0, EDGES_SHM_SIZE);\n\n\t\t\ttarget_module = target_module->next;\n\t\t}\n\t}\n\telse\n\t{\n\t\twhile (attempts < 5 && !state->shm_handle) {\n\t\t\tattempts++;\n\t\t\tgenerate_fuzzer_id(state);\n\t\t\tif (state->edges)\n\t\t\t\tstate->shm_handle = setup_shm_region(state->fuzzer_id, -1, (u8**)&state->edges_memory, 1);\n\t\t\telse\n\t\t\t\tstate->shm_handle = setup_shm_region(state->fuzzer_id, -1, &state->trace_bits, 0);\n\t\t}\n\t\tif (!state->shm_handle) {\n\t\t\tFATAL_MSG(\"Couldn't create shm region\");\n\t\t}\n\n\t\tif (reset_virgin_bits)\n\t\t\tmemset(state->virgin_bits, 0xFF, MAP_SIZE);\n\t\tif (state->edges)\n\t\t\tmemset(state->edges_memory, 0, EDGES_SHM_SIZE);\n\t}\n}\n\n/**\n * This function kills a process with the specified exit code \n * @param dwProcessId - the process id of the process to kill\n * @param uExitCode - the exit code that the specified process should be killed with\n * @return - a BOOL describing whether the process was successfully terminated (TRUE) or not (FALSE)\n */\nBOOL TerminateProcessByPid(DWORD dwProcessId, UINT uExitCode)\n{\n\tDWORD dwDesiredAccess = PROCESS_TERMINATE;\n\tBOOL  bInheritHandle = FALSE;\n\tHANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);\n\tif (hProcess == NULL)\n\t\treturn FALSE;\n\n\tBOOL result = TerminateProcess(hProcess, uExitCode);\n\n\tCloseHandle(hProcess);\n\n\treturn result;\n}\n\n/**\n * This function wraps the creation of a pipe\n * @param pipe_name - The name of the pipe to create\n * @param timeout - The maximum time to wait for the pipe to be created\n * @return - A handle to the created pipe\n */\nstatic HANDLE create_pipe(char * pipe_name, DWORD timeout)\n{\n\tHANDLE pipe;\n\n\tpipe = CreateNamedPipe(\n\t\tpipe_name,                // pipe name\n\t\tPIPE_ACCESS_DUPLEX |      // read/write access\n\t\tFILE_FLAG_OVERLAPPED,     // asynchronous (so we can time out)\n\t\t0,\n\t\t1,                        // max. instances\n\t\t512,                      // output buffer size\n\t\t512,                      // input buffer size\n\t\ttimeout,                  // client time-out\n\t\tNULL);                    // default security attribute\n\n\tif (pipe == INVALID_HANDLE_VALUE)\n\t\tFATAL_MSG(\"CreateNamedPipe failed for pipe %s, GLE=%d.\", pipe_name, GetLastError());\n\treturn pipe;\n}\n\n/**\n * This function connects to a pipe.\n * @param pipe - A handle to the pipe to connect to\n * @param pipe_name - The name of the pipe to connect to.  Only used in help messages, if creation fails.\n * @param timeout - The maximum time to wait for the client to connect to the pipe\n * @return - TRUE if the connection succeeds, FALSE otherwise\n */\nstatic BOOL connect_to_pipe(HANDLE pipe, char * pipe_name, DWORD timeout)\n{\n\tBOOL success = FALSE;\n\tOVERLAPPED overlap = { 0 };\n\toverlap.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);\n\n\tif (ConnectNamedPipe(pipe, &overlap)) {\n\t\t// Overlapped ConnectNamedPipe is expected to always return 0\n\t\tERROR_MSG(\"ConnectNamedPipe failed for the pipe %s, GLE=%d.\", pipe_name, GetLastError());\n\t\treturn FALSE;\n\t}\n\tswitch (GetLastError()) {\n\tcase ERROR_PIPE_CONNECTED:\n\t\tsuccess = TRUE;\n\t\tbreak;\n\tcase ERROR_IO_PENDING:\n\t\tif (WaitForSingleObject(overlap.hEvent, timeout) == WAIT_OBJECT_0) {\n\t\t\t// Pipe is connected\n\t\t\tDWORD ignored_bytestransferred;\n\t\t\tsuccess = GetOverlappedResult(pipe, &overlap, &ignored_bytestransferred, FALSE);\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Timed out or failed\n\t\t\tCancelIo(pipe);\n\t\t}\n\t}\n\n\tif (!success) {\n\t\tERROR_MSG(\"Did not receive connection from DynamoRIO child process on pipe %s, GLE=%d.\", pipe_name, GetLastError());\n\t\tERROR_MSG(\"Try increasing the instrumentation timeout option (currently set to %lu).\", timeout);\n\t}\n\n\tCloseHandle(overlap.hEvent);\n\n\treturn success;\n}\n\n/**\n* This function cleans up a pipe.\n* @param pipe - A handle to the pipe to clean up\n*/\nstatic void cleanup_pipe(HANDLE * pipe)\n{\n\tif (*pipe) {\n\t\tDisconnectNamedPipe(*pipe);\n\t\tCloseHandle(*pipe);\n\t\t*pipe = NULL;\n\t}\n}\n\n/**\n * This function terminates the fuzzed process (running in drrun.exe).\n * @param state - The dynamorio_state_t object containing this instrumentation's state\n * @param wait_exit - The maximum number of milliseconds to wait when trying to wait for fuzzed process.\n */\nstatic void destroy_target_process(dynamorio_state_t * state, int wait_exit) {\n\t//TODO this seems like it'll be really slow.  Optimize it if possible\n\n\tchar kill_cmd[512];\n\tHANDLE kill_handle;\n\n\tif (state->child_handle) {\n\n\t\t//nudge the child process\n\t\tif (WaitForSingleObject(state->child_handle, wait_exit) == WAIT_TIMEOUT) {\n\n\t\t\t//Try to nudge the process first\n\t\t\tsnprintf(kill_cmd, sizeof(kill_cmd) - 1, \"%s\\\\drconfig.exe -nudge_pid %d 0 1\", state->dynamorio_dir, state->child_pid);\n\t\t\tif (start_process_and_write_to_stdin(kill_cmd, NULL, 0, &kill_handle))\n\t\t\t\tFATAL_MSG(\"Could not nudge process with drconfig\");\n\t\t\tCloseHandle(kill_handle);\n\n\t\t\t//wait until the child process exits\n\t\t\tif (WaitForSingleObject(state->child_handle, state->timeout) == WAIT_TIMEOUT) {\n\n\t\t\t\t//It didn't exit, so kill drrun\n\t\t\t\tif (!TerminateProcess(state->child_handle, 9))\n\t\t\t\t\tFATAL_MSG(\"Could not stop fuzzed program (pid %d) with TerminateProcess (GLE=%d)\", state->child_pid, GetLastError());\n\n\t\t\t\t//Clean up the target process as well\n\t\t\t\tTerminateProcessByPid(state->child_pid, 9);\n\t\t\t}\n\t\t}\n\t\tCloseHandle(state->child_handle);\n\t\tstate->child_handle = NULL;\n\t}\n\n\tcleanup_pipe(&state->pipe_handle);\n}\n\n/**\n * This function starts the fuzzed process inside of DynamoRIO\n * @param state - The dynamorio_state_t object containing this instrumentation's state\n * @param cmd_line - the command line of the fuzzed process to start\n * @param stdin_input - the input to pass to the fuzzed process's stdin\n * @param stdin_length - the length of the stdin_input parameter\n */\nstatic void create_target_process(dynamorio_state_t * state, char* cmd_line, char * stdin_input, size_t stdin_length) {\n\tchar* dr_cmd;\n\tFILE *fp;\n\tsize_t pidsize;\n\tchar buffer[MAX_PATH];\n\n\tstate->pipe_handle = create_pipe(state->pipe_name, state->timeout);\n\n\t//Create the child process\n\tdr_cmd = alloc_printf(\n\t\t\"%s\\\\drrun.exe -pidfile %s -no_follow_children -c \\\"%s\\\\winafl.dll\\\" %s -fuzzer_id %s -- %s\",\n\t\tstate->dynamorio_dir, state->pidfile, state->winafl_dir, state->client_params, state->fuzzer_id, cmd_line);\n\tif (start_process_and_write_to_stdin(dr_cmd, stdin_input, stdin_length, &state->child_handle))\n\t\tFATAL_MSG(\"Child process died when started with command line: %s\", dr_cmd);\n\n\tif (!connect_to_pipe(state->pipe_handle, state->pipe_name, state->timeout)) //Connect to the comms pipe\n\t{\n\t\tif (get_process_status(state->child_handle) == 0) // process is not alive\n\t\t\tFATAL_MSG(\"Child process died when started with command line: %s\", dr_cmd);\n\t\telse\n\t\t\tFATAL_MSG(\"Error communicating with child process with command line: %s\", dr_cmd);\n\t}\n\n\tck_free(dr_cmd);\n\n\t//by the time pipe has connected the pidfile must have been created\n\tfp = fopen(state->pidfile, \"rb\");\n\tif (!fp)\n\t\tFATAL_MSG(\"Error opening pidfile %s\", state->pidfile);\n\tpidsize = fread(buffer, 1, sizeof(buffer)-1, fp);\n\tbuffer[pidsize] = 0;\n\tfclose(fp);\n\tremove(state->pidfile);\n\tstate->child_pid = atoi(buffer);\n\n\t//Reset the fuzz iteration count\n\tstate->fuzz_iterations_current = 0;\n}\n\n/**\n * This function ends the fuzzed process (if it wasn't previously ended), cleans\n * up the pipe, and calculates the whether a new path was taken.\n * @param state - The dynamorio_state_t object containing this instrumentation's state\n * @return - returns -1 on error, -2 when in edge mode, or the results of\n * has_new_coverage/has_new_coverage_per_module functions\n */\nstatic int finish_fuzz_round(dynamorio_state_t * state) {\n\tDWORD num_bytes_available;\n\tchar result;\n\tDWORD num_read;\n\tint ret;\n\n\tif (state->analyzed_last_round)\n\t\treturn state->last_path_was_new;\n\n\t//Determine if the last process hung or not.  If there's nothing in the pipe, then it obviously hung.\n\tif (!PeekNamedPipe(state->pipe_handle, NULL, 0, NULL, &num_bytes_available, NULL))\n\t\treturn -1;\n\n\tif (!num_bytes_available)\n\t{\n\t\tdestroy_target_process(state, 0);\n\t\tstate->last_process_status = FUZZ_HANG;\n\t}\n\telse\n\t{\n\t\t//Read the result from the child\n\t\tReadFile(state->pipe_handle, &result, 1, &num_read, NULL);\n\n\t\t//See if we should restart the client\n\t\tstate->fuzz_iterations_current++;\n\t\tif (state->fuzz_iterations_current == state->fuzz_iterations_max) {\n\t\t\tdestroy_target_process(state, state->timeout);\n\t\t}\n\n\t\t//Record the process status\n\t\tif (num_read == 1 && result == 'K') //Normal\n\t\t{\n\t\t\tstate->last_process_status = FUZZ_NONE;\n\t\t}\n\t\telse //The process hung or crashed, restart it\n\t\t{\n\t\t\tdestroy_target_process(state, 0);\n\t\t\tif (num_read == 1 && result == 'C') //Crash\n\t\t\t\tstate->last_process_status = FUZZ_CRASH;\n\t\t\telse //unknown char or couldn't read, Hang\n\t\t\t\tstate->last_process_status = FUZZ_HANG;\n\t\t}\n\t}\n\n\t//Now check to see if the instrumentation found a new path\n\tif (state->edges)\n\t\tret = -2;\n\telse if (state->per_module_coverage)\n\t\tret = has_new_coverage_per_module(state);\n\telse\n\t\tret = has_new_coverage(state->trace_bits, state->virgin_bits, state->ignore_bytes, &state->last_shm_hash, state->dump_map_dir);\n\tstate->last_path_was_new = ret;\n\tstate->analyzed_last_round = 1;\n\treturn ret;\n}\n\n/**\n * Checks if the target process is done fuzzing the inputs yet.  If it has finished, it will have\n * written the results to the dynamorio instrumentation's pipe.\n\n * @param state - The dynamorio_state_t object containing this instrumentation's state\n * @return - 0 if the process has not done testing the fuzzed input, 1 if the process is done, -1 on error.\n */\nint dynamorio_is_process_done(void * instrumentation_state)\n{\n\tdynamorio_state_t * state = (dynamorio_state_t *)instrumentation_state;\n\tDWORD num_bytes_available;\n\n\tif (!state->enable_called)\n\t\treturn -1;\n\n\tif (!PeekNamedPipe(state->pipe_handle, NULL, 0, NULL, &num_bytes_available, NULL))\n\t\treturn -1;\n\n\treturn num_bytes_available != 0;\n}\n\n////////////////////////////////////////////////////////////////\n// Instrumentation methods /////////////////////////////////////\n////////////////////////////////////////////////////////////////\n\n/**\n * This function loads the ignore_bytes (the bytes in the edges bitmap that should be ignored\n * when checking which edges are new).\n * @param state - The dynamorio_state_t object containing this instrumentation's state\n */\nstatic void load_ignore_bytes(dynamorio_state_t * state)\n{\n\tchar filename[4096];\n\tint size;\n\ttarget_module_t * target_module;\n\n\tif (!state->per_module_coverage && state->ignore_bytes_file)\n\t{\n\t\tsize = read_file(state->ignore_bytes_file, (char **)&state->ignore_bytes);\n\t\tif (size < 0)\n\t\t\tFATAL_MSG(\"Could not open ignore bytes file %s\", state->ignore_bytes_file);\n\t\telse if (size != MAP_SIZE)\n\t\t\tFATAL_MSG(\"Incorrect size of ignore bytes file %s\", state->ignore_bytes_file);\n\t}\n\telse if(state->per_module_coverage && state->ignore_bytes_dir)\n\t{\n\t\tFOREACH_MODULE(target_module, state)\n\t\t{\n\t\t\tsnprintf(filename, sizeof(filename), \"%s\\\\%s.dat\", state->ignore_bytes_dir, state->module_names[target_module->index]);\n\t\t\tsize = read_file(filename, (char **)&target_module->ignore_bytes);\n\t\t\tif (size >= 0 && size != MAP_SIZE) //ignore missing ignore bytes files\n\t\t\t\tFATAL_MSG(\"Incorrect size of ignore bytes file %s\", filename);\n\t\t\telse if (size >= 0)\n\t\t\t\tDEBUG_MSG(\"Loaded ignore bytes file %s for modules %s\", filename, state->module_names[target_module->index]);\n\t\t}\n\t}\n}\n\n/**\n * This function generates the arguments that will be passed to the winafl.dll DynamoRIO tool.\n * @param state - The dynamorio_state_t object containing this instrumentation's state\n */\nstatic void generate_client_params(dynamorio_state_t * state)\n{\n\tchar * temp;\n\tsize_t size, i;\n\n\t//Format client params\n\tsize = 10 * 4096;\n\ttemp = (char *)malloc(size);\n\tif (!temp)\n\t\tFATAL_MSG(\"Couldn't get memory for client_params\");\n\tsnprintf(temp, size - 1, \"%s -fuzz_iterations %d\", state->client_params ? state->client_params : \"\", state->fuzz_iterations_max);\n\tif (state->num_modules)\n\t{\n\t\tchar line[1024];\n\t\tchar * modules_filename = get_temp_filename(\".txt\");\n\t\tFILE * fp = fopen(modules_filename, \"wb\");\n\t\tif (!fp)\n\t\t\tFATAL_MSG(\"Couldn't open modules file '%s'\", modules_filename);\n\t\tfor (i = 0; i < state->num_modules; i++)\n\t\t{\n\t\t\tsnprintf(line, sizeof(line), \"%s\\n\", state->module_names[i]);\n\t\t\tfwrite(line, 1, strlen(line), fp);\n\t\t}\n\t\tfclose(fp);\n\t\tsnprintf(temp, size - 1, \"%s -coverage_module_file %s\", temp, modules_filename);\n\t\tfree(modules_filename);\n\t}\n\tif (state->per_module_coverage)\n\t\tsnprintf(temp, size - 1, \"%s -per_module_coverage\", temp);\n\t\n\tif (state->edges)\n\t\tsnprintf(temp, size - 1, \"%s -verbose_edges\", temp);\n\n\tif (state->client_params)\n\t\tfree(state->client_params);\n\tstate->client_params = temp;\n}\n\n/**\n* This function adds the string \\bin32\\ or \\bin64\\ to the end of the provided\n* dynamorio base path. The architecture is chosen to match the binary in\n* target_path, or the fuzzer if target_path is NULL.\n* @param base_path - char * containing the base dynamorio directory\n* @param target_path - char * containing the path to the binary being fuzzed,\n* or NULL if that option has not been provided to the fuzzer\n* @return - A newly allocated char * pointing to the path with the architecture\n* suffix added\n*/\nstatic char * add_architecture_to_path(char * base_path, char * target_path) {\n\tchar * temp;\n\tDWORD binary_type;\n\n\ttemp = (char *)malloc(MAX_PATH + 1);\n\tif (!temp)\n\t\tFATAL_MSG(\"Couldn't get memory for dynamorio_dir\");\n\tmemset(temp, 0, MAX_PATH + 1);\n\n\tif (target_path)\n\t{\n\t\tif (GetBinaryTypeA(target_path, &binary_type))\n\t\t{\n\t\t\t//Pick the path based on the target file's architecture\n\t\t\tif (binary_type == SCS_32BIT_BINARY)\n\t\t\t\tsnprintf(temp, MAX_PATH - 1, \"%s\\\\bin32\\\\\", base_path);\n\t\t\telse if (binary_type == SCS_64BIT_BINARY)\n\t\t\t\tsnprintf(temp, MAX_PATH - 1, \"%s\\\\bin64\\\\\", base_path);\n\n\t\t\t//Assign the default path\n\t\t\tif (binary_type == SCS_32BIT_BINARY || binary_type == SCS_64BIT_BINARY)\n\t\t\t\treturn temp;\n\t\t}\n\t}\n\n\t//Couldn't get the architecture from the target path\n\t//so just guess the dynamorio path that matches the current architecture\n#ifdef _M_X64\n\tsnprintf(temp, MAX_PATH - 1, \"%s\\\\bin64\\\\\", base_path);\n#else\n\tsnprintf(temp, MAX_PATH - 1, \"%s\\\\bin32\\\\\", base_path);\n#endif\n\treturn temp;\n}\n\n/**\n * This function populates the default_dynamorio_dir field of the state. It\n * searches the folders containing the fuzzer to find a dynamorio directory in\n * one of a few likely locations.\n * @param state - a pointer to the state to modify\n * @param target_path - char * containing the path to the binary being fuzzed,\n * or NULL if that option has not been provided to the fuzzer\n */\nstatic void pick_default_dynamorio_dir(dynamorio_state_t * state, char * target_path)\n{\n\tchar * path;\n\tsize_t pathlen;\n\n\tif (state->default_dynamorio_dir)\n\t\tfree(state->default_dynamorio_dir);\n\tstate->default_dynamorio_dir = NULL;\n\n\t//Try to autodetect the dynamorio directory\n\t// Usual location for binary distribution\n\tpath = filename_relative_to_binary_dir(\"..\\\\dynamorio\\\\bin32\\\\drrun.exe\");\n\tif (!path)\n\t{  // Usual location for 32-bit developer environment\n\t\tpath = filename_relative_to_binary_dir(\"..\\\\..\\\\..\\\\dynamorio\\\\bin32\\\\drrun.exe\");\n\t}\n\tif (!path)\n\t{  // Usual location for 64-bit developer environment\n\t\tpath = filename_relative_to_binary_dir(\"..\\\\..\\\\..\\\\..\\\\dynamorio\\\\bin64\\\\drrun.exe\");\n\t}\n\tif (!path)\n\t\treturn;\n\n\tpathlen = strlen(path);\n\tpath[pathlen - 16] = '\\0'; // Remove \"\\\\binXX\\\\drrun.exe\"\n\tstate->default_dynamorio_dir = add_architecture_to_path(path, target_path);\n\tfree(path);\n}\n\n/**\n * This function copies a dynamorio_state_t object, or allocates a new one with the default parameters.\n * @param original - The dynamorio_state_t object that should be copied.  If this parameter is NULL,\n * a new dynamorio_state_t is allocated with the default options.\n * @return - the newly allocated dynamorio_state_t object.\n */\nstatic dynamorio_state_t * copy_state(dynamorio_state_t * original)\n{\n\tsize_t i;\n\tdynamorio_state_t * ret = (dynamorio_state_t *)malloc(sizeof(dynamorio_state_t));\n\ttarget_module_t * target_module, *ret_target_module, *new_target_module;\n\tif (!ret)\n\t\treturn NULL;\n\tmemset(ret, 0, sizeof(dynamorio_state_t));\n\n\tif (!original)\n\t{ //No original passed in, just make the default one\n\t\tpick_default_dynamorio_dir(ret, NULL);\n\t\tret->default_winafl_dir = filename_relative_to_binary_dir(\".\");\n\t\tret->fuzz_iterations_max = 1;\n\t\tret->timeout = 1000; //1 second\n\t\tret->edges = 0;\n\t\tret->analyzed_last_round = 1;\n\t\treturn ret;\n\t}\n\t\n\t//Copy all the relevant options\n\tret->default_dynamorio_dir = strdup(original->default_dynamorio_dir);\n\tif (original->dynamorio_dir) ret->dynamorio_dir = strdup(original->dynamorio_dir);\n\tret->winafl_dir = strdup(original->winafl_dir);\n\tif (original->target_path) ret->target_path = strdup(original->target_path);\n\tif (original->dump_map_dir) ret->dump_map_dir = strdup(original->dump_map_dir);\n\tif (original->ignore_bytes_dir) ret->ignore_bytes_dir = strdup(original->ignore_bytes_dir);\n\tif (original->ignore_bytes_file) ret->ignore_bytes_file = strdup(original->ignore_bytes_file);\n\tret->per_module_coverage = original->per_module_coverage;\n\tret->fuzz_iterations_max = original->fuzz_iterations_max;\n\tif (original->client_params) ret->client_params = strdup(original->client_params);\n\tret->timeout = original->timeout;\n\tret->fuzz_iterations_current = original->fuzz_iterations_current;\n\tret->edges = original->edges;\n\n\tif (original->per_module_coverage)\n\t{\n\t\tret->num_modules = original->num_modules;\n\t\tret->module_names = (char **)malloc(ret->num_modules * sizeof(char *));\n\t\tfor (i = 0; i < ret->num_modules; i++)\n\t\t\tret->module_names[i] = strdup(original->module_names[i]);\n\n\t\tret_target_module = NULL;\n\t\tFOREACH_MODULE(target_module, original)\n\t\t{\n\t\t\tnew_target_module = (target_module_t *)malloc(sizeof(target_module_t));\n\t\t\tmemset(new_target_module, 0, sizeof(target_module_t));\n\t\t\tnew_target_module->index = target_module->index;\n\t\t\tmemcpy(new_target_module->virgin_bits, original->virgin_bits, MAP_SIZE);\n\t\t\tnew_target_module->last_shm_hash = target_module->last_shm_hash;\n\t\t\tnew_target_module->last_path_was_new = target_module->last_path_was_new;\n\t\t\tif (target_module->ignore_bytes)\n\t\t\t{\n\t\t\t\tnew_target_module->ignore_bytes = (u8 *)malloc(MAP_SIZE);\n\t\t\t\tmemcpy(new_target_module->ignore_bytes, target_module->ignore_bytes, MAP_SIZE);\n\t\t\t}\n\n\t\t\t//Add the new module to the linked list of modules\n\t\t\tif (ret_target_module)\n\t\t\t\tret->modules = new_target_module;\n\t\t\telse\n\t\t\t\tret_target_module->next = new_target_module;\n\t\t\tret_target_module = new_target_module;\n\t\t}\n\t}\n\telse\n\t{\n\t\tmemcpy(ret->virgin_bits, original->virgin_bits, MAP_SIZE);\n\t\tret->last_shm_hash = original->last_shm_hash;\n\t\tret->last_path_was_new = original->last_path_was_new;\n\t}\n\n\treturn ret;\n}\n\n/**\n * This function creates a dynamorio_state_t object based on the given options.\n * @param options - A JSON string of the options to set in the new dynamorio_state_t. See the\n * help function for more information on the specific options available.\n * @return the dynamorio_state_t generated from the options in the JSON options string, or NULL on failure\n */\nstatic dynamorio_state_t * setup_options(char * options)\n{\n\tdynamorio_state_t * state;\n\tsize_t i, length;\n\ttarget_module_t * target_module;\n\tchar * temp;\n\tchar buffer[MAX_PATH];\n\n\tstate = copy_state(NULL);\n\tif (!state)\n\t\treturn NULL;\n\n\t//Parse the options\n\tPARSE_OPTION_STRING(state, options, dynamorio_dir, \"dynamorio_dir\", dynamorio_cleanup);\n\tPARSE_OPTION_STRING(state, options, winafl_dir, \"winafl_dir\", dynamorio_cleanup);\n\tPARSE_OPTION_STRING(state, options, target_path, \"target_path\", dynamorio_cleanup);\n\tPARSE_OPTION_STRING(state, options, dump_map_dir, \"dump_map_dir\", dynamorio_cleanup);\n\tPARSE_OPTION_STRING(state, options, ignore_bytes_dir, \"ignore_bytes_dir\", dynamorio_cleanup);\n\tPARSE_OPTION_STRING(state, options, ignore_bytes_file, \"ignore_bytes_file\", dynamorio_cleanup);\n\tPARSE_OPTION_STRING(state, options, client_params, \"client_params\", dynamorio_cleanup);\n\tPARSE_OPTION_INT(state, options, fuzz_iterations_max, \"fuzz_iterations\", dynamorio_cleanup);\n\tPARSE_OPTION_INT(state, options, per_module_coverage, \"per_module_coverage\", dynamorio_cleanup);\n\tPARSE_OPTION_INT(state, options, timeout, \"timeout\", dynamorio_cleanup);\n\tPARSE_OPTION_ARRAY(state, options, module_names, num_modules, \"coverage_modules\", dynamorio_cleanup);\n\tPARSE_OPTION_INT(state, options, edges, \"edges\", dynamorio_cleanup);\n\n\tif (!state->num_modules && state->target_path) { //if the user didn't specify a module, we'll pick the executable itself by default\n\t\tstate->num_modules = 1;\n\t\tstate->module_names = malloc(sizeof(char *));\n\t\tlength = strlen(state->target_path) + 1;\n\t\tstate->module_names[0] = malloc(length);\n\t\tstrncpy(state->module_names[0], PathFindFileName(state->target_path), length);\n\t\tINFO_MSG(\"No Coverage Module selected, choosing the target executable \\\"%s\\\" by default.\", state->module_names[0]);\n\t}\n\n\tif (!state->num_modules)\n\t\tFATAL_MSG(\"No Coverage Module selected, please specify one with the coverage_modules option.\");\n\n\tif (state->target_path)\n\t{\n\t\tpick_default_dynamorio_dir(state, state->target_path);\n\t}\n\n\tif (state->dynamorio_dir) //if the user specified a dynamorio directory, use that. Otherwise use the default one\n\t{\n\t\ttemp = state->dynamorio_dir;\n\t\tstate->dynamorio_dir = add_architecture_to_path(temp, state->target_path);\n\t\tfree(temp);\n\t}\n\telse\n\t{\n\t\tif (state->default_dynamorio_dir)\n\t\t\tstate->dynamorio_dir = strdup(state->default_dynamorio_dir);\n\t\telse\n\t\t\tFATAL_MSG(\"Dynamorio was not found in the default location, and dynamorio_dir was not specified.\");\n\t}\n\n\tif (!state->winafl_dir) { //if the user didn't specify a winafl directory, try to automatically determine one\n\t\tstate->winafl_dir = add_architecture_to_path(state->default_winafl_dir, state->target_path);\n\t}\n\n\t//Verify winafl.dll exists\n\tsnprintf(buffer, sizeof(buffer) - 1, \"%s\\\\winafl.dll\", state->winafl_dir);\n\tif (access(buffer, 0))\n\t\tFATAL_MSG(\"Failed to find the winafl.dll in %s. Use the winafl_dir option to modify the directory to look for winafl.dll, and ensure that you have matching bitness (bin32 vs 64) between winafl.dll and the fuzz target.\", state->winafl_dir);\n\n\t//printf(\"Modules (%zu):\\n\", state->num_modules);\n\tfor (i = 0; i < state->num_modules; i++)\n\t{\n\t\t//printf(\"%d: %s\\n\", i, state->module_names[i]);\n\t\ttarget_module = (target_module_t *)malloc(sizeof(target_module_t));\n\t\tmemset(target_module, 0, sizeof(target_module_t));\n\t\ttarget_module->index = i;\n\t\ttarget_module->next = state->modules;\n\t\tstate->modules = target_module;\n\t}\n\t//printf(\"\\n\");\n\n\tgenerate_client_params(state);\n\tload_ignore_bytes(state);\n\treturn state;\n}\n\n/**\n * This function allocates and initializes a new instrumentation specific state object based on the given options.\n * @param options - a JSON string that contains the instrumentation specific string of options\n * @param state - an instrumentation specific JSON string previously returned from dynamorio_get_state that should be loaded\n * @return - An instrumentation specific state object on success or NULL on failure\n */\nvoid * dynamorio_create(char * options, char * state)\n{\n\tdynamorio_state_t * dynamorio_state;\n\n\tdynamorio_state = setup_options(options);\n\tif (!dynamorio_state)\n\t\treturn NULL;\n\n\tif (state && dynamorio_set_state(dynamorio_state, state))\n\t{\n\t\tdynamorio_cleanup(dynamorio_state);\n\t\treturn NULL;\n\t}\n\n\treturn dynamorio_state;\n}\n\n/**\n * This function cleans up all resources with the passed in instrumentation state.\n * @param instrumentation_state - an instrumentation specific state object previously created by the dynamorio_create function\n * This state object should not be referenced after this function returns.\n */\nvoid dynamorio_cleanup(void * instrumentation_state)\n{\n\ttarget_module_t * target_module, *next;\n\n\tdynamorio_state_t * state = (dynamorio_state_t *)instrumentation_state;\n\tdestroy_target_process(state, 0);\n\tremove_shm(state->trace_bits, state->shm_handle);\n\n\tfor (target_module = state->modules; target_module; )\n\t{\n\t\tnext = target_module->next;\n\t\tremove_shm(target_module->trace_bits, target_module->shm_handle);\n\t\tfree(state->ignore_bytes);\n\t\tfree(state->module_names[target_module->index]);\n\t\tfree(target_module);\n\t\ttarget_module = next;\n\t}\n\n\tif (state->pidfile) ck_free(state->pidfile);\n\tif (state->pipe_name) ck_free(state->pipe_name);\n\tif (state->fuzzer_id) ck_free(state->fuzzer_id);\n\tfree(state->default_dynamorio_dir);\n\tfree(state->dynamorio_dir);\n\tfree(state->default_winafl_dir);\n\tfree(state->winafl_dir);\n\tfree(state->target_path);\n\tfree(state->dump_map_dir);\n\tfree(state->client_params);\n\tfree(state->ignore_bytes_dir);\n\tfree(state->ignore_bytes_file);\n\tfree(state->module_names);\n\tfree(state->ignore_bytes);\n\tfree(state);\n}\n\n/**\n * This function merges the coverage information from two instrumentation states.\n * @param instrumentation_state - an instrumentation specific state object previously created by the dynamorio_create function\n * @param other_instrumentation_state - an instrumentation specific state object previously created by the dynamorio_create function\n * @return - An instrumentation specific state object that contains the combination of both of the passed in instrumentation states\n * on success, or NULL on failure\n */\nvoid * dynamorio_merge(void * instrumentation_state, void * other_instrumentation_state)\n{\n\ttarget_module_t * ret_module, * new_module;\n\tsize_t i, j;\n\tint found;\n\tdynamorio_state_t * ret;\n\tdynamorio_state_t * first = (dynamorio_state_t *)instrumentation_state;\n\tdynamorio_state_t * second = (dynamorio_state_t *)other_instrumentation_state;\n\n\t//Check that the instrumenation states are similar enough\n\tif (first->per_module_coverage != second->per_module_coverage\n\t\t|| first->num_modules != second->num_modules)\n\t\treturn NULL;\n\n\tfor (i = 0; i < first->num_modules; i++)\n\t{\n\t\tfound = 0;\n\t\tfor (j = 0; j < first->num_modules; j++)\n\t\t{\n\t\t\tif (!strcmp(first->module_names[i], second->module_names[j]))\n\t\t\t\tfound = 1;\n\t\t}\n\t\tif (!found)\n\t\t\treturn NULL;\n\t}\n\n\tret = copy_state(first);\n\tif (!ret)\n\t\treturn NULL;\n\n\tif (ret->per_module_coverage)\n\t{\n\t\tFOREACH_MODULE(ret_module, ret)\n\t\t{\n\t\t\tFOREACH_MODULE(new_module, second)\n\t\t\t{\n\t\t\t\tif (!strcmp(ret->module_names[ret_module->index], second->module_names[new_module->index]))\n\t\t\t\t{\n\t\t\t\t\tmerge_bitmaps(ret_module->virgin_bits, new_module->virgin_bits);\n\t\t\t\t\t//We don't really need to track these, they're not relevant for merged instrumentations\n\t\t\t\t\tret_module->last_path_was_new = ret_module->last_shm_hash = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\tmerge_bitmaps(ret->virgin_bits, second->virgin_bits);\n\t\tret->last_path_was_new = ret->last_shm_hash = 0;\n\t}\n\treturn ret;\n}\n\n/**\n * This function returns the state information holding the previous execution path info.  The returned value can later be passed to\n * dynamorio_create or dynamorio_set_state to load the state.\n * @param instrumentation_state - an instrumentation specific state object previously created by the dynamorio_create function\n * @return - A JSON string that holds the instrumentation specific state object information on success, or NULL on failure\n */\nchar * dynamorio_get_state(void * instrumentation_state)\n{\n\tdynamorio_state_t * state = (dynamorio_state_t *)instrumentation_state;\n\tjson_t *state_obj, *module_obj, *temp, *module_list;\n\ttarget_module_t * target_module;\n\tchar * ret;\n\n\tstate_obj = json_object();\n\tif (!state_obj)\n\t\treturn NULL;\n\n\tADD_INT(temp, state->last_process_status, state_obj, \"last_process_status\");\n\t\n\tif (!state->per_module_coverage)\n\t{\n\t\tADD_MEM(temp, (const char *)state->virgin_bits, MAP_SIZE, state_obj, \"virgin_bits\");\n\t\tADD_INT(temp, state->last_shm_hash, state_obj, \"last_shm_hash\");\n\t\tADD_INT(temp, state->last_path_was_new, state_obj, \"last_path_was_new\");\n\t}\n\telse\n\t{\n\t\tmodule_list = json_array();\n\t\tif (!module_list)\n\t\t\treturn NULL;\n\t\tFOREACH_MODULE(target_module, state)\n\t\t{\n\t\t\tmodule_obj = json_object();\n\t\t\tif (!module_obj)\n\t\t\t\treturn NULL;\n\t\t\tADD_STRING(temp, state->module_names[target_module->index], module_obj, \"name\");\n\t\t\tADD_MEM(temp, (const char *)target_module->virgin_bits, MAP_SIZE, module_obj, \"virgin_bits\");\n\t\t\tADD_INT(temp, target_module->last_shm_hash, module_obj, \"last_shm_hash\");\n\t\t\tADD_INT(temp, target_module->last_path_was_new, module_obj, \"last_path_was_new\");\n\t\t\tjson_array_append_new(module_list, module_obj);\n\t\t}\n\t\tjson_object_set_new(state_obj, \"modules\", module_list);\n\t}\n\n\tret = json_dumps(state_obj, 0);\n\tjson_decref(state_obj);\n\treturn ret;\n\n}\n\n/**\n * This function frees an instrumentation state previously obtained via dynamorio_get_state.\n * @param state - the instrumentation state to free\n */\nvoid dynamorio_free_state(char * state)\n{\n\tfree(state);\n}\n\n#define get_item(arg1, dest, temp, func, name, ret) \\\n\ttemp = func(arg1, name, &ret);                  \\\n\tif (ret <= 0)                                   \\\n\t\treturn 1;                                   \\\n\tdest = temp;\n\n#define get_virgin_bits(arg1, dest, temp, func, ret)   \\\n\ttemp = func(arg1, \"virgin_bits\", &ret);            \\\n\tif (ret <= 0)                                      \\\n\t\treturn 1;                                      \\\n\tmemcpy(dest, temp, MAP_SIZE);                      \\\n    free(temp);\n\n/**\n * This function sets the instrumentation state to the passed in state previously obtained via dynamorio_get_state.\n * @param instrumentation_state - an instrumentation specific state object previously created by the dynamorio_create function\n * @param state - an instrumentation state previously obtained via dynamorio_get_state\n * @return - 0 on success, non-zero on failure.\n */\nint dynamorio_set_state(void * instrumentation_state, char * state)\n{\n\tint result, inner_result, tempint, found;\n\tchar * tempstr;\n\tjson_t * module_obj;\n\ttarget_module_t * target_module;\n\tdynamorio_state_t * dynamorio_state = (dynamorio_state_t *)instrumentation_state;\n\n\tif (!state)\n\t\treturn 1;\n\n\t//If a child process is running when the state is being set\n\tdestroy_target_process(dynamorio_state, 0);//kill it so we don't orphan it\n\n\tget_item(state, dynamorio_state->last_process_status, tempint, get_int_options, \"last_process_status\", result);\n\tdynamorio_state->analyzed_last_round = 1;\n\n\tif (!dynamorio_state->per_module_coverage)\n\t{\n\t\tget_item(state, dynamorio_state->last_shm_hash, tempint, get_int_options, \"last_shm_hash\", result);\n\t\tget_item(state, dynamorio_state->last_path_was_new, tempint, get_int_options, \"last_path_was_new\", result);\n\t\tget_virgin_bits(state, dynamorio_state->virgin_bits, tempstr, get_mem_options, result);\n\t}\n\telse\n\t{\n\t\tFOREACH_OBJECT_JSON_ARRAY_ITEM_BEGIN(state, modules, \"modules\", module_obj, result)\n\n\t\t\ttempstr = get_string_options_from_json(module_obj, \"name\", &inner_result);\n\t\t\tif (inner_result <= 0)\n\t\t\t\treturn 1;\n\t\t\tfound = 0;\n\n\t\t\tFOREACH_MODULE(target_module, dynamorio_state)\n\t\t\t{\n\t\t\t\tif (!strcmp(dynamorio_state->module_names[target_module->index], tempstr))\n\t\t\t\t{\n\t\t\t\t\tget_item(module_obj, target_module->last_shm_hash, tempint, get_int_options_from_json, \"last_shm_hash\", inner_result);\n\t\t\t\t\tget_item(module_obj, target_module->last_path_was_new, tempint, get_int_options_from_json, \"last_path_was_new\", inner_result);\n\t\t\t\t\tget_virgin_bits(module_obj, target_module->virgin_bits, tempstr, get_mem_options_from_json, inner_result);\n\t\t\t\t\tfound = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfree(tempstr);\n\t\t\tif (!found)\n\t\t\t\treturn 1;\n\t\tFOREACH_OBJECT_JSON_ARRAY_ITEM_END(modules);\n\n\t\tif (result < 0)\n\t\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n/**\n * This function enables the instrumentation and runs the fuzzed process.  If the process needs to be restarted, it will be.\n * @param instrumentation_state - an instrumentation specific state object previously created by the dynamorio_create function\n * @process - a pointer to return a handle to the process that instrumentation was enabled on\n * @cmd_line - the command line of the fuzzed process to enable instrumentation on\n * @input - a buffer to the input that should be sent to the fuzzed process on stdin\n * @input_length - the length of the input parameter\n * returns 0 on success, -1 on failure\n */\nint dynamorio_enable(void * instrumentation_state, HANDLE * process, char * cmd_line, char * input, size_t input_length)\n{\n\tdynamorio_state_t * state = (dynamorio_state_t *)instrumentation_state;\n\tDWORD num_written;\n\ttarget_module_t * target_module;\n\n\tif (!state->fuzzer_id)\n\t{\n\t\tsetup_shm_and_pick_fuzzer_id(state, 1);\n\t\tstate->pipe_name = (char *)alloc_printf(\"\\\\\\\\.\\\\pipe\\\\afl_pipe_%s\", state->fuzzer_id);\n\t\tstate->pidfile = alloc_printf(\"childpid_%s.txt\", state->fuzzer_id);\n\t}\n\n\tif (!state->child_handle   //if we haven't started the child yet\n\t\t|| get_process_status(state->child_handle) == 0 //or the child died\n\t\t|| input_length != 0) //or the fuzzer wants to send input on stdin (which doesn't work with persistence mode)\n\t{\n\t\tif (state->child_handle)\n\t\t\tdestroy_target_process(state, 0);\n\t\tcreate_target_process(state, cmd_line, input, input_length);\n\t}\n\telse //the child is alive and we haven't cleaned up from last round\n\t\tfinish_fuzz_round(state);\n\n\t*process = state->child_handle;\n\n\t//Blank the map state\n\tif (state->per_module_coverage)\n\t{\n\t\tFOREACH_MODULE(target_module, state)\n\t\t\tmemset(state->edges ? (void *)target_module->edges_memory : target_module->trace_bits, 0, state->edges ? EDGES_SHM_SIZE : MAP_SIZE);\n\t}\n\telse\n\t\tmemset(state->edges ? (void *)state->edges_memory : state->trace_bits, 0, state->edges ? EDGES_SHM_SIZE : MAP_SIZE);\n\n\t//Tell the child instrumentation to go\n\tWriteFile(state->pipe_handle, \"F\", 1, &num_written, NULL);\n\tstate->analyzed_last_round = 0;\n\tstate->enable_called = 1;\n\n\treturn 0;\n}\n\n/**\n * This function determines if the last run had new coverage.\n * @param trace_bits - the edge bitmap of the most recent run\n * @parma virgin_bits - the edge bitmap of all edges previously seen\n * @param ignore_bytes - the edge bitmap of which bytes in the edge bitmap should be ignored\n * @param last_shm_hash - a pointer to a hash of the last run's trace_bits region.  This pointer will be\n * updated with the current run's trace_bits' hash.\n * @param dump_map_dir - This optional parameter will cause the trace_bits bitmap to be dumped to the directory\n * specified by this parameter.\n * @return - returns 1 if new edge was found or an edge's hit count changed, or 0 otherwise\n */\nstatic int has_new_coverage(u8 * trace_bits, u8 * virgin_bits, u8 * ignore_bytes, u32 * last_shm_hash, char * dump_map_dir)\n{\n\tu8 hnb;\n\tu32 hash, temp;\n\n#ifdef __x86_64__\n\tclassify_counts((u64*)trace_bits);\n#else\n\tclassify_counts((u32*)trace_bits);\n#endif // ^__x86_64__\n\n\t//A quick check of the last hash we saw to see if this output took the same path\n\t//Used to speed up the memory compare\n\tif (ignore_bytes)\n\t{\n\t\thash = hash32_with_ignore(trace_bits, ignore_bytes, MAP_SIZE, HASH_CONST);\n\t\ttemp = hash32(trace_bits, MAP_SIZE, HASH_CONST); //TODO REMOVE\n\t}\n\telse\n\t\ttemp = hash = hash32(trace_bits, MAP_SIZE, HASH_CONST);\n\n\tDEBUG_MSG(\"Dynamorio Instrumentation got hash %08x temp %08x (last hash %08x)\", hash, temp, *last_shm_hash);\n\tif (hash == *last_shm_hash)\n\t\treturn 0;\n\n\tif (dump_map_dir)\n\t{\t//Write out the hash bitmap for debugging purposes\n\t\tchar buffer[MAX_PATH];\n\t\tsnprintf(buffer, sizeof(buffer) - 1, \"%s\\\\%08x\", dump_map_dir, hash);\n\t\twrite_buffer_to_file(buffer, (char *)trace_bits, MAP_SIZE);\n\t}\n\n\t//We had a new path (or hash collision), record it to the virgin bits\n\t*last_shm_hash = hash;\n\tif (ignore_bytes)\n\t\thnb = has_new_bits_with_ignore(trace_bits, virgin_bits, ignore_bytes);\n\telse\n\t\thnb = has_new_bits(trace_bits, virgin_bits);\n\tDEBUG_MSG(\"has_new_bits = %hhu\", hnb);\n\treturn hnb != 0;\n}\n\n\n/**\n * This function determines if which of the target_modules being tracked have new edges hit from the most recent run.\n * This function should only be called when per_module_coverage is enabled.\n * @param state - a dynamorio_state_t object previously created by the dynamorio_create function\n * @return - returns 1 if new edge was found or an edge's hit count changed, or 0 otherwise\n */\nstatic int has_new_coverage_per_module(dynamorio_state_t * state)\n{\n\ttarget_module_t * target_module;\n\tint isnew, ret = 0;\n\tu32 last_hash;\n\n\tFOREACH_MODULE(target_module, state)\n\t{\n\t\tlast_hash = target_module->last_shm_hash;\n\t\tisnew = has_new_coverage(target_module->trace_bits, target_module->virgin_bits, target_module->ignore_bytes, &target_module->last_shm_hash, state->dump_map_dir);\n\t\tret |= isnew;\n\t\ttarget_module->last_path_was_new = isnew;\n\t\tif (isnew)\n\t\t\tDEBUG_MSG(\"Module %s has new bits (hash %08x, last hash %08x)\", state->module_names[target_module->index], target_module->last_shm_hash, last_hash);\n\t}\n\treturn ret != 0;\n}\n\n/**\n * This function determines whether the process being instrumented has taken a new path.  It should be\n * called after the process has finished processing the tested input.\n * @param instrumentation_state - an instrumentation specific state object previously created by the dynamorio_create function\n * @return - 1 if the previously setup process (via the enable function) took a new path, 0 if it did not, or -1 on failure.\n */\nint dynamorio_is_new_path(void * instrumentation_state)\n{\n\tdynamorio_state_t * state = (dynamorio_state_t *)instrumentation_state;\n\tif (!state->enable_called)\n\t\treturn -1;\n\treturn finish_fuzz_round(state);\n}\n\n/**\n * This function will return the result of the fuzz job. It should be called\n * after the process has finished processing the tested input.\n * @param instrumentation_state - an instrumentation specific structure previously created by the create() function\n * @return - either FUZZ_NONE, FUZZ_HANG, or FUZZ_CRASH, or -1 on error.\n */\nint dynamorio_get_fuzz_result(void * instrumentation_state)\n{\n\tdynamorio_state_t * state = (dynamorio_state_t *)instrumentation_state;\n\tif (!state->enable_called)\n\t\treturn -1;\n\tif (finish_fuzz_round(state) < 0)\n\t\treturn -1;\n\treturn state->last_process_status;\n}\n\n/**\n * This function returns information about each of the modules that the instrumentation is tracing.\n * @param instrumentation_state - an instrumentation specific state object previously created by the dynamorio_create function\n * @param index - an index into the module list for the module that information should be retrieved about.  The return value\n * will indicate if a module exists for this index.  Indices start at 0 and increase from there.\n * @param is_new - This parameter returns whether or not the last run of the instrumentation returned a new path for the module\n * with the specified index.  In order for the information returned in this parameter to be accurate, the is_new_path method should\n * be called first.  This parameter is optional and can be set to NULL.\n * @param module_name - This parameter returns the filename of the module at the specified index.  This parameter is optional and can\n * be set to NULL.  The value returned in this parameter should not be freed by the caller.\n * @param info - This parameter returns the an AFL style bitmap of the edges associated with the module at the specified index.  This\n * parameter is optional and can be set to NULL.  The value returned in this parameter should not be freed by the caller\n * @param size - This parameter returns the size of the AFL style bitmap of edges returned in the info parameter.  This parameter is\n * optional and can be set to NULL.\n * @return - 0 if the module with the specified index is found, non-zero on error or if the module is not found\n */\nint dynamorio_get_module_info(void * instrumentation_state, int index, int * is_new, char ** module_name, char ** info, int * size)\n{\n\tdynamorio_state_t * state = (dynamorio_state_t *)instrumentation_state;\n\ttarget_module_t * target_module;\n\n\tif (info || is_new) {\n\t\tif (!state->enable_called)\n\t\t\treturn -1;\n\t\tif (finish_fuzz_round(state) < 0)\n\t\t\treturn -1;\n\t}\n\n\tFOREACH_MODULE(target_module, state)\n\t{\n\t\tif (target_module->index == index)\n\t\t{\n\t\t\tif(is_new)\n\t\t\t\t*is_new = target_module->last_path_was_new;\n\t\t\tif(module_name)\n\t\t\t\t*module_name = state->module_names[index];\n\t\t\tif (info) {\n\t\t\t\tif (state->edges) //If they asked for edges, we don't have the trace info\n\t\t\t\t\t*info = NULL;\n\t\t\t\telse\n\t\t\t\t\t*info = (char *)target_module->trace_bits;\n\t\t\t}\n\t\t\tif(size)\n\t\t\t\t*size = MAP_SIZE;\n\t\t\treturn 0;\n\t\t}\n\t}\n\treturn 1;\n}\n\n/*\n * This function gets a list of the edges hit during the instrumented programs most recent run\n * @param instrumentation_state - an instrumentation specific state object previously created by the dynamorio_create function\n * @param index - The index of the module to retrieve the edges for.  This parameter is only needed if the per_module_coverage\n * option is enabled.\n * @return - a list of the edges hit during the instrumented programs most recent run, or NULL on error\n */\ninstrumentation_edges_t * dynamorio_get_edges(void * instrumentation_state, int index)\n{\n\tdynamorio_state_t * state = (dynamorio_state_t *)instrumentation_state;\n\ttarget_module_t * target_module;\n\n\tif (!state->enable_called)\n\t\treturn -1;\n\n\tif (!state->edges) //If they didn't ask for edges ahead of time, we don't have them\n\t\treturn NULL;\n\n\tif (finish_fuzz_round(state) == -1)\n\t\treturn NULL;\n\n\tif (!state->per_module_coverage)\n\t\treturn state->edges_memory;\n\n\tFOREACH_MODULE(target_module, state)\n\t{\n\t\tif (target_module->index == index)\n\t\t\treturn target_module->edges_memory;\n\t}\n\n\treturn NULL;\n}\n\n/**\n * This function returns help text for this instrumentation.  This help text will describe the instrumentation and any options\n * that can be passed to dynamorio_create.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nint dynamorio_help(char ** help_str)\n{\n\t*help_str = strdup(\n\"dynamorio - DynamoRIO instrumentation (based heavily on winafl)\\n\"\n\"Options:\\n\"\n\"  dynamorio_dir         Set the directory with DynamoRIO binaries in it\\n\"\n\"  winafl_dir            Set the directory with winafl.dll in it\\n\"\n\"  target_path           The path to the target program to fuzz\\n\"\n\"  dump_map_dir          Set the directory to dump the instrumentation bitmap\\n\"\n\"                          to, for debugging purposes\\n\"\n\"  ignore_bytes_dir      Set the directory to load ignore bit files from when\\n\"\n\"                          per_module_coverage is set (of the form\\n\"\n\"                          $ignore_bits_dir\\\\$dll_name.dll.dat).\\n\"\n\"  ignore_bytes_file     Set the file to load ignore bit files from when\\n\"\n\"                          per_module_coverage is not set.\\n\"\n\"  timeout               The number of milliseconds to wait when communicating\\n\"\n\"                          with the instrumentation in the target process\\n\"\n\"  client_params         Parameters to pass to the winafl.dll DynamoRIO tool\\n\"\n\"                          (Do not specify per_module_coverage,\\n\"\n\"                          fuzz_iterations, or coverage_modules here)\\n\"\n\"  fuzz_iterations       Maximum number of iterations for the target function\\n\"\n\"                          to run before restarting the target process\\n\"\n\"  coverage_modules      An array of modules that should be instrumented to\\n\"\n\"                          record coverage information\\n\"\n\"  per_module_coverage   Whether coverage should be tracked in one bitmap (0),\\n\"\n\"                          or in a separate bitmap for each module (1)\\n\"\n\"\\n\"\n\t);\n\tif (*help_str == NULL)\n\t\treturn -1;\n\treturn 0;\n}\n\n/**\n * This function will log information about the given instrumentation state to the logger.  It's mostly useful for debugging.\n * @param instrumentation_state - an instrumentation specific state object previously created by the dynamorio_create function\n */\nvoid dynamorio_print_state(void * instrumentation_state)\n{\n\tdynamorio_state_t * state = (dynamorio_state_t *)instrumentation_state;\n\ttarget_module_t * target_module;\n\n\tif (!state->per_module_coverage)\n\t\tINFO_MSG(\"DynamoRIO State: last_hash %08x (hash %08x) last_path_as_new %d\", state->last_shm_hash,\n\t\t\thash32(state->virgin_bits, MAP_SIZE, HASH_CONST), state->last_path_was_new);\n\telse\n\t{\n\t\tINFO_MSG(\"DynamoRIO State:\");\n\t\tFOREACH_MODULE(target_module, state)\n\t\t{\n\t\t\tINFO_MSG(\"module %s: last_hash %08x (hash %08x) last_path_as_new %d\", state->module_names[target_module->index],\n\t\t\t\ttarget_module->last_shm_hash, hash32(target_module->virgin_bits, MAP_SIZE, HASH_CONST), target_module->last_path_was_new);\n\t\t}\n\t}\n}\n\n\n\n\n"
  },
  {
    "path": "instrumentation/dynamorio_instrumentation.h",
    "content": "#pragma once\n\n#include <Windows.h>\n\n#include \"winafl_types.h\"\n#include \"winafl_config.h\"\n\nvoid * dynamorio_create(char * options, char * state);\nvoid dynamorio_cleanup(void * instrumentation_state);\nvoid * dynamorio_merge(void * instrumentation_state, void * other_instrumentation_state);\nchar * dynamorio_get_state(void * instrumentation_state);\nvoid dynamorio_free_state(char * state);\nint dynamorio_set_state(void * instrumentation_state, char * state);\nint dynamorio_enable(void * instrumentation_state, HANDLE * process, char * cmd_line, char * input, size_t input_length);\nint dynamorio_is_new_path(void * instrumentation_state);\nint dynamorio_get_module_info(void * instrumentation_state, int index, int * is_new, char ** module_name, char ** info, int * size);\ninstrumentation_edges_t * dynamorio_get_edges(void * instrumentation_state, int index);\nint dynamorio_is_process_done(void * instrumentation_state);\nint dynamorio_get_fuzz_result(void * instrumentation_state);\nint dynamorio_help(char ** help_str);\n\nvoid dynamorio_print_state(void * instrumentation_state);\n\n#define FOREACH_MODULE(x, state)  for(x = state->modules; x; x = x->next)\n\nstruct target_module\n{\n\tint index;\n\tHANDLE shm_handle;              /* Handle of the SHM region         */\n\tu8 * trace_bits;                /* SHM with instrumentation bitmap  */\n\tu8  virgin_bits[MAP_SIZE];      /* Regions yet untouched by fuzzing */\n\tu32 last_shm_hash;              /* The most recent hash of the SHM region */\n\tint last_path_was_new;\n\tu8 * ignore_bytes;\n\n\tinstrumentation_edges_t * edges_memory; /* SHM with list of edges */\n\t\n\tstruct target_module * next;\n};\ntypedef struct target_module target_module_t;\n\n\nstruct dynamorio_state\n{\n\t//Options\n\tchar * default_dynamorio_dir;\n\tchar * dynamorio_dir;\n\tchar * default_winafl_dir;\n\tchar * winafl_dir;\n\tchar * target_path;\n\tchar * dump_map_dir;\n\tchar * ignore_bytes_dir;\n\tchar * ignore_bytes_file;\n\tint per_module_coverage;\n\tint fuzz_iterations_max;\n\tchar * client_params;\n\tint timeout;\n\tint edges;\n\n\tHANDLE child_handle;             /* Handle to the child process      */\n\ts32 child_pid;                   /* PID of the fuzzed program        */\n\tHANDLE pipe_handle;              /* Handle of the comms named pipe   */\n\tHANDLE shm_handle;               /* Handle of the SHM region         */\n\n\tchar ** module_names;\n\tsize_t num_modules;\n\ttarget_module_t * modules;\n\n\tchar * pidfile;                 /* pid file name */\n\tchar * pipe_name;               /* name of the pipe to communicate with Dynamorio */\n\tint fuzz_iterations_current;\n\n\tu8  virgin_bits[MAP_SIZE];      /* Regions yet untouched by fuzzing */\n\n\tchar *fuzzer_id;                /* The fuzzer ID or a randomized\n\t\t\t\t\t\t\t\t       seed allowing multiple instances */\n\tu8 * trace_bits;                /* SHM with instrumentation bitmap  */\n\tu8 * ignore_bytes;\n\tu32 last_shm_hash;              /* The most recent hash of the SHM region */\n\tint last_path_was_new;\n\tint last_process_status;\n\tint analyzed_last_round;\n\tint enable_called;\n\n\tinstrumentation_edges_t * edges_memory; /* SHM with list of edges  */\n};\ntypedef struct dynamorio_state dynamorio_state_t;\n"
  },
  {
    "path": "instrumentation/forkserver.c",
    "content": "#define _GNU_SOURCE\n#include <signal.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/types.h>\n#include <sys/wait.h>\n#include <unistd.h>\n\n#include \"forkserver_internal.h\"\n\nstatic void forkserver_persistence_init(void);\n\n//////////////////////////////////////////////////////////////\n//Fork Server ////////////////////////////////////////////////\n//////////////////////////////////////////////////////////////\n\n//The fork server design was inspired by the LLVM mode of AFL. It however,\n//has been modified significantly to suit our purposes.  The LLVM mode of\n//AFL is available at:\n//https://github.com/mirrorer/afl/blob/master/llvm_mode/afl-llvm-rt.o.c#L95\n\nvoid __forkserver_init(void)\n{\n  int response = 0x41414141;\n  char command;\n  int child_pid = -1;\n  int target_pipe[2];\n\n  // Phone home and tell the parent that we're OK. If parent isn't there,\n  // assume we're not running in forkserver mode and just execute program.\n  if(write(FORKSRV_TO_FUZZER, &response, sizeof(int)) != sizeof(int))\n    return;\n\n  if(getenv(PERSIST_MAX_VAR)) {\n    forkserver_persistence_init();\n    return;\n  }\n\n  if(pipe(target_pipe))\n    _exit(1);\n\n  while (1) {\n\n    // Wait for parent by reading from the pipe. Exit if read fails.\n    if(read(FUZZER_TO_FORKSRV, &command, sizeof(command)) != sizeof(command))\n      _exit(1);\n\n    switch(command) {\n\n      case EXIT:\n        _exit(0);\n        break;\n\n      case FORK:\n      case FORK_RUN:\n\n        child_pid = fork();\n        if(child_pid < 0)\n          _exit(1);\n\n        //In child process: close fds, resume execution.\n        if(!child_pid) {\n          close(FUZZER_TO_FORKSRV);\n          close(FORKSRV_TO_FUZZER);\n          close(target_pipe[1]);\n\n          //If we're just forking, wait for the forkserver to tell us to go\n          if(command == FORK && read(target_pipe[0], &response, sizeof(int)) != sizeof(int))\n            _exit(1);\n\n          close(target_pipe[0]);\n          return;\n        }\n        response = child_pid;\n\n        break;\n\n      case RUN:\n        //Make sure the target process has started\n        if(child_pid == -1) {\n          response = FORKSERVER_ERROR;\n          break;\n        }\n        //Tell the target process to go\n        response = 0;\n        if(write(target_pipe[1], &response, sizeof(int)) != sizeof(int))\n          _exit(1);\n        break;\n\n      case GET_STATUS:\n        if(waitpid(child_pid, &response, 0) < 0)\n          _exit(1);\n        break;\n    }\n\n    if(write(FORKSRV_TO_FUZZER, &response, sizeof(int)) != sizeof(int))\n      _exit(1);\n  }\n}\n\n//////////////////////////////////////////////////////////////\n//Persistence Mode ///////////////////////////////////////////\n//////////////////////////////////////////////////////////////\n\nstatic int max_cnt = 0;\nstatic int cycle_cnt = 0;\nstatic int forkserver_cycle_cnt = 0;\n\nstatic void forkserver_persistence_init(void)\n{\n  int response = 0x41414141;\n  char command;\n  int child_pid = -1;\n\n  //Get the maximum number of persistent executions\n  max_cnt = atoi(getenv(PERSIST_MAX_VAR));\n  if(!max_cnt)\n    _exit(1);\n\n  while (1) {\n\n    // Wait for parent by reading from the pipe. Exit if read fails.\n    if(read(FUZZER_TO_FORKSRV, &command, sizeof(command)) != sizeof(command))\n      _exit(1);\n\n    switch(command) {\n\n      case EXIT:\n\n        if(child_pid != -1)\n          kill(child_pid, SIGKILL);\n        _exit(0);\n        break;\n\n      case FORK:\n      case FORK_RUN:\n\n        if(child_pid == -1 || forkserver_cycle_cnt == max_cnt) {\n\n          if(child_pid != -1 && forkserver_cycle_cnt == max_cnt) {\n            //if we've hit the maximum cycle count, continue the child, so it may exit\n            //and clean up.  We do this now, rather than in GET_STATUS commands, to ensure that\n            //the exit portion of the target process does not get traced.\n            kill(child_pid, SIGCONT);\n            if(waitpid(child_pid, &response, 0) < 0)\n              _exit(1);\n            forkserver_cycle_cnt = 0;\n          }\n\n          child_pid = fork();\n          if(child_pid < 0)\n            _exit(1);\n\n          //In child process: close fds, resume execution.\n          if(!child_pid) {\n            close(FUZZER_TO_FORKSRV);\n            close(FORKSRV_TO_FUZZER);\n            return;\n          }\n\n          if(waitpid(child_pid, &response, WUNTRACED) < 0 || !WIFSTOPPED(response)) {\n            //Failed to start the child, kill it and report failure\n            kill(child_pid, SIGKILL);\n            child_pid = -1;\n          }\n        }\n        response = child_pid;\n\n        if(command != FORK_RUN && response != -1) //If the command is FORK_RUN, fall into the RUN case\n          break;\n\n      case RUN:\n        //Tell the target process to go\n        if(child_pid == -1) {\n          response = FORKSERVER_ERROR;\n          break;\n        }\n        kill(child_pid, SIGCONT);\n        forkserver_cycle_cnt++;\n        if(command != FORK_RUN) //Don't overwrite the FORK case's response\n          response = 0;\n        break;\n\n      case GET_STATUS:\n\n        if(waitpid(child_pid, &response, WUNTRACED) < 0)\n          _exit(1);\n\n        if(WIFEXITED(response) || WIFSIGNALED(response)) { //The process ended, either\n          child_pid = -1; //by hitting the max_cnt count and exiting, or by crashing\n          forkserver_cycle_cnt = 0;\n        }\n        else if(WIFSTOPPED(response)) //If we hit a SIGSTOP, then the child didn't\n          response = 0;               //die, just return 0 to the parent\n\n        break;\n    }\n\n    if(write(FORKSRV_TO_FUZZER, &response, sizeof(response)) != sizeof(response))\n      _exit(1);\n  }\n}\n\nint __killerbeez_loop(void) {\n  raise(SIGSTOP);\n  return cycle_cnt++ != max_cnt;\n}\n\n"
  },
  {
    "path": "instrumentation/forkserver.h",
    "content": "#pragma once\n\n//Macros and fucntion definitions for use when instrumenting target programs\nint __killerbeez_loop(void);\n#define KILLERBEEZ_LOOP() __killerbeez_loop()\nvoid __forkserver_init(void);\n#define KILLERBEEZ_INIT() __forkserver_init()\n"
  },
  {
    "path": "instrumentation/forkserver_config.h",
    "content": "#pragma once\n//This header file controls the function that the forkserver hooks in order to\n//startup in the target process.  By modifying these marcos, the forkserver can\n//be made to start much later in the target process, allowing for reduced\n//startup code of each new process.\n\n//Whether to disable function hooking.  This should only be set if the target\n//program has been modified to explicitly call KILLERBEEZ_INIT().\n#define DISABLE_HOOKING 0\n\n//Whether we should hook __libc_start_main or not.  This is a default option\n//that should work for most Linux programs.\n#define USE_LIBC_START_MAIN 1\n\n//If we're not hooking __libc_start_main, this defines the function to hook\n#define CUSTOM_FUNCTION_NAME custom_function_to_hook\n\n//If we're not hooking __libc_start_main, this defines whether we should start\n//the forkserver before (1) or after (0) the function that we are hooking\n#define RUN_BEFORE_CUSTOM_FUNCTION 0\n"
  },
  {
    "path": "instrumentation/forkserver_hooking.c",
    "content": "#define _GNU_SOURCE\n#include <dlfcn.h>\n\n#include \"forkserver.h\"\n#include \"forkserver_config.h\"\n\n#if !DISABLE_HOOKING\n\n//////////////////////////////////////////////////////////////\n//Types, Function Prototypes, and Globals ////////////////////\n//////////////////////////////////////////////////////////////\n\n//In order to allow for the hooking of functions, regardless of their arguments, we define the hook\n//function as having a ton of void * arguments.  This allows us to pass these arguments on (regardless\n//of whether they actually exist or not).\ntypedef void * (*orig_function_type)(void *, void *, void *, void *, void *, void *, void *, void *);\n\n//Whether or not we've already started the forkserver\nstatic int init_done = 0;\n\n//A pointer to the original function that we hooked\nstatic orig_function_type orig_func = 0;\n\n//////////////////////////////////////////////////////////////\n//Function Hooking ///////////////////////////////////////////\n//////////////////////////////////////////////////////////////\n\n#ifdef __APPLE__\n\n//Define a fake prototype here, otherwise it will complain when it's used.\nvoid CUSTOM_FUNCTION_NAME(void);\n\n#define FUNCTION CUSTOM_FUNCTION_NAME\n#define NEW_FUNCTION new_##FUNCTION\n#define DYLD_INTERPOSE(_replacment,_replacee) \\\n  __attribute__((used)) static struct{ const void* replacment; const void* replacee; } _interpose_##_replacee \\\n__attribute__ ((section (\"__DATA,__interpose\"))) = { (const void*)(unsigned long)&_replacment, (const void*)(unsigned long)&_replacee };\n\n#else //LINUX\n\n#if USE_LIBC_START_MAIN\n#define FUNCTION __libc_start_main\n#else\n#define FUNCTION CUSTOM_FUNCTION_NAME\n#endif\n\n#define NEW_FUNCTION FUNCTION\n\n#endif\n\n//Convert FUNCTION into \"FUNCTION\" so we can use it to call dlsym\n#define STRINGIFY_INNER(s) (#s)\n#define STRINGIFY(name) STRINGIFY_INNER(name)\n#define FUNCTION_NAME STRINGIFY(FUNCTION)\n\n#if USE_LIBC_START_MAIN\nstatic orig_function_type orig_main = 0;\n\nvoid * fake_main(void * a0, void * a1, void * a2, void * a3, void * a4, void * a5, void * a6, void * a7)\n{\n  __forkserver_init();\n  return orig_main(a0, a1, a2, a3, a4, a5, a6, a7);\n}\n#endif\n\nvoid * NEW_FUNCTION(void * a0, void * a1, void * a2, void * a3, void * a4, void * a5, void * a6, void * a7)\n{\n  void * ret;\n\n  if(orig_func == 0)\n    orig_func = (orig_function_type)dlsym(RTLD_NEXT, FUNCTION_NAME);\n\n#if USE_LIBC_START_MAIN //we're hooking __libc_start_main\n\n  orig_main = a0;\n  ret = orig_func((void *)fake_main, a1, a2, a3, a4, a5, a6, a7);\n\n#else //We're hooking a custom function\n\n#if RUN_BEFORE_CUSTOM_FUNCTION //If we want to run before the hooked function\n  if(!init_done) {\n    __forkserver_init();\n    init_done = 1;\n  }\n#endif\n\n  ret = orig_func(a0, a1, a2, a3, a4, a5, a6, a7);\n\n#if !RUN_BEFORE_CUSTOM_FUNCTION //If we want to run after the hooked function\n  if(!init_done) {\n    __forkserver_init();\n    init_done = 1;\n  }\n#endif\n\n#endif\n\n  return ret;\n}\n\n#ifdef __APPLE__\nDYLD_INTERPOSE(NEW_FUNCTION, FUNCTION)\n#endif\n\n#endif //!DISABLE_HOOKING\n"
  },
  {
    "path": "instrumentation/forkserver_internal.h",
    "content": "#pragma once\n\n#define PERSIST_MAX_VAR \"PERSISTENCE_MAX_CNT\"\n#define DEFER_ENV_VAR   \"DEFER_ENV_VAR\"\n\n//Designated file descriptors for read/write to the forkserver\n//and target process\n#define FUZZER_TO_FORKSRV   198\n#define FORKSRV_TO_FUZZER   199\n#define QEMU_TSL_FD         200\n#define MAX_FORKSRV_FD      201\n\n//Commands that the fuzzer can send to the forkserver\n#define EXIT       0\n#define FORK       1\n#define RUN        2\n#define FORK_RUN   3\n#define GET_STATUS 4\n\n//Possible response codes returned from the forkserver\n#define FORKSERVER_ERROR -1\n#define FORKSERVER_NO_RESULTS_READY -2\n\nstruct forkserver {\n  int fuzzer_to_forksrv;\n  int forksrv_to_fuzzer;\n  int target_stdin;\n  int sent_get_status;\n  int last_status;\n  int pid;\n};\ntypedef struct forkserver forkserver_t;\n\n//These functions control all interactions with the forkserver, sending the\n//commands listed above\nvoid fork_server_init(forkserver_t * fs, char * target_path, char ** argv, int use_forkserver_library,\n  int persistence_max_cnt, int needs_stdin_fd);\nint fork_server_exit(forkserver_t * fs);\nint fork_server_fork(forkserver_t * fs);\nint fork_server_fork_run(forkserver_t * fs);\nint fork_server_run(forkserver_t * fs);\nint fork_server_get_status(forkserver_t * fs, int wait);\nint fork_server_get_pending_status(forkserver_t * fs, int wait);\n\n"
  },
  {
    "path": "instrumentation/instrumentation.c",
    "content": "#ifndef _WIN32\n//Headers necessary for the forkserver\n#include <errno.h>\n#include <fcntl.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/ioctl.h>\n#include <sys/resource.h>\n#include <sys/stat.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <sys/wait.h>\n#include <unistd.h>\n#include <signal.h>\n#endif\n\n#include \"instrumentation.h\"\n#include <utils.h>\n\n\n#ifndef _WIN32\n//The forkserver is not supported on Windows\n\n#include \"forkserver_internal.h\"\n\n#define STRINGIFY_INTERNAL(x) #x\n#define STRINGIFY(x) STRINGIFY_INTERNAL(x)\n#define MSAN_ERROR 86\n\n//The amount of time to wait before considering the fork server initialization failed\n#define FORK_SERVER_STARTUP_TIME 10\n\n//Save a fd to the /dev/null, so we don't have to keep opening/closing it\nstatic int dev_null_fd =  -1;\n\n//TODO implement memory limiting\nstatic int mem_limit = 0;\n\n//TODO asan detection\nstatic int uses_asan = 0;\n\n/**\n * This function locates the fork server library\n * @param buffer - A buffer to return the path to the fork server library\n * @param buffer_len - The length of the buffer parameter\n */\nstatic void find_fork_server_library(char * buffer, size_t buffer_len)\n{\n#ifdef __APPLE__\n  char * library_name = \"libforkserver.dylib\";\n#else\n  char * library_name = \"libforkserver.so\";\n#endif\n\n  char * directory = filename_relative_to_binary_dir(\".\");\n  snprintf(buffer, buffer_len, \"%s/%s\", directory, library_name);\n  if (!file_exists(buffer))\n    FATAL_MSG(\"Failed to find the %s in %s.\", library_name, directory);\n}\n\n//////////////////////////////////////////////////////////////\n// Fork Server Initialization ////////////////////////////////\n//////////////////////////////////////////////////////////////\n/**\n *\n * @param needs_stdin_fd - whether we should open a library for the stdin of\n *                         the newly created process\n * @param target_path - The path to the program to start\n * @param argv - Arguments to pass to the program\n * @param fs - A forkserver_t structure to hold the fork server state, or NULL\n *             if not using a fork server\n * @param use_forkserver_library - Whether or not to use\n *                                 LD_PRELOAD/DYLD_INSERT_LIBRARIES to inject\n *                                 the fork server\n * @param st_pipe - pointer to an array of two status pipes for the fork server\n * @param ctl_pipe - pointer to an array of two control pipes for the fork server\n * @param persistence_max_cnt - if fork server is in use, and perssistent mode\n *                              is in use, this is the number of inputs which\n *                              will be handled by each execution of the target\n * @return the process ID of spawned process\n */\nstatic pid_t run_target(int needs_stdin_fd, char *target_path, char **argv,\n                forkserver_t * fs, int use_forkserver_library, int *st_pipe,\n                int *ctl_pipe, int persistence_max_cnt) {\n/*\n  This function is based on the AFL run_target function present in afl-fuzz.c,\n  available at this URL:\n  https://github.com/mirrorer/afl/blob/master/afl-fuzz.c#L1968.\n  AFL's license is as shown below:\n\n  american fuzzy lop - fuzzer code\n  --------------------------------\n  Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n  Forkserver design by Jann Horn <jannhorn@googlemail.com>\n\n  Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at:\n\n    http://www.apache.org/licenses/LICENSE-2.0\n */\n  int child_pid;\n\n  DEBUG_MSG(\"Forking child process for target executable...\");\n  child_pid = fork();\n  if(child_pid < 0) FATAL_MSG(\"fork() failed\");\n\n  DEBUG_MSG(\"Fork succeeded, child pid: %d\", child_pid);\n  if(!child_pid) {\n    struct rlimit r;\n\n    // Umpf. On OpenBSD, the default fd limit for root users is set to\n    // soft 128. Let's try to fix that...\n    if (!getrlimit(RLIMIT_NOFILE, &r) && r.rlim_cur < MAX_FORKSRV_FD) {\n      r.rlim_cur = MAX_FORKSRV_FD;\n      setrlimit(RLIMIT_NOFILE, &r); // Ignore errors\n    }\n\n    if (mem_limit) {\n      r.rlim_max = r.rlim_cur = ((rlim_t)mem_limit) << 20;\n#ifdef RLIMIT_AS\n      setrlimit(RLIMIT_AS, &r); // Ignore errors\n#else\n      // This takes care of OpenBSD, which doesn't have RLIMIT_AS, but\n      // according to reliable sources, RLIMIT_DATA covers anonymous\n      // maps - so we should be getting good protection against OOM bugs.\n      setrlimit(RLIMIT_DATA, &r); // Ignore errors\n#endif // ^RLIMIT_AS\n      DEBUG_MSG(\"Set memory limits\");\n    }\n\n    // Dumping cores is slow and can lead to anomalies if SIGKILL is delivered\n    // before the dump is complete.\n\n    r.rlim_max = r.rlim_cur = 0;\n\n    setrlimit(RLIMIT_CORE, &r); // Ignore errors\n\n    /* Isolate the process and configure standard descriptors. If out_file is\n         specified, stdin is /dev/null; otherwise, out_fd is cloned instead. */\n    setsid();\n\n    if(dev_null_fd < 0)\n      dev_null_fd = open(\"/dev/null\", O_RDWR);\n    if(needs_stdin_fd) {\n      dup2(fs->target_stdin, 0);\n      close(fs->target_stdin);\n    } else {\n      dup2(dev_null_fd, 0);\n    }\n    DEBUG_MSG(\"About to send stdout to /dev/null\");\n    if(dup2(dev_null_fd, 1) < 0)\n      WARNING_MSG(\"Sending stdout to /dev/null failed! errno=%d\", errno);\n    DEBUG_MSG(\"About to send stderr to /dev/null\");\n    if(dup2(dev_null_fd, 2) < 0)\n      WARNING_MSG(\"Sending stderr to /dev/null failed! errno=%d\", errno);\n    DEBUG_MSG(\"Child is still alive and well!\");\n\n    // The forkserver requires setting up some control pipes for interaction\n    // between the fuzzer and forkserver (which lives in the target process)\n    if(fs) {\n      DEBUG_MSG(\"Setting up pipes for forkserver...\");\n      // Set up control and status pipes, close the unneeded original fds.\n      if(dup2(ctl_pipe[0], FUZZER_TO_FORKSRV) < 0)\n        FATAL_MSG(\"dup2() failed\");\n      if(dup2(st_pipe[1], FORKSRV_TO_FUZZER) < 0)\n        FATAL_MSG(\"dup2() failed\");\n      DEBUG_MSG(\"Forkserver pipes set up\");\n\n      close(ctl_pipe[0]);\n      close(ctl_pipe[1]);\n      close(st_pipe[0]);\n      close(st_pipe[1]);\n      DEBUG_MSG(\"Extra pipes closed\");\n    }\n\n    /* On Linux, would be faster to use O_CLOEXEC. Maybe TODO. */\n    close(dev_null_fd);\n    DEBUG_MSG(\"Setting up pipes is complete...\");\n\n    // If we are using a forksrv, we might need to inject it dynamically if it\n    // is not already in the executable.  We also want to make sure we set the\n    // environment variable which is used for persistence mode, and finally we\n    // add the optimization to load all the libraries once so this is only\n    // done on the execv, as opposed to each time the target process calls fork\n    if(fs) {\n      // Preload the forkserver library\n      if(use_forkserver_library) {\n        char fork_server_library_path[MAX_PATH];\n        find_fork_server_library(fork_server_library_path, sizeof(fork_server_library_path));\n  #ifdef __APPLE__\n        setenv(\"DYLD_INSERT_LIBRARIES\", fork_server_library_path, 1);\n  #else\n        setenv(\"LD_PRELOAD\", fork_server_library_path, 1);\n  #endif\n      }\n\n      if(persistence_max_cnt) {\n        char buffer[16];\n        snprintf(buffer, sizeof(buffer),\"%d\",persistence_max_cnt);\n        setenv(PERSIST_MAX_VAR, buffer, 1);\n      }\n\n      // This should improve performance a bit, since it stops the linker from\n      // doing extra work post-fork().\n      if (!getenv(\"LD_BIND_LAZY\")) setenv(\"LD_BIND_NOW\", \"1\", 0);\n    }\n\n    // Set sane defaults for ASAN if nothing else specified.\n    setenv(\"ASAN_OPTIONS\", \"abort_on_error=1:\"\n                           \"detect_leaks=0:\"\n                           \"symbolize=0:\"\n                           \"allocator_may_return_null=1\", 0);\n\n    // MSAN uses slightly different arguments when using the forkserver\n    if(fs) {\n      // MSAN is tricky, because it doesn't support abort_on_error=1 at this\n      // point. So, we do this in a very hacky way.\n      setenv(\"MSAN_OPTIONS\", \"exit_code=\" STRINGIFY(MSAN_ERROR) \":\"\n                             \"symbolize=0:\"\n                             \"abort_on_error=1:\"\n                             \"allocator_may_return_null=1:\"\n                             \"msan_track_origins=0\", 0);\n    } else {\n      setenv(\"MSAN_OPTIONS\", \"exit_code=\" STRINGIFY(MSAN_ERROR) \":\"\n                             \"symbolize=0:\"\n                             \"msan_track_origins=0\", 0);\n    }\n\n    DEBUG_MSG(\"Setup done, about to execv: %s\", target_path);\n    execv(target_path, argv);\n    // The only time execv() returns is if it failed\n    FATAL_MSG(\"Target executable failed to execute (execv())\");\n    exit(1);\n  }\n\n  return child_pid;\n}\n\n/**\n * This function starts a program with the fork server embedded in it\n * @param fs - A forkserver_t structure to hold the fork server state\n * @param target_path - The path to the program to start\n * @param argv - Arguments to pass to the program\n * @param use_forkserver_library - Whether or not to use LD_PRELOAD/DYLD_INSERT_LIBRARIES to inject the fork server\n * library or not\n * @param persistence_max_cnt - the maximum number of fuzz iterations a persistence mode process should run\n * @param needs_stdin_fd - whether we should open a library for the stdin of the newly created process\n */\nvoid fork_server_init(forkserver_t * fs, char * target_path, char ** argv, int use_forkserver_library,\n  int persistence_max_cnt, int needs_stdin_fd)\n{\n  static struct itimerval it;\n  int st_pipe[2], ctl_pipe[2];\n  int err, status, forksrv_pid;\n  int rlen = -1, timed_out = 1;\n  char stdin_filename[100];\n  time_t start_time;\n\n  if(dev_null_fd < 0) {\n    dev_null_fd = open(\"/dev/null\", O_RDWR);\n    if (dev_null_fd < 0)\n      FATAL_MSG(\"Unable to open /dev/null\");\n  }\n\n  fs->sent_get_status = 0;\n  fs->last_status = -1;\n\n  if(needs_stdin_fd) {\n    strncpy(stdin_filename, \"/tmp/fuzzfileXXXXXX\", sizeof(stdin_filename));\n    fs->target_stdin = mkstemp(stdin_filename);\n    if(fs->target_stdin < 0)\n      FATAL_MSG(\"Couldn't make temp file\\n\");\n  }\n  else\n    fs->target_stdin = -1;\n\n  DEBUG_MSG(\"Spinning up the fork server...\");\n\n/*\n  The code in the rest of this function is based on the AFL startup fork server\n  present in afl-fuzz.c, available at this URL:\n  https://github.com/mirrorer/afl/blob/master/afl-fuzz.c#L1968.\n  AFL's license is as shown below:\n\n  american fuzzy lop - fuzzer code\n  --------------------------------\n  Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n  Forkserver design by Jann Horn <jannhorn@googlemail.com>\n\n  Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at:\n\n    http://www.apache.org/licenses/LICENSE-2.0\n */\n  if(pipe(st_pipe) || pipe(ctl_pipe))\n    FATAL_MSG(\"pipe() failed\");\n\n  forksrv_pid = run_target(needs_stdin_fd, target_path, argv, fs, use_forkserver_library,\n             st_pipe, ctl_pipe, persistence_max_cnt);\n\n  // Close the unneeded endpoints.\n  close(ctl_pipe[0]);\n  close(st_pipe[1]);\n\n  fs->fuzzer_to_forksrv = ctl_pipe[1];\n  fs->forksrv_to_fuzzer = st_pipe[0];\n  fs->pid = forksrv_pid;\n\n  // Wait for the fork server to come up, but don't wait too long.\n  // Note, we do this looping, rather than blocking on read and using\n  // a SIGALRM to breakout on time out, because we want to avoid globals\n  // so the code can be used without worrying about any existing signal handlers\n  start_time = time(NULL);\n  while(time(NULL) - start_time < FORK_SERVER_STARTUP_TIME) {\n    err = ioctl(fs->forksrv_to_fuzzer, FIONREAD, &rlen);\n    if(!err && rlen == sizeof(int)) {\n      rlen = read(fs->forksrv_to_fuzzer, &status, sizeof(status));\n      timed_out = 0;\n      break;\n    }\n    usleep(5);\n  }\n\n  // If we have a four-byte \"hello\" message from the server, we're all set.\n  // Otherwise, try to figure out what went wrong.\n  if (rlen == 4) {\n    DEBUG_MSG(\"All right - fork server (PID %d) is up.\", forksrv_pid);\n    return;\n  }\n\n  kill(forksrv_pid, SIGKILL);\n  if(timed_out)\n    FATAL_MSG(\"Timeout while initializing fork server\\n\");\n\n  if (waitpid(forksrv_pid, &status, 0) <= 0)\n    FATAL_MSG(\"waitpid() failed\");\n\n  if (WIFSIGNALED(status)) {\n\n    if (mem_limit && mem_limit < 500 && uses_asan) {\n\n      ERROR_MSG(\n           \"Whoops, the target binary crashed suddenly, before receiving any input\\n\"\n           \"    from the fuzzer! Since it seems to be built with ASAN and you have a\\n\"\n           \"    restrictive memory limit configured, this is expected\");\n\n    } else if (!mem_limit) {\n\n      ERROR_MSG(\n           \"Whoops, the target binary crashed suddenly, before receiving any input\\n\"\n           \"    from the fuzzer! There are several probable explanations:\\n\\n\"\n\n           \"    - The binary is just buggy and explodes entirely on its own. If so, you\\n\"\n           \"      need to fix the underlying problem or find a better replacement.\\n\\n\"\n\n#ifdef __APPLE__\n\n           \"    - On MacOS X, the semantics of fork() syscalls are non-standard and may\\n\"\n           \"      break afl-fuzz performance optimizations when running platform-specific\\n\"\n           \"      targets. To fix this, try running without the forkserver.\\n\\n\"\n\n#endif // __APPLE__\n\n           \"    - Less likely, there is a horrible bug in the fuzzer.\");\n\n    } else {\n\n      ERROR_MSG(\n           \"Whoops, the target binary crashed suddenly, before receiving any input\\n\"\n           \"    from the fuzzer! There are several probable explanations:\\n\\n\"\n\n           \"    - The current memory limit (%s) is too restrictive, causing the\\n\"\n           \"      target to hit an OOM condition in the dynamic linker. Try bumping up\\n\"\n           \"      the limit with the -m setting in the command line. A simple way confirm\\n\"\n           \"      this diagnosis would be:\\n\\n\"\n\n#ifdef RLIMIT_AS\n           \"      ( ulimit -Sv $[%llu << 10]; /path/to/fuzzed_app )\\n\\n\"\n#else\n           \"      ( ulimit -Sd $[%llu << 10]; /path/to/fuzzed_app )\\n\\n\"\n#endif // ^RLIMIT_AS\n\n           \"      Tip: you can use http://jwilk.net/software/recidivm to quickly\\n\"\n           \"      estimate the required amount of virtual memory for the binary.\\n\\n\"\n\n           \"    - The binary is just buggy and explodes entirely on its own. If so, you\\n\"\n           \"      need to fix the underlying problem or find a better replacement.\\n\\n\"\n\n#ifdef __APPLE__\n\n           \"    - On MacOS X, the semantics of fork() syscalls are non-standard and may\\n\"\n           \"      break afl-fuzz performance optimizations when running platform-specific\\n\"\n           \"      targets. To fix this, try running without the forkserver.\\n\\n\"\n\n#endif // __APPLE__\n\n           \"    - Less likely, there is a horrible bug in the fuzzer.\",\n           mem_limit << 20, mem_limit - 1);\n\n    }\n\n    FATAL_MSG(\"Fork server crashed with signal %d\", WTERMSIG(status));\n\n  }\n\n  if (mem_limit && mem_limit < 500 && uses_asan) {\n\n    ERROR_MSG(\n           \"Hmm, looks like the target binary terminated before we could complete a\\n\"\n           \"    handshake with the injected code. Since it seems to be built with ASAN and\\n\"\n           \"    you have a restrictive memory limit configured, this is expected.\");\n\n  } else if (!mem_limit) {\n\n    ERROR_MSG(\n         \"Hmm, looks like the target binary terminated before we could complete a\\n\"\n         \"    handshake with the injected code. Perhaps there is a horrible bug in the\\n\"\n         \"    fuzzer.\");\n\n  } else {\n\n    ERROR_MSG(\n         \"Hmm, looks like the target binary terminated before we could complete a\\n\"\n         \"    handshake with the injected code. There are a few probable explanations:\\n\\n\"\n\n         \"    - The current memory limit (%s) is too restrictive, causing an OOM\\n\"\n         \"      fault in the dynamic linker. This can be fixed with the -m option. A\\n\"\n         \"      simple way to confirm the diagnosis may be:\\n\\n\"\n\n#ifdef RLIMIT_AS\n         \"      ( ulimit -Sv $[%llu << 10]; /path/to/fuzzed_app )\\n\\n\"\n#else\n         \"      ( ulimit -Sd $[%llu << 10]; /path/to/fuzzed_app )\\n\\n\"\n#endif // ^RLIMIT_AS\n\n         \"      Tip: you can use http://jwilk.net/software/recidivm to quickly\\n\"\n         \"      estimate the required amount of virtual memory for the binary.\\n\\n\"\n\n         \"    - Less likely, there is a horrible bug in the fuzzer. If other options\\n\"\n         \"      fail.\",\n         mem_limit << 20, mem_limit - 1);\n\n  }\n\n  FATAL_MSG(\"Fork server handshake failed\");\n}\n\n//////////////////////////////////////////////////////////////\n// Fork Server Communication Functions ///////////////////////\n//////////////////////////////////////////////////////////////\n\n/**\n * This function sends a command to the fork server\n * @param fs - A forkserver_t structure to hold the fork server state\n * @param command - the command to send\n * @return - 0 on success, FORKSERVER_ERROR on failure\n */\nstatic int send_command(forkserver_t * fs, char command)\n{\n  if (write(fs->fuzzer_to_forksrv, &command, sizeof(command)) != sizeof(command))\n    return FORKSERVER_ERROR;\n  return 0;\n}\n\n/**\n * This function reads a response from the fork server\n * @param fs - A forkserver_t structure to hold the fork server state\n * @return - the response value on success, FORKSERVER_ERROR on failure\n */\nstatic int read_response(forkserver_t * fs)\n{\n  int response;\n  if (read(fs->forksrv_to_fuzzer, &response, sizeof(response)) != sizeof(response))\n    return FORKSERVER_ERROR;\n  return response;\n}\n\n/**\n * This function tells the forkserver to exit, and closes any open file descriptors to it\n * @param fs - A forkserver_t structure to hold the fork server state\n * @return - the 0 on success, FORKSERVER_ERROR on failure\n */\nint fork_server_exit(forkserver_t * fs)\n{\n  int ret = send_command(fs, EXIT);\n  if(!ret) {\n    close(fs->fuzzer_to_forksrv);\n    close(fs->forksrv_to_fuzzer);\n    close(fs->target_stdin);\n  }\n  return ret;\n}\n\n/**\n * This function tells the forkserver to fork or fork and run, and returns the newly created process's pid\n * @param fs - A forkserver_t structure to hold the fork server state\n * @param command - Either the FORK or FORK_RUN command\n * @return - the newly created process's pid on success, FORKSERVER_ERROR on failure\n */\nstatic int send_fork(forkserver_t * fs, char command)\n{\n  if(send_command(fs, command))\n    return FORKSERVER_ERROR;\n  fs->sent_get_status = 0;\n  return read_response(fs); //Wait for the target pid\n}\n\n/**\n * This function tells the forkserver to fork, and returns the newly created process's pid\n * @param fs - A forkserver_t structure to hold the fork server state\n * @return - the newly created process's pid on success, FORKSERVER_ERROR on failure\n */\nint fork_server_fork(forkserver_t * fs)\n{\n  return send_fork(fs, FORK);\n}\n\n/**\n * This function tells the forkserver to fork and run, and returns the newly created process's pid\n * @param fs - A forkserver_t structure to hold the fork server state\n * @return - the newly created process's pid on success, FORKSERVER_ERROR on failure\n */\nint fork_server_fork_run(forkserver_t * fs)\n{\n  return send_fork(fs, FORK_RUN);\n}\n\n/**\n * This function tells the forkserver to run\n * @param fs - A forkserver_t structure to hold the fork server state\n * @return - 0 on success, FORKSERVER_ERROR on failure\n */\nint fork_server_run(forkserver_t * fs)\n{\n  if(send_command(fs, RUN))\n    return FORKSERVER_ERROR;\n  if(read_response(fs) != 0)\n    return FORKSERVER_ERROR;\n  return 0;\n}\n\n/**\n * This function gets the response of prevously sent GET_STATUS command from the fork server (i.e. the process's exit status)\n * @param fs - A forkserver_t structure to hold the fork server state\n * @param wait - whether this function should block or not\n * @return - the finished process's exit status (see waitpid) on success, FORKSERVER_ERROR on failure, or\n * FORKSERVER_NO_RESULTS_READY when not blocking and the forkserver has not responded yet\n */\nint fork_server_get_pending_status(forkserver_t * fs, int wait)\n{\n  unsigned long bytes_available = 0;\n  int err;\n\n  if(fs->sent_get_status && fs->last_status != -1)\n    return fs->last_status;\n\n  if(wait)\n    return read_response(fs); //Wait for the target's exit status\n  else {\n    err = ioctl(fs->forksrv_to_fuzzer, FIONREAD, &bytes_available);\n    if(!err && bytes_available == sizeof(int)) {\n      fs->last_status = read_response(fs); //Wait for the target's exit status\n      return fs->last_status;\n    }\n  }\n  return FORKSERVER_NO_RESULTS_READY;\n}\n\n/**\n * This function sends a GET_STATUS command to the fork server and gets the response (i.e. the process's exit status)\n * @param fs - A forkserver_t structure to hold the fork server state\n * @param wait - whether this function should block or not\n * @return - the finished process's exit status (see waitpid) on success, FORKSERVER_ERROR on failure, or\n * FORKSERVER_NO_RESULTS_READY when not blocking and the forkserver has not responded yet\n */\nint fork_server_get_status(forkserver_t * fs, int wait)\n{\n  if(!fs->sent_get_status) {\n    if(send_command(fs, GET_STATUS))\n      return FORKSERVER_ERROR;\n    fs->sent_get_status = 1;\n    fs->last_status = -1;\n  }\n  return fork_server_get_pending_status(fs, wait);\n}\n\n#endif //!_WIN32\n"
  },
  {
    "path": "instrumentation/instrumentation.h",
    "content": "#pragma once\n\n#include <stdint.h>\n#include <stdlib.h>\n#ifdef _WIN32\n#include <Windows.h> // HANDLE\n#endif\n\n#ifdef INSTRUMENTATION_EXPORTS\n#define INSTRUMENTATION_API __declspec(dllexport)\n#elif defined(INSTRUMENTATION_NO_IMPORT)\n#define INSTRUMENTATION_API\n#else\n#define INSTRUMENTATION_API __declspec(dllimport)\n#endif\n\nstruct instrumentation_edge\n{\n#ifdef _M_X64\n\tuint64_t from;\n\tuint64_t to;\n#else\n\tuint32_t from;\n\tuint32_t to;\n#endif\n};\ntypedef struct instrumentation_edge instrumentation_edge_t;\n\nstruct instrumentation_edges\n{\n#ifdef _M_X64\n\tuint64_t num_edges;\n#else\n\tuint32_t num_edges;\n#endif\n\tinstrumentation_edge_t edges[1];\n};\ntypedef struct instrumentation_edges instrumentation_edges_t;\n\nstruct instrumentation\n{\n\tvoid *(*create)(char * options, char * state);\n\tvoid(*cleanup)(void * instrumentation_state);\n\tvoid *(*merge)(void * instrumentation_state, void * other_instrumentation_state);\n\n\tchar * (*get_state)(void * instrumentation_state);\n\tvoid(*free_state)(char * state);\n\tint(*set_state)(void * instrumentation_state, char * state);\n\n\t#ifdef _WIN32\n\tint(*enable)(void * instrumentation_state, HANDLE * process, char * cmd_line, char * input, size_t input_length);\n\t#else\n\tint(*enable)(void * instrumentation_state, pid_t * process, char * cmd_line, char * input, size_t input_length);\n\t#endif\n\tint(*is_new_path)(void * instrumentation_state);\n\tint(*get_fuzz_result)(void * instrumentation_state);\n\n\t//Optional\n\tint (*get_module_info)(void * instrumentation_state, int index, int * is_new, char ** module_name, char ** info, int * size);\n\tinstrumentation_edges_t * (*get_edges)(void * instrumentation_state, int index);\n\tint(*is_process_done)(void * instrumentation_state);\n};\ntypedef struct instrumentation instrumentation_t;\n"
  },
  {
    "path": "instrumentation/instrumentation_factory.c",
    "content": "#include \"instrumentation_factory.h\"\n#ifdef _WIN32\n#include \"debug_instrumentation.h\"\n#include \"dynamorio_instrumentation.h\"\n#else\n#include \"return_code_instrumentation.h\"\n#include \"afl_instrumentation.h\"\n#if !__APPLE__ // Linux\n#include \"linux_ipt_instrumentation.h\"\n#endif\n#endif\n\n#include <string.h>\n#include <stdlib.h>\n#include <stdio.h>\n\n#define FACTORY_ERROR()  { free(ret); return NULL; }\n\n/**\n* This function obtains a instrumentation_t object by calling the instrumentation specified by instrumentation_type's create method.\n* @param instrumentation_type - the name of the instrumentation that should be created.  Currently known instrumentation types are: dynamorio.\n* @param options - a JSON string that contains the instrumentation specific string of options\n* @return - a instrumentation_t object of the specified type on success or NULL on failure\n*/\ninstrumentation_t * instrumentation_factory(char * instrumentation_type)\n{\n\tinstrumentation_t * ret = (instrumentation_t *)malloc(sizeof(instrumentation_t));\n\tmemset(ret, 0, sizeof(instrumentation_t));\n\t#ifdef _WIN32\n\tif (!strcmp(instrumentation_type, \"debug\"))\n\t{\n\t\tret->create = debug_create;\n\t\tret->cleanup = debug_cleanup;\n\t\tret->merge = debug_merge;\n\t\tret->get_state = debug_get_state;\n\t\tret->free_state = debug_free_state;\n\t\tret->set_state = debug_set_state;\n\t\tret->enable = debug_enable;\n\t\tret->is_new_path = debug_is_new_path;\n\t\tret->get_fuzz_result = debug_get_fuzz_result;\n\t\tret->is_process_done = debug_is_process_done;\n\t}\n\telse if (!strcmp(instrumentation_type, \"dynamorio\"))\n\t{\n\t\tret->create = dynamorio_create;\n\t\tret->cleanup = dynamorio_cleanup;\n\t\tret->merge = dynamorio_merge;\n\t\tret->get_state = dynamorio_get_state;\n\t\tret->free_state = dynamorio_free_state;\n\t\tret->set_state = dynamorio_set_state;\n\t\tret->enable = dynamorio_enable;\n\t\tret->is_new_path = dynamorio_is_new_path;\n\t\tret->get_module_info = dynamorio_get_module_info;\n\t\tret->get_edges = dynamorio_get_edges;\n\t\tret->is_process_done = dynamorio_is_process_done;\n\t\tret->get_fuzz_result = dynamorio_get_fuzz_result;\n\t}\n\t#else\n\tif (!strcmp(instrumentation_type, \"return_code\"))\n\t{\n\t\tret->create = return_code_create;\n\t\tret->cleanup = return_code_cleanup;\n\t\tret->merge = return_code_merge;\n\t\tret->get_state = return_code_get_state;\n\t\tret->free_state = return_code_free_state;\n\t\tret->set_state = return_code_set_state;\n\t\tret->enable = return_code_enable;\n\t\tret->is_new_path = return_code_is_new_path;\n\t\tret->get_fuzz_result = return_code_get_fuzz_result;\n\t\tret->is_process_done = return_code_is_process_done;\n\t}\n\telse if (!strcmp(instrumentation_type, \"afl\"))\n\t{\n\t\tret->create = afl_create;\n\t\tret->cleanup = afl_cleanup;\n\t\tret->merge = afl_merge;\n\t\tret->get_state = afl_get_state;\n\t\tret->free_state = afl_free_state;\n\t\tret->set_state = afl_set_state;\n\t\tret->enable = afl_enable;\n\t\tret->is_new_path = afl_is_new_path;\n\t\tret->get_fuzz_result = afl_get_fuzz_result;\n\t\tret->is_process_done = afl_is_process_done;\n\t}\n\t#if !__APPLE__ // Linux\n\telse if (!strcmp(instrumentation_type, \"ipt\"))\n\t{\n\t\tret->create = linux_ipt_create;\n\t\tret->cleanup = linux_ipt_cleanup;\n\t\tret->merge = linux_ipt_merge;\n\t\tret->get_state = linux_ipt_get_state;\n\t\tret->free_state = linux_ipt_free_state;\n\t\tret->set_state = linux_ipt_set_state;\n\t\tret->enable = linux_ipt_enable;\n\t\tret->is_new_path = linux_ipt_is_new_path;\n\t\tret->get_fuzz_result = linux_ipt_get_fuzz_result;\n\t\tret->is_process_done = linux_ipt_is_process_done;\n\t}\n\t#endif\n\t#endif\n\telse\n\t\tFACTORY_ERROR();\n\treturn ret;\n}\n\n#define APPEND_HELP(text, new_text, func)                               \\\n  if(!func(&new_text)) {                                                \\\n    text = (char *)realloc(text, strlen(text) + strlen(new_text) + 1);  \\\n    strcat(text, new_text);                                             \\\n    free(new_text);                                                     \\\n  }\n\n/**\n* This function returns help text for all available instrumentations.  This help text will describe the instrumentations and any options\n* that can be passed to their create functions.\n* @return - a newly allocated string containing the help text.\n*/\nchar * instrumentation_help(void)\n{\n\tchar * text, *new_text;\n\ttext = strdup(\"Instrumentation Options:\\n\\n\");\n\t#ifdef _WIN32\n\tAPPEND_HELP(text, new_text, debug_help);\n\tAPPEND_HELP(text, new_text, dynamorio_help);\n\t#else\n\tAPPEND_HELP(text, new_text, return_code_help);\n\tAPPEND_HELP(text, new_text, afl_help);\n\t#if !__APPLE__ // Linux\n\tAPPEND_HELP(text, new_text, linux_ipt_help);\n\t#endif\n\t#endif\n\treturn text;\n}\n"
  },
  {
    "path": "instrumentation/instrumentation_factory.h",
    "content": "#pragma once\n\n#include \"instrumentation.h\"\n\nINSTRUMENTATION_API instrumentation_t * instrumentation_factory(char * instrumentation_type);\nINSTRUMENTATION_API char * instrumentation_help(void);"
  },
  {
    "path": "instrumentation/linux_ipt_instrumentation.c",
    "content": "// Linux-only Intel PT instrumentation.\n#define _GNU_SOURCE\n\n#include <errno.h>\n#include <fcntl.h>\n#include <linux/perf_event.h>\n#include <signal.h>\n#include <string.h>\n#include <sys/ioctl.h>\n#include <sys/mman.h>\n#include <sys/stat.h>\n#include <sys/syscall.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#include \"instrumentation.h\"\n#include \"linux_ipt_instrumentation.h\"\n#include \"forkserver_internal.h\"\n#include \"uthash.h\"\n#include \"xxhash.h\"\n\n#include <utils.h>\n#include <jansson_helper.h>\n\n////////////////////////////////////////////////////////////////\n// IPT Packet Analyzer /////////////////////////////////////////\n////////////////////////////////////////////////////////////////\n\n//Uncomment this #define to make the IPT parser print each packet and parser details\n//#define IPT_DEBUG\n\n#ifdef IPT_DEBUG\n//Prints each IPT packet and the packet bytes\n#define IPT_DEBUG_MSG_PACKET(...) DEBUG_MSG(__VA_ARGS__)\n//Prints status messages about the parser\n#define IPT_DEBUG_MSG(...)        DEBUG_MSG(__VA_ARGS__)\n#else\n#define IPT_DEBUG_MSG_PACKET(...)\n#define IPT_DEBUG_MSG(...)\n#endif\n\n#define BYTES_LEFT(num)    ((end - p) >= (num))\n#define BIT_TEST(num, bit) ((num) & (1 << (bit)))\n\n/**\n * This function sign extends a number\n * @param num - the number to sign extend\n * @param sign_bit - which bit in num is the value's current sign bit\n * @return - the sign extended number\n */\nstatic uint64_t sign_extend(uint64_t num, uint8_t sign_bit)\n{\n  uint64_t mask = ~0ULL << sign_bit;\n  return num & (1ULL << (sign_bit - 1)) ? num | mask : num & ~mask;\n}\n\n/**\n * This function parsers an IPT TIP/FUP packet and obtains the IP address that it refers to\n * @param outp - The position of the TIP/FUP packet bytes in the IPT packet buffer.  This pointer will\n * be updated to point after the parsed TIP/FUP packet.\n * @param end - The end of the IPT packet buffer.  Used to ensure, we don't read past the end\n * @param last_ip - The IP address that was in the most recent TIP/FUP packet. This value will be\n * updated with the IP address from the parsed packet.\n * @return - the IP address from the TIP/FUP packet.\n */\nstatic uint64_t handle_ip_packet(unsigned char ** outp, unsigned char *end, uint64_t *last_ip)\n{\n  unsigned char *p = *outp;\n  uint64_t new_ip;\n  int num_bytes;\n  uint64_t new_bytes;\n\n  int ip_bytes = p[0] >> 5;\n\n  if (ip_bytes == 0) //IP is out of context\n    return 0;\n  else if(ip_bytes == 1) { //Bottom 32 bits, last_ip top 48\n    num_bytes = 2;\n    new_bytes = *((uint64_t *)(p+1)) & 0xFFFFULL;\n    new_ip = (*last_ip & (0xFFFFFFFFFFFFULL << 16)) | new_bytes;\n  } else if(ip_bytes == 2) { //Bottom 32 bits, last_ip top 32\n    num_bytes = 4;\n    new_bytes = *((uint64_t *)(p+1)) & 0xFFFFFFFFULL;\n    new_ip = (*last_ip & (0xFFFFFFFFULL << 32)) | new_bytes;\n  } else if(ip_bytes == 3) { //Bottom 48 bits, sign extended\n    num_bytes = 6;\n    new_bytes = *((uint64_t *)(p+1)) & 0xFFFFFFFFFFFFULL;\n    new_ip = sign_extend(new_bytes, 48);\n  } else if(ip_bytes == 4) { //Bottom 48 bits, last_ip top 16\n    num_bytes = 6;\n    new_bytes = *((uint64_t *)(p+1)) & 0xFFFFFFFFFFFFULL;\n    new_ip = (*last_ip & (0xFFFFULL << 48)) | new_bytes;\n  } else if(ip_bytes == 6) { //All 64 bits\n    num_bytes = 8;\n    new_ip = *((uint64_t *)(p+1));\n  } else {\n    WARNING_MSG(\"Got unknown IP packet (IPBytes=%d)\", ip_bytes);\n    return 0;\n  }\n\n  if (!BYTES_LEFT(num_bytes)) {\n    WARNING_MSG(\"Got error in handle_ip_packet: Not enough bytes for decoding IP (have %lu, need %lu)\", end-p, ip_bytes);\n    return 0;\n  }\n\n  *outp = p + num_bytes;\n  *last_ip = new_ip;\n  return new_ip;\n}\n\n/**\n * This function adds any remaining TNT packet bits to the TNT hash being recorded\n * @param ipt_hashes - A pointer to the hash structure with the TNT hash to update\n */\nstatic void finish_tnt_hash(struct ipt_hash_state * ipt_hashes)\n{\n  if(ipt_hashes->num_bits != 0) {\n    if(XXH64_update(ipt_hashes->tnt, &ipt_hashes->tnt_bits, sizeof(uint64_t)) == XXH_ERROR)\n      WARNING_MSG(\"Updating the TNT hash failed!\"); //Should never happen\n  }\n  //Add in the total number of bits, so we can differentiate between a packet with TNN and a packet with TN\n  if(XXH64_update(ipt_hashes->tnt, &ipt_hashes->total_num_bits, sizeof(uint64_t)) == XXH_ERROR)\n    WARNING_MSG(\"Updating the TNT hash failed!\"); //Should never happen\n}\n\n/**\n * This function adds TNT packet bits to the TNT hash being recorded\n * @param ipt_hashes - A pointer to the hash structure with the TNT hash to update\n * @param tnt_bits - the TNT bits to add to the hash\n * @param num_bits - the number of bits in the tnt_bits parameter\n */\nstatic void add_tnt_to_hash(struct ipt_hash_state * ipt_hashes, unsigned char * tnt_bits, int num_bits)\n{\n  uint64_t i;\n#ifdef IPT_DEBUG\n  char bit_string[64];\n\n  for(i = 0; i < num_bits; i++)\n    bit_string[i] = BIT_TEST(tnt_bits[i / 8], i % 8) ? 'T' : 'N';\n  bit_string[num_bits] = 0;\n\n  IPT_DEBUG_MSG(\"TNT bits %d: %s\", num_bits, bit_string);\n#endif\n\n  for(i = 0; i < num_bits; i++) {\n    ipt_hashes->tnt_bits |= (BIT_TEST(tnt_bits[i / 8], i % 8) << ipt_hashes->num_bits);\n    ipt_hashes->num_bits++;\n    if(ipt_hashes->num_bits == sizeof(ipt_hashes->tnt_bits)) {\n      if(XXH64_update(ipt_hashes->tnt, &ipt_hashes->tnt_bits, sizeof(uint64_t)) == XXH_ERROR)\n        WARNING_MSG(\"Updating the TNT hash failed!\"); //Should never happen\n      ipt_hashes->tnt_bits = 0;\n      ipt_hashes->num_bits = 0;\n    }\n  }\n  ipt_hashes->total_num_bits += num_bits;\n}\n\n/**\n * This function adds a TIP packet's IP address to the TIP hash being recorded\n * @param state - The linux_ipt_state_t object containing this instrumentation's state\n * @param tip - the IP address to add to the TIP hash\n */\nstatic void add_tip_to_hash(linux_ipt_state_t * state, uint64_t tip)\n{\n  uint64_t adjusted_address = tip;\n  int i;\n  long index = -1;\n\n  IPT_DEBUG_MSG(\"TIP %lx\", tip);\n\n  //Adjust the reported address to remove ASLR\n  if(state->num_coverage_libraries) {\n    for(i = 0; i < state->num_coverage_libraries; i++) {\n      if(state->library_starts[i] <= tip && tip < state->library_ends[i]) {\n        index = i;\n        break;\n      }\n    }\n\n    //Normalize the address, then mix in the hash of the library to ensure there are not collisions\n    //when two separate libraries report a TIP at the same offset\n    if(index != -1)\n      adjusted_address = (tip - state->library_starts[i]) | (((uint64_t)state->library_hashes[i]) << 32);\n  } else if(state->target_start <= tip && tip < state->target_end) //if the address is in the target executable\n    adjusted_address = tip - state->target_start; //normalize the address with the target's start address\n\n  if(XXH64_update(state->ipt_hashes.tip, &adjusted_address, sizeof(uint64_t)) == XXH_ERROR)\n    WARNING_MSG(\"Updating the TIP hash failed!\"); //Should never happen\n}\n\n/**\n * This function determines how many bits are in a TNT packet\n * @param packet - A pointer to the IPT packet buffer\n * @param max - the maximum possible bits that could be in a packet\n */\nstatic int get_tnt_num_bits(unsigned char * packet, int max_bits)\n{\n  int num_bits;\n  for(num_bits = max_bits; num_bits >= 0; num_bits--) { //Find the stop bit\n    if(BIT_TEST(packet[num_bits / 8], num_bits % 8))\n      break;\n  }\n  return num_bits;\n}\n\n/**\n * This function parses the IPT packet buffer to determine if the execution trace was new or not.  If it was, the\n * execution trace's hash is added to the hashtable to ensure we do not mark it as new again.\n * @param state - The linux_ipt_state_t object containing this instrumentation's state\n * @param return - -1 on error, 0 if the IPT packets in the IPT packet buffer don't describe a unique run, or 1 if they do\n */\nstatic int analyze_ipt(linux_ipt_state_t * state)\n{\n  unsigned char * p, * start, * end, * psb_pos;\n  struct ipt_hashtable_entry * hashes, * match = NULL;\n  uint64_t ip_address;\n  size_t num_bytes_at_end;\n  int unknown_packet_hit = 0;\n\n  const unsigned char psb[0x10] = {\n    0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82,\n    0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82\n  };\n\n  //Disable IPT while we're analyzing it\n  ioctl(state->perf_fd, PERF_EVENT_IOC_DISABLE, 0);\n\n  //Perform a quick sanity check to ensure the IPT trace data is sane\n  if (state->pem->aux_head == state->pem->aux_tail) {\n    WARNING_MSG(\"No IPT trace data was recorded, something is likely wrong.\");\n    return -1;\n  } else if (state->persistence_max_cnt == 0 && state->pem->aux_head < state->pem->aux_tail) {\n    WARNING_MSG(\"The IPT trace data has overflown. Use the ipt_mmap_size option to increase the size.\");\n    return -1;\n  }\n\n  //Reset the IPT hashes struct\n  state->ipt_hashes.tnt_bits = 0;\n  state->ipt_hashes.num_bits = 0;\n  state->ipt_hashes.total_num_bits = 0;\n  if(XXH64_reset(state->ipt_hashes.tnt, 0) == XXH_ERROR ||\n      XXH64_reset(state->ipt_hashes.tip, 0) == XXH_ERROR)\n    return -1;\n\n  hashes = malloc(sizeof(struct ipt_hashtable_entry));\n  if(!hashes)\n    return -1;\n\n  //Reorder the buffer if it wrapped around to make parsing easier\n  if(state->pem->aux_head < state->pem->aux_tail) {\n    state->reorder_buffer = malloc(state->ipt_mmap_size);\n    num_bytes_at_end = state->pem->aux_size - state->pem->aux_tail;\n    memcpy(state->reorder_buffer, state->perf_aux_buf + state->pem->aux_tail, num_bytes_at_end);\n    memcpy(state->reorder_buffer + num_bytes_at_end, state->perf_aux_buf, state->pem->aux_head);\n\n    start = state->reorder_buffer;\n    end = state->reorder_buffer + num_bytes_at_end + state->pem->aux_head;\n  } else {\n    start = (char *)state->perf_aux_buf + state->pem->aux_tail;\n    end = (char *)state->perf_aux_buf + state->pem->aux_head;\n  }\n  p = start;\n\n#ifdef IPT_DEBUG\n  write_buffer_to_file(\"/tmp/ipt_dump\", start, end-start);\n#endif\n\n  //Rather than use Intel's libipt, we instead parse the buffer ourselves to ensure we can do so\n  //quickly.  As we only need the TIP/TNT packets, this parser attempts to parse as little else\n  //as possible.  Further, we only record hashes of the TIP/TNT packets, as full decoding of the\n  //IPT packets to match them to the basic blocks transitions is far too slow.\n  while(p < end) {\n\n    if(unknown_packet_hit) {\n      psb_pos = memmem(p, end - p, psb, sizeof(psb));\n      if(!psb_pos) {\n        DEBUG_MSG(\"Couldn't find PSB packet\");\n        break;\n      }\n      if(psb_pos - p != 0)\n        IPT_DEBUG_MSG(\"Skipping %d bytes\", psb_pos - p);\n      p = psb_pos + sizeof(psb);\n      state->last_ip = 0;\n      unknown_packet_hit = 0;\n    }\n\n    while(p < end)\n    {\n      IPT_DEBUG_MSG_PACKET(\"%04x: %02x %02x %02x %02x %02x %02x %02x %02x\", p - start,\n          (unsigned char)p[0], (unsigned char)p[1], (unsigned char)p[2], (unsigned char)p[3],\n          (unsigned char)p[4], (unsigned char)p[5], (unsigned char)p[6], (unsigned char)p[7]);\n\n      if (p[0] == 2 && BYTES_LEFT(2)) {\n        if (p[1] == 0xa3 && BYTES_LEFT(8)) { // Long TNT\n          IPT_DEBUG_MSG_PACKET(\"Long TNT\");\n          add_tnt_to_hash(&state->ipt_hashes, p+2, get_tnt_num_bits(p+2, 47));\n          p += 8;\n          continue;\n        }\n        if (p[1] == 0x43 && BYTES_LEFT(8)) { // PIP\n          IPT_DEBUG_MSG_PACKET(\"PIP\");\n          p += 8;\n          continue;\n        }\n        if (p[1] == 3 && BYTES_LEFT(4)) { // CBR\n          IPT_DEBUG_MSG_PACKET(\"CBR\");\n          p += 4;\n          continue;\n        }\n        if (p[1] == 0x83) { //TRACESTOP\n          IPT_DEBUG_MSG_PACKET(\"TRACESTOP\");\n          p += 2;\n          continue;\n        }\n        if (p[1] == 0xf3 && BYTES_LEFT(8)) { // OVF\n          p += 8;\n          WARNING_MSG(\"IPT received overflow packet\");\n          continue;\n        }\n        if (p[1] == 0x82 && BYTES_LEFT(16) && !memcmp(p, psb, 16)) { // PSB\n          IPT_DEBUG_MSG_PACKET(\"PSB\");\n          p += 16;\n          state->last_ip = 0;\n          continue;\n        }\n        if (p[1] == 0x23) { // PSBEND\n          IPT_DEBUG_MSG_PACKET(\"PSBEND\");\n          p += 2;\n          continue;\n        }\n        if (p[1] == 0xc3 && BYTES_LEFT(11) && p[2] == 0x88) { //MNT\n          IPT_DEBUG_MSG_PACKET(\"MNT\");\n          p += 10;\n          continue;\n        }\n        if (p[1] == 0x73 && BYTES_LEFT(7)) { //TMA\n          IPT_DEBUG_MSG_PACKET(\"TMA\");\n          p += 7;\n          continue;\n        }\n        if (p[1] == 0xc8 && BYTES_LEFT(7)) { //VMCS\n          IPT_DEBUG_MSG_PACKET(\"VMCS\");\n          p += 7;\n          continue;\n        }\n      }\n\n      if(!(p[0] & 1)) {\n        if (p[0] == 0) { // PAD\n          IPT_DEBUG_MSG_PACKET(\"PAD\");\n          p++;\n          continue;\n        }\n\n        // Short TNT\n        char tnt_bits = p[0] >> 1;\n        add_tnt_to_hash(&state->ipt_hashes, &tnt_bits, get_tnt_num_bits(&tnt_bits, 6));\n        IPT_DEBUG_MSG_PACKET(\"SHORT TNT\");\n        p++;\n        continue;\n      }\n\n#define TIP_TYPE_TIP     0xd\n#define TIP_TYPE_TIP_PGE 0x11\n#define TIP_TYPE_TIP_PGD 0x1\n#define TIP_TYPE_FUP     0x1d\n\n      char tip_type = p[0] & 0x1f;\n      if(tip_type == TIP_TYPE_TIP || tip_type == TIP_TYPE_TIP_PGE\n          || tip_type == TIP_TYPE_TIP_PGD || tip_type == TIP_TYPE_FUP) {\n        ip_address = handle_ip_packet(&p, end, &state->last_ip);\n        IPT_DEBUG_MSG_PACKET(\"TIP/PGE/PGD/FUP\");\n        if(tip_type == TIP_TYPE_TIP)\n          add_tip_to_hash(state, ip_address);\n        p++;\n        continue;\n      }\n\n      if (p[0] == 0x99 && BYTES_LEFT(2)) { // MODE\n        IPT_DEBUG_MSG_PACKET(\"MODE\");\n        p += 2;\n        continue;\n      }\n\n      if (p[0] == 0x19 && BYTES_LEFT(8)) { // TSC\n        IPT_DEBUG_MSG_PACKET(\"TSC\");\n        p+=8;\n        continue;\n      }\n      if (p[0] == 0x59 && BYTES_LEFT(2)) { // MTC\n        IPT_DEBUG_MSG_PACKET(\"MTC\");\n        p += 2;\n        continue;\n      }\n      if ((p[0] & 3) == 3) { // CYC\n        IPT_DEBUG_MSG_PACKET(\"CYC\");\n        if ((p[0] & 4) && BYTES_LEFT(1)) {\n          do {\n            p++;\n          } while ((p[0] & 1) && BYTES_LEFT(1));\n        }\n        p++;\n        continue;\n      }\n\n      WARNING_MSG(\"Hit unknown packet type at offset 0x%lx\", p - start);\n      unknown_packet_hit = 1;\n      break;\n    }\n  }\n\n  //Create a hashtable entry to lookup/add\n  finish_tnt_hash(&state->ipt_hashes);\n  memset(hashes, 0, sizeof(struct ipt_hashtable_entry));\n  hashes->id.tip = XXH64_digest(state->ipt_hashes.tip);\n  hashes->id.tnt = XXH64_digest(state->ipt_hashes.tnt);\n  DEBUG_MSG(\"Got TIP hash 0x%llx and TNT hash 0x%llx\", hashes->id.tip, hashes->id.tnt);\n\n  //Look for our hashes in the hashtable, and add them if they're not already in it\n  HASH_FIND(hh, state->head, &hashes->id, sizeof(struct ipt_hashtable_key), match);\n  if(!match)\n    HASH_ADD(hh, state->head, id, sizeof(struct ipt_hashtable_key), hashes);\n  else\n    free(hashes);\n  return match == NULL;\n}\n\n////////////////////////////////////////////////////////////////\n// Private methods /////////////////////////////////////////////\n////////////////////////////////////////////////////////////////\n\n/**\n * This function wraps the perf_event_open syscall, which does not have one in libc\n */\nstatic long perf_event_open(struct perf_event_attr* hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags)\n{\n  return syscall(__NR_perf_event_open, hw_event, (uintptr_t)pid, (uintptr_t)cpu, (uintptr_t)group_fd, (uintptr_t)flags);\n}\n\n/**\n * This function cleans up the IPT related file descriptor and memory mappings\n * @param state - The linux_ipt_state_t object containing this instrumentation's state\n */\nstatic void cleanup_ipt(linux_ipt_state_t * state)\n{\n  if(state->perf_aux_buf && state->perf_aux_buf != MAP_FAILED && state->pem && state->pem != MAP_FAILED) {\n    munmap(state->perf_aux_buf, state->pem->aux_size);\n    state->perf_aux_buf = NULL;\n    munmap(state->pem, state->ipt_mmap_size + getpagesize());\n    state->pem = NULL;\n  }\n  if(state->perf_fd >= 0)\n    close(state->perf_fd);\n  state->perf_fd = -1;\n}\n\n/**\n * This function determines the size used in an IPT filter for the specified filename.\n * @param filename - the filename determine the IPT filter size for\n * @return - the size that should be specified in an IPT filter for the given filename\n */\nstatic size_t get_file_filter_size(char * filename)\n{\n  struct stat statbuf;\n  size_t pagesize = getpagesize();\n  size_t ret;\n\n  if(stat(filename, &statbuf))\n    FATAL_MSG(\"Couldn't get size of \\\"%s\\\"\", filename);\n\n  ret = statbuf.st_size;\n  if(ret % pagesize != 0)\n    ret = (((ret + pagesize) / pagesize) * pagesize);\n  return ret;\n}\n\n/**\n * This function creates an IPT filter for the the coverage libraries specified in a linux_ipt_state\n * @param state - The linux_ipt_state_t object containing this instrumentation's state\n * @return - an IPT filter that can be passed to the Linux perf subsystem, which will instruction IPT to only\n * generate IPT packets for the regions defined in the linux_ipt_state.\n */\nstatic char * create_ipt_filter(linux_ipt_state_t * state)\n{\n  char item_filter[1000], filter[4096];\n  size_t i;\n\n  //See https://elixir.bootlin.com/linux/v4.17.8/source/kernel/events/core.c#L8806 for the filter format\n  //start is autodetected by the kernel\n  memset(filter, 0, sizeof(filter));\n  if(state->num_coverage_libraries) {\n    for(i = 0; i < state->num_coverage_libraries; i++) {\n      snprintf(item_filter, sizeof(item_filter), \"filter 0/%ld@%s%s\", get_file_filter_size(state->coverage_libraries[i]),\n        state->coverage_libraries[i], i != state->num_coverage_libraries - 1 ? \"\\n\" : \"\");\n      strncat(filter, item_filter, sizeof(filter) - (strlen(filter) + 1));\n    }\n  } else\n    snprintf(filter, sizeof(filter), \"filter 0/%ld@%s\", get_file_filter_size(state->target_path), state->target_path);\n\n  IPT_DEBUG_MSG(\"Using filter: %s\", filter);\n  return strdup(filter);\n}\n\n/**\n * This function sets up IPT tracing for the specified process\n * @param state - The linux_ipt_state_t object containing this instrumentation's state\n * @param pid - The process ID of the process to trace\n * @return - 0 on success, non-zero on failure\n */\nstatic int setup_ipt(linux_ipt_state_t * state, pid_t pid)\n{\n  struct perf_event_attr pe;\n\n  state->last_ip = 0;\n\n  memset(&pe, 0, sizeof(struct perf_event_attr));\n  pe.size = sizeof(struct perf_event_attr);\n  pe.config = (1U << 11); // Disable RET compression, makes parsing easier\n  pe.disabled = 0;\n  pe.enable_on_exec = 0;\n  pe.exclude_hv = 1;\n  pe.exclude_kernel = 1;\n  pe.type = state->intel_pt_type;\n\n  state->perf_fd = perf_event_open(&pe, pid, -1, -1, PERF_FLAG_FD_CLOEXEC);\n  if(state->perf_fd < 0) {\n    ERROR_MSG(\"Could not open the perf event file system (perf_event_open failed with errno %d (%s))\", errno, strerror(errno));\n    ERROR_MSG(\"Try adjusting the perf system permissions with: echo 1 | sudo tee /proc/sys/kernel/perf_event_paranoid\");\n    return 1;\n  }\n\n  if(!state->filter)\n    state->filter = create_ipt_filter(state);\n  if(ioctl(state->perf_fd, PERF_EVENT_IOC_SET_FILTER, state->filter)) {\n    ERROR_MSG(\"perf filter failed! (errno %d: %s)\", errno, strerror(errno));\n    return 1;\n  }\n\n  state->pem = mmap(NULL, state->ipt_mmap_size + getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, state->perf_fd, 0);\n  if(state->pem == MAP_FAILED) {\n    ERROR_MSG(\"Perf mmap failed (ipt_mmap_size=%d)\\n\", state->ipt_mmap_size);\n    return 1;\n  }\n\n  state->pem->aux_offset = state->pem->data_offset + state->pem->data_size;\n  state->pem->aux_size = state->ipt_mmap_size;\n  state->perf_aux_buf = mmap(NULL, state->pem->aux_size, PROT_READ, MAP_SHARED, state->perf_fd, state->pem->aux_offset);\n  if(state->perf_aux_buf == MAP_FAILED) {\n    ERROR_MSG(\"Perf AUX mmap failed (ipt_mmap_size=%d)\\n\", state->ipt_mmap_size);\n    return 1;\n  }\n  return 0;\n}\n\n/**\n * This function records the address information for the traced libraries or executable\n * inside of the fork server (which will have the same addresses as all target processes).\n * @param state - The linux_ipt_state_t object containing this instrumentation's state\n */\nstatic void record_fork_server_address_info(linux_ipt_state_t * state)\n{\n  char filename[64], line[1024+MAX_PATH], map_filename[MAX_PATH], last_filename[MAX_PATH];\n  FILE * fp;\n  uint64_t start, end;\n  int count, index, file_len;\n  size_t i;\n  char * file_buffer;\n  XXH32_state_t * hash;\n\n  //Allocate the library start/end arrays\n  if(state->num_coverage_libraries) {\n    state->library_starts = calloc(state->num_coverage_libraries, sizeof(uint64_t));\n    state->library_ends = calloc(state->num_coverage_libraries, sizeof(uint64_t));\n    state->library_hashes = calloc(state->num_coverage_libraries, sizeof(uint32_t));\n    if(!state->library_starts || !state->library_ends || !state->library_hashes)\n      FATAL_MSG(\"Failed allocating memory for library address ranges and hashes\");\n  }\n\n  //Open /proc/$pid/maps\n  snprintf(filename, sizeof(filename), \"/proc/%d/maps\", state->fs.pid);\n  fp = fopen(filename, \"r\");\n  if(!fp)\n    FATAL_MSG(\"Failed to open the fork server's maps file (%s)\", filename);\n\n  //Parse the maps file line by line, looking for the libraries or main executable\n  while (fgets(line, sizeof(line), fp) != NULL)\n  {\n    memset(map_filename, 0, sizeof(map_filename));\n    count = sscanf(line, \"%16lx-%16lx %*4s %*8s %*s %*d %1024s\\n\", &start, &end, map_filename);\n    if(count != 3)\n      continue;\n    if(state->num_coverage_libraries) {\n      for(i = 0; i < state->num_coverage_libraries; i++) {\n        if(strcmp(map_filename, state->coverage_libraries[i]) == 0) {\n          if(state->library_starts[i] == 0)\n            state->library_starts[i] = start;\n          state->library_ends[i] = end;\n        }\n      }\n\n    } else if(strcmp(map_filename, state->target_path) == 0) {\n      if(state->target_start == 0)\n        state->target_start = start;\n      state->target_end = end;\n    }\n  }\n  fclose(fp);\n\n  //Give a warning if we weren't able to find a library's or the main executable's start/end address\n  if(state->num_coverage_libraries) {\n    for(i = 0; i < state->num_coverage_libraries; i++) {\n      if(!state->library_starts[i] || !state->library_ends[i]) {\n        WARNING_MSG(\"Could not determine the address of the %s library in memory.  The generated hashes will be specific to \"\n          \"this run if ASLR is enabled.\", state->coverage_libraries[i]);\n        state->library_starts[i] = state->library_ends[i] = 0;\n      } else {\n        //Read the library\n        file_len = read_file(state->coverage_libraries[i], &file_buffer);\n        if(file_len < 0)\n          FATAL_MSG(\"Couldn't open the library %s to calculate its hash\", state->coverage_libraries[i]);\n\n        //Calculate the library's hash\n        hash = XXH32_createState();\n        if(XXH32_reset(hash, 0) == XXH_ERROR ||\n            XXH32_update(hash, file_buffer, file_len) == XXH_ERROR)\n          FATAL_MSG(\"Failed calculating hash of library %s\", state->coverage_libraries[i]); //Should never happen\n        state->library_hashes[i] = XXH32_digest(hash);\n\n        //Deallocate the hash and file contents\n        XXH32_freeState(hash);\n        free(file_buffer);\n      }\n    }\n\n  } else if(!state->target_start || !state->target_end) {\n    WARNING_MSG(\"Could not determine the address of the target executable in memory.  The generated hashes will be specific to \"\n      \"this run if ASLR is enabled and the executable is PIE.\");\n    state->target_start = state->target_end = 0;\n  }\n}\n\n/**\n * This function terminates the fuzzed process.\n * @param state - The linux_ipt_state_t object containing this instrumentation's state\n */\nstatic void destroy_target_process(linux_ipt_state_t * state, int force)\n{\n  if(state->child_pid && state->child_pid != -1) {\n    if(!state->persistence_max_cnt || force) {\n      kill(state->child_pid, SIGKILL);\n      state->child_pid = 0;\n    }\n    state->last_status = fork_server_get_status(&state->fs, 1);\n  }\n}\n\n/**\n * This function starts the fuzzed process\n * @param state - The linux_ipt_state_t object containing this instrumentation's state\n * @param cmd_line - the command line of the fuzzed process to start\n * @param stdin_input - the input to pass to the fuzzed process's stdin\n * @param stdin_length - the length of the stdin_input parameter\n * @return - zero on success, non-zero on failure.\n */\nstatic int create_target_process(linux_ipt_state_t * state, char* cmd_line, char * stdin_input, size_t stdin_length)\n{\n  char ** argv;\n  char * temp_path;\n  int i, pid;\n\n  if(!state->fork_server_setup) {\n    if(split_command_line(cmd_line, &temp_path, &argv))\n      return -1;\n\n    //Get the absolute path for the target\n    state->target_path = realpath(temp_path, NULL);\n    if(state->target_path) {\n      fork_server_init(&state->fs, state->target_path, argv, 1, state->persistence_max_cnt, stdin_length != 0);\n      record_fork_server_address_info(state);\n      state->fork_server_setup = 1;\n    }\n\n    //Free the split up command line\n    for(i = 0; argv[i]; i++)\n      free(argv[i]);\n    free(argv);\n    free(temp_path);\n\n    //if realpath failed, return failure\n    if(!state->target_path)\n      return -1;\n  }\n\n  pid = fork_server_fork(&state->fs);\n  if(pid < 0)\n    return -1;\n\n  if(pid != state->child_pid) {\n    //New target process, cleanup the old IPT state and set it up for the new target\n    state->child_pid = pid;\n    cleanup_ipt(state);\n    if(setup_ipt(state, state->child_pid))\n      return -1;\n  } else {\n    //Persistence mode with the same target process being used, adjust the ring buffers and reenable IPT\n    __sync_synchronize(); //smp_mb()\n    __atomic_store_n(&state->pem->aux_tail, state->pem->aux_head, __ATOMIC_SEQ_CST);\n    ioctl(state->perf_fd, PERF_EVENT_IOC_ENABLE, 0);\n  }\n\n  if(state->fs.target_stdin != -1) {\n    //Take care of the stdin input, write over the file, then truncate it accordingly\n    lseek(state->fs.target_stdin, 0, SEEK_SET);\n    if(stdin_input != NULL && stdin_length != 0) {\n      if(write(state->fs.target_stdin, stdin_input, stdin_length) != stdin_length)\n        FATAL_MSG(\"Short write to target's stdin file\");\n    }\n    if(ftruncate(state->fs.target_stdin, stdin_length))\n      FATAL_MSG(\"ftruncate() failed\");\n    lseek(state->fs.target_stdin, 0, SEEK_SET);\n  }\n  return 0;\n}\n\n/**\n * This function reads a number from the given file\n * @param filename - the path to the file to read a number from.\n * @return - The number that was in the specified file, or -1 on error\n */\nstatic int get_file_int(char * filename)\n{\n  int ret, fd;\n  char buffer[16];\n\n  fd = open(filename, O_RDONLY);\n  if(fd < 0)\n    return -1;\n\n  memset(buffer, 0, sizeof(buffer));\n  ret = read(fd, buffer, sizeof(buffer)-1);\n  if(ret > 0)\n    ret = atoi(buffer);\n  else\n    ret = -1;\n  close(fd);\n  return ret;\n}\n\n/**\n * This function reads the Intel PT state of the current processor from the sys filesystem\n * @param state - The linux_ipt_state_t object containing this instrumentation's state\n * @return - 0 on success, non-zero if IPT or IP address filtering are not supported\n */\nstatic int get_ipt_system_info(linux_ipt_state_t * state)\n{\n  int ret;\n\n  if(access(\"/sys/devices/intel_pt/\", F_OK)) {\n    INFO_MSG(\"Intel PT not supported (/sys/devices/intel_pt/ does not exist)\");\n    return -1;\n  }\n\n  ret = get_file_int(\"/sys/devices/intel_pt/type\");\n  if(ret <= 0) {\n    INFO_MSG(\"Intel PT not supported\");\n    return -1;\n  }\n  state->intel_pt_type = ret;\n\n  //For the moment, we'll only support Intel PT with address filtering\n  ret = get_file_int(\"/sys/devices/intel_pt/caps/ip_filtering\");\n  if(ret <= 0) {\n    INFO_MSG(\"Intel PT address filtering not supported\");\n    return -1;\n  }\n\n  ret = get_file_int(\"/sys/devices/intel_pt/caps/num_address_ranges\");\n  if(ret <= 0) {\n    INFO_MSG(\"Intel PT address filtering not supported\");\n    return -1;\n  }\n  if(ret < state->num_coverage_libraries) {\n    INFO_MSG(\"Too many coverage libraries specified. Intel PT address filtering on \"\n      \"this system only supports %d, but %d were specified.\", ret, state->num_coverage_libraries);\n    return -1;\n  }\n  state->num_address_ranges = ret;\n\n  return 0;\n}\n\n////////////////////////////////////////////////////////////////\n// Instrumentation methods /////////////////////////////////////\n////////////////////////////////////////////////////////////////\n\n/**\n * This function creates a linux_ipt_state_t object based on the given options.\n * @param options - A JSON string of the options to set in the new linux_ipt_state_t. See the\n * help function for more information on the specific options available.\n * @return the linux_ipt_state_t generated from the options in the JSON options string, or NULL on failure\n */\nstatic linux_ipt_state_t * setup_options(char * options)\n{\n  linux_ipt_state_t * state;\n  char * temp_path;\n  size_t i;\n  size_t pagesize = getpagesize();\n\n  state = malloc(sizeof(linux_ipt_state_t));\n  if(!state)\n    return NULL;\n  memset(state, 0, sizeof(linux_ipt_state_t));\n\n  //Setup defaults\n  state->ipt_mmap_size = 1024*1024; //1MB\n\n  //Parse the options\n  if(options) {\n    PARSE_OPTION_INT(state, options, persistence_max_cnt, \"persistence_max_cnt\", linux_ipt_cleanup);\n    PARSE_OPTION_INT(state, options, ipt_mmap_size, \"ipt_mmap_size\", linux_ipt_cleanup);\n    PARSE_OPTION_ARRAY(state, options, coverage_libraries, num_coverage_libraries, \"coverage_libraries\", linux_ipt_cleanup);\n  }\n\n  for(i = 0; i < state->num_coverage_libraries; i++) {\n    if(!file_exists(state->coverage_libraries[i])) {\n      ERROR_MSG(\"Could not access the specified coverage library \\\"%s\\\" does not exist\", state->coverage_libraries[i]);\n      linux_ipt_cleanup(state);\n      return NULL;\n    }\n\n    //Get the absolute path for the library\n    temp_path = realpath(state->coverage_libraries[i], NULL);\n    if(!temp_path) {\n      ERROR_MSG(\"Could not determine the absolute address of the specified coverage library \\\"%s\\\"\", state->coverage_libraries[i]);\n      linux_ipt_cleanup(state);\n      return NULL;\n    }\n    free(state->coverage_libraries[i]);\n    state->coverage_libraries[i] = temp_path;\n  }\n\n  //Fix up the IPT mmap size if it's not page aligned\n  if(state->ipt_mmap_size % pagesize != 0)\n    state->ipt_mmap_size = (((state->ipt_mmap_size + pagesize) / pagesize) * pagesize);\n\n  //If we're in persistence mode, allocate the reorder buffer\n  if(state->persistence_max_cnt) {\n    state->reorder_buffer = malloc(state->ipt_mmap_size);\n    if(!state->reorder_buffer) {\n      linux_ipt_cleanup(state);\n      return NULL;\n    }\n  }\n\n  return state;\n}\n\n/**\n * This function allocates and initializes a new instrumentation specific state object based on the given options.\n * @param options - a JSON string that contains the instrumentation specific string of options\n * @param state - an instrumentation specific JSON string previously returned from linux_ipt_get_state that should be loaded\n * @return - An instrumentation specific state object on success or NULL on failure\n */\nvoid * linux_ipt_create(char * options, char * state)\n{\n  linux_ipt_state_t * linux_ipt_state = setup_options(options);\n  if(!linux_ipt_state)\n    return NULL;\n\n  if(get_ipt_system_info(linux_ipt_state)) {\n    linux_ipt_cleanup(linux_ipt_state);\n    return NULL;\n  }\n\n  linux_ipt_state->ipt_hashes.tip = XXH64_createState();\n  linux_ipt_state->ipt_hashes.tnt = XXH64_createState();\n  if(!linux_ipt_state->ipt_hashes.tip || !linux_ipt_state->ipt_hashes.tnt) {\n    linux_ipt_cleanup(linux_ipt_state);\n    return NULL;\n  }\n\n  if(state && linux_ipt_set_state(linux_ipt_state, state)) {\n    linux_ipt_cleanup(linux_ipt_state);\n    return NULL;\n  }\n\n  return linux_ipt_state;\n}\n\n/**\n * This function cleans up all resources with the passed in instrumentation state.\n * @param instrumentation_state - an instrumentation specific state object previously created by the linux_ipt_create function\n * This state object should not be referenced after this function returns.\n */\nvoid linux_ipt_cleanup(void * instrumentation_state)\n{\n  struct ipt_hashtable_entry * hash, * tmp;\n  size_t i;\n  linux_ipt_state_t * state = (linux_ipt_state_t *)instrumentation_state;\n\n  //Kill any remaining target processes\n  destroy_target_process(state, 1);\n\n  //Cleanup the fork server\n  if(state->fork_server_setup) {\n    fork_server_exit(&state->fs);\n    state->fork_server_setup = 0;\n  }\n\n  //Cleanup our xxhashes\n  if(state->ipt_hashes.tnt != NULL)\n    XXH64_freeState(state->ipt_hashes.tip);\n  if(state->ipt_hashes.tnt != NULL)\n    XXH64_freeState(state->ipt_hashes.tnt);\n\n  //Cleanup the perf IPT fd and mmaps\n  cleanup_ipt(state);\n\n  //Cleanup the hashtable entries\n  HASH_ITER(hh, state->head, hash, tmp) {\n    HASH_DEL(state->head, hash);\n    free(hash);\n  }\n\n  for(i = 0; i < state->num_coverage_libraries; i++)\n    free(state->coverage_libraries[i]);\n  free(state->library_starts);\n  free(state->library_ends);\n  free(state->library_hashes);\n  free(state->coverage_libraries);\n  free(state->reorder_buffer);\n  free(state->filter);\n  free(state->target_path);\n  free(state);\n}\n\n/**\n * This function merges the coverage information from two instrumentation states.\n * @param instrumentation_state - an instrumentation specific state object previously created by the linux_ipt_create function\n * @param other_instrumentation_state - an instrumentation specific state object previously created by the linux_ipt_create function\n * @return - An instrumentation specific state object that contains the combination of both of the passed in instrumentation states\n * on success, or NULL on failure\n */\nvoid * linux_ipt_merge(void * instrumentation_state, void * other_instrumentation_state)\n{\n  linux_ipt_state_t * merged;\n  struct ipt_hashtable_entry * entry = NULL, * hash = NULL, * tmp = NULL, * match = NULL;\n  linux_ipt_state_t * first = (linux_ipt_state_t *)instrumentation_state;\n  linux_ipt_state_t * second = (linux_ipt_state_t *)other_instrumentation_state;\n\n  merged = linux_ipt_create(NULL, NULL);\n  if (!merged)\n    return NULL;\n\n  //Add the first state's entries\n  HASH_ITER(hh, first->head, hash, tmp)\n  {\n    entry = malloc(sizeof(struct ipt_hashtable_entry));\n    memset(entry, 0, sizeof(entry));\n    entry->id.tip = hash->id.tip;\n    entry->id.tnt = hash->id.tnt;\n    HASH_ADD(hh, merged->head, id, sizeof(struct ipt_hashtable_key), entry);\n  }\n\n  //Add the second state's entries\n  HASH_ITER(hh, second->head, hash, tmp)\n  {\n    entry = malloc(sizeof(struct ipt_hashtable_entry));\n    memset(entry, 0, sizeof(entry));\n    entry->id.tip = hash->id.tip;\n    entry->id.tnt = hash->id.tnt;\n    HASH_FIND(hh, merged->head, &entry->id, sizeof(struct ipt_hashtable_key), match);\n    if(!match)\n      HASH_ADD(hh, merged->head, id, sizeof(struct ipt_hashtable_key), entry);\n  }\n\n  return merged;\n}\n\n/**\n * This function returns the state information holding the previous execution path info.  The returned value can later be passed to\n * linux_ipt_create or linux_ipt_set_state to load the state.\n * @param instrumentation_state - an instrumentation specific state object previously created by the linux_ipt_create function\n * @return - A JSON string that holds the instrumentation specific state object information on success, or NULL on failure\n */\nchar * linux_ipt_get_state(void * instrumentation_state)\n{\n  linux_ipt_state_t * state = (linux_ipt_state_t *)instrumentation_state;\n  json_t *state_obj, *hash_obj, *hash_list, *temp;\n  struct ipt_hashtable_entry * hash = NULL, * tmp = NULL;\n  char * ret;\n\n  state_obj = json_object();\n  if (!state_obj)\n    return NULL;\n\n  ADD_INT(temp, state->last_status, state_obj, \"last_status\");\n  ADD_INT(temp, state->process_finished, state_obj, \"process_finished\");\n  ADD_INT(temp, state->last_fuzz_result, state_obj, \"last_fuzz_result\");\n  ADD_INT(temp, state->fuzz_results_set, state_obj, \"fuzz_results_set\");\n  ADD_INT(temp, state->last_is_new_path, state_obj, \"last_is_new_path\");\n\n  hash_list = json_array();\n  if (!hash_list)\n    return NULL;\n  HASH_ITER(hh, state->head, hash, tmp)\n  {\n    hash_obj = json_mem((const char *)&hash->id, sizeof(struct ipt_hashtable_key));\n    if (!hash_obj)\n      return NULL;\n    json_array_append_new(hash_list, hash_obj);\n  }\n  json_object_set_new(state_obj, \"hash_list\", hash_list);\n\n  ret = json_dumps(state_obj, 0);\n  json_decref(state_obj);\n  return ret;\n}\n\n/**\n * This function frees an instrumentation state previously obtained via linux_ipt_get_state.\n * @param state - the instrumentation state to free\n */\nvoid linux_ipt_free_state(char * state)\n{\n  free(state);\n}\n\n/**\n * This function sets the instrumentation state to the passed in state previously obtained via linux_ipt_get_state.\n * @param instrumentation_state - an instrumentation specific state object previously created by the linux_ipt_create function\n * @param state - an instrumentation state previously obtained via linux_ipt_get_state\n * @return - 0 on success, non-zero on failure.\n */\nint linux_ipt_set_state(void * instrumentation_state, char * state)\n{\n  linux_ipt_state_t * current_state = (linux_ipt_state_t *)instrumentation_state;\n  struct ipt_hashtable_entry * entry = NULL, * hash = NULL, * tmp = NULL, * match = NULL;\n  json_t * hash_obj;\n  int result, temp_int;\n  size_t length;\n\n  if(!state)\n    return 1;\n\n  //If a child process is running when the state is being set\n  destroy_target_process(current_state, 0); //kill it so we don't orphan it\n\n  //Free any existing hashes already in the hashtable\n  HASH_ITER(hh, current_state->head, hash, tmp) {\n    HASH_DEL(current_state->head, hash);\n    free(hash);\n  }\n\n  GET_INT(temp_int, state, current_state->last_status, \"last_status\", result);\n  GET_INT(temp_int, state, current_state->process_finished, \"process_finished\", result);\n  GET_INT(temp_int, state, current_state->last_fuzz_result, \"last_fuzz_result\", result);\n  GET_INT(temp_int, state, current_state->fuzz_results_set, \"fuzz_results_set\", result);\n  GET_INT(temp_int, state, current_state->last_is_new_path, \"last_is_new_path\", result);\n\n  FOREACH_OBJECT_JSON_ARRAY_ITEM_BEGIN(state, hash_list, \"hash_list\", hash_obj, result)\n\n    length = json_mem_length(hash_obj);\n    if(length != sizeof(struct ipt_hashtable_key))\n      return 1;\n\n    entry = malloc(sizeof(struct ipt_hashtable_entry));\n    if(!entry)\n      return 1;\n\n    memset(entry, 0, sizeof(entry));\n    memcpy(&entry->id, json_mem_value(hash_obj), sizeof(struct ipt_hashtable_key));\n    HASH_FIND(hh, current_state->head, &entry->id, sizeof(struct ipt_hashtable_key), match);\n    if(!match)\n      HASH_ADD(hh, current_state->head, id, sizeof(struct ipt_hashtable_key), entry);\n\n  FOREACH_OBJECT_JSON_ARRAY_ITEM_END(hash_list)\n\n  return 0; //No state to set, so just return success\n}\n\n/**\n * This function enables the instrumentation and runs the fuzzed process.\n * @param instrumentation_state - an instrumentation specific state object previously created by the linux_ipt_create function\n * @process - a pointer to return a handle to the process that the instrumentation was enabled on\n * @cmd_line - the command line of the fuzzed process to enable instrumentation on\n * @input - a buffer to the input that should be sent to the fuzzed process\n * @input_length - the length of the input parameter\n * returns 0 on success, -1 on failure\n */\nint linux_ipt_enable(void * instrumentation_state, pid_t * process, char * cmd_line, char * input, size_t input_length)\n{\n  linux_ipt_state_t * state = (linux_ipt_state_t *)instrumentation_state;\n  if(state->child_pid)\n    destroy_target_process(state, 0);\n\n  if(create_target_process(state, cmd_line, input, input_length))\n    return -1;\n  state->process_finished = 0;\n  state->fuzz_results_set = 0;\n\n  if(fork_server_run(&state->fs))\n    return -1;\n\n  *process = state->child_pid;\n  return 0;\n}\n\nstatic int finish_fuzz_round(linux_ipt_state_t * state)\n{\n  if(!state->fuzz_results_set) {\n    //if it's still alive, it's a hang\n    if(!linux_ipt_is_process_done(state)) {\n      destroy_target_process(state, 1);\n      state->last_fuzz_result = FUZZ_HANG;\n    }\n    //If it died from a signal (and it wasn't SIGKILL, that we send), it's a crash\n    else if(WIFSIGNALED(state->last_status) && WTERMSIG(state->last_status) != SIGKILL)\n      state->last_fuzz_result = FUZZ_CRASH;\n    //Otherwise, just set FUZZ_NONE\n    else\n      state->last_fuzz_result = FUZZ_NONE;\n    state->fuzz_results_set = 1;\n  }\n\n  return state->last_fuzz_result;\n}\n\n/**\n * This function determines whether the process being instrumented has taken a new path.  Calling this function will stop the\n * process if it is not yet finished.\n * @param instrumentation_state - an instrumentation specific state object previously created by the linux_ipt_create function\n * @return - 1 if the previously setup process (via the enable function) took a new path, 0 if it did not, or -1 on failure.\n */\nint linux_ipt_is_new_path(void * instrumentation_state)\n{\n  linux_ipt_state_t * state = (linux_ipt_state_t *)instrumentation_state;\n\n  //Ensure that the process has finished parsing the input (or stop it if it's not)\n  finish_fuzz_round(state);\n\n  //If we haven't cleaned up the IPT state, then it must not have been\n  if(state->perf_fd >= 0) //analyzed.  Analyze it now and cleanup the IPT state\n    state->last_is_new_path = analyze_ipt(state);\n\n  return state->last_is_new_path;\n}\n\n/**\n * This function will return the result of the fuzz job. It should be called\n * after the process has finished processing the tested input.\n * @param instrumentation_state - an instrumentation specific structure previously created by the linux_ipt_create function\n * @return - either FUZZ_NONE, FUZZ_HANG, FUZZ_CRASH, or -1 on error.\n */\nint linux_ipt_get_fuzz_result(void * instrumentation_state)\n{\n  return finish_fuzz_round((linux_ipt_state_t *)instrumentation_state);\n}\n\n/**\n * Checks if the target process is done fuzzing the inputs yet.\n * @param state - The linux_ipt_state_t object containing this instrumentation's state\n * @return - 0 if the process is not done testing the fuzzed input, non-zero if the process is done.\n */\nint linux_ipt_is_process_done(void * instrumentation_state)\n{\n  int status;\n  linux_ipt_state_t * state = (linux_ipt_state_t *)instrumentation_state;\n\n  if(state->process_finished)\n    return 1;\n\n  status = fork_server_get_status(&state->fs, 0);\n  //it's still alive or an error occurred and we can't tell\n  if(status < 0 || status == FORKSERVER_NO_RESULTS_READY)\n    return 0;\n  state->last_status = status;\n  state->process_finished = 1;\n  return 1;\n}\n\n/**\n * This function returns help text for the Linux IPT instrumentation.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nint linux_ipt_help(char ** help_str)\n{\n  *help_str = strdup(\n\"ipt - Linux IPT instrumentation\\n\"\n\"Options:\\n\"\n\"  persistence_max_cnt  The number of executions to run in one process while\\n\"\n\"                         fuzzing in persistence mode\\n\"\n\"  ipt_mmap_size        The amount of memory to use for the IPT trace data\\n\"\n\"                         buffer\\n\"\n\"  coverage_libraries   An array of library or executable filenames that IPT\\n\"\n\"                         should record trace information.  By default, only\\n\"\n\"                         the executable is traced.\\n\"\n\"\\n\"\n  );\n  if (*help_str == NULL)\n    return -1;\n  return 0;\n}\n\n"
  },
  {
    "path": "instrumentation/linux_ipt_instrumentation.h",
    "content": "#pragma once\n\n#include \"forkserver_internal.h\"\n#include \"uthash.h\"\n#include \"xxhash.h\"\n\nvoid * linux_ipt_create(char * options, char * state);\nvoid linux_ipt_cleanup(void * instrumentation_state);\nvoid * linux_ipt_merge(void * instrumentation_state, void * other_instrumentation_state);\nchar * linux_ipt_get_state(void * instrumentation_state);\nvoid linux_ipt_free_state(char * state);\nint linux_ipt_set_state(void * instrumentation_state, char * state);\nint linux_ipt_enable(void * instrumentation_state, pid_t * process, char * cmd_line, char * input, size_t input_length);\nint linux_ipt_is_new_path(void * instrumentation_state);\nint linux_ipt_is_process_done(void * instrumentation_state);\nint linux_ipt_get_fuzz_result(void * instrumentation_state);\nint linux_ipt_help(char ** help_str);\n\nstruct ipt_hashtable_key {\n  uint64_t tip;\n  uint64_t tnt;\n};\n\nstruct ipt_hashtable_entry {\n    struct ipt_hashtable_key id;\n    UT_hash_handle hh;\n};\n\nstruct ipt_hash_state\n{\n  uint64_t tnt_bits;\n  uint64_t num_bits;\n  uint64_t total_num_bits;\n  XXH64_state_t * tnt;\n  XXH64_state_t * tip;\n};\n\nstruct linux_ipt_state\n{\n  int persistence_max_cnt;\n  int ipt_mmap_size;\n\n  char ** coverage_libraries;\n  uint64_t * library_starts;\n  uint64_t * library_ends;\n  uint32_t * library_hashes;\n  size_t num_coverage_libraries;\n\n  char * target_path;\n  uint64_t target_start;\n  uint64_t target_end;\n\n  int num_address_ranges;\n  int fork_server_setup;\n  int intel_pt_type;\n\n  int perf_fd;\n  struct perf_event_mmap_page * pem;\n  void * perf_aux_buf;\n  char * reorder_buffer;\n  uint64_t last_ip;\n  char * filter;\n\n  struct ipt_hash_state ipt_hashes;\n  struct ipt_hashtable_entry * head;\n\n  pid_t child_pid;\n  forkserver_t fs;\n  int last_status;\n  int process_finished;\n  int last_fuzz_result;\n  int fuzz_results_set;\n  int last_is_new_path;\n};\ntypedef struct linux_ipt_state linux_ipt_state_t;\n"
  },
  {
    "path": "instrumentation/return_code_instrumentation.c",
    "content": "// Linux-only return code instrumentation.\n\n#include <signal.h>    // kill\n#include <string.h>    // memset\n#include <sys/types.h>\n#include <unistd.h>\n\n#include \"instrumentation.h\"\n#include \"return_code_instrumentation.h\"\n#include \"forkserver_internal.h\"\n\n#include <utils.h>\n#include <jansson_helper.h>\n\n////////////////////////////////////////////////////////////////\n// Private methods /////////////////////////////////////////////\n////////////////////////////////////////////////////////////////\n\n/**\n * This function terminates the fuzzed process and sets the result in the\n * instrumentation state.\n *\n * @param state - The return_code_state_t object containing this\n * instrumentation's state\n */\nstatic void destroy_target_process(return_code_state_t * state)\n{\n\tif(state->child_pid && state->child_pid != -1) {\n\t\tif(!state->use_fork_server)\n\t\t\tstate->last_status = get_process_status(state->child_pid);\n\n\t\tkill(state->child_pid, SIGKILL);\n\t\tstate->child_pid = 0;\n\n\t\tif(state->use_fork_server)\n\t\t\tstate->last_status = fork_server_get_status(&state->fs, 1);\n\t}\n}\n\n/**\n * This function starts the fuzzed process\n * @param state - The return_code_state_t object containing this instrumentation's state\n * @param cmd_line - the command line of the fuzzed process to start\n * @param stdin_input - the input to pass to the fuzzed process's stdin\n * @param stdin_length - the length of the stdin_input parameter\n * @return - zero on success, non-zero on failure.\n */\nstatic int create_target_process(return_code_state_t * state, char* cmd_line, char * stdin_input, size_t stdin_length)\n{\n\tint i;\n\tchar ** argv;\n\tchar * target_path;\n\n\tstate->last_status = FUZZ_RUNNING;\n\tstate->process_reaped = 0;\n\n\tif(state->use_fork_server) {\n\t\tif(!state->fork_server_setup) {\n\t\t\tif(split_command_line(cmd_line, &target_path, &argv))\n\t\t\t\treturn -1;\n\n\t\t\t//Start the fork server\n\t\t\tfork_server_init(&state->fs, target_path, argv, 1, 0, stdin_length != 0);\n\t\t\tstate->fork_server_setup = 1;\n\n\t\t\t//Free the split up command line\n\t\t\tfor(i = 0; argv[i]; i++)\n\t\t\t\tfree(argv[i]);\n\t\t\tfree(argv);\n\t\t\tfree(target_path);\n\t\t}\n\n\t\tif(state->fs.target_stdin != -1) {\n\t\t\t//Take care of the stdin input, write over the file, then truncate it accordingly\n\t\t\tlseek(state->fs.target_stdin, 0, SEEK_SET);\n\t\t\tif(stdin_input != NULL && stdin_length != 0) {\n\t\t\t\tif(write(state->fs.target_stdin, stdin_input, stdin_length) != stdin_length)\n\t\t\t\t\tFATAL_MSG(\"Short write to target's stdin file\");\n\t\t\t}\n\t\t\tif(ftruncate(state->fs.target_stdin, stdin_length))\n\t\t\t\tFATAL_MSG(\"ftruncate() failed\");\n\t\t\tlseek(state->fs.target_stdin, 0, SEEK_SET);\n\t\t}\n\n\t\t//Start the new child and tell it to go\n\t\tstate->child_pid = fork_server_fork_run(&state->fs);\n\t\tif(state->child_pid < 0) {\n\t\t\tERROR_MSG(\"Fork server failed to fork a new child\\n\");\n\t\t\treturn -1;\n\t\t}\n\n\t} else {\n\t\tif (start_process_and_write_to_stdin(cmd_line, stdin_input, stdin_length, &state->child_pid)) {\n\t\t\tstate->child_pid = 0;\n\t\t\tERROR_MSG(\"Failed to create process with command line: %s\\n\", cmd_line);\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n/**\n * This function creates a return_code_state_t object based on the given options.\n * @param options - A JSON string of the options to set in the new\n *                  return_code_state_t. See the help function for more information on\n *                  the specific options available.\n * @return the return_code_state_t generated from the options in the JSON options\n *         string, or NULL on failure\n */\nstatic return_code_state_t * setup_options(char *options) {\n\treturn_code_state_t * state;\n\n\tstate = malloc(sizeof(return_code_state_t));\n\tif(!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(return_code_state_t));\n\tstate->use_fork_server = 1;  // default to use the fork server\n\n\tif(options) {\n\t\tPARSE_OPTION_INT(state, options, use_fork_server, \"use_fork_server\", return_code_cleanup);\n\t}\n\treturn state;\n}\n\n////////////////////////////////////////////////////////////////\n// Instrumentation methods /////////////////////////////////////\n////////////////////////////////////////////////////////////////\n\n/**\n * This function allocates and initializes a new instrumentation specific state object based on the given options.\n * @param options - a JSON string that contains the instrumentation specific string of options\n * @param state - an instrumentation specific JSON string previously returned from return_code_get_state that should be loaded\n * @return - An instrumentation specific state object on success or NULL on failure\n */\nvoid * return_code_create(char * options, char * state)\n{\n\treturn_code_state_t * return_code_state = setup_options(options);\n\tif (!return_code_state)\n\t\treturn NULL;\n\n\tif (state && return_code_set_state(return_code_state, state))\n\t{\n\t\treturn_code_cleanup(return_code_state);\n\t\treturn NULL;\n\t}\n\n\treturn return_code_state;\n}\n\n/**\n * This function cleans up all resources with the passed in instrumentation state.\n * @param instrumentation_state - an instrumentation specific state object previously created by the return_code_create function\n * This state object should not be referenced after this function returns.\n */\nvoid return_code_cleanup(void * instrumentation_state)\n{\n\treturn_code_state_t * state = (return_code_state_t *)instrumentation_state;\n\n\tdestroy_target_process(state);\n\n\tfree(state);\n}\n\n/**\n * This function merges the coverage information from two instrumentation states.  This will always fail for the\n * return_code instrumentation, since it does not record instrumentation data.\n * @param instrumentation_state - an instrumentation specific state object previously created by the return_code_create function\n * @param other_instrumentation_state - an instrumentation specific state object previously created by the return_code_create function\n * @return - An instrumentation specific state object that contains the combination of both of the passed in instrumentation states\n * on success, or NULL on failure\n */\nvoid * return_code_merge(void * instrumentation_state, void * other_instrumentation_state)\n{\n\treturn NULL; // No instrumentation data, so we can't ever merge\n}\n\n/**\n * This function returns the state information holding the previous execution path info.  The returned value can later be passed to\n * return_code_create or return_code_set_state to load the state.\n * @param instrumentation_state - an instrumentation specific state object previously created by the return_code_create function\n * @return - A JSON string that holds the instrumentation specific state object information on success, or NULL on failure\n */\nchar * return_code_get_state(void * instrumentation_state)\n{\n\treturn_code_state_t * state = (return_code_state_t *)instrumentation_state;\n\tjson_t *state_obj, *temp;\n\tchar * ret;\n\n\tstate_obj = json_object();\n\tADD_INT(temp, state->last_status, state_obj, \"last_status\");\n\tret = json_dumps(state_obj, 0);\n\tjson_decref(state_obj);\n\treturn ret;\n}\n\n/**\n * This function frees an instrumentation state previously obtained via return_code_get_state.\n * @param state - the instrumentation state to free\n */\nvoid return_code_free_state(char * state)\n{\n\tfree(state);\n}\n\n/**\n * This function sets the instrumentation state to the passed in state previously obtained via return_code_get_state.\n * @param instrumentation_state - an instrumentation specific state object previously created by the return_code_create function\n * @param state - an instrumentation state previously obtained via return_code_get_state\n * @return - 0 on success, non-zero on failure.\n */\nint return_code_set_state(void * instrumentation_state, char * state)\n{\n\treturn_code_state_t * current_state = (return_code_state_t *)instrumentation_state;\n\tint result, temp_int;\n\tif (!state)\n\t\treturn 1;\n\n\tGET_INT(temp_int, state, current_state->last_status, \"last_status\", result);\n\treturn 0;\n}\n\n/**\n * This function enables the instrumentation and runs the fuzzed process.  If the process needs to be restarted, it will be.\n * @param instrumentation_state - an instrumentation specific state object previously created by the return_code_create function\n * @process - a pointer to return a handle to the process that instrumentation was enabled on\n * @cmd_line - the command line of the fuzzed process to enable instrumentation on\n * @input - a buffer to the input that should be sent to the fuzzed process on stdin\n * @input_length - the length of the input parameter\n * returns 0 on success, -1 on failure\n */\nint return_code_enable(void * instrumentation_state, pid_t * process, char * cmd_line, char * input, size_t input_length)\n{\n\treturn_code_state_t * state = (return_code_state_t *)instrumentation_state;\n\tif(state->child_pid)\n\t\tdestroy_target_process(state);\n\tif (create_target_process(state, cmd_line, input, input_length))\n\t\treturn -1;\n\tstate->enable_called = 1;\n\t*process = state->child_pid;\n\treturn 0;\n}\n\n/**\n * This function determines whether the process being instrumented has taken a new path.  The return_code instrumentation does\n * not track the fuzzed process's path, so it is unable to determine if the process took a new path.\n * @param instrumentation_state - an instrumentation specific state object previously created by the return_code_create function\n * @return - 0 when a new path wasn't detected (as it always won't be with the return_code instrumentation), or -1 on failure.\n */\nint return_code_is_new_path(void * instrumentation_state)\n{\n\treturn_code_state_t * state = (return_code_state_t *)instrumentation_state;\n\tif(!state->enable_called)\n\t\treturn -1;\n\treturn 0; //We don't gather instrumentation data, so we can't ever tell if we hit a new path.\n}\n\n/**\n * This function will return the result of the fuzz job. It should be called\n * after the process has finished processing the tested input, which should always be the case\n * with the return_code instrumentation, since test_next_input should always wait for the process to finish.\n * @param instrumentation_state - an instrumentation specific structure previously created by the create() function\n * @return - either FUZZ_NONE, FUZZ_HANG, FUZZ_CRASH, or -1 on error.\n */\nint return_code_get_fuzz_result(void * instrumentation_state)\n{\n\treturn_code_state_t * state = (return_code_state_t *)instrumentation_state;\n\tif(!state->enable_called)\n\t\treturn -1;\n\treturn state->last_status;\n}\n\n/**\n * Checks if the target process is done fuzzing the inputs yet.  If it has finished, it will have\n * written last_status, the result of the fuzz job.\n *\n * @param state - The return_code_state_t object containing this instrumentation's state\n * @return - 0 if the process has not done testing the fuzzed input, 1 if the process is done, -1 on error\n */\nint return_code_is_process_done(void * instrumentation_state)\n{\n\tint status;\n\treturn_code_state_t * state = (return_code_state_t *)instrumentation_state;\n\n\tif(!state->enable_called)\n\t\treturn -1;\n\n\tif (state->process_reaped == 1)\n\t{\n\t\treturn state->last_status;\n\t}\n\telse\n\t{\n\t\tif(state->use_fork_server) {\n\t\t\tstatus = fork_server_get_status(&state->fs, 0);\n\t\t\t//it's still alive or an error occurred and we can't tell\n\t\t\tif(status < 0 || status == FORKSERVER_NO_RESULTS_READY)\n\t\t\t\treturn 0;\n\n\t\t\tif(WIFSIGNALED(status) && WTERMSIG(status) != SIGKILL)\n\t\t\t\tstate->last_status = FUZZ_CRASH;\n\t\t\telse\n\t\t\t\tstate->last_status = FUZZ_NONE;\n\n\t\t\tstate->process_reaped = 1;\n\t\t\treturn 1;\n\t\t} else {\n\t\t\tint fuzz_result = get_process_status(state->child_pid);\n\n\t\t\t// expects 2, 1, 0, or -1\n\t\t\tif (fuzz_result == FUZZ_RUNNING) // it's aliiiiive\n\t\t\t\t// don't set last_status here, because hangs are handled by the timeout in the driver.\n\t\t\t\treturn 0;\n\t\t\telse if (fuzz_result == FUZZ_CRASH || fuzz_result == FUZZ_NONE) // crash or clean exit\n\t\t\t{\n\t\t\t\tstate->last_status = fuzz_result;\n\t\t\t\tstate->process_reaped = 1;\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\telse // get_process_status returned an error\n\t\t\t{\n\t\t\t\tstate->last_status = fuzz_result;\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * This function returns help text for this instrumentation.  This help text will describe the instrumentation and any options\n * that can be passed to return_code_create.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nint return_code_help(char ** help_str)\n{\n\t*help_str = strdup(\n\t\t\"return_code - Linux/Mac return_code \\\"instrumentation\\\"\\n\"\n\t\t\"Options:\\n\"\n\t\t\"  use_fork_server      Whether to inject the fork server library; 1=yes, 0=no (default=1)\\n\"\n\t\t\"\\n\"\n\t);\n\tif (*help_str == NULL)\n\t\treturn -1;\n\treturn 0;\n}\n"
  },
  {
    "path": "instrumentation/return_code_instrumentation.h",
    "content": "#pragma once\n#include \"forkserver_internal.h\"\n\nvoid * return_code_create(char * options, char * state);\nvoid return_code_cleanup(void * instrumentation_state);\nvoid * return_code_merge(void * instrumentation_state, void * other_instrumentation_state);\nchar * return_code_get_state(void * instrumentation_state);\nvoid return_code_free_state(char * state);\nint return_code_set_state(void * instrumentation_state, char * state);\nint return_code_enable(void * instrumentation_state, pid_t * process, char * cmd_line, char * input, size_t input_length);\nint return_code_is_new_path(void * instrumentation_state);\nint return_code_get_fuzz_result(void * instrumentation_state);\nint return_code_is_process_done(void * instrumentation_state);\nint return_code_help(char ** help_str);\n\nstruct return_code_state\n{\n\tint fork_server_setup;\n\tint use_fork_server;\n\tforkserver_t fs;\n\n\tpid_t child_pid;\n\n\tint enable_called;\n\tint last_status;\n\tint process_reaped; // used to prevent further calls to get_process_status if the process has been reaped\n};\ntypedef struct return_code_state return_code_state_t;\n"
  },
  {
    "path": "instrumentation/uthash.h",
    "content": "/*\nCopyright (c) 2003-2018, Troy D. Hanson     http://troydhanson.github.com/uthash/\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\nTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\nOR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\nPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef UTHASH_H\n#define UTHASH_H\n\n#define UTHASH_VERSION 2.0.2\n\n#include <string.h>   /* memcmp, memset, strlen */\n#include <stddef.h>   /* ptrdiff_t */\n#include <stdlib.h>   /* exit */\n\n/* These macros use decltype or the earlier __typeof GNU extension.\n   As decltype is only available in newer compilers (VS2010 or gcc 4.3+\n   when compiling c++ source) this code uses whatever method is needed\n   or, for VS2008 where neither is available, uses casting workarounds. */\n#if !defined(DECLTYPE) && !defined(NO_DECLTYPE)\n#if defined(_MSC_VER)   /* MS compiler */\n#if _MSC_VER >= 1600 && defined(__cplusplus)  /* VS2010 or newer in C++ mode */\n#define DECLTYPE(x) (decltype(x))\n#else                   /* VS2008 or older (or VS2010 in C mode) */\n#define NO_DECLTYPE\n#endif\n#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__)\n#define NO_DECLTYPE\n#else                   /* GNU, Sun and other compilers */\n#define DECLTYPE(x) (__typeof(x))\n#endif\n#endif\n\n#ifdef NO_DECLTYPE\n#define DECLTYPE(x)\n#define DECLTYPE_ASSIGN(dst,src)                                                 \\\ndo {                                                                             \\\n  char **_da_dst = (char**)(&(dst));                                             \\\n  *_da_dst = (char*)(src);                                                       \\\n} while (0)\n#else\n#define DECLTYPE_ASSIGN(dst,src)                                                 \\\ndo {                                                                             \\\n  (dst) = DECLTYPE(dst)(src);                                                    \\\n} while (0)\n#endif\n\n/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */\n#if defined(_WIN32)\n#if defined(_MSC_VER) && _MSC_VER >= 1600\n#include <stdint.h>\n#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__)\n#include <stdint.h>\n#else\ntypedef unsigned int uint32_t;\ntypedef unsigned char uint8_t;\n#endif\n#elif defined(__GNUC__) && !defined(__VXWORKS__)\n#include <stdint.h>\n#else\ntypedef unsigned int uint32_t;\ntypedef unsigned char uint8_t;\n#endif\n\n#ifndef uthash_malloc\n#define uthash_malloc(sz) malloc(sz)      /* malloc fcn                      */\n#endif\n#ifndef uthash_free\n#define uthash_free(ptr,sz) free(ptr)     /* free fcn                        */\n#endif\n#ifndef uthash_bzero\n#define uthash_bzero(a,n) memset(a,'\\0',n)\n#endif\n#ifndef uthash_memcmp\n#define uthash_memcmp(a,b,n) memcmp(a,b,n)\n#endif\n#ifndef uthash_strlen\n#define uthash_strlen(s) strlen(s)\n#endif\n\n#ifndef uthash_noexpand_fyi\n#define uthash_noexpand_fyi(tbl)          /* can be defined to log noexpand  */\n#endif\n#ifndef uthash_expand_fyi\n#define uthash_expand_fyi(tbl)            /* can be defined to log expands   */\n#endif\n\n#ifndef HASH_NONFATAL_OOM\n#define HASH_NONFATAL_OOM 0\n#endif\n\n#if HASH_NONFATAL_OOM\n/* malloc failures can be recovered from */\n\n#ifndef uthash_nonfatal_oom\n#define uthash_nonfatal_oom(obj) do {} while (0)    /* non-fatal OOM error */\n#endif\n\n#define HASH_RECORD_OOM(oomed) do { (oomed) = 1; } while (0)\n#define IF_HASH_NONFATAL_OOM(x) x\n\n#else\n/* malloc failures result in lost memory, hash tables are unusable */\n\n#ifndef uthash_fatal\n#define uthash_fatal(msg) exit(-1)        /* fatal OOM error */\n#endif\n\n#define HASH_RECORD_OOM(oomed) uthash_fatal(\"out of memory\")\n#define IF_HASH_NONFATAL_OOM(x)\n\n#endif\n\n/* initial number of buckets */\n#define HASH_INITIAL_NUM_BUCKETS 32U     /* initial number of buckets        */\n#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */\n#define HASH_BKT_CAPACITY_THRESH 10U     /* expand when bucket count reaches */\n\n/* calculate the element whose hash handle address is hhp */\n#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))\n/* calculate the hash handle from element address elp */\n#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle *)(((char*)(elp)) + ((tbl)->hho)))\n\n#define HASH_ROLLBACK_BKT(hh, head, itemptrhh)                                   \\\ndo {                                                                             \\\n  struct UT_hash_handle *_hd_hh_item = (itemptrhh);                              \\\n  unsigned _hd_bkt;                                                              \\\n  HASH_TO_BKT(_hd_hh_item->hashv, (head)->hh.tbl->num_buckets, _hd_bkt);         \\\n  (head)->hh.tbl->buckets[_hd_bkt].count++;                                      \\\n  _hd_hh_item->hh_next = NULL;                                                   \\\n  _hd_hh_item->hh_prev = NULL;                                                   \\\n} while (0)\n\n#define HASH_VALUE(keyptr,keylen,hashv)                                          \\\ndo {                                                                             \\\n  HASH_FCN(keyptr, keylen, hashv);                                               \\\n} while (0)\n\n#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out)                 \\\ndo {                                                                             \\\n  (out) = NULL;                                                                  \\\n  if (head) {                                                                    \\\n    unsigned _hf_bkt;                                                            \\\n    HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt);                  \\\n    if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) {                         \\\n      HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \\\n    }                                                                            \\\n  }                                                                              \\\n} while (0)\n\n#define HASH_FIND(hh,head,keyptr,keylen,out)                                     \\\ndo {                                                                             \\\n  unsigned _hf_hashv;                                                            \\\n  HASH_VALUE(keyptr, keylen, _hf_hashv);                                         \\\n  HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out);               \\\n} while (0)\n\n#ifdef HASH_BLOOM\n#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM)\n#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL)\n#define HASH_BLOOM_MAKE(tbl,oomed)                                               \\\ndo {                                                                             \\\n  (tbl)->bloom_nbits = HASH_BLOOM;                                               \\\n  (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN);                 \\\n  if (!(tbl)->bloom_bv) {                                                        \\\n    HASH_RECORD_OOM(oomed);                                                      \\\n  } else {                                                                       \\\n    uthash_bzero((tbl)->bloom_bv, HASH_BLOOM_BYTELEN);                           \\\n    (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE;                                     \\\n  }                                                                              \\\n} while (0)\n\n#define HASH_BLOOM_FREE(tbl)                                                     \\\ndo {                                                                             \\\n  uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN);                              \\\n} while (0)\n\n#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U)))\n#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U)))\n\n#define HASH_BLOOM_ADD(tbl,hashv)                                                \\\n  HASH_BLOOM_BITSET((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U)))\n\n#define HASH_BLOOM_TEST(tbl,hashv)                                               \\\n  HASH_BLOOM_BITTEST((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U)))\n\n#else\n#define HASH_BLOOM_MAKE(tbl,oomed)\n#define HASH_BLOOM_FREE(tbl)\n#define HASH_BLOOM_ADD(tbl,hashv)\n#define HASH_BLOOM_TEST(tbl,hashv) (1)\n#define HASH_BLOOM_BYTELEN 0U\n#endif\n\n#define HASH_MAKE_TABLE(hh,head,oomed)                                           \\\ndo {                                                                             \\\n  (head)->hh.tbl = (UT_hash_table*)uthash_malloc(sizeof(UT_hash_table));         \\\n  if (!(head)->hh.tbl) {                                                         \\\n    HASH_RECORD_OOM(oomed);                                                      \\\n  } else {                                                                       \\\n    uthash_bzero((head)->hh.tbl, sizeof(UT_hash_table));                         \\\n    (head)->hh.tbl->tail = &((head)->hh);                                        \\\n    (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS;                      \\\n    (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2;            \\\n    (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head);                  \\\n    (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc(                    \\\n        HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket));               \\\n    (head)->hh.tbl->signature = HASH_SIGNATURE;                                  \\\n    if (!(head)->hh.tbl->buckets) {                                              \\\n      HASH_RECORD_OOM(oomed);                                                    \\\n      uthash_free((head)->hh.tbl, sizeof(UT_hash_table));                        \\\n    } else {                                                                     \\\n      uthash_bzero((head)->hh.tbl->buckets,                                      \\\n          HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket));             \\\n      HASH_BLOOM_MAKE((head)->hh.tbl, oomed);                                    \\\n      IF_HASH_NONFATAL_OOM(                                                      \\\n        if (oomed) {                                                             \\\n          uthash_free((head)->hh.tbl->buckets,                                   \\\n              HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket));           \\\n          uthash_free((head)->hh.tbl, sizeof(UT_hash_table));                    \\\n        }                                                                        \\\n      )                                                                          \\\n    }                                                                            \\\n  }                                                                              \\\n} while (0)\n\n#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \\\ndo {                                                                             \\\n  (replaced) = NULL;                                                             \\\n  HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \\\n  if (replaced) {                                                                \\\n    HASH_DELETE(hh, head, replaced);                                             \\\n  }                                                                              \\\n  HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \\\n} while (0)\n\n#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \\\ndo {                                                                             \\\n  (replaced) = NULL;                                                             \\\n  HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \\\n  if (replaced) {                                                                \\\n    HASH_DELETE(hh, head, replaced);                                             \\\n  }                                                                              \\\n  HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \\\n} while (0)\n\n#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced)                   \\\ndo {                                                                             \\\n  unsigned _hr_hashv;                                                            \\\n  HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv);                         \\\n  HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \\\n} while (0)\n\n#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn)    \\\ndo {                                                                             \\\n  unsigned _hr_hashv;                                                            \\\n  HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv);                         \\\n  HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \\\n} while (0)\n\n#define HASH_APPEND_LIST(hh, head, add)                                          \\\ndo {                                                                             \\\n  (add)->hh.next = NULL;                                                         \\\n  (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail);           \\\n  (head)->hh.tbl->tail->next = (add);                                            \\\n  (head)->hh.tbl->tail = &((add)->hh);                                           \\\n} while (0)\n\n#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn)                                 \\\ndo {                                                                             \\\n  do {                                                                           \\\n    if (cmpfcn(DECLTYPE(head)(_hs_iter), add) > 0) {                             \\\n      break;                                                                     \\\n    }                                                                            \\\n  } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next));           \\\n} while (0)\n\n#ifdef NO_DECLTYPE\n#undef HASH_AKBI_INNER_LOOP\n#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn)                                 \\\ndo {                                                                             \\\n  char *_hs_saved_head = (char*)(head);                                          \\\n  do {                                                                           \\\n    DECLTYPE_ASSIGN(head, _hs_iter);                                             \\\n    if (cmpfcn(head, add) > 0) {                                                 \\\n      DECLTYPE_ASSIGN(head, _hs_saved_head);                                     \\\n      break;                                                                     \\\n    }                                                                            \\\n    DECLTYPE_ASSIGN(head, _hs_saved_head);                                       \\\n  } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next));           \\\n} while (0)\n#endif\n\n#if HASH_NONFATAL_OOM\n\n#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed)            \\\ndo {                                                                             \\\n  if (!(oomed)) {                                                                \\\n    unsigned _ha_bkt;                                                            \\\n    (head)->hh.tbl->num_items++;                                                 \\\n    HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt);                  \\\n    HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed);    \\\n    if (oomed) {                                                                 \\\n      HASH_ROLLBACK_BKT(hh, head, &(add)->hh);                                   \\\n      HASH_DELETE_HH(hh, head, &(add)->hh);                                      \\\n      (add)->hh.tbl = NULL;                                                      \\\n      uthash_nonfatal_oom(add);                                                  \\\n    } else {                                                                     \\\n      HASH_BLOOM_ADD((head)->hh.tbl, hashval);                                   \\\n      HASH_EMIT_KEY(hh, head, keyptr, keylen_in);                                \\\n    }                                                                            \\\n  } else {                                                                       \\\n    (add)->hh.tbl = NULL;                                                        \\\n    uthash_nonfatal_oom(add);                                                    \\\n  }                                                                              \\\n} while (0)\n\n#else\n\n#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed)            \\\ndo {                                                                             \\\n  unsigned _ha_bkt;                                                              \\\n  (head)->hh.tbl->num_items++;                                                   \\\n  HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt);                    \\\n  HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed);      \\\n  HASH_BLOOM_ADD((head)->hh.tbl, hashval);                                       \\\n  HASH_EMIT_KEY(hh, head, keyptr, keylen_in);                                    \\\n} while (0)\n\n#endif\n\n\n#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \\\ndo {                                                                             \\\n  IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; )                                     \\\n  (add)->hh.hashv = (hashval);                                                   \\\n  (add)->hh.key = (char*) (keyptr);                                              \\\n  (add)->hh.keylen = (unsigned) (keylen_in);                                     \\\n  if (!(head)) {                                                                 \\\n    (add)->hh.next = NULL;                                                       \\\n    (add)->hh.prev = NULL;                                                       \\\n    HASH_MAKE_TABLE(hh, add, _ha_oomed);                                         \\\n    IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { )                                    \\\n      (head) = (add);                                                            \\\n    IF_HASH_NONFATAL_OOM( } )                                                    \\\n  } else {                                                                       \\\n    void *_hs_iter = (head);                                                     \\\n    (add)->hh.tbl = (head)->hh.tbl;                                              \\\n    HASH_AKBI_INNER_LOOP(hh, head, add, cmpfcn);                                 \\\n    if (_hs_iter) {                                                              \\\n      (add)->hh.next = _hs_iter;                                                 \\\n      if (((add)->hh.prev = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev)) {     \\\n        HH_FROM_ELMT((head)->hh.tbl, (add)->hh.prev)->next = (add);              \\\n      } else {                                                                   \\\n        (head) = (add);                                                          \\\n      }                                                                          \\\n      HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev = (add);                      \\\n    } else {                                                                     \\\n      HASH_APPEND_LIST(hh, head, add);                                           \\\n    }                                                                            \\\n  }                                                                              \\\n  HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed);       \\\n  HASH_FSCK(hh, head, \"HASH_ADD_KEYPTR_BYHASHVALUE_INORDER\");                    \\\n} while (0)\n\n#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn)             \\\ndo {                                                                             \\\n  unsigned _hs_hashv;                                                            \\\n  HASH_VALUE(keyptr, keylen_in, _hs_hashv);                                      \\\n  HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \\\n} while (0)\n\n#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \\\n  HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn)\n\n#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn)                 \\\n  HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn)\n\n#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add)        \\\ndo {                                                                             \\\n  IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; )                                     \\\n  (add)->hh.hashv = (hashval);                                                   \\\n  (add)->hh.key = (char*) (keyptr);                                              \\\n  (add)->hh.keylen = (unsigned) (keylen_in);                                     \\\n  if (!(head)) {                                                                 \\\n    (add)->hh.next = NULL;                                                       \\\n    (add)->hh.prev = NULL;                                                       \\\n    HASH_MAKE_TABLE(hh, add, _ha_oomed);                                         \\\n    IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { )                                    \\\n      (head) = (add);                                                            \\\n    IF_HASH_NONFATAL_OOM( } )                                                    \\\n  } else {                                                                       \\\n    (add)->hh.tbl = (head)->hh.tbl;                                              \\\n    HASH_APPEND_LIST(hh, head, add);                                             \\\n  }                                                                              \\\n  HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed);       \\\n  HASH_FSCK(hh, head, \"HASH_ADD_KEYPTR_BYHASHVALUE\");                            \\\n} while (0)\n\n#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add)                            \\\ndo {                                                                             \\\n  unsigned _ha_hashv;                                                            \\\n  HASH_VALUE(keyptr, keylen_in, _ha_hashv);                                      \\\n  HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add);      \\\n} while (0)\n\n#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add)            \\\n  HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add)\n\n#define HASH_ADD(hh,head,fieldname,keylen_in,add)                                \\\n  HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add)\n\n#define HASH_TO_BKT(hashv,num_bkts,bkt)                                          \\\ndo {                                                                             \\\n  bkt = ((hashv) & ((num_bkts) - 1U));                                           \\\n} while (0)\n\n/* delete \"delptr\" from the hash table.\n * \"the usual\" patch-up process for the app-order doubly-linked-list.\n * The use of _hd_hh_del below deserves special explanation.\n * These used to be expressed using (delptr) but that led to a bug\n * if someone used the same symbol for the head and deletee, like\n *  HASH_DELETE(hh,users,users);\n * We want that to work, but by changing the head (users) below\n * we were forfeiting our ability to further refer to the deletee (users)\n * in the patch-up process. Solution: use scratch space to\n * copy the deletee pointer, then the latter references are via that\n * scratch pointer rather than through the repointed (users) symbol.\n */\n#define HASH_DELETE(hh,head,delptr)                                              \\\n    HASH_DELETE_HH(hh, head, &(delptr)->hh)\n\n#define HASH_DELETE_HH(hh,head,delptrhh)                                         \\\ndo {                                                                             \\\n  struct UT_hash_handle *_hd_hh_del = (delptrhh);                                \\\n  if ((_hd_hh_del->prev == NULL) && (_hd_hh_del->next == NULL)) {                \\\n    HASH_BLOOM_FREE((head)->hh.tbl);                                             \\\n    uthash_free((head)->hh.tbl->buckets,                                         \\\n                (head)->hh.tbl->num_buckets * sizeof(struct UT_hash_bucket));    \\\n    uthash_free((head)->hh.tbl, sizeof(UT_hash_table));                          \\\n    (head) = NULL;                                                               \\\n  } else {                                                                       \\\n    unsigned _hd_bkt;                                                            \\\n    if (_hd_hh_del == (head)->hh.tbl->tail) {                                    \\\n      (head)->hh.tbl->tail = HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev);     \\\n    }                                                                            \\\n    if (_hd_hh_del->prev != NULL) {                                              \\\n      HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev)->next = _hd_hh_del->next;   \\\n    } else {                                                                     \\\n      DECLTYPE_ASSIGN(head, _hd_hh_del->next);                                   \\\n    }                                                                            \\\n    if (_hd_hh_del->next != NULL) {                                              \\\n      HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->next)->prev = _hd_hh_del->prev;   \\\n    }                                                                            \\\n    HASH_TO_BKT(_hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt);        \\\n    HASH_DEL_IN_BKT((head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del);               \\\n    (head)->hh.tbl->num_items--;                                                 \\\n  }                                                                              \\\n  HASH_FSCK(hh, head, \"HASH_DELETE_HH\");                                         \\\n} while (0)\n\n/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */\n#define HASH_FIND_STR(head,findstr,out)                                          \\\ndo {                                                                             \\\n    unsigned _uthash_hfstr_keylen = (unsigned)uthash_strlen(findstr);            \\\n    HASH_FIND(hh, head, findstr, _uthash_hfstr_keylen, out);                     \\\n} while (0)\n#define HASH_ADD_STR(head,strfield,add)                                          \\\ndo {                                                                             \\\n    unsigned _uthash_hastr_keylen = (unsigned)uthash_strlen((add)->strfield);    \\\n    HASH_ADD(hh, head, strfield[0], _uthash_hastr_keylen, add);                  \\\n} while (0)\n#define HASH_REPLACE_STR(head,strfield,add,replaced)                             \\\ndo {                                                                             \\\n    unsigned _uthash_hrstr_keylen = (unsigned)uthash_strlen((add)->strfield);    \\\n    HASH_REPLACE(hh, head, strfield[0], _uthash_hrstr_keylen, add, replaced);    \\\n} while (0)\n#define HASH_FIND_INT(head,findint,out)                                          \\\n    HASH_FIND(hh,head,findint,sizeof(int),out)\n#define HASH_ADD_INT(head,intfield,add)                                          \\\n    HASH_ADD(hh,head,intfield,sizeof(int),add)\n#define HASH_REPLACE_INT(head,intfield,add,replaced)                             \\\n    HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced)\n#define HASH_FIND_PTR(head,findptr,out)                                          \\\n    HASH_FIND(hh,head,findptr,sizeof(void *),out)\n#define HASH_ADD_PTR(head,ptrfield,add)                                          \\\n    HASH_ADD(hh,head,ptrfield,sizeof(void *),add)\n#define HASH_REPLACE_PTR(head,ptrfield,add,replaced)                             \\\n    HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced)\n#define HASH_DEL(head,delptr)                                                    \\\n    HASH_DELETE(hh,head,delptr)\n\n/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined.\n * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.\n */\n#ifdef HASH_DEBUG\n#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)\n#define HASH_FSCK(hh,head,where)                                                 \\\ndo {                                                                             \\\n  struct UT_hash_handle *_thh;                                                   \\\n  if (head) {                                                                    \\\n    unsigned _bkt_i;                                                             \\\n    unsigned _count = 0;                                                         \\\n    char *_prev;                                                                 \\\n    for (_bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; ++_bkt_i) {           \\\n      unsigned _bkt_count = 0;                                                   \\\n      _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head;                            \\\n      _prev = NULL;                                                              \\\n      while (_thh) {                                                             \\\n        if (_prev != (char*)(_thh->hh_prev)) {                                   \\\n          HASH_OOPS(\"%s: invalid hh_prev %p, actual %p\\n\",                       \\\n              (where), (void*)_thh->hh_prev, (void*)_prev);                      \\\n        }                                                                        \\\n        _bkt_count++;                                                            \\\n        _prev = (char*)(_thh);                                                   \\\n        _thh = _thh->hh_next;                                                    \\\n      }                                                                          \\\n      _count += _bkt_count;                                                      \\\n      if ((head)->hh.tbl->buckets[_bkt_i].count !=  _bkt_count) {                \\\n        HASH_OOPS(\"%s: invalid bucket count %u, actual %u\\n\",                    \\\n            (where), (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count);         \\\n      }                                                                          \\\n    }                                                                            \\\n    if (_count != (head)->hh.tbl->num_items) {                                   \\\n      HASH_OOPS(\"%s: invalid hh item count %u, actual %u\\n\",                     \\\n          (where), (head)->hh.tbl->num_items, _count);                           \\\n    }                                                                            \\\n    _count = 0;                                                                  \\\n    _prev = NULL;                                                                \\\n    _thh =  &(head)->hh;                                                         \\\n    while (_thh) {                                                               \\\n      _count++;                                                                  \\\n      if (_prev != (char*)_thh->prev) {                                          \\\n        HASH_OOPS(\"%s: invalid prev %p, actual %p\\n\",                            \\\n            (where), (void*)_thh->prev, (void*)_prev);                           \\\n      }                                                                          \\\n      _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh);                         \\\n      _thh = (_thh->next ? HH_FROM_ELMT((head)->hh.tbl, _thh->next) : NULL);     \\\n    }                                                                            \\\n    if (_count != (head)->hh.tbl->num_items) {                                   \\\n      HASH_OOPS(\"%s: invalid app item count %u, actual %u\\n\",                    \\\n          (where), (head)->hh.tbl->num_items, _count);                           \\\n    }                                                                            \\\n  }                                                                              \\\n} while (0)\n#else\n#define HASH_FSCK(hh,head,where)\n#endif\n\n/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to\n * the descriptor to which this macro is defined for tuning the hash function.\n * The app can #include <unistd.h> to get the prototype for write(2). */\n#ifdef HASH_EMIT_KEYS\n#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)                                   \\\ndo {                                                                             \\\n  unsigned _klen = fieldlen;                                                     \\\n  write(HASH_EMIT_KEYS, &_klen, sizeof(_klen));                                  \\\n  write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen);                        \\\n} while (0)\n#else\n#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)\n#endif\n\n/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */\n#ifdef HASH_FUNCTION\n#define HASH_FCN HASH_FUNCTION\n#else\n#define HASH_FCN HASH_JEN\n#endif\n\n/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */\n#define HASH_BER(key,keylen,hashv)                                               \\\ndo {                                                                             \\\n  unsigned _hb_keylen = (unsigned)keylen;                                        \\\n  const unsigned char *_hb_key = (const unsigned char*)(key);                    \\\n  (hashv) = 0;                                                                   \\\n  while (_hb_keylen-- != 0U) {                                                   \\\n    (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++;                           \\\n  }                                                                              \\\n} while (0)\n\n\n/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at\n * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */\n#define HASH_SAX(key,keylen,hashv)                                               \\\ndo {                                                                             \\\n  unsigned _sx_i;                                                                \\\n  const unsigned char *_hs_key = (const unsigned char*)(key);                    \\\n  hashv = 0;                                                                     \\\n  for (_sx_i=0; _sx_i < keylen; _sx_i++) {                                       \\\n    hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i];                       \\\n  }                                                                              \\\n} while (0)\n/* FNV-1a variation */\n#define HASH_FNV(key,keylen,hashv)                                               \\\ndo {                                                                             \\\n  unsigned _fn_i;                                                                \\\n  const unsigned char *_hf_key = (const unsigned char*)(key);                    \\\n  (hashv) = 2166136261U;                                                         \\\n  for (_fn_i=0; _fn_i < keylen; _fn_i++) {                                       \\\n    hashv = hashv ^ _hf_key[_fn_i];                                              \\\n    hashv = hashv * 16777619U;                                                   \\\n  }                                                                              \\\n} while (0)\n\n#define HASH_OAT(key,keylen,hashv)                                               \\\ndo {                                                                             \\\n  unsigned _ho_i;                                                                \\\n  const unsigned char *_ho_key=(const unsigned char*)(key);                      \\\n  hashv = 0;                                                                     \\\n  for(_ho_i=0; _ho_i < keylen; _ho_i++) {                                        \\\n      hashv += _ho_key[_ho_i];                                                   \\\n      hashv += (hashv << 10);                                                    \\\n      hashv ^= (hashv >> 6);                                                     \\\n  }                                                                              \\\n  hashv += (hashv << 3);                                                         \\\n  hashv ^= (hashv >> 11);                                                        \\\n  hashv += (hashv << 15);                                                        \\\n} while (0)\n\n#define HASH_JEN_MIX(a,b,c)                                                      \\\ndo {                                                                             \\\n  a -= b; a -= c; a ^= ( c >> 13 );                                              \\\n  b -= c; b -= a; b ^= ( a << 8 );                                               \\\n  c -= a; c -= b; c ^= ( b >> 13 );                                              \\\n  a -= b; a -= c; a ^= ( c >> 12 );                                              \\\n  b -= c; b -= a; b ^= ( a << 16 );                                              \\\n  c -= a; c -= b; c ^= ( b >> 5 );                                               \\\n  a -= b; a -= c; a ^= ( c >> 3 );                                               \\\n  b -= c; b -= a; b ^= ( a << 10 );                                              \\\n  c -= a; c -= b; c ^= ( b >> 15 );                                              \\\n} while (0)\n\n#define HASH_JEN(key,keylen,hashv)                                               \\\ndo {                                                                             \\\n  unsigned _hj_i,_hj_j,_hj_k;                                                    \\\n  unsigned const char *_hj_key=(unsigned const char*)(key);                      \\\n  hashv = 0xfeedbeefu;                                                           \\\n  _hj_i = _hj_j = 0x9e3779b9u;                                                   \\\n  _hj_k = (unsigned)(keylen);                                                    \\\n  while (_hj_k >= 12U) {                                                         \\\n    _hj_i +=    (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 )                      \\\n        + ( (unsigned)_hj_key[2] << 16 )                                         \\\n        + ( (unsigned)_hj_key[3] << 24 ) );                                      \\\n    _hj_j +=    (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 )                      \\\n        + ( (unsigned)_hj_key[6] << 16 )                                         \\\n        + ( (unsigned)_hj_key[7] << 24 ) );                                      \\\n    hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 )                         \\\n        + ( (unsigned)_hj_key[10] << 16 )                                        \\\n        + ( (unsigned)_hj_key[11] << 24 ) );                                     \\\n                                                                                 \\\n     HASH_JEN_MIX(_hj_i, _hj_j, hashv);                                          \\\n                                                                                 \\\n     _hj_key += 12;                                                              \\\n     _hj_k -= 12U;                                                               \\\n  }                                                                              \\\n  hashv += (unsigned)(keylen);                                                   \\\n  switch ( _hj_k ) {                                                             \\\n    case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */         \\\n    case 10: hashv += ( (unsigned)_hj_key[9] << 16 );  /* FALLTHROUGH */         \\\n    case 9:  hashv += ( (unsigned)_hj_key[8] << 8 );   /* FALLTHROUGH */         \\\n    case 8:  _hj_j += ( (unsigned)_hj_key[7] << 24 );  /* FALLTHROUGH */         \\\n    case 7:  _hj_j += ( (unsigned)_hj_key[6] << 16 );  /* FALLTHROUGH */         \\\n    case 6:  _hj_j += ( (unsigned)_hj_key[5] << 8 );   /* FALLTHROUGH */         \\\n    case 5:  _hj_j += _hj_key[4];                      /* FALLTHROUGH */         \\\n    case 4:  _hj_i += ( (unsigned)_hj_key[3] << 24 );  /* FALLTHROUGH */         \\\n    case 3:  _hj_i += ( (unsigned)_hj_key[2] << 16 );  /* FALLTHROUGH */         \\\n    case 2:  _hj_i += ( (unsigned)_hj_key[1] << 8 );   /* FALLTHROUGH */         \\\n    case 1:  _hj_i += _hj_key[0];                                                \\\n  }                                                                              \\\n  HASH_JEN_MIX(_hj_i, _hj_j, hashv);                                             \\\n} while (0)\n\n/* The Paul Hsieh hash function */\n#undef get16bits\n#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__)             \\\n  || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)\n#define get16bits(d) (*((const uint16_t *) (d)))\n#endif\n\n#if !defined (get16bits)\n#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)             \\\n                       +(uint32_t)(((const uint8_t *)(d))[0]) )\n#endif\n#define HASH_SFH(key,keylen,hashv)                                               \\\ndo {                                                                             \\\n  unsigned const char *_sfh_key=(unsigned const char*)(key);                     \\\n  uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen;                                \\\n                                                                                 \\\n  unsigned _sfh_rem = _sfh_len & 3U;                                             \\\n  _sfh_len >>= 2;                                                                \\\n  hashv = 0xcafebabeu;                                                           \\\n                                                                                 \\\n  /* Main loop */                                                                \\\n  for (;_sfh_len > 0U; _sfh_len--) {                                             \\\n    hashv    += get16bits (_sfh_key);                                            \\\n    _sfh_tmp  = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv;              \\\n    hashv     = (hashv << 16) ^ _sfh_tmp;                                        \\\n    _sfh_key += 2U*sizeof (uint16_t);                                            \\\n    hashv    += hashv >> 11;                                                     \\\n  }                                                                              \\\n                                                                                 \\\n  /* Handle end cases */                                                         \\\n  switch (_sfh_rem) {                                                            \\\n    case 3: hashv += get16bits (_sfh_key);                                       \\\n            hashv ^= hashv << 16;                                                \\\n            hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18;              \\\n            hashv += hashv >> 11;                                                \\\n            break;                                                               \\\n    case 2: hashv += get16bits (_sfh_key);                                       \\\n            hashv ^= hashv << 11;                                                \\\n            hashv += hashv >> 17;                                                \\\n            break;                                                               \\\n    case 1: hashv += *_sfh_key;                                                  \\\n            hashv ^= hashv << 10;                                                \\\n            hashv += hashv >> 1;                                                 \\\n  }                                                                              \\\n                                                                                 \\\n  /* Force \"avalanching\" of final 127 bits */                                    \\\n  hashv ^= hashv << 3;                                                           \\\n  hashv += hashv >> 5;                                                           \\\n  hashv ^= hashv << 4;                                                           \\\n  hashv += hashv >> 17;                                                          \\\n  hashv ^= hashv << 25;                                                          \\\n  hashv += hashv >> 6;                                                           \\\n} while (0)\n\n#ifdef HASH_USING_NO_STRICT_ALIASING\n/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads.\n * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.\n * MurmurHash uses the faster approach only on CPU's where we know it's safe.\n *\n * Note the preprocessor built-in defines can be emitted using:\n *\n *   gcc -m64 -dM -E - < /dev/null                  (on gcc)\n *   cc -## a.c (where a.c is a simple test file)   (Sun Studio)\n */\n#if (defined(__i386__) || defined(__x86_64__)  || defined(_M_IX86))\n#define MUR_GETBLOCK(p,i) p[i]\n#else /* non intel */\n#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 3UL) == 0UL)\n#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 3UL) == 1UL)\n#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 3UL) == 2UL)\n#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 3UL) == 3UL)\n#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL))\n#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__))\n#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24))\n#define MUR_TWO_TWO(p)   ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16))\n#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >>  8))\n#else /* assume little endian non-intel */\n#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24))\n#define MUR_TWO_TWO(p)   ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16))\n#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) <<  8))\n#endif\n#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) :           \\\n                            (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \\\n                             (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) :  \\\n                                                      MUR_ONE_THREE(p))))\n#endif\n#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))\n#define MUR_FMIX(_h) \\\ndo {                 \\\n  _h ^= _h >> 16;    \\\n  _h *= 0x85ebca6bu; \\\n  _h ^= _h >> 13;    \\\n  _h *= 0xc2b2ae35u; \\\n  _h ^= _h >> 16;    \\\n} while (0)\n\n#define HASH_MUR(key,keylen,hashv)                                     \\\ndo {                                                                   \\\n  const uint8_t *_mur_data = (const uint8_t*)(key);                    \\\n  const int _mur_nblocks = (int)(keylen) / 4;                          \\\n  uint32_t _mur_h1 = 0xf88D5353u;                                      \\\n  uint32_t _mur_c1 = 0xcc9e2d51u;                                      \\\n  uint32_t _mur_c2 = 0x1b873593u;                                      \\\n  uint32_t _mur_k1 = 0;                                                \\\n  const uint8_t *_mur_tail;                                            \\\n  const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+(_mur_nblocks*4)); \\\n  int _mur_i;                                                          \\\n  for (_mur_i = -_mur_nblocks; _mur_i != 0; _mur_i++) {                \\\n    _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i);                        \\\n    _mur_k1 *= _mur_c1;                                                \\\n    _mur_k1 = MUR_ROTL32(_mur_k1,15);                                  \\\n    _mur_k1 *= _mur_c2;                                                \\\n                                                                       \\\n    _mur_h1 ^= _mur_k1;                                                \\\n    _mur_h1 = MUR_ROTL32(_mur_h1,13);                                  \\\n    _mur_h1 = (_mur_h1*5U) + 0xe6546b64u;                              \\\n  }                                                                    \\\n  _mur_tail = (const uint8_t*)(_mur_data + (_mur_nblocks*4));          \\\n  _mur_k1=0;                                                           \\\n  switch ((keylen) & 3U) {                                             \\\n    case 0: break;                                                     \\\n    case 3: _mur_k1 ^= (uint32_t)_mur_tail[2] << 16; /* FALLTHROUGH */ \\\n    case 2: _mur_k1 ^= (uint32_t)_mur_tail[1] << 8;  /* FALLTHROUGH */ \\\n    case 1: _mur_k1 ^= (uint32_t)_mur_tail[0];                         \\\n    _mur_k1 *= _mur_c1;                                                \\\n    _mur_k1 = MUR_ROTL32(_mur_k1,15);                                  \\\n    _mur_k1 *= _mur_c2;                                                \\\n    _mur_h1 ^= _mur_k1;                                                \\\n  }                                                                    \\\n  _mur_h1 ^= (uint32_t)(keylen);                                       \\\n  MUR_FMIX(_mur_h1);                                                   \\\n  hashv = _mur_h1;                                                     \\\n} while (0)\n#endif  /* HASH_USING_NO_STRICT_ALIASING */\n\n/* iterate over items in a known bucket to find desired item */\n#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out)               \\\ndo {                                                                             \\\n  if ((head).hh_head != NULL) {                                                  \\\n    DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head));                     \\\n  } else {                                                                       \\\n    (out) = NULL;                                                                \\\n  }                                                                              \\\n  while ((out) != NULL) {                                                        \\\n    if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) {       \\\n      if (uthash_memcmp((out)->hh.key, keyptr, keylen_in) == 0) {                \\\n        break;                                                                   \\\n      }                                                                          \\\n    }                                                                            \\\n    if ((out)->hh.hh_next != NULL) {                                             \\\n      DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next));                \\\n    } else {                                                                     \\\n      (out) = NULL;                                                              \\\n    }                                                                            \\\n  }                                                                              \\\n} while (0)\n\n/* add an item to a bucket  */\n#define HASH_ADD_TO_BKT(head,hh,addhh,oomed)                                     \\\ndo {                                                                             \\\n  UT_hash_bucket *_ha_head = &(head);                                            \\\n  _ha_head->count++;                                                             \\\n  (addhh)->hh_next = _ha_head->hh_head;                                          \\\n  (addhh)->hh_prev = NULL;                                                       \\\n  if (_ha_head->hh_head != NULL) {                                               \\\n    _ha_head->hh_head->hh_prev = (addhh);                                        \\\n  }                                                                              \\\n  _ha_head->hh_head = (addhh);                                                   \\\n  if ((_ha_head->count >= ((_ha_head->expand_mult + 1U) * HASH_BKT_CAPACITY_THRESH)) \\\n      && !(addhh)->tbl->noexpand) {                                              \\\n    HASH_EXPAND_BUCKETS(addhh,(addhh)->tbl, oomed);                              \\\n    IF_HASH_NONFATAL_OOM(                                                        \\\n      if (oomed) {                                                               \\\n        HASH_DEL_IN_BKT(head,addhh);                                             \\\n      }                                                                          \\\n    )                                                                            \\\n  }                                                                              \\\n} while (0)\n\n/* remove an item from a given bucket */\n#define HASH_DEL_IN_BKT(head,delhh)                                              \\\ndo {                                                                             \\\n  UT_hash_bucket *_hd_head = &(head);                                            \\\n  _hd_head->count--;                                                             \\\n  if (_hd_head->hh_head == (delhh)) {                                            \\\n    _hd_head->hh_head = (delhh)->hh_next;                                        \\\n  }                                                                              \\\n  if ((delhh)->hh_prev) {                                                        \\\n    (delhh)->hh_prev->hh_next = (delhh)->hh_next;                                \\\n  }                                                                              \\\n  if ((delhh)->hh_next) {                                                        \\\n    (delhh)->hh_next->hh_prev = (delhh)->hh_prev;                                \\\n  }                                                                              \\\n} while (0)\n\n/* Bucket expansion has the effect of doubling the number of buckets\n * and redistributing the items into the new buckets. Ideally the\n * items will distribute more or less evenly into the new buckets\n * (the extent to which this is true is a measure of the quality of\n * the hash function as it applies to the key domain).\n *\n * With the items distributed into more buckets, the chain length\n * (item count) in each bucket is reduced. Thus by expanding buckets\n * the hash keeps a bound on the chain length. This bounded chain\n * length is the essence of how a hash provides constant time lookup.\n *\n * The calculation of tbl->ideal_chain_maxlen below deserves some\n * explanation. First, keep in mind that we're calculating the ideal\n * maximum chain length based on the *new* (doubled) bucket count.\n * In fractions this is just n/b (n=number of items,b=new num buckets).\n * Since the ideal chain length is an integer, we want to calculate\n * ceil(n/b). We don't depend on floating point arithmetic in this\n * hash, so to calculate ceil(n/b) with integers we could write\n *\n *      ceil(n/b) = (n/b) + ((n%b)?1:0)\n *\n * and in fact a previous version of this hash did just that.\n * But now we have improved things a bit by recognizing that b is\n * always a power of two. We keep its base 2 log handy (call it lb),\n * so now we can write this with a bit shift and logical AND:\n *\n *      ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)\n *\n */\n#define HASH_EXPAND_BUCKETS(hh,tbl,oomed)                                        \\\ndo {                                                                             \\\n  unsigned _he_bkt;                                                              \\\n  unsigned _he_bkt_i;                                                            \\\n  struct UT_hash_handle *_he_thh, *_he_hh_nxt;                                   \\\n  UT_hash_bucket *_he_new_buckets, *_he_newbkt;                                  \\\n  _he_new_buckets = (UT_hash_bucket*)uthash_malloc(                              \\\n           2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket));            \\\n  if (!_he_new_buckets) {                                                        \\\n    HASH_RECORD_OOM(oomed);                                                      \\\n  } else {                                                                       \\\n    uthash_bzero(_he_new_buckets,                                                \\\n        2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket));               \\\n    (tbl)->ideal_chain_maxlen =                                                  \\\n       ((tbl)->num_items >> ((tbl)->log2_num_buckets+1U)) +                      \\\n       ((((tbl)->num_items & (((tbl)->num_buckets*2U)-1U)) != 0U) ? 1U : 0U);    \\\n    (tbl)->nonideal_items = 0;                                                   \\\n    for (_he_bkt_i = 0; _he_bkt_i < (tbl)->num_buckets; _he_bkt_i++) {           \\\n      _he_thh = (tbl)->buckets[ _he_bkt_i ].hh_head;                             \\\n      while (_he_thh != NULL) {                                                  \\\n        _he_hh_nxt = _he_thh->hh_next;                                           \\\n        HASH_TO_BKT(_he_thh->hashv, (tbl)->num_buckets * 2U, _he_bkt);           \\\n        _he_newbkt = &(_he_new_buckets[_he_bkt]);                                \\\n        if (++(_he_newbkt->count) > (tbl)->ideal_chain_maxlen) {                 \\\n          (tbl)->nonideal_items++;                                               \\\n          _he_newbkt->expand_mult = _he_newbkt->count / (tbl)->ideal_chain_maxlen; \\\n        }                                                                        \\\n        _he_thh->hh_prev = NULL;                                                 \\\n        _he_thh->hh_next = _he_newbkt->hh_head;                                  \\\n        if (_he_newbkt->hh_head != NULL) {                                       \\\n          _he_newbkt->hh_head->hh_prev = _he_thh;                                \\\n        }                                                                        \\\n        _he_newbkt->hh_head = _he_thh;                                           \\\n        _he_thh = _he_hh_nxt;                                                    \\\n      }                                                                          \\\n    }                                                                            \\\n    uthash_free((tbl)->buckets, (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \\\n    (tbl)->num_buckets *= 2U;                                                    \\\n    (tbl)->log2_num_buckets++;                                                   \\\n    (tbl)->buckets = _he_new_buckets;                                            \\\n    (tbl)->ineff_expands = ((tbl)->nonideal_items > ((tbl)->num_items >> 1)) ?   \\\n        ((tbl)->ineff_expands+1U) : 0U;                                          \\\n    if ((tbl)->ineff_expands > 1U) {                                             \\\n      (tbl)->noexpand = 1;                                                       \\\n      uthash_noexpand_fyi(tbl);                                                  \\\n    }                                                                            \\\n    uthash_expand_fyi(tbl);                                                      \\\n  }                                                                              \\\n} while (0)\n\n\n/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */\n/* Note that HASH_SORT assumes the hash handle name to be hh.\n * HASH_SRT was added to allow the hash handle name to be passed in. */\n#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn)\n#define HASH_SRT(hh,head,cmpfcn)                                                 \\\ndo {                                                                             \\\n  unsigned _hs_i;                                                                \\\n  unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize;               \\\n  struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail;            \\\n  if (head != NULL) {                                                            \\\n    _hs_insize = 1;                                                              \\\n    _hs_looping = 1;                                                             \\\n    _hs_list = &((head)->hh);                                                    \\\n    while (_hs_looping != 0U) {                                                  \\\n      _hs_p = _hs_list;                                                          \\\n      _hs_list = NULL;                                                           \\\n      _hs_tail = NULL;                                                           \\\n      _hs_nmerges = 0;                                                           \\\n      while (_hs_p != NULL) {                                                    \\\n        _hs_nmerges++;                                                           \\\n        _hs_q = _hs_p;                                                           \\\n        _hs_psize = 0;                                                           \\\n        for (_hs_i = 0; _hs_i < _hs_insize; ++_hs_i) {                           \\\n          _hs_psize++;                                                           \\\n          _hs_q = ((_hs_q->next != NULL) ?                                       \\\n            HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL);                   \\\n          if (_hs_q == NULL) {                                                   \\\n            break;                                                               \\\n          }                                                                      \\\n        }                                                                        \\\n        _hs_qsize = _hs_insize;                                                  \\\n        while ((_hs_psize != 0U) || ((_hs_qsize != 0U) && (_hs_q != NULL))) {    \\\n          if (_hs_psize == 0U) {                                                 \\\n            _hs_e = _hs_q;                                                       \\\n            _hs_q = ((_hs_q->next != NULL) ?                                     \\\n              HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL);                 \\\n            _hs_qsize--;                                                         \\\n          } else if ((_hs_qsize == 0U) || (_hs_q == NULL)) {                     \\\n            _hs_e = _hs_p;                                                       \\\n            if (_hs_p != NULL) {                                                 \\\n              _hs_p = ((_hs_p->next != NULL) ?                                   \\\n                HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL);               \\\n            }                                                                    \\\n            _hs_psize--;                                                         \\\n          } else if ((cmpfcn(                                                    \\\n                DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_p)),             \\\n                DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_q))              \\\n                )) <= 0) {                                                       \\\n            _hs_e = _hs_p;                                                       \\\n            if (_hs_p != NULL) {                                                 \\\n              _hs_p = ((_hs_p->next != NULL) ?                                   \\\n                HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL);               \\\n            }                                                                    \\\n            _hs_psize--;                                                         \\\n          } else {                                                               \\\n            _hs_e = _hs_q;                                                       \\\n            _hs_q = ((_hs_q->next != NULL) ?                                     \\\n              HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL);                 \\\n            _hs_qsize--;                                                         \\\n          }                                                                      \\\n          if ( _hs_tail != NULL ) {                                              \\\n            _hs_tail->next = ((_hs_e != NULL) ?                                  \\\n              ELMT_FROM_HH((head)->hh.tbl, _hs_e) : NULL);                       \\\n          } else {                                                               \\\n            _hs_list = _hs_e;                                                    \\\n          }                                                                      \\\n          if (_hs_e != NULL) {                                                   \\\n            _hs_e->prev = ((_hs_tail != NULL) ?                                  \\\n              ELMT_FROM_HH((head)->hh.tbl, _hs_tail) : NULL);                    \\\n          }                                                                      \\\n          _hs_tail = _hs_e;                                                      \\\n        }                                                                        \\\n        _hs_p = _hs_q;                                                           \\\n      }                                                                          \\\n      if (_hs_tail != NULL) {                                                    \\\n        _hs_tail->next = NULL;                                                   \\\n      }                                                                          \\\n      if (_hs_nmerges <= 1U) {                                                   \\\n        _hs_looping = 0;                                                         \\\n        (head)->hh.tbl->tail = _hs_tail;                                         \\\n        DECLTYPE_ASSIGN(head, ELMT_FROM_HH((head)->hh.tbl, _hs_list));           \\\n      }                                                                          \\\n      _hs_insize *= 2U;                                                          \\\n    }                                                                            \\\n    HASH_FSCK(hh, head, \"HASH_SRT\");                                             \\\n  }                                                                              \\\n} while (0)\n\n/* This function selects items from one hash into another hash.\n * The end result is that the selected items have dual presence\n * in both hashes. There is no copy of the items made; rather\n * they are added into the new hash through a secondary hash\n * hash handle that must be present in the structure. */\n#define HASH_SELECT(hh_dst, dst, hh_src, src, cond)                              \\\ndo {                                                                             \\\n  unsigned _src_bkt, _dst_bkt;                                                   \\\n  void *_last_elt = NULL, *_elt;                                                 \\\n  UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL;                         \\\n  ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst));                 \\\n  if ((src) != NULL) {                                                           \\\n    for (_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) {    \\\n      for (_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head;               \\\n        _src_hh != NULL;                                                         \\\n        _src_hh = _src_hh->hh_next) {                                            \\\n        _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh);                         \\\n        if (cond(_elt)) {                                                        \\\n          IF_HASH_NONFATAL_OOM( int _hs_oomed = 0; )                             \\\n          _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho);                 \\\n          _dst_hh->key = _src_hh->key;                                           \\\n          _dst_hh->keylen = _src_hh->keylen;                                     \\\n          _dst_hh->hashv = _src_hh->hashv;                                       \\\n          _dst_hh->prev = _last_elt;                                             \\\n          _dst_hh->next = NULL;                                                  \\\n          if (_last_elt_hh != NULL) {                                            \\\n            _last_elt_hh->next = _elt;                                           \\\n          }                                                                      \\\n          if ((dst) == NULL) {                                                   \\\n            DECLTYPE_ASSIGN(dst, _elt);                                          \\\n            HASH_MAKE_TABLE(hh_dst, dst, _hs_oomed);                             \\\n            IF_HASH_NONFATAL_OOM(                                                \\\n              if (_hs_oomed) {                                                   \\\n                uthash_nonfatal_oom(_elt);                                       \\\n                (dst) = NULL;                                                    \\\n                continue;                                                        \\\n              }                                                                  \\\n            )                                                                    \\\n          } else {                                                               \\\n            _dst_hh->tbl = (dst)->hh_dst.tbl;                                    \\\n          }                                                                      \\\n          HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt);      \\\n          HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt], hh_dst, _dst_hh, _hs_oomed); \\\n          (dst)->hh_dst.tbl->num_items++;                                        \\\n          IF_HASH_NONFATAL_OOM(                                                  \\\n            if (_hs_oomed) {                                                     \\\n              HASH_ROLLBACK_BKT(hh_dst, dst, _dst_hh);                           \\\n              HASH_DELETE_HH(hh_dst, dst, _dst_hh);                              \\\n              _dst_hh->tbl = NULL;                                               \\\n              uthash_nonfatal_oom(_elt);                                         \\\n              continue;                                                          \\\n            }                                                                    \\\n          )                                                                      \\\n          HASH_BLOOM_ADD(_dst_hh->tbl, _dst_hh->hashv);                          \\\n          _last_elt = _elt;                                                      \\\n          _last_elt_hh = _dst_hh;                                                \\\n        }                                                                        \\\n      }                                                                          \\\n    }                                                                            \\\n  }                                                                              \\\n  HASH_FSCK(hh_dst, dst, \"HASH_SELECT\");                                         \\\n} while (0)\n\n#define HASH_CLEAR(hh,head)                                                      \\\ndo {                                                                             \\\n  if ((head) != NULL) {                                                          \\\n    HASH_BLOOM_FREE((head)->hh.tbl);                                             \\\n    uthash_free((head)->hh.tbl->buckets,                                         \\\n                (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket));      \\\n    uthash_free((head)->hh.tbl, sizeof(UT_hash_table));                          \\\n    (head) = NULL;                                                               \\\n  }                                                                              \\\n} while (0)\n\n#define HASH_OVERHEAD(hh,head)                                                   \\\n (((head) != NULL) ? (                                                           \\\n (size_t)(((head)->hh.tbl->num_items   * sizeof(UT_hash_handle))   +             \\\n          ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket))   +             \\\n           sizeof(UT_hash_table)                                   +             \\\n           (HASH_BLOOM_BYTELEN))) : 0U)\n\n#ifdef NO_DECLTYPE\n#define HASH_ITER(hh,head,el,tmp)                                                \\\nfor(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \\\n  (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL)))\n#else\n#define HASH_ITER(hh,head,el,tmp)                                                \\\nfor(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL));      \\\n  (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL)))\n#endif\n\n/* obtain a count of items in the hash */\n#define HASH_COUNT(head) HASH_CNT(hh,head)\n#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U)\n\ntypedef struct UT_hash_bucket {\n   struct UT_hash_handle *hh_head;\n   unsigned count;\n\n   /* expand_mult is normally set to 0. In this situation, the max chain length\n    * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If\n    * the bucket's chain exceeds this length, bucket expansion is triggered).\n    * However, setting expand_mult to a non-zero value delays bucket expansion\n    * (that would be triggered by additions to this particular bucket)\n    * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH.\n    * (The multiplier is simply expand_mult+1). The whole idea of this\n    * multiplier is to reduce bucket expansions, since they are expensive, in\n    * situations where we know that a particular bucket tends to be overused.\n    * It is better to let its chain length grow to a longer yet-still-bounded\n    * value, than to do an O(n) bucket expansion too often.\n    */\n   unsigned expand_mult;\n\n} UT_hash_bucket;\n\n/* random signature used only to find hash tables in external analysis */\n#define HASH_SIGNATURE 0xa0111fe1u\n#define HASH_BLOOM_SIGNATURE 0xb12220f2u\n\ntypedef struct UT_hash_table {\n   UT_hash_bucket *buckets;\n   unsigned num_buckets, log2_num_buckets;\n   unsigned num_items;\n   struct UT_hash_handle *tail; /* tail hh in app order, for fast append    */\n   ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */\n\n   /* in an ideal situation (all buckets used equally), no bucket would have\n    * more than ceil(#items/#buckets) items. that's the ideal chain length. */\n   unsigned ideal_chain_maxlen;\n\n   /* nonideal_items is the number of items in the hash whose chain position\n    * exceeds the ideal chain maxlen. these items pay the penalty for an uneven\n    * hash distribution; reaching them in a chain traversal takes >ideal steps */\n   unsigned nonideal_items;\n\n   /* ineffective expands occur when a bucket doubling was performed, but\n    * afterward, more than half the items in the hash had nonideal chain\n    * positions. If this happens on two consecutive expansions we inhibit any\n    * further expansion, as it's not helping; this happens when the hash\n    * function isn't a good fit for the key domain. When expansion is inhibited\n    * the hash will still work, albeit no longer in constant time. */\n   unsigned ineff_expands, noexpand;\n\n   uint32_t signature; /* used only to find hash tables in external analysis */\n#ifdef HASH_BLOOM\n   uint32_t bloom_sig; /* used only to test bloom exists in external analysis */\n   uint8_t *bloom_bv;\n   uint8_t bloom_nbits;\n#endif\n\n} UT_hash_table;\n\ntypedef struct UT_hash_handle {\n   struct UT_hash_table *tbl;\n   void *prev;                       /* prev element in app order      */\n   void *next;                       /* next element in app order      */\n   struct UT_hash_handle *hh_prev;   /* previous hh in bucket order    */\n   struct UT_hash_handle *hh_next;   /* next hh in bucket order        */\n   void *key;                        /* ptr to enclosing struct's key  */\n   unsigned keylen;                  /* enclosing struct's key len     */\n   unsigned hashv;                   /* result of hash-fcn(key)        */\n} UT_hash_handle;\n\n#endif /* UTHASH_H */\n"
  },
  {
    "path": "instrumentation/winafl_alloc_inl.h",
    "content": "/*\n   american fuzzy lop - error-checking, memory-zeroing alloc routines\n   ------------------------------------------------------------------\n\n   Original AFL code written by Michal Zalewski <lcamtuf@google.com>\n\n   Windows fork written and maintained by Ivan Fratric <ifratric@google.com>\n\n   Copyright 2016 Google Inc. All Rights Reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n   This file has been modified from the original to suit the purposes of this\n   project.\n */\n\n#ifndef _HAVE_ALLOC_INL_H\n#define _HAVE_ALLOC_INL_H\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"winafl_config.h\"\n#include \"winafl_types.h\"\n#include \"winafl_debug.h\"\n\n/* User-facing macro to sprintf() to a dynamically allocated buffer. */\n/*\n#define alloc_printf(_str, ...) ({ \\\n    u8* _tmp; \\\n    s32 _len = snprintf(NULL, 0, _str); \\\n    if (_len < 0) FATAL(\"Whoa, snprintf() fails?!\"); \\\n    _tmp = ck_alloc(_len + 1); \\\n    snprintf((char*)_tmp, _len + 1, _str); \\\n    _tmp; \\\n  })\n*/\n\n/* Macro to enforce allocation limits as a last-resort defense against\n   integer overflows. */\n\n#define ALLOC_CHECK_SIZE(_s) do { \\\n    if ((_s) > MAX_ALLOC) \\\n      ABORT(\"Bad alloc request: %u bytes\", (_s)); \\\n  } while (0)\n\n/* Macro to check malloc() failures and the like. */\n\n#define ALLOC_CHECK_RESULT(_r, _s) do { \\\n    if (!(_r)) \\\n      ABORT(\"Out of memory: can't allocate %u bytes\", (_s)); \\\n  } while (0)\n\n/* Magic tokens used to mark used / freed chunks. */\n\n#define ALLOC_MAGIC_C1  0xFF00FF00 /* Used head (dword)  */\n#define ALLOC_MAGIC_F   0xFE00FE00 /* Freed head (dword) */\n#define ALLOC_MAGIC_C2  0xF0       /* Used tail (byte)   */\n\n/* Positions of guard tokens in relation to the user-visible pointer. */\n\n#define ALLOC_C1(_ptr)  (((u32*)(_ptr))[-2])\n#define ALLOC_S(_ptr)   (((u32*)(_ptr))[-1])\n#define ALLOC_C2(_ptr)  (((u8*)(_ptr))[ALLOC_S(_ptr)])\n\n#define ALLOC_OFF_HEAD  8\n#define ALLOC_OFF_TOTAL (ALLOC_OFF_HEAD + 1)\n\n/* Allocator increments for ck_realloc_block(). */\n\n#define ALLOC_BLK_INC    256\n\n/* Sanity-checking macros for pointers. */\n\n#define CHECK_PTR(_p) do { \\\n    if (_p) { \\\n      if (ALLOC_C1(_p) ^ ALLOC_MAGIC_C1) {\\\n        if (ALLOC_C1(_p) == ALLOC_MAGIC_F) \\\n          ABORT(\"Use after free.\"); \\\n        else ABORT(\"Corrupted head alloc canary.\"); \\\n      } \\\n      if (ALLOC_C2(_p) ^ ALLOC_MAGIC_C2) \\\n        ABORT(\"Corrupted tail alloc canary.\"); \\\n    } \\\n  } while (0)\n\n#define CHECK_PTR_EXPR(_p) ({ \\\n    typeof (_p) _tmp = (_p); \\\n    CHECK_PTR(_tmp); \\\n    _tmp; \\\n  })\n\n\n/* Allocate a buffer, explicitly not zeroing it. Returns NULL for zero-sized\n   requests. */\n\nstatic inline void* DFL_ck_alloc_nozero(u32 size) {\n\n  char* ret;\n\n  if (!size) return NULL;\n\n  ALLOC_CHECK_SIZE(size);\n  ret = (char *)malloc(size + ALLOC_OFF_TOTAL);\n  ALLOC_CHECK_RESULT(ret, size);\n\n  ret += ALLOC_OFF_HEAD;\n\n  ALLOC_C1(ret) = ALLOC_MAGIC_C1;\n  ALLOC_S(ret)  = size;\n  ALLOC_C2(ret) = ALLOC_MAGIC_C2;\n\n  return ret;\n\n}\n\n\n/* Allocate a buffer, returning zeroed memory. */\n\nstatic inline void* DFL_ck_alloc(u32 size) {\n\n  void* mem;\n\n  if (!size) return NULL;\n  mem = DFL_ck_alloc_nozero(size);\n\n  return memset(mem, 0, size);\n\n}\n\n\n/* Free memory, checking for double free and corrupted heap. When DEBUG_BUILD\n   is set, the old memory will be also clobbered with 0xFF. */\n\nstatic inline void DFL_ck_free(char* mem) {\n\n  if (!mem) return;\n\n  CHECK_PTR(mem);\n\n#ifdef DEBUG_BUILD\n\n  /* Catch pointer issues sooner. */\n  memset(mem, 0xFF, ALLOC_S(mem));\n\n#endif /* DEBUG_BUILD */\n\n  ALLOC_C1(mem) = ALLOC_MAGIC_F;\n\n  free(mem - ALLOC_OFF_HEAD);\n\n}\n\n\n/* Re-allocate a buffer, checking for issues and zeroing any newly-added tail.\n   With DEBUG_BUILD, the buffer is always reallocated to a new addresses and the\n   old memory is clobbered with 0xFF. */\n\nstatic inline void* DFL_ck_realloc(char* orig, u32 size) {\n\n  char* ret;\n  u32   old_size = 0;\n\n  if (!size) {\n\n    DFL_ck_free(orig);\n    return NULL;\n\n  }\n\n  if (orig) {\n\n    CHECK_PTR(orig);\n\n#ifndef DEBUG_BUILD\n    ALLOC_C1(orig) = ALLOC_MAGIC_F;\n#endif /* !DEBUG_BUILD */\n\n    old_size  = ALLOC_S(orig);\n    orig     -= ALLOC_OFF_HEAD;\n\n    ALLOC_CHECK_SIZE(old_size);\n\n  }\n\n  ALLOC_CHECK_SIZE(size);\n\n#ifndef DEBUG_BUILD\n\n  ret = (char *)realloc(orig, size + ALLOC_OFF_TOTAL);\n  ALLOC_CHECK_RESULT(ret, size);\n\n#else\n\n  /* Catch pointer issues sooner: force relocation and make sure that the\n     original buffer is wiped. */\n\n  ret = malloc(size + ALLOC_OFF_TOTAL);\n  ALLOC_CHECK_RESULT(ret, size);\n\n  if (orig) {\n\n    memcpy(ret + ALLOC_OFF_HEAD, orig + ALLOC_OFF_HEAD, MIN(size, old_size));\n    memset(orig + ALLOC_OFF_HEAD, 0xFF, old_size);\n\n    ALLOC_C1(orig + ALLOC_OFF_HEAD) = ALLOC_MAGIC_F;\n\n    free(orig);\n\n  }\n\n#endif /* ^!DEBUG_BUILD */\n\n  ret += ALLOC_OFF_HEAD;\n\n  ALLOC_C1(ret) = ALLOC_MAGIC_C1;\n  ALLOC_S(ret)  = size;\n  ALLOC_C2(ret) = ALLOC_MAGIC_C2;\n\n  if (size > old_size)\n    memset(ret + old_size, 0, size - old_size);\n\n  return ret;\n\n}\n\n\n/* Re-allocate a buffer with ALLOC_BLK_INC increments (used to speed up\n   repeated small reallocs without complicating the user code). */\n\nstatic inline void* DFL_ck_realloc_block(void* orig, u32 size) {\n\n#ifndef DEBUG_BUILD\n\n  if (orig) {\n\n    CHECK_PTR(orig);\n\n    if (ALLOC_S(orig) >= size) return orig;\n\n    size += ALLOC_BLK_INC;\n\n  }\n\n#endif /* !DEBUG_BUILD */\n\n  return DFL_ck_realloc((char *)orig, size);\n\n}\n\n\n/* Create a buffer with a copy of a string. Returns NULL for NULL inputs. */\n\nstatic inline u8* DFL_ck_strdup(u8* str) {\n\n  char* ret;\n  u32   size;\n\n  if (!str) return NULL;\n\n  size = strlen((char*)str) + 1;\n\n  ALLOC_CHECK_SIZE(size);\n  ret = (char *)malloc(size + ALLOC_OFF_TOTAL);\n  ALLOC_CHECK_RESULT(ret, size);\n\n  ret += ALLOC_OFF_HEAD;\n\n  ALLOC_C1(ret) = ALLOC_MAGIC_C1;\n  ALLOC_S(ret)  = size;\n  ALLOC_C2(ret) = ALLOC_MAGIC_C2;\n\n  return (u8 *)memcpy(ret, str, size);\n\n}\n\n\n/* Create a buffer with a copy of a memory block. Returns NULL for zero-sized\n   or NULL inputs. */\n\nstatic inline void* DFL_ck_memdup(void* mem, u32 size) {\n\n  char* ret;\n\n  if (!mem || !size) return NULL;\n\n  ALLOC_CHECK_SIZE(size);\n  ret = (char *)malloc(size + ALLOC_OFF_TOTAL);\n  ALLOC_CHECK_RESULT(ret, size);\n  \n  ret += ALLOC_OFF_HEAD;\n\n  ALLOC_C1(ret) = ALLOC_MAGIC_C1;\n  ALLOC_S(ret)  = size;\n  ALLOC_C2(ret) = ALLOC_MAGIC_C2;\n\n  return memcpy(ret, mem, size);\n\n}\n\n\n/* Create a buffer with a block of text, appending a NUL terminator at the end.\n   Returns NULL for zero-sized or NULL inputs. */\n\nstatic inline u8* DFL_ck_memdup_str(u8* mem, u32 size) {\n\n  u8* ret;\n\n  if (!mem || !size) return NULL;\n\n  ALLOC_CHECK_SIZE(size);\n  ret = (u8*)malloc(size + ALLOC_OFF_TOTAL + 1);\n  ALLOC_CHECK_RESULT(ret, size);\n  \n  ret += ALLOC_OFF_HEAD;\n\n  ALLOC_C1(ret) = ALLOC_MAGIC_C1;\n  ALLOC_S(ret)  = size;\n  ALLOC_C2(ret) = ALLOC_MAGIC_C2;\n\n  memcpy(ret, mem, size);\n  ret[size] = 0;\n\n  return ret;\n\n}\n\n\n#ifndef DEBUG_BUILD\n\n/* In non-debug mode, we just do straightforward aliasing of the above functions\n   to user-visible names such as ck_alloc(). */\n\n#define ck_alloc          DFL_ck_alloc\n#define ck_alloc_nozero   DFL_ck_alloc_nozero\n#define ck_realloc        DFL_ck_realloc\n#define ck_realloc_block  DFL_ck_realloc_block\n#define ck_strdup         DFL_ck_strdup\n#define ck_memdup         DFL_ck_memdup\n#define ck_memdup_str     DFL_ck_memdup_str\n#define ck_free           DFL_ck_free\n\n#define alloc_report()\n\n#else\n\n/* In debugging mode, we also track allocations to detect memory leaks, and the\n   flow goes through one more layer of indirection. */\n\n/* Alloc tracking data structures: */\n\n#define ALLOC_BUCKETS     4096\n\nstruct TRK_obj {\n  void *ptr;\n  char *file, *func;\n  u32  line;\n};\n\n#ifdef AFL_MAIN\n\nstruct TRK_obj* TRK[ALLOC_BUCKETS];\nu32 TRK_cnt[ALLOC_BUCKETS];\n\n#  define alloc_report() TRK_report()\n\n#else\n\nextern struct TRK_obj* TRK[ALLOC_BUCKETS];\nextern u32 TRK_cnt[ALLOC_BUCKETS];\n\n#  define alloc_report()\n\n#endif /* ^AFL_MAIN */\n\n/* Bucket-assigning function for a given pointer: */\n\n#define TRKH(_ptr) (((((u32)(_ptr)) >> 16) ^ ((u32)(_ptr))) % ALLOC_BUCKETS)\n\n\n/* Add a new entry to the list of allocated objects. */\n\nstatic inline void TRK_alloc_buf(void* ptr, const char* file, const char* func,\n                                 u32 line) {\n\n  u32 i, bucket;\n\n  if (!ptr) return;\n\n  bucket = TRKH(ptr);\n\n  /* Find a free slot in the list of entries for that bucket. */\n\n  for (i = 0; i < TRK_cnt[bucket]; i++)\n\n    if (!TRK[bucket][i].ptr) {\n\n      TRK[bucket][i].ptr  = ptr;\n      TRK[bucket][i].file = (char*)file;\n      TRK[bucket][i].func = (char*)func;\n      TRK[bucket][i].line = line;\n      return;\n\n    }\n\n  /* No space available - allocate more. */\n\n  TRK[bucket] = DFL_ck_realloc_block(TRK[bucket],\n    (TRK_cnt[bucket] + 1) * sizeof(struct TRK_obj));\n\n  TRK[bucket][i].ptr  = ptr;\n  TRK[bucket][i].file = (char*)file;\n  TRK[bucket][i].func = (char*)func;\n  TRK[bucket][i].line = line;\n\n  TRK_cnt[bucket]++;\n\n}\n\n\n/* Remove entry from the list of allocated objects. */\n\nstatic inline void TRK_free_buf(void* ptr, const char* file, const char* func,\n                                u32 line) {\n\n  u32 i, bucket;\n\n  if (!ptr) return;\n\n  bucket = TRKH(ptr);\n\n  /* Find the element on the list... */\n\n  for (i = 0; i < TRK_cnt[bucket]; i++)\n\n    if (TRK[bucket][i].ptr == ptr) {\n\n      TRK[bucket][i].ptr = 0;\n      return;\n\n    }\n\n  WARNF(\"ALLOC: Attempt to free non-allocated memory in %s (%s:%u)\",\n        func, file, line);\n\n}\n\n\n/* Do a final report on all non-deallocated objects. */\n\nstatic inline void TRK_report(void) {\n\n  u32 i, bucket;\n\n  fflush(0);\n\n  for (bucket = 0; bucket < ALLOC_BUCKETS; bucket++)\n    for (i = 0; i < TRK_cnt[bucket]; i++)\n      if (TRK[bucket][i].ptr)\n        WARNF(\"ALLOC: Memory never freed, created in %s (%s:%u)\",\n              TRK[bucket][i].func, TRK[bucket][i].file, TRK[bucket][i].line);\n\n}\n\n\n/* Simple wrappers for non-debugging functions: */\n\nstatic inline void* TRK_ck_alloc(u32 size, const char* file, const char* func,\n                                 u32 line) {\n\n  void* ret = DFL_ck_alloc(size);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void* TRK_ck_realloc(void* orig, u32 size, const char* file,\n                                   const char* func, u32 line) {\n\n  void* ret = DFL_ck_realloc(orig, size);\n  TRK_free_buf(orig, file, func, line);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void* TRK_ck_realloc_block(void* orig, u32 size, const char* file,\n                                         const char* func, u32 line) {\n\n  void* ret = DFL_ck_realloc_block(orig, size);\n  TRK_free_buf(orig, file, func, line);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void* TRK_ck_strdup(u8* str, const char* file, const char* func,\n                                  u32 line) {\n\n  void* ret = DFL_ck_strdup(str);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void* TRK_ck_memdup(void* mem, u32 size, const char* file,\n                                  const char* func, u32 line) {\n\n  void* ret = DFL_ck_memdup(mem, size);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void* TRK_ck_memdup_str(void* mem, u32 size, const char* file,\n                                      const char* func, u32 line) {\n\n  void* ret = DFL_ck_memdup_str(mem, size);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void TRK_ck_free(void* ptr, const char* file,\n                                const char* func, u32 line) {\n\n  TRK_free_buf(ptr, file, func, line);\n  DFL_ck_free(ptr);\n\n}\n\n/* Aliasing user-facing names to tracking functions: */\n\n#define ck_alloc(_p1) \\\n  TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_alloc_nozero(_p1) \\\n  TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_realloc(_p1, _p2) \\\n  TRK_ck_realloc(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_realloc_block(_p1, _p2) \\\n  TRK_ck_realloc_block(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_strdup(_p1) \\\n  TRK_ck_strdup(_p1, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_memdup(_p1, _p2) \\\n  TRK_ck_memdup(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_memdup_str(_p1, _p2) \\\n  TRK_ck_memdup_str(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_free(_p1) \\\n  TRK_ck_free(_p1, __FILE__, __FUNCTION__, __LINE__)\n\n#endif /* ^!DEBUG_BUILD */\n\n#endif /* ! _HAVE_ALLOC_INL_H */\n"
  },
  {
    "path": "instrumentation/winafl_config.h",
    "content": "/*\n   american fuzzy lop - vaguely configurable bits\n   ----------------------------------------------\n\n   Original AFL code written by Michal Zalewski <lcamtuf@google.com>\n\n   Windows fork written and maintained by Ivan Fratric <ifratric@google.com>\n\n   Copyright 2016 Google Inc. All Rights Reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n   This file has been modified from the original to suit the purposes of this\n   project.\n */\n\n#ifndef _HAVE_CONFIG_H\n#define _HAVE_CONFIG_H\n\n#define inline __inline\n\n#include \"winafl_types.h\"\n\n/******************************************************\n *                                                    *\n *  Settings that may be of interest to power users:  *\n *                                                    *\n ******************************************************/\n\n/* Comment out to disable terminal colors: */\n\n// #define USE_COLOR\n\n/* Comment out to disable fancy ANSI boxes and use poor man's 7-bit UI: */\n\n//#define FANCY_BOXES\n\n/* Default timeout for fuzzed code (milliseconds): */\n\n#define EXEC_TIMEOUT        1000\n\n/* Timeout rounding factor when auto-scaling (milliseconds): */\n\n#define EXEC_TM_ROUND       20\n\n/* Default memory limit for child process (MB): */\n\n#ifndef __x86_64__ \n#  define MEM_LIMIT         25\n#else\n#  define MEM_LIMIT         50\n#endif /* ^!__x86_64__ */\n\n/* Default memory limit when running in QEMU mode (MB): */\n\n#define MEM_LIMIT_QEMU      200\n\n/* Number of calibration cycles per every new test case (and for test\n   cases that show variable behavior): */\n\n#define CAL_CYCLES          10\n#define CAL_CYCLES_LONG     40\n\n/* The same, but when AFL_NO_VAR_CHECK is set in the environment: */\n\n#define CAL_CYCLES_NO_VAR   4\n\n/* Number of subsequent hangs before abandoning an input file: */\n\n#define HANG_LIMIT          250\n\n/* Maximum number of unique hangs or crashes to record: */\n\n#define KEEP_UNIQUE_HANG    500\n#define KEEP_UNIQUE_CRASH   5000\n\n/* Baseline number of random tweaks during a single 'havoc' stage: */\n\n#define HAVOC_CYCLES        5000\n\n/* Maximum multiplier for the above (should be a power of two, beware\n   of 32-bit int overflows): */\n\n#define HAVOC_MAX_MULT      16\n\n/* Absolute minimum number of havoc cycles (after all adjustments): */\n\n#define HAVOC_MIN           10\n\n/* Maximum stacking for havoc-stage tweaks. The actual value is calculated\n   like this: \n\n   n = random between 1 and HAVOC_STACK_POW2\n   stacking = 2^n\n\n   In other words, the default (n = 7) produces 2, 4, 8, 16, 32, 64, or\n   128 stacked tweaks: */\n\n#define HAVOC_STACK_POW2    7\n\n/* Caps on block sizes for cloning and deletion operations. Each of these\n   ranges has a 33% probability of getting picked, except for the first\n   two cycles where smaller blocks are favored: */\n\n#define HAVOC_BLK_SMALL     32\n#define HAVOC_BLK_MEDIUM    128\n#define HAVOC_BLK_LARGE     1500\n\n/* Probabilities of skipping non-favored entries in the queue, expressed as\n   percentages: */\n\n#define SKIP_TO_NEW_PROB    99 /* ...when there are new, pending favorites */\n#define SKIP_NFAV_OLD_PROB  95 /* ...no new favs, cur entry already fuzzed */\n#define SKIP_NFAV_NEW_PROB  75 /* ...no new favs, cur entry not fuzzed yet */\n\n/* Splicing cycle count: */\n\n#define SPLICE_CYCLES       20\n\n/* Nominal per-splice havoc cycle length: */\n\n#define SPLICE_HAVOC        500\n\n/* Maximum offset for integer addition / subtraction stages: */\n\n#define ARITH_MAX           35\n\n/* Limits for the test case trimmer. The absolute minimum chunk size; and\n   the starting and ending divisors for chopping up the input file: */\n\n#define TRIM_MIN_BYTES      4\n#define TRIM_START_STEPS    16\n#define TRIM_END_STEPS      1024\n\n/* Maximum size of input file, in bytes (keep under 100MB): */\n\n#define MAX_FILE            (1 * 1024 * 1024)\n\n/* The same, for the test case minimizer: */\n\n#define TMIN_MAX_FILE       (10 * 1024 * 1024)\n\n/* Block normalization steps for afl-tmin: */\n\n#define TMIN_SET_MIN_SIZE   4\n#define TMIN_SET_STEPS      128\n\n/* Maximum dictionary token size (-x), in bytes: */\n\n#define MAX_DICT_FILE       128\n\n/* Length limits for auto-detected dictionary tokens: */\n\n#define MIN_AUTO_EXTRA      3\n#define MAX_AUTO_EXTRA      32\n\n/* Maximum number of user-specified dictionary tokens to use in deterministic\n   steps; past this point, the \"extras/user\" step will be still carried out,\n   but with proportionally lower odds: */\n\n#define MAX_DET_EXTRAS      200\n\n/* Maximum number of auto-extracted dictionary tokens to actually use in fuzzing\n   (first value), and to keep in memory as candidates. The latter should be much\n   higher than the former. */\n\n#define USE_AUTO_EXTRAS     50\n#define MAX_AUTO_EXTRAS     (USE_AUTO_EXTRAS * 10)\n\n/* Scaling factor for the effector map used to skip some of the more\n   expensive deterministic steps. The actual divisor is set to\n   2^EFF_MAP_SCALE2 bytes: */\n\n#define EFF_MAP_SCALE2      3\n\n/* Minimum input file length at which the effector logic kicks in: */\n\n#define EFF_MIN_LEN         128\n\n/* Maximum effector density past which everything is just fuzzed\n   unconditionally (%): */\n\n#define EFF_MAX_PERC        90\n\n/* UI refresh frequency (Hz): */\n\n#define UI_TARGET_HZ        1\n\n/* Fuzzer stats file and plot update intervals (sec): */\n\n#define STATS_UPDATE_SEC    60\n#define PLOT_UPDATE_SEC     5\n\n/* Smoothing divisor for CPU load and exec speed stats (1 - no smoothing). */\n\n#define AVG_SMOOTHING       16\n\n/* Sync interval (every n havoc cycles): */\n\n#define SYNC_INTERVAL       5\n\n/* Output directory reuse grace period (minutes): */\n\n#define OUTPUT_GRACE        25\n\n/* Uncomment to use simple file names (id_NNNNNN): */\n\n#define SIMPLE_FILES\n\n/* List of interesting values to use in fuzzing. */\n\n#define INTERESTING_8 \\\n  -128,          /* Overflow signed 8-bit when decremented  */ \\\n  -1,            /*                                         */ \\\n   0,            /*                                         */ \\\n   1,            /*                                         */ \\\n   16,           /* One-off with common buffer size         */ \\\n   32,           /* One-off with common buffer size         */ \\\n   64,           /* One-off with common buffer size         */ \\\n   100,          /* One-off with common buffer size         */ \\\n   127           /* Overflow signed 8-bit when incremented  */\n\n#define INTERESTING_16 \\\n  -32768,        /* Overflow signed 16-bit when decremented */ \\\n  -129,          /* Overflow signed 8-bit                   */ \\\n   128,          /* Overflow signed 8-bit                   */ \\\n   255,          /* Overflow unsig 8-bit when incremented   */ \\\n   256,          /* Overflow unsig 8-bit                    */ \\\n   512,          /* One-off with common buffer size         */ \\\n   1000,         /* One-off with common buffer size         */ \\\n   1024,         /* One-off with common buffer size         */ \\\n   4096,         /* One-off with common buffer size         */ \\\n   32767         /* Overflow signed 16-bit when incremented */\n\n#define INTERESTING_32 \\\n  -2147483648LL, /* Overflow signed 32-bit when decremented */ \\\n  -100663046,    /* Large negative number (endian-agnostic) */ \\\n  -32769,        /* Overflow signed 16-bit                  */ \\\n   32768,        /* Overflow signed 16-bit                  */ \\\n   65535,        /* Overflow unsig 16-bit when incremented  */ \\\n   65536,        /* Overflow unsig 16 bit                   */ \\\n   100663045,    /* Large positive number (endian-agnostic) */ \\\n   2147483647    /* Overflow signed 32-bit when incremented */\n\n/***********************************************************\n *                                                         *\n *  Really exotic stuff you probably don't want to touch:  *\n *                                                         *\n ***********************************************************/\n\n/* Call count interval between reseeding the libc PRNG from /dev/urandom: */\n\n#define RESEED_RNG          10000\n\n/* Maximum line length passed from GCC to 'as' and used for parsing\n   configuration files: */\n\n#define MAX_LINE            8192\n\n/* Environment variable used to pass SHM ID to the called program. */\n\n#define SHM_ENV_VAR         \"__AFL_SHM_ID\"\n\n/* Other less interesting, internal-only variables. */\n\n#define CLANG_ENV_VAR       \"__AFL_CLANG_MODE\"\n#define AS_LOOP_ENV_VAR     \"__AFL_AS_LOOPCHECK\"\n#define PERSIST_ENV_VAR     \"__AFL_PERSISTENT\"\n#define DEFER_ENV_VAR       \"__AFL_DEFER_FORKSRV\"\n\n/* In-code signatures for deferred and persistent mode. */\n\n#define PERSIST_SIG         \"##SIG_AFL_PERSISTENT##\"\n#define DEFER_SIG           \"##SIG_AFL_DEFER_FORKSRV##\"\n\n/* Distinctive bitmap signature used to indicate failed execution: */\n\n#define EXEC_FAIL_SIG       0xfee1dead\n\n/* Distinctive exit code used to indicate MSAN trip condition: */\n\n#define MSAN_ERROR          86\n\n/* Designated file descriptors for forkserver commands (the application will\n   use FORKSRV_FD and FORKSRV_FD + 1): */\n\n#define FORKSRV_FD          198\n\n/* Fork server init timeout multiplier: we'll wait the user-selected\n   timeout plus this much for the fork server to spin up. */\n\n#define FORK_WAIT_MULT      10\n\n/* Calibration timeout adjustments, to be a bit more generous when resuming\n   fuzzing sessions or trying to calibrate already-added internal finds.\n   The first value is a percentage, the other is in milliseconds: */\n\n#define CAL_TMOUT_PERC      125\n#define CAL_TMOUT_ADD       50\n\n/* Number of chances to calibrate a case before giving up: */\n\n#define CAL_CHANCES         3\n\n/* Map size for the traced binary (2^MAP_SIZE_POW2). Must be greater than\n   2; you probably want to keep it under 18 or so for performance reasons\n   (adjusting AFL_INST_RATIO when compiling is probably a better way to solve\n   problems with complex programs). You need to recompile the target binary\n   after changing this - otherwise, SEGVs may ensue. */\n\n#define MAP_SIZE_POW2       16\n#define MAP_SIZE            (1 << MAP_SIZE_POW2)\n\n/* Maximum allocator request size (keep well under INT_MAX): */\n\n#define MAX_ALLOC           0x40000000\n\n/* A made-up hashing seed: */\n\n#define HASH_CONST          0xa5b35705\n\n/* Constants for afl-gotcpu to control busy loop timing: */\n\n#define  CTEST_TARGET_MS    5000\n#define  CTEST_BUSY_CYCLES  (10 * 1000 * 1000)\n\n/* Uncomment this to use inferior block-coverage-based instrumentation. Note\n   that you need to recompile the target binary for this to have any effect: */\n\n// #define COVERAGE_ONLY\n\n/* Uncomment this to ignore hit counts and output just one bit per tuple.\n   As with the previous setting, you will need to recompile the target\n   binary: */\n\n// #define SKIP_COUNTS\n\n/* Uncomment this to use instrumentation data to record newly discovered paths,\n   but do not use them as seeds for fuzzing. This is useful for conveniently\n   measuring coverage that could be attained by a \"dumb\" fuzzing algorithm: */\n\n// #define IGNORE_FINDS\n\n#define EDGES_SHM_SIZE (100 * 1024 * 1024) //100MB\n\n#endif /* ! _HAVE_CONFIG_H */\n"
  },
  {
    "path": "instrumentation/winafl_debug.h",
    "content": "/*\n   american fuzzy lop - debug / error handling macros\n   --------------------------------------------------\n\n   Original AFL code written by Michal Zalewski <lcamtuf@google.com>\n\n   Windows fork written and maintained by Ivan Fratric <ifratric@google.com>\n\n   Copyright 2016 Google Inc. All Rights Reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n   This file has been modified from the original to suit the purposes of this\n   project.\n */\n\n#ifndef _HAVE_DEBUG_H\n#define _HAVE_DEBUG_H\n\n#include <errno.h>\n\n#include \"winafl_types.h\"\n#include \"winafl_config.h\"\n\n/*******************\n * Terminal colors *\n *******************/\n\n#ifdef USE_COLOR\n\n#  define cBLK \"\\x1b[0;30m\"\n#  define cRED \"\\x1b[0;31m\"\n#  define cGRN \"\\x1b[0;32m\"\n#  define cBRN \"\\x1b[0;33m\"\n#  define cBLU \"\\x1b[0;34m\"\n#  define cMGN \"\\x1b[0;35m\"\n#  define cCYA \"\\x1b[0;36m\"\n#  define cNOR \"\\x1b[0;37m\"\n#  define cGRA \"\\x1b[1;30m\"\n#  define cLRD \"\\x1b[1;31m\"\n#  define cLGN \"\\x1b[1;32m\"\n#  define cYEL \"\\x1b[1;33m\"\n#  define cLBL \"\\x1b[1;34m\"\n#  define cPIN \"\\x1b[1;35m\"\n#  define cLCY \"\\x1b[1;36m\"\n#  define cBRI \"\\x1b[1;37m\"\n#  define cRST \"\\x1b[0m\"\n\n#else\n\n#  define cBLK \"\"\n#  define cRED \"\"\n#  define cGRN \"\"\n#  define cBRN \"\"\n#  define cBLU \"\"\n#  define cMGN \"\"\n#  define cCYA \"\"\n#  define cNOR \"\"\n#  define cGRA \"\"\n#  define cLRD \"\"\n#  define cLGN \"\"\n#  define cYEL \"\"\n#  define cLBL \"\"\n#  define cPIN \"\"\n#  define cLCY \"\"\n#  define cBRI \"\"\n#  define cRST \"\"\n\n#endif /* ^USE_COLOR */\n\n/*************************\n * Box drawing sequences *\n *************************/\n\n#ifdef FANCY_BOXES\n\n#  define SET_G1   \"\\x1b)0\"       /* Set G1 for box drawing    */\n#  define RESET_G1 \"\\x1b)B\"       /* Reset G1 to ASCII         */\n#  define bSTART   \"\\x0e\"         /* Enter G1 drawing mode     */\n#  define bSTOP    \"\\x0f\"         /* Leave G1 drawing mode     */\n#  define bH       \"q\"            /* Horizontal line           */\n#  define bV       \"x\"            /* Vertical line             */\n#  define bLT      \"l\"            /* Left top corner           */\n#  define bRT      \"k\"            /* Right top corner          */\n#  define bLB      \"m\"            /* Left bottom corner        */\n#  define bRB      \"j\"            /* Right bottom corner       */\n#  define bX       \"n\"            /* Cross                     */\n#  define bVR      \"t\"            /* Vertical, branch right    */\n#  define bVL      \"u\"            /* Vertical, branch left     */\n#  define bHT      \"v\"            /* Horizontal, branch top    */\n#  define bHB      \"w\"            /* Horizontal, branch bottom */\n\n#else\n\n#  define SET_G1   \"\"\n#  define RESET_G1 \"\"\n#  define bSTART   \"\"\n#  define bSTOP    \"\"\n#  define bH       \"-\"\n#  define bV       \"|\"\n#  define bLT      \"+\"\n#  define bRT      \"+\"\n#  define bLB      \"+\"\n#  define bRB      \"+\"\n#  define bX       \"+\"\n#  define bVR      \"+\"\n#  define bVL      \"+\"\n#  define bHT      \"+\"\n#  define bHB      \"+\"\n\n#endif /* ^FANCY_BOXES */\n\n/***********************\n * Misc terminal codes *\n ***********************/\n\n//#define TERM_HOME     \"\\x1b[H\"\n//#define TERM_CLEAR    TERM_HOME \"\\x1b[2J\"\n//#define cEOL          \"\\x1b[0K\"\n//#define CURSOR_HIDE   \"\\x1b[?25l\"\n//#define CURSOR_SHOW   \"\\x1b[?25h\"\n\n#define TERM_HOME     \"\"\n#define TERM_CLEAR    \"\"\n#define cEOL          \"\"\n#define CURSOR_HIDE   \"\"\n#define CURSOR_SHOW   \"\"\n\n/************************\n * Debug & error macros *\n ************************/\n\n/* Just print stuff to the appropriate stream. */\n\n#ifdef MESSAGES_TO_STDOUT\n#  define SAYF(...)    printf(__VA_ARGS__)\n#else \n#  define SAYF(...)    fprintf(stderr, __VA_ARGS__)\n#endif /* ^MESSAGES_TO_STDOUT */\n\n/* Show a prefixed warning. */\n\n#define WARNF(...) do { \\\n    SAYF(cYEL \"[!] \" cBRI \"WARNING: \" cRST __VA_ARGS__); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Show a prefixed \"doing something\" message. */\n\n#define ACTF(...) do { \\\n    SAYF(cLBL \"[*] \" cRST __VA_ARGS__); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Show a prefixed \"success\" message. */\n\n#define OKF(...) do { \\\n    SAYF(cLGN \"[+] \" cRST __VA_ARGS__); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Show a prefixed fatal error message (not used in afl). */\n\n#define BADF(...) do { \\\n    SAYF(cLRD \"\\n[-] \" cRST __VA_ARGS__); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Die with a verbose non-OS fatal error message. */\n\n#define FATAL(...) do { \\\n    SAYF(bSTOP RESET_G1 CURSOR_SHOW cLRD \"\\n[-] PROGRAM ABORT : \" cBRI __VA_ARGS__); \\\n    SAYF(cLRD \"\\n         Location : \" cRST \"%s(), %s:%u\\n\\n\", \\\n         __FUNCTION__, __FILE__, __LINE__); \\\n    exit(1); \\\n  } while (0)\n\n/* Die by calling abort() to provide a core dump. */\n\n#define ABORT(...) do { \\\n    SAYF(bSTOP RESET_G1 CURSOR_SHOW cLRD \"\\n[-] PROGRAM ABORT : \" cBRI __VA_ARGS__); \\\n    SAYF(cLRD \"\\n    Stop location : \" cRST \"%s(), %s:%u\\n\\n\", \\\n         __FUNCTION__, __FILE__, __LINE__); \\\n    abort(); \\\n  } while (0)\n\n/* Die while also including the output of perror(). */\n\n#define PFATAL(...) do { \\\n    fflush(stdout); \\\n    SAYF(bSTOP RESET_G1 CURSOR_SHOW cLRD \"\\n[-]  SYSTEM ERROR : \" cBRI __VA_ARGS__); \\\n    SAYF(cLRD \"\\n    Stop location : \" cRST \"%s(), %s:%u\\n\", \\\n         __FUNCTION__, __FILE__, __LINE__); \\\n    SAYF(cLRD \"       OS message : \" cRST \"%s\\n\", strerror(errno)); \\\n    exit(1); \\\n  } while (0)\n\n/* Die with FAULT() or PFAULT() depending on the value of res (used to\n   interpret different failure modes for read(), write(), etc). */\n\n#define RPFATAL(res, ...) do { \\\n    if (res < 0) PFATAL(__VA_ARGS__); else FATAL(__VA_ARGS__); \\\n  } while (0)\n\n/* Error-checking versions of read() and write() that call RPFATAL() as\n   appropriate. */\n\n#define ck_write(fd, buf, len, fn) do { \\\n    u32 _len = (len); \\\n    s32 _res = _write(fd, buf, _len); \\\n    if (_res != _len) RPFATAL(_res, \"Short write to %s\", fn); \\\n  } while (0)\n\n#define ck_read(fd, buf, len, fn) do { \\\n    u32 _len = (len); \\\n    s32 _res = _read(fd, buf, _len); \\\n    if (_res != _len) RPFATAL(_res, \"Short read from %s\", fn); \\\n  } while (0)\n\n#endif /* ! _HAVE_DEBUG_H */\n"
  },
  {
    "path": "instrumentation/winafl_hash.h",
    "content": "/*\n   american fuzzy lop - hashing function\n   -------------------------------------\n\n   Original AFL code written by Michal Zalewski <lcamtuf@google.com>\n\n   Windows fork written and maintained by Ivan Fratric <ifratric@google.com>\n\n   Copyright 2016 Google Inc. All Rights Reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n   This file has been modified from the original to suit the purposes of this\n   project.\n*/\n\n/* \n   The hash32() function is a variant of MurmurHash3, a good\n   non-cryptosafe hashing function developed by Austin Appleby.\n\n   For simplicity, this variant does *NOT* accept buffer lengths\n   that are not divisible by 8 bytes. The 32-bit version is otherwise\n   similar to the original; the 64-bit one is a custom hack with\n   mostly-unproven properties.\n\n   Austin's original code is public domain.\n\n*/\n\n#ifndef _HAVE_HASH_H\n#define _HAVE_HASH_H\n\n#include \"winafl_types.h\"\n\n#if defined(_M_X64) || defined(__x86_64__)\n\n#define ROL64(_x, _r)  ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r))))\n\nstatic inline u32 hash32(const void* key, u32 len, u32 seed) {\n\n  const u64* data = (u64*)key;\n  u64 h1 = seed ^ len;\n\n  len >>= 3;\n\n  while (len--) {\n\n    u64 k1 = *data++;\n\n    k1 *= 0x87c37b91114253d5ULL;\n    k1  = ROL64(k1, 31);\n    k1 *= 0x4cf5ad432745937fULL;\n\n    h1 ^= k1;\n    h1  = ROL64(h1, 27);\n    h1  = h1 * 5 + 0x52dce729;\n\n  }\n\n  h1 ^= h1 >> 33;\n  h1 *= 0xff51afd7ed558ccdULL;\n  h1 ^= h1 >> 33;\n  h1 *= 0xc4ceb9fe1a85ec53ULL;\n  h1 ^= h1 >> 33;\n\n  return h1;\n\n}\n\nstatic inline u32 hash32_with_ignore(const void* key, const void * ignore, u32 len, u32 seed) {\n\n\tconst u64* data = (u64*)key;\n\tconst u64* ignore_data = (u64*)ignore;\n\tu64 h1 = seed ^ len;\n\n\tlen >>= 3;\n\n\twhile (len--) {\n\n\t\tu64 k1 = *data++;\n\t\tu64 i1 = *ignore_data++;\n\t\tk1 = k1 & i1; //mask off any ignore'd bytes\n\n\t\tk1 *= 0x87c37b91114253d5ULL;\n\t\tk1 = ROL64(k1, 31);\n\t\tk1 *= 0x4cf5ad432745937fULL;\n\n\t\th1 ^= k1;\n\t\th1 = ROL64(h1, 27);\n\t\th1 = h1 * 5 + 0x52dce729;\n\n\t}\n\n\th1 ^= h1 >> 33;\n\th1 *= 0xff51afd7ed558ccdULL;\n\th1 ^= h1 >> 33;\n\th1 *= 0xc4ceb9fe1a85ec53ULL;\n\th1 ^= h1 >> 33;\n\n\treturn h1;\n\n}\n\n#else \n\n#define ROL32(_x, _r)  ((((u32)(_x)) << (_r)) | (((u32)(_x)) >> (32 - (_r))))\n\nstatic inline u32 hash32(const void* key, u32 len, u32 seed) {\n\n  const u32* data  = (u32*)key;\n  u32 h1 = seed ^ len;\n\n  len >>= 2;\n\n  while (len--) {\n\n    u32 k1 = *data++;\n\n    k1 *= 0xcc9e2d51;\n    k1  = ROL32(k1, 15);\n    k1 *= 0x1b873593;\n\n    h1 ^= k1;\n    h1  = ROL32(h1, 13);\n    h1  = h1 * 5 + 0xe6546b64;\n\n  }\n\n  h1 ^= h1 >> 16;\n  h1 *= 0x85ebca6b;\n  h1 ^= h1 >> 13;\n  h1 *= 0xc2b2ae35;\n  h1 ^= h1 >> 16;\n\n  return h1;\n\n}\n\n\nstatic inline u32 hash32_with_ignore(const void* key, const void * ignore, u32 len, u32 seed) {\n\n\tconst u32* data = (u32*)key;\n\tconst u32* ignore_data = (u32*)ignore;\n\tconst u8* ignore_byte = (u8*)ignore;\n\n\tu32 h1 = seed ^ len;\n\n\tlen >>= 2;\n\n\twhile (len--) {\n\n\t\tu32 k1 = *data++;\n/*\n\t\tu32 i1 = *ignore_data++;\n\t\tk1 = k1 & i1; //mask off any ignore'd bytes\n*/\n\t\tu8 i1;\n\n\t\ti1 = *ignore_byte;\n\t\tignore_byte++;\n\t\tif (i1)\n\t\t\tk1 = k1 & 0xffffff00;\n\n\t\ti1 = *ignore_byte;\n\t\tignore_byte++;\n\t\tif (i1)\n\t\t\tk1 = k1 & 0xffff00ff;\n\n\t\ti1 = *ignore_byte;\n\t\tignore_byte++;\n\t\tif (i1)\n\t\t\tk1 = k1 & 0xff00ffff;\n\n\t\ti1 = *ignore_byte;\n\t\tignore_byte++;\n\t\tif (i1)\n\t\t\tk1 = k1 & 0x00ffffff;\n\n\n\n\t\tk1 *= 0xcc9e2d51;\n\t\tk1 = ROL32(k1, 15);\n\t\tk1 *= 0x1b873593;\n\n\t\th1 ^= k1;\n\t\th1 = ROL32(h1, 13);\n\t\th1 = h1 * 5 + 0xe6546b64;\n\n\t}\n\n\th1 ^= h1 >> 16;\n\th1 *= 0x85ebca6b;\n\th1 ^= h1 >> 13;\n\th1 *= 0xc2b2ae35;\n\th1 ^= h1 >> 16;\n\n\treturn h1;\n\n}\n\n#endif /* ^__x86_64__ */\n\n#endif /* !_HAVE_HASH_H */\n"
  },
  {
    "path": "instrumentation/winafl_types.h",
    "content": "/*\n   american fuzzy lop - type definitions and minor macros\n   ------------------------------------------------------\n\n   Original AFL code written by Michal Zalewski <lcamtuf@google.com>\n\n   Windows fork written and maintained by Ivan Fratric <ifratric@google.com>\n\n   Copyright 2016 Google Inc. All Rights Reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n   This file has been modified from the original to suit the purposes of this\n   project.\n */\n\n#ifndef _HAVE_TYPES_H\n#define _HAVE_TYPES_H\n\n#include <stdint.h>\n#include <stdlib.h>\n\ntypedef uint8_t  u8;\ntypedef uint16_t u16;\ntypedef uint32_t u32;\n\n/*\n\n   Ugh. There is an unintended compiler / glibc #include glitch caused by\n   combining the u64 type an %llu in format strings, necessitating a workaround.\n\n   In essence, the compiler is always looking for 'unsigned long long' for %llu.\n   On 32-bit systems, the u64 type (aliased to uint64_t) is expanded to\n   'unsigned long long' in <bits/types.h>, so everything checks out.\n\n   But on 64-bit systems, it is #ifdef'ed in the same file as 'unsigned long'.\n   Now, it only happens in circumstances where the type happens to have the\n   expected bit width, *but* the compiler does not know that... and complains\n   about 'unsigned long' being unsafe to pass to %llu.\n\n */\n\n#ifdef __x86_64__\ntypedef unsigned long long u64;\n#else\ntypedef uint64_t u64;\n#endif /* ^sizeof(...) */\n\ntypedef int8_t   s8;\ntypedef int16_t  s16;\ntypedef int32_t  s32;\ntypedef int64_t  s64;\n\n#ifndef MIN\n#  define MIN(_a,_b) ((_a) > (_b) ? (_b) : (_a))\n#  define MAX(_a,_b) ((_a) > (_b) ? (_a) : (_b))\n#endif /* !MIN */\n\n#define SWAP16(x) (((x) >> 8) | ((x) << 8))\n#define SWAP32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24))\n\n#define R(x) (random() % (x))\n\n#define STRINGIFY_INTERNAL(x) #x\n#define STRINGIFY(x) STRINGIFY_INTERNAL(x)\n\n#define MEM_BARRIER() \\\n  asm volatile(\"\" ::: \"memory\")\n\n#endif /* ! _HAVE_TYPES_H */\n"
  },
  {
    "path": "instrumentation/wingui.c",
    "content": "#include <windows.h>\n/*\n * Given a ProcessId this function will attempt to determine if it is\n * \"stuck\" on a modal dialog. These are usualy some sport of error\n * and flow stoppage without a full crash, forcing us to wait for\n * timeout otherwise. We don't read the message, only know that it is\n * there incase the other process hangs. We don't want to get stuck.\n */\nBOOL IsProcessInModalDialog(\n    DWORD dwTargetProcessId\n)\n{\n    HWND hwndFoundDialog = NULL;\n    HWND hwndDialogOwner = NULL;\n    DWORD dwThreadId;\n    DWORD dwProcessId;\n    do\n    {\n        hwndFoundDialog = FindWindowExA( // Find a \"Dialog\" class window\n            GetDesktopWindow(),\n            hwndFoundDialog,\n            MAKEINTATOM(32770), // \"#32770 (Dialog)\"\n            NULL\n        );\n        if ( hwndFoundDialog )\n        {\n            hwndDialogOwner = GetWindow( hwndFoundDialog, GW_OWNER ); // Fetch it's owner\n\n            if ( !IsWindowEnabled( hwndDialogOwner ) ) // If owner is disabled, possibly modal dialog\n            {\n                dwThreadId = GetWindowThreadProcessId(\n                    hwndDialogOwner,\n                    &dwProcessId\n                );\n                if ( dwProcessId == dwTargetProcessId ) return TRUE;\n            }\n        }\n    } \n    while ( hwndFoundDialog != NULL );\n\n    return FALSE;\n}\n"
  },
  {
    "path": "instrumentation/wingui.h",
    "content": "#pragma once\n\n#include <windows.h>\n\nextern \"C\" BOOL IsProcessInModalDialog( DWORD dwTargetProcessId );\n"
  },
  {
    "path": "instrumentation/xxhash.c",
    "content": "/*\n*  xxHash - Fast Hash algorithm\n*  Copyright (C) 2012-2016, Yann Collet\n*\n*  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions are\n*  met:\n*\n*  * Redistributions of source code must retain the above copyright\n*  notice, this list of conditions and the following disclaimer.\n*  * Redistributions in binary form must reproduce the above\n*  copyright notice, this list of conditions and the following disclaimer\n*  in the documentation and/or other materials provided with the\n*  distribution.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*\n*  You can contact the author at :\n*  - xxHash homepage: http://www.xxhash.com\n*  - xxHash source repository : https://github.com/Cyan4973/xxHash\n*/\n\n\n/* *************************************\n*  Tuning parameters\n***************************************/\n/*!XXH_FORCE_MEMORY_ACCESS :\n * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.\n * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.\n * The below switch allow to select different access method for improved performance.\n * Method 0 (default) : use `memcpy()`. Safe and portable.\n * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).\n *            This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.\n * Method 2 : direct access. This method doesn't depend on compiler but violate C standard.\n *            It can generate buggy code on targets which do not support unaligned memory accesses.\n *            But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)\n * See http://stackoverflow.com/a/32095106/646947 for details.\n * Prefer these methods in priority order (0 > 1 > 2)\n */\n#ifndef XXH_FORCE_MEMORY_ACCESS   /* can be defined externally, on command line for example */\n#  if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \\\n                        || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \\\n                        || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )\n#    define XXH_FORCE_MEMORY_ACCESS 2\n#  elif (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \\\n  (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \\\n                    || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \\\n                    || defined(__ARM_ARCH_7S__) ))\n#    define XXH_FORCE_MEMORY_ACCESS 1\n#  endif\n#endif\n\n/*!XXH_ACCEPT_NULL_INPUT_POINTER :\n * If input pointer is NULL, xxHash default behavior is to dereference it, triggering a segfault.\n * When this macro is enabled, xxHash actively checks input for null pointer.\n * It it is, result for null input pointers is the same as a null-length input.\n */\n#ifndef XXH_ACCEPT_NULL_INPUT_POINTER   /* can be defined externally */\n#  define XXH_ACCEPT_NULL_INPUT_POINTER 0\n#endif\n\n/*!XXH_FORCE_NATIVE_FORMAT :\n * By default, xxHash library provides endian-independent Hash values, based on little-endian convention.\n * Results are therefore identical for little-endian and big-endian CPU.\n * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.\n * Should endian-independence be of no importance for your application, you may set the #define below to 1,\n * to improve speed for Big-endian CPU.\n * This option has no impact on Little_Endian CPU.\n */\n#ifndef XXH_FORCE_NATIVE_FORMAT   /* can be defined externally */\n#  define XXH_FORCE_NATIVE_FORMAT 0\n#endif\n\n/*!XXH_FORCE_ALIGN_CHECK :\n * This is a minor performance trick, only useful with lots of very small keys.\n * It means : check for aligned/unaligned input.\n * The check costs one initial branch per hash;\n * set it to 0 when the input is guaranteed to be aligned,\n * or when alignment doesn't matter for performance.\n */\n#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */\n#  if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)\n#    define XXH_FORCE_ALIGN_CHECK 0\n#  else\n#    define XXH_FORCE_ALIGN_CHECK 1\n#  endif\n#endif\n\n\n/* *************************************\n*  Includes & Memory related functions\n***************************************/\n/*! Modify the local functions below should you wish to use some other memory routines\n*   for malloc(), free() */\n#include <stdlib.h>\nstatic void* XXH_malloc(size_t s) { return malloc(s); }\nstatic void  XXH_free  (void* p)  { free(p); }\n/*! and for memcpy() */\n#include <string.h>\nstatic void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }\n\n#include <assert.h>   /* assert */\n\n#define XXH_STATIC_LINKING_ONLY\n#include \"xxhash.h\"\n\n\n/* *************************************\n*  Compiler Specific Options\n***************************************/\n#ifdef _MSC_VER    /* Visual Studio */\n#  pragma warning(disable : 4127)      /* disable: C4127: conditional expression is constant */\n#  define FORCE_INLINE static __forceinline\n#else\n#  if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   /* C99 */\n#    ifdef __GNUC__\n#      define FORCE_INLINE static inline __attribute__((always_inline))\n#    else\n#      define FORCE_INLINE static inline\n#    endif\n#  else\n#    define FORCE_INLINE static\n#  endif /* __STDC_VERSION__ */\n#endif\n\n\n/* *************************************\n*  Basic Types\n***************************************/\n#ifndef MEM_MODULE\n# if !defined (__VMS) \\\n  && (defined (__cplusplus) \\\n  || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )\n#   include <stdint.h>\n    typedef uint8_t  BYTE;\n    typedef uint16_t U16;\n    typedef uint32_t U32;\n# else\n    typedef unsigned char      BYTE;\n    typedef unsigned short     U16;\n    typedef unsigned int       U32;\n# endif\n#endif\n\n#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))\n\n/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */\nstatic U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; }\n\n#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))\n\n/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */\n/* currently only defined for gcc and icc */\ntypedef union { U32 u32; } __attribute__((packed)) unalign;\nstatic U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }\n\n#else\n\n/* portable and safe solution. Generally efficient.\n * see : http://stackoverflow.com/a/32095106/646947\n */\nstatic U32 XXH_read32(const void* memPtr)\n{\n    U32 val;\n    memcpy(&val, memPtr, sizeof(val));\n    return val;\n}\n\n#endif   /* XXH_FORCE_DIRECT_MEMORY_ACCESS */\n\n\n/* ****************************************\n*  Compiler-specific Functions and Macros\n******************************************/\n#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)\n\n/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */\n#if defined(_MSC_VER)\n#  define XXH_rotl32(x,r) _rotl(x,r)\n#  define XXH_rotl64(x,r) _rotl64(x,r)\n#else\n#  define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))\n#  define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))\n#endif\n\n#if defined(_MSC_VER)     /* Visual Studio */\n#  define XXH_swap32 _byteswap_ulong\n#elif XXH_GCC_VERSION >= 403\n#  define XXH_swap32 __builtin_bswap32\n#else\nstatic U32 XXH_swap32 (U32 x)\n{\n    return  ((x << 24) & 0xff000000 ) |\n            ((x <<  8) & 0x00ff0000 ) |\n            ((x >>  8) & 0x0000ff00 ) |\n            ((x >> 24) & 0x000000ff );\n}\n#endif\n\n\n/* *************************************\n*  Architecture Macros\n***************************************/\ntypedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;\n\n/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */\n#ifndef XXH_CPU_LITTLE_ENDIAN\nstatic int XXH_isLittleEndian(void)\n{\n    const union { U32 u; BYTE c[4]; } one = { 1 };   /* don't use static : performance detrimental  */\n    return one.c[0];\n}\n#   define XXH_CPU_LITTLE_ENDIAN   XXH_isLittleEndian()\n#endif\n\n\n/* ***************************\n*  Memory reads\n*****************************/\ntypedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;\n\nFORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)\n{\n    if (align==XXH_unaligned)\n        return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));\n    else\n        return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr);\n}\n\nFORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)\n{\n    return XXH_readLE32_align(ptr, endian, XXH_unaligned);\n}\n\nstatic U32 XXH_readBE32(const void* ptr)\n{\n    return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);\n}\n\n\n/* *************************************\n*  Macros\n***************************************/\n#define XXH_STATIC_ASSERT(c)  { enum { XXH_sa = 1/(int)(!!(c)) }; }  /* use after variable declarations */\nXXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }\n\n\n/* *******************************************************************\n*  32-bit hash functions\n*********************************************************************/\nstatic const U32 PRIME32_1 = 2654435761U;\nstatic const U32 PRIME32_2 = 2246822519U;\nstatic const U32 PRIME32_3 = 3266489917U;\nstatic const U32 PRIME32_4 =  668265263U;\nstatic const U32 PRIME32_5 =  374761393U;\n\nstatic U32 XXH32_round(U32 seed, U32 input)\n{\n    seed += input * PRIME32_2;\n    seed  = XXH_rotl32(seed, 13);\n    seed *= PRIME32_1;\n    return seed;\n}\n\n/* mix all bits */\nstatic U32 XXH32_avalanche(U32 h32)\n{\n    h32 ^= h32 >> 15;\n    h32 *= PRIME32_2;\n    h32 ^= h32 >> 13;\n    h32 *= PRIME32_3;\n    h32 ^= h32 >> 16;\n    return(h32);\n}\n\n#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)\n\nstatic U32\nXXH32_finalize(U32 h32, const void* ptr, size_t len,\n                XXH_endianess endian, XXH_alignment align)\n\n{\n    const BYTE* p = (const BYTE*)ptr;\n#define PROCESS1             \\\n    h32 += (*p) * PRIME32_5; \\\n    p++;                     \\\n    h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;\n\n#define PROCESS4                         \\\n    h32 += XXH_get32bits(p) * PRIME32_3; \\\n    p+=4;                                \\\n    h32  = XXH_rotl32(h32, 17) * PRIME32_4 ;\n\n    switch(len&15)  /* or switch(bEnd - p) */\n    {\n      case 12:      PROCESS4;\n                    /* fallthrough */\n      case 8:       PROCESS4;\n                    /* fallthrough */\n      case 4:       PROCESS4;\n                    return XXH32_avalanche(h32);\n\n      case 13:      PROCESS4;\n                    /* fallthrough */\n      case 9:       PROCESS4;\n                    /* fallthrough */\n      case 5:       PROCESS4;\n                    PROCESS1;\n                    return XXH32_avalanche(h32);\n\n      case 14:      PROCESS4;\n                    /* fallthrough */\n      case 10:      PROCESS4;\n                    /* fallthrough */\n      case 6:       PROCESS4;\n                    PROCESS1;\n                    PROCESS1;\n                    return XXH32_avalanche(h32);\n\n      case 15:      PROCESS4;\n                    /* fallthrough */\n      case 11:      PROCESS4;\n                    /* fallthrough */\n      case 7:       PROCESS4;\n                    /* fallthrough */\n      case 3:       PROCESS1;\n                    /* fallthrough */\n      case 2:       PROCESS1;\n                    /* fallthrough */\n      case 1:       PROCESS1;\n                    /* fallthrough */\n      case 0:       return XXH32_avalanche(h32);\n    }\n    assert(0);\n    return h32;   /* reaching this point is deemed impossible */\n}\n\n\nFORCE_INLINE U32\nXXH32_endian_align(const void* input, size_t len, U32 seed,\n                    XXH_endianess endian, XXH_alignment align)\n{\n    const BYTE* p = (const BYTE*)input;\n    const BYTE* bEnd = p + len;\n    U32 h32;\n\n#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)\n    if (p==NULL) {\n        len=0;\n        bEnd=p=(const BYTE*)(size_t)16;\n    }\n#endif\n\n    if (len>=16) {\n        const BYTE* const limit = bEnd - 15;\n        U32 v1 = seed + PRIME32_1 + PRIME32_2;\n        U32 v2 = seed + PRIME32_2;\n        U32 v3 = seed + 0;\n        U32 v4 = seed - PRIME32_1;\n\n        do {\n            v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4;\n            v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4;\n            v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4;\n            v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4;\n        } while (p < limit);\n\n        h32 = XXH_rotl32(v1, 1)  + XXH_rotl32(v2, 7)\n            + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);\n    } else {\n        h32  = seed + PRIME32_5;\n    }\n\n    h32 += (U32)len;\n\n    return XXH32_finalize(h32, p, len&15, endian, align);\n}\n\n\nXXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed)\n{\n#if 0\n    /* Simple version, good for code maintenance, but unfortunately slow for small inputs */\n    XXH32_state_t state;\n    XXH32_reset(&state, seed);\n    XXH32_update(&state, input, len);\n    return XXH32_digest(&state);\n#else\n    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;\n\n    if (XXH_FORCE_ALIGN_CHECK) {\n        if ((((size_t)input) & 3) == 0) {   /* Input is 4-bytes aligned, leverage the speed benefit */\n            if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n                return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);\n            else\n                return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);\n    }   }\n\n    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n        return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);\n    else\n        return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);\n#endif\n}\n\n\n\n/*======   Hash streaming   ======*/\n\nXXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)\n{\n    return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));\n}\nXXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)\n{\n    XXH_free(statePtr);\n    return XXH_OK;\n}\n\nXXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState)\n{\n    memcpy(dstState, srcState, sizeof(*dstState));\n}\n\nXXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed)\n{\n    XXH32_state_t state;   /* using a local state to memcpy() in order to avoid strict-aliasing warnings */\n    memset(&state, 0, sizeof(state));\n    state.v1 = seed + PRIME32_1 + PRIME32_2;\n    state.v2 = seed + PRIME32_2;\n    state.v3 = seed + 0;\n    state.v4 = seed - PRIME32_1;\n    /* do not write into reserved, planned to be removed in a future version */\n    memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved));\n    return XXH_OK;\n}\n\n\nFORCE_INLINE\nXXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian)\n{\n    const BYTE* p = (const BYTE*)input;\n    const BYTE* const bEnd = p + len;\n\n    if (input==NULL)\n#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)\n        return XXH_OK;\n#else\n        return XXH_ERROR;\n#endif\n\n    state->total_len_32 += (unsigned)len;\n    state->large_len |= (len>=16) | (state->total_len_32>=16);\n\n    if (state->memsize + len < 16)  {   /* fill in tmp buffer */\n        XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);\n        state->memsize += (unsigned)len;\n        return XXH_OK;\n    }\n\n    if (state->memsize) {   /* some data left from previous update */\n        XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);\n        {   const U32* p32 = state->mem32;\n            state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++;\n            state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++;\n            state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++;\n            state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian));\n        }\n        p += 16-state->memsize;\n        state->memsize = 0;\n    }\n\n    if (p <= bEnd-16) {\n        const BYTE* const limit = bEnd - 16;\n        U32 v1 = state->v1;\n        U32 v2 = state->v2;\n        U32 v3 = state->v3;\n        U32 v4 = state->v4;\n\n        do {\n            v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4;\n            v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4;\n            v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4;\n            v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4;\n        } while (p<=limit);\n\n        state->v1 = v1;\n        state->v2 = v2;\n        state->v3 = v3;\n        state->v4 = v4;\n    }\n\n    if (p < bEnd) {\n        XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));\n        state->memsize = (unsigned)(bEnd-p);\n    }\n\n    return XXH_OK;\n}\n\n\nXXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len)\n{\n    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;\n\n    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n        return XXH32_update_endian(state_in, input, len, XXH_littleEndian);\n    else\n        return XXH32_update_endian(state_in, input, len, XXH_bigEndian);\n}\n\n\nFORCE_INLINE U32\nXXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)\n{\n    U32 h32;\n\n    if (state->large_len) {\n        h32 = XXH_rotl32(state->v1, 1)\n            + XXH_rotl32(state->v2, 7)\n            + XXH_rotl32(state->v3, 12)\n            + XXH_rotl32(state->v4, 18);\n    } else {\n        h32 = state->v3 /* == seed */ + PRIME32_5;\n    }\n\n    h32 += state->total_len_32;\n\n    return XXH32_finalize(h32, state->mem32, state->memsize, endian, XXH_aligned);\n}\n\n\nXXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)\n{\n    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;\n\n    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n        return XXH32_digest_endian(state_in, XXH_littleEndian);\n    else\n        return XXH32_digest_endian(state_in, XXH_bigEndian);\n}\n\n\n/*======   Canonical representation   ======*/\n\n/*! Default XXH result types are basic unsigned 32 and 64 bits.\n*   The canonical representation follows human-readable write convention, aka big-endian (large digits first).\n*   These functions allow transformation of hash result into and from its canonical format.\n*   This way, hash values can be written into a file or buffer, remaining comparable across different systems.\n*/\n\nXXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)\n{\n    XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));\n    if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);\n    memcpy(dst, &hash, sizeof(*dst));\n}\n\nXXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)\n{\n    return XXH_readBE32(src);\n}\n\n\n#ifndef XXH_NO_LONG_LONG\n\n/* *******************************************************************\n*  64-bit hash functions\n*********************************************************************/\n\n/*======   Memory access   ======*/\n\n#ifndef MEM_MODULE\n# define MEM_MODULE\n# if !defined (__VMS) \\\n  && (defined (__cplusplus) \\\n  || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )\n#   include <stdint.h>\n    typedef uint64_t U64;\n# else\n    /* if compiler doesn't support unsigned long long, replace by another 64-bit type */\n    typedef unsigned long long U64;\n# endif\n#endif\n\n\n#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))\n\n/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */\nstatic U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; }\n\n#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))\n\n/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */\n/* currently only defined for gcc and icc */\ntypedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign64;\nstatic U64 XXH_read64(const void* ptr) { return ((const unalign64*)ptr)->u64; }\n\n#else\n\n/* portable and safe solution. Generally efficient.\n * see : http://stackoverflow.com/a/32095106/646947\n */\n\nstatic U64 XXH_read64(const void* memPtr)\n{\n    U64 val;\n    memcpy(&val, memPtr, sizeof(val));\n    return val;\n}\n\n#endif   /* XXH_FORCE_DIRECT_MEMORY_ACCESS */\n\n#if defined(_MSC_VER)     /* Visual Studio */\n#  define XXH_swap64 _byteswap_uint64\n#elif XXH_GCC_VERSION >= 403\n#  define XXH_swap64 __builtin_bswap64\n#else\nstatic U64 XXH_swap64 (U64 x)\n{\n    return  ((x << 56) & 0xff00000000000000ULL) |\n            ((x << 40) & 0x00ff000000000000ULL) |\n            ((x << 24) & 0x0000ff0000000000ULL) |\n            ((x << 8)  & 0x000000ff00000000ULL) |\n            ((x >> 8)  & 0x00000000ff000000ULL) |\n            ((x >> 24) & 0x0000000000ff0000ULL) |\n            ((x >> 40) & 0x000000000000ff00ULL) |\n            ((x >> 56) & 0x00000000000000ffULL);\n}\n#endif\n\nFORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)\n{\n    if (align==XXH_unaligned)\n        return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));\n    else\n        return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr);\n}\n\nFORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)\n{\n    return XXH_readLE64_align(ptr, endian, XXH_unaligned);\n}\n\nstatic U64 XXH_readBE64(const void* ptr)\n{\n    return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);\n}\n\n\n/*======   xxh64   ======*/\n\nstatic const U64 PRIME64_1 = 11400714785074694791ULL;\nstatic const U64 PRIME64_2 = 14029467366897019727ULL;\nstatic const U64 PRIME64_3 =  1609587929392839161ULL;\nstatic const U64 PRIME64_4 =  9650029242287828579ULL;\nstatic const U64 PRIME64_5 =  2870177450012600261ULL;\n\nstatic U64 XXH64_round(U64 acc, U64 input)\n{\n    acc += input * PRIME64_2;\n    acc  = XXH_rotl64(acc, 31);\n    acc *= PRIME64_1;\n    return acc;\n}\n\nstatic U64 XXH64_mergeRound(U64 acc, U64 val)\n{\n    val  = XXH64_round(0, val);\n    acc ^= val;\n    acc  = acc * PRIME64_1 + PRIME64_4;\n    return acc;\n}\n\nstatic U64 XXH64_avalanche(U64 h64)\n{\n    h64 ^= h64 >> 33;\n    h64 *= PRIME64_2;\n    h64 ^= h64 >> 29;\n    h64 *= PRIME64_3;\n    h64 ^= h64 >> 32;\n    return h64;\n}\n\n\n#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)\n\nstatic U64\nXXH64_finalize(U64 h64, const void* ptr, size_t len,\n               XXH_endianess endian, XXH_alignment align)\n{\n    const BYTE* p = (const BYTE*)ptr;\n\n#define PROCESS1_64          \\\n    h64 ^= (*p) * PRIME64_5; \\\n    p++;                     \\\n    h64 = XXH_rotl64(h64, 11) * PRIME64_1;\n\n#define PROCESS4_64          \\\n    h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; \\\n    p+=4;                    \\\n    h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;\n\n#define PROCESS8_64 {        \\\n    U64 const k1 = XXH64_round(0, XXH_get64bits(p)); \\\n    p+=8;                    \\\n    h64 ^= k1;               \\\n    h64  = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; \\\n}\n\n    switch(len&31) {\n      case 24: PROCESS8_64;\n                    /* fallthrough */\n      case 16: PROCESS8_64;\n                    /* fallthrough */\n      case  8: PROCESS8_64;\n               return XXH64_avalanche(h64);\n\n      case 28: PROCESS8_64;\n                    /* fallthrough */\n      case 20: PROCESS8_64;\n                    /* fallthrough */\n      case 12: PROCESS8_64;\n                    /* fallthrough */\n      case  4: PROCESS4_64;\n               return XXH64_avalanche(h64);\n\n      case 25: PROCESS8_64;\n                    /* fallthrough */\n      case 17: PROCESS8_64;\n                    /* fallthrough */\n      case  9: PROCESS8_64;\n               PROCESS1_64;\n               return XXH64_avalanche(h64);\n\n      case 29: PROCESS8_64;\n                    /* fallthrough */\n      case 21: PROCESS8_64;\n                    /* fallthrough */\n      case 13: PROCESS8_64;\n                    /* fallthrough */\n      case  5: PROCESS4_64;\n               PROCESS1_64;\n               return XXH64_avalanche(h64);\n\n      case 26: PROCESS8_64;\n                    /* fallthrough */\n      case 18: PROCESS8_64;\n                    /* fallthrough */\n      case 10: PROCESS8_64;\n               PROCESS1_64;\n               PROCESS1_64;\n               return XXH64_avalanche(h64);\n\n      case 30: PROCESS8_64;\n                    /* fallthrough */\n      case 22: PROCESS8_64;\n                    /* fallthrough */\n      case 14: PROCESS8_64;\n                    /* fallthrough */\n      case  6: PROCESS4_64;\n               PROCESS1_64;\n               PROCESS1_64;\n               return XXH64_avalanche(h64);\n\n      case 27: PROCESS8_64;\n                    /* fallthrough */\n      case 19: PROCESS8_64;\n                    /* fallthrough */\n      case 11: PROCESS8_64;\n               PROCESS1_64;\n               PROCESS1_64;\n               PROCESS1_64;\n               return XXH64_avalanche(h64);\n\n      case 31: PROCESS8_64;\n                    /* fallthrough */\n      case 23: PROCESS8_64;\n                    /* fallthrough */\n      case 15: PROCESS8_64;\n                    /* fallthrough */\n      case  7: PROCESS4_64;\n                    /* fallthrough */\n      case  3: PROCESS1_64;\n                    /* fallthrough */\n      case  2: PROCESS1_64;\n                    /* fallthrough */\n      case  1: PROCESS1_64;\n                    /* fallthrough */\n      case  0: return XXH64_avalanche(h64);\n    }\n\n    /* impossible to reach */\n    assert(0);\n    return 0;  /* unreachable, but some compilers complain without it */\n}\n\nFORCE_INLINE U64\nXXH64_endian_align(const void* input, size_t len, U64 seed,\n                XXH_endianess endian, XXH_alignment align)\n{\n    const BYTE* p = (const BYTE*)input;\n    const BYTE* bEnd = p + len;\n    U64 h64;\n\n#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)\n    if (p==NULL) {\n        len=0;\n        bEnd=p=(const BYTE*)(size_t)32;\n    }\n#endif\n\n    if (len>=32) {\n        const BYTE* const limit = bEnd - 32;\n        U64 v1 = seed + PRIME64_1 + PRIME64_2;\n        U64 v2 = seed + PRIME64_2;\n        U64 v3 = seed + 0;\n        U64 v4 = seed - PRIME64_1;\n\n        do {\n            v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8;\n            v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8;\n            v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8;\n            v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8;\n        } while (p<=limit);\n\n        h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);\n        h64 = XXH64_mergeRound(h64, v1);\n        h64 = XXH64_mergeRound(h64, v2);\n        h64 = XXH64_mergeRound(h64, v3);\n        h64 = XXH64_mergeRound(h64, v4);\n\n    } else {\n        h64  = seed + PRIME64_5;\n    }\n\n    h64 += (U64) len;\n\n    return XXH64_finalize(h64, p, len, endian, align);\n}\n\n\nXXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed)\n{\n#if 0\n    /* Simple version, good for code maintenance, but unfortunately slow for small inputs */\n    XXH64_state_t state;\n    XXH64_reset(&state, seed);\n    XXH64_update(&state, input, len);\n    return XXH64_digest(&state);\n#else\n    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;\n\n    if (XXH_FORCE_ALIGN_CHECK) {\n        if ((((size_t)input) & 7)==0) {  /* Input is aligned, let's leverage the speed advantage */\n            if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n                return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);\n            else\n                return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);\n    }   }\n\n    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n        return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);\n    else\n        return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);\n#endif\n}\n\n/*======   Hash Streaming   ======*/\n\nXXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)\n{\n    return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));\n}\nXXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)\n{\n    XXH_free(statePtr);\n    return XXH_OK;\n}\n\nXXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState)\n{\n    memcpy(dstState, srcState, sizeof(*dstState));\n}\n\nXXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed)\n{\n    XXH64_state_t state;   /* using a local state to memcpy() in order to avoid strict-aliasing warnings */\n    memset(&state, 0, sizeof(state));\n    state.v1 = seed + PRIME64_1 + PRIME64_2;\n    state.v2 = seed + PRIME64_2;\n    state.v3 = seed + 0;\n    state.v4 = seed - PRIME64_1;\n     /* do not write into reserved, planned to be removed in a future version */\n    memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved));\n    return XXH_OK;\n}\n\nFORCE_INLINE\nXXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian)\n{\n    const BYTE* p = (const BYTE*)input;\n    const BYTE* const bEnd = p + len;\n\n    if (input==NULL)\n#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)\n        return XXH_OK;\n#else\n        return XXH_ERROR;\n#endif\n\n    state->total_len += len;\n\n    if (state->memsize + len < 32) {  /* fill in tmp buffer */\n        XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);\n        state->memsize += (U32)len;\n        return XXH_OK;\n    }\n\n    if (state->memsize) {   /* tmp buffer is full */\n        XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize);\n        state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian));\n        state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian));\n        state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian));\n        state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian));\n        p += 32-state->memsize;\n        state->memsize = 0;\n    }\n\n    if (p+32 <= bEnd) {\n        const BYTE* const limit = bEnd - 32;\n        U64 v1 = state->v1;\n        U64 v2 = state->v2;\n        U64 v3 = state->v3;\n        U64 v4 = state->v4;\n\n        do {\n            v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8;\n            v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8;\n            v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8;\n            v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8;\n        } while (p<=limit);\n\n        state->v1 = v1;\n        state->v2 = v2;\n        state->v3 = v3;\n        state->v4 = v4;\n    }\n\n    if (p < bEnd) {\n        XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));\n        state->memsize = (unsigned)(bEnd-p);\n    }\n\n    return XXH_OK;\n}\n\nXXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len)\n{\n    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;\n\n    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n        return XXH64_update_endian(state_in, input, len, XXH_littleEndian);\n    else\n        return XXH64_update_endian(state_in, input, len, XXH_bigEndian);\n}\n\nFORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian)\n{\n    U64 h64;\n\n    if (state->total_len >= 32) {\n        U64 const v1 = state->v1;\n        U64 const v2 = state->v2;\n        U64 const v3 = state->v3;\n        U64 const v4 = state->v4;\n\n        h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);\n        h64 = XXH64_mergeRound(h64, v1);\n        h64 = XXH64_mergeRound(h64, v2);\n        h64 = XXH64_mergeRound(h64, v3);\n        h64 = XXH64_mergeRound(h64, v4);\n    } else {\n        h64  = state->v3 /*seed*/ + PRIME64_5;\n    }\n\n    h64 += (U64) state->total_len;\n\n    return XXH64_finalize(h64, state->mem64, (size_t)state->total_len, endian, XXH_aligned);\n}\n\nXXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in)\n{\n    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;\n\n    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n        return XXH64_digest_endian(state_in, XXH_littleEndian);\n    else\n        return XXH64_digest_endian(state_in, XXH_bigEndian);\n}\n\n\n/*====== Canonical representation   ======*/\n\nXXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)\n{\n    XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));\n    if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);\n    memcpy(dst, &hash, sizeof(*dst));\n}\n\nXXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)\n{\n    return XXH_readBE64(src);\n}\n\n#endif  /* XXH_NO_LONG_LONG */\n"
  },
  {
    "path": "instrumentation/xxhash.h",
    "content": "/*\n   xxHash - Extremely Fast Hash algorithm\n   Header File\n   Copyright (C) 2012-2016, Yann Collet.\n\n   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are\n   met:\n\n       * Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n       * Redistributions in binary form must reproduce the above\n   copyright notice, this list of conditions and the following disclaimer\n   in the documentation and/or other materials provided with the\n   distribution.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n   You can contact the author at :\n   - xxHash source repository : https://github.com/Cyan4973/xxHash\n*/\n\n/* Notice extracted from xxHash homepage :\n\nxxHash is an extremely fast Hash algorithm, running at RAM speed limits.\nIt also successfully passes all tests from the SMHasher suite.\n\nComparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)\n\nName            Speed       Q.Score   Author\nxxHash          5.4 GB/s     10\nCrapWow         3.2 GB/s      2       Andrew\nMumurHash 3a    2.7 GB/s     10       Austin Appleby\nSpookyHash      2.0 GB/s     10       Bob Jenkins\nSBox            1.4 GB/s      9       Bret Mulvey\nLookup3         1.2 GB/s      9       Bob Jenkins\nSuperFastHash   1.2 GB/s      1       Paul Hsieh\nCityHash64      1.05 GB/s    10       Pike & Alakuijala\nFNV             0.55 GB/s     5       Fowler, Noll, Vo\nCRC32           0.43 GB/s     9\nMD5-32          0.33 GB/s    10       Ronald L. Rivest\nSHA1-32         0.28 GB/s    10\n\nQ.Score is a measure of quality of the hash function.\nIt depends on successfully passing SMHasher test set.\n10 is a perfect score.\n\nA 64-bit version, named XXH64, is available since r35.\nIt offers much better speed, but for 64-bit applications only.\nName     Speed on 64 bits    Speed on 32 bits\nXXH64       13.8 GB/s            1.9 GB/s\nXXH32        6.8 GB/s            6.0 GB/s\n*/\n\n#ifndef XXHASH_H_5627135585666179\n#define XXHASH_H_5627135585666179 1\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n\n/* ****************************\n*  Definitions\n******************************/\n#include <stddef.h>   /* size_t */\ntypedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;\n\n\n/* ****************************\n *  API modifier\n ******************************/\n/** XXH_INLINE_ALL (and XXH_PRIVATE_API)\n *  This is useful to include xxhash functions in `static` mode\n *  in order to inline them, and remove their symbol from the public list.\n *  Inlining can offer dramatic performance improvement on small keys.\n *  Methodology :\n *     #define XXH_INLINE_ALL\n *     #include \"xxhash.h\"\n * `xxhash.c` is automatically included.\n *  It's not useful to compile and link it as a separate module.\n */\n#define XXH_INLINE_ALL\n\n\n#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)\n#  ifndef XXH_STATIC_LINKING_ONLY\n#    define XXH_STATIC_LINKING_ONLY\n#  endif\n#  if defined(__GNUC__)\n#    define XXH_PUBLIC_API static __inline __attribute__((unused))\n#  elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)\n#    define XXH_PUBLIC_API static inline\n#  elif defined(_MSC_VER)\n#    define XXH_PUBLIC_API static __inline\n#  else\n     /* this version may generate warnings for unused static functions */\n#    define XXH_PUBLIC_API static\n#  endif\n#else\n#  define XXH_PUBLIC_API   /* do nothing */\n#endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */\n\n/*! XXH_NAMESPACE, aka Namespace Emulation :\n *\n * If you want to include _and expose_ xxHash functions from within your own library,\n * but also want to avoid symbol collisions with other libraries which may also include xxHash,\n *\n * you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library\n * with the value of XXH_NAMESPACE (therefore, avoid NULL and numeric values).\n *\n * Note that no change is required within the calling program as long as it includes `xxhash.h` :\n * regular symbol name will be automatically translated by this header.\n */\n#ifdef XXH_NAMESPACE\n#  define XXH_CAT(A,B) A##B\n#  define XXH_NAME2(A,B) XXH_CAT(A,B)\n#  define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber)\n#  define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32)\n#  define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState)\n#  define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState)\n#  define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset)\n#  define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update)\n#  define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest)\n#  define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState)\n#  define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash)\n#  define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical)\n#  define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)\n#  define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)\n#  define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)\n#  define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)\n#  define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)\n#  define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest)\n#  define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState)\n#  define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash)\n#  define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical)\n#endif\n\n\n/* *************************************\n*  Version\n***************************************/\n#define XXH_VERSION_MAJOR    0\n#define XXH_VERSION_MINOR    6\n#define XXH_VERSION_RELEASE  5\n#define XXH_VERSION_NUMBER  (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)\nXXH_PUBLIC_API unsigned XXH_versionNumber (void);\n\n\n/*-**********************************************************************\n*  32-bit hash\n************************************************************************/\ntypedef unsigned int XXH32_hash_t;\n\n/*! XXH32() :\n    Calculate the 32-bit hash of sequence \"length\" bytes stored at memory address \"input\".\n    The memory between input & input+length must be valid (allocated and read-accessible).\n    \"seed\" can be used to alter the result predictably.\n    Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s */\nXXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed);\n\n/*======   Streaming   ======*/\ntypedef struct XXH32_state_s XXH32_state_t;   /* incomplete type */\nXXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);\nXXH_PUBLIC_API XXH_errorcode  XXH32_freeState(XXH32_state_t* statePtr);\nXXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state);\n\nXXH_PUBLIC_API XXH_errorcode XXH32_reset  (XXH32_state_t* statePtr, unsigned int seed);\nXXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);\nXXH_PUBLIC_API XXH32_hash_t  XXH32_digest (const XXH32_state_t* statePtr);\n\n/*\n * Streaming functions generate the xxHash of an input provided in multiple segments.\n * Note that, for small input, they are slower than single-call functions, due to state management.\n * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized.\n *\n * XXH state must first be allocated, using XXH*_createState() .\n *\n * Start a new hash by initializing state with a seed, using XXH*_reset().\n *\n * Then, feed the hash state by calling XXH*_update() as many times as necessary.\n * The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.\n *\n * Finally, a hash value can be produced anytime, by using XXH*_digest().\n * This function returns the nn-bits hash as an int or long long.\n *\n * It's still possible to continue inserting input into the hash state after a digest,\n * and generate some new hashes later on, by calling again XXH*_digest().\n *\n * When done, free XXH state space if it was allocated dynamically.\n */\n\n/*======   Canonical representation   ======*/\n\ntypedef struct { unsigned char digest[4]; } XXH32_canonical_t;\nXXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);\nXXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);\n\n/* Default result type for XXH functions are primitive unsigned 32 and 64 bits.\n * The canonical representation uses human-readable write convention, aka big-endian (large digits first).\n * These functions allow transformation of hash result into and from its canonical format.\n * This way, hash values can be written into a file / memory, and remain comparable on different systems and programs.\n */\n\n\n#ifndef XXH_NO_LONG_LONG\n/*-**********************************************************************\n*  64-bit hash\n************************************************************************/\ntypedef unsigned long long XXH64_hash_t;\n\n/*! XXH64() :\n    Calculate the 64-bit hash of sequence of length \"len\" stored at memory address \"input\".\n    \"seed\" can be used to alter the result predictably.\n    This function runs faster on 64-bit systems, but slower on 32-bit systems (see benchmark).\n*/\nXXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed);\n\n/*======   Streaming   ======*/\ntypedef struct XXH64_state_s XXH64_state_t;   /* incomplete type */\nXXH_PUBLIC_API XXH64_state_t* XXH64_createState(void);\nXXH_PUBLIC_API XXH_errorcode  XXH64_freeState(XXH64_state_t* statePtr);\nXXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state);\n\nXXH_PUBLIC_API XXH_errorcode XXH64_reset  (XXH64_state_t* statePtr, unsigned long long seed);\nXXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);\nXXH_PUBLIC_API XXH64_hash_t  XXH64_digest (const XXH64_state_t* statePtr);\n\n/*======   Canonical representation   ======*/\ntypedef struct { unsigned char digest[8]; } XXH64_canonical_t;\nXXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);\nXXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);\n#endif  /* XXH_NO_LONG_LONG */\n\n\n\n#ifdef XXH_STATIC_LINKING_ONLY\n\n/* ================================================================================================\n   This section contains declarations which are not guaranteed to remain stable.\n   They may change in future versions, becoming incompatible with a different version of the library.\n   These declarations should only be used with static linking.\n   Never use them in association with dynamic linking !\n=================================================================================================== */\n\n/* These definitions are only present to allow\n * static allocation of XXH state, on stack or in a struct for example.\n * Never **ever** use members directly. */\n\n#if !defined (__VMS) \\\n  && (defined (__cplusplus) \\\n  || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )\n#   include <stdint.h>\n\nstruct XXH32_state_s {\n   uint32_t total_len_32;\n   uint32_t large_len;\n   uint32_t v1;\n   uint32_t v2;\n   uint32_t v3;\n   uint32_t v4;\n   uint32_t mem32[4];\n   uint32_t memsize;\n   uint32_t reserved;   /* never read nor write, might be removed in a future version */\n};   /* typedef'd to XXH32_state_t */\n\nstruct XXH64_state_s {\n   uint64_t total_len;\n   uint64_t v1;\n   uint64_t v2;\n   uint64_t v3;\n   uint64_t v4;\n   uint64_t mem64[4];\n   uint32_t memsize;\n   uint32_t reserved[2];          /* never read nor write, might be removed in a future version */\n};   /* typedef'd to XXH64_state_t */\n\n# else\n\nstruct XXH32_state_s {\n   unsigned total_len_32;\n   unsigned large_len;\n   unsigned v1;\n   unsigned v2;\n   unsigned v3;\n   unsigned v4;\n   unsigned mem32[4];\n   unsigned memsize;\n   unsigned reserved;   /* never read nor write, might be removed in a future version */\n};   /* typedef'd to XXH32_state_t */\n\n#   ifndef XXH_NO_LONG_LONG  /* remove 64-bit support */\nstruct XXH64_state_s {\n   unsigned long long total_len;\n   unsigned long long v1;\n   unsigned long long v2;\n   unsigned long long v3;\n   unsigned long long v4;\n   unsigned long long mem64[4];\n   unsigned memsize;\n   unsigned reserved[2];     /* never read nor write, might be removed in a future version */\n};   /* typedef'd to XXH64_state_t */\n#    endif\n\n# endif\n\n\n#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)\n#  include \"xxhash.c\"   /* include xxhash function bodies as `static`, for inlining */\n#endif\n\n#endif /* XXH_STATIC_LINKING_ONLY */\n\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif /* XXHASH_H_5627135585666179 */\n"
  },
  {
    "path": "jansson/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (jansson)\n\ninclude_directories (${PROJECT_SOURCE_DIR}/)\nSET(JANSSON_SRC\n\t${PROJECT_SOURCE_DIR}/dump.c\n\t${PROJECT_SOURCE_DIR}/error.c\n\t${PROJECT_SOURCE_DIR}/hashtable.c\n\t${PROJECT_SOURCE_DIR}/hashtable_seed.c\n\t${PROJECT_SOURCE_DIR}/jansson_helper.c\n\t${PROJECT_SOURCE_DIR}/load.c\n\t${PROJECT_SOURCE_DIR}/memory.c\n\t${PROJECT_SOURCE_DIR}/pack_unpack.c\n\t${PROJECT_SOURCE_DIR}/strbuffer.c\n\t${PROJECT_SOURCE_DIR}/strconv.c\n\t${PROJECT_SOURCE_DIR}/utf.c\n\t${PROJECT_SOURCE_DIR}/value.c\n)\nsource_group(\"Library Sources\" FILES ${JANSSON_SRC})\n\nadd_library(jansson SHARED ${JANSSON_SRC})\ntarget_compile_definitions(jansson PUBLIC JANSSON_EXPORTS)\n\nadd_library(jansson_object OBJECT ${JANSSON_SRC})\nif (NOT WIN32)\n  set_target_properties(jansson_object PROPERTIES COMPILE_FLAGS \"-fPIC\")\nendif (NOT WIN32)\ntarget_compile_definitions(jansson_object PUBLIC JANSSON_NO_IMPORT)\n\nadd_library(jansson_static STATIC ${JANSSON_SRC})\ntarget_compile_definitions(jansson_static PUBLIC JANSSON_NO_IMPORT)\n"
  },
  {
    "path": "jansson/dump.c",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n *\n * Jansson is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n */\n\n#ifndef _GNU_SOURCE\n#define _GNU_SOURCE\n#endif\n\n#include \"jansson_private.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n\n#include \"jansson.h\"\n#include \"strbuffer.h\"\n#include \"utf.h\"\n\n#define MAX_INTEGER_STR_LENGTH  100\n#define MAX_REAL_STR_LENGTH     100\n\n#define FLAGS_TO_INDENT(f)      ((f) & 0x1F)\n#define FLAGS_TO_PRECISION(f)   (((f) >> 11) & 0x1F)\n\nstruct buffer {\n\tconst size_t size;\n\tsize_t used;\n\tchar *data;\n};\n\nstatic int dump_to_strbuffer(const char *buffer, size_t size, void *data)\n{\n\treturn strbuffer_append_bytes((strbuffer_t *)data, buffer, size);\n}\n\nstatic int dump_to_buffer(const char *buffer, size_t size, void *data)\n{\n\tstruct buffer *buf = (struct buffer *)data;\n\n\tif (buf->used + size <= buf->size)\n\t\tmemcpy(&buf->data[buf->used], buffer, size);\n\n\tbuf->used += size;\n\treturn 0;\n}\n\nstatic int dump_to_file(const char *buffer, size_t size, void *data)\n{\n\tFILE *dest = (FILE *)data;\n\tif (fwrite(buffer, size, 1, dest) != 1)\n\t\treturn -1;\n\treturn 0;\n}\n\nstatic int dump_to_fd(const char *buffer, size_t size, void *data)\n{\n\tint *dest = (int *)data;\n#ifdef HAVE_UNISTD_H\n\tif (write(*dest, buffer, size) == (ssize_t)size)\n\t\treturn 0;\n#endif\n\treturn -1;\n}\n\n/* 32 spaces (the maximum indentation size) */\nstatic const char whitespace[] = \"                                \";\n\nstatic int dump_indent(size_t flags, int depth, int space, json_dump_callback_t dump, void *data)\n{\n\tif (FLAGS_TO_INDENT(flags) > 0)\n\t{\n\t\tunsigned int ws_count = FLAGS_TO_INDENT(flags), n_spaces = depth * ws_count;\n\n\t\tif (dump(\"\\n\", 1, data))\n\t\t\treturn -1;\n\n\t\twhile (n_spaces > 0)\n\t\t{\n\t\t\tint cur_n = n_spaces < sizeof whitespace - 1 ? n_spaces : sizeof whitespace - 1;\n\n\t\t\tif (dump(whitespace, cur_n, data))\n\t\t\t\treturn -1;\n\n\t\t\tn_spaces -= cur_n;\n\t\t}\n\t}\n\telse if (space && !(flags & JSON_COMPACT))\n\t{\n\t\treturn dump(\" \", 1, data);\n\t}\n\treturn 0;\n}\n\nstatic int dump_mem(const char *mem, size_t len, json_dump_callback_t dump, void *data)\n{\n\tconst unsigned char *pos;\n\tunsigned char buffer[200];\n\tint num_chars;\n\n\tif (dump(\"\\\"\" MEM_TOKEN, 1 + strlen(MEM_TOKEN), data))\n\t\treturn -1;\n\n\tfor (pos = (const unsigned char *)mem; pos < (const unsigned char *)(mem + len); pos += num_chars / 2)\n\t{\n\t\tif (pos + 0x20 < (const unsigned char *)(mem + len))\n\t\t\tnum_chars = snprintf(buffer, sizeof(buffer), \n\t\t\t\t\"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\"\n\t\t\t\t\"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\",\n\t\t\t\t*pos, *(pos + 1), *(pos + 2), *(pos + 3), *(pos + 4), *(pos + 5), *(pos + 6), *(pos + 7),\n\t\t\t\t*(pos + 8), *(pos + 9), *(pos + 10), *(pos + 11), *(pos + 12), *(pos + 13), *(pos + 14), *(pos + 15),\n\t\t\t\t*(pos + 16), *(pos + 17), *(pos + 18), *(pos + 19), *(pos + 20), *(pos + 21), *(pos + 22), *(pos + 23),\n\t\t\t\t*(pos + 24), *(pos + 25), *(pos + 26), *(pos + 27), *(pos + 28), *(pos + 29), *(pos + 30), *(pos + 31));\n\t\telse\n\t\t\tnum_chars = snprintf(buffer, sizeof(buffer), \"%02X\", *pos);\n\n\t\tif (dump(buffer, num_chars, data))\n\t\t\treturn -1;\n\t}\n\n\treturn dump(\"\\\"\", 1, data);\n}\n\n\nstatic int dump_string(const char *str, size_t len, json_dump_callback_t dump, void *data, size_t flags)\n{\n\tconst char *pos, *end, *lim;\n\tint32_t codepoint;\n\n\tif (dump(\"\\\"\", 1, data))\n\t\treturn -1;\n\n\tend = pos = str;\n\tlim = str + len;\n\twhile (1)\n\t{\n\t\tconst char *text;\n\t\tchar seq[13];\n\t\tint length;\n\n\t\twhile (end < lim)\n\t\t{\n\t\t\tend = utf8_iterate(pos, lim - pos, &codepoint);\n\t\t\tif (!end)\n\t\t\t\treturn -1;\n\n\t\t\t/* mandatory escape or control char */\n\t\t\tif (codepoint == '\\\\' || codepoint == '\"' || codepoint < 0x20)\n\t\t\t\tbreak;\n\n\t\t\t/* slash */\n\t\t\tif ((flags & JSON_ESCAPE_SLASH) && codepoint == '/')\n\t\t\t\tbreak;\n\n\t\t\t/* non-ASCII */\n\t\t\tif ((flags & JSON_ENSURE_ASCII) && codepoint > 0x7F)\n\t\t\t\tbreak;\n\n\t\t\tpos = end;\n\t\t}\n\n\t\tif (pos != str) {\n\t\t\tif (dump(str, pos - str, data))\n\t\t\t\treturn -1;\n\t\t}\n\n\t\tif (end == pos)\n\t\t\tbreak;\n\n\t\t/* handle \\, /, \", and control codes */\n\t\tlength = 2;\n\t\tswitch (codepoint)\n\t\t{\n\t\tcase '\\\\': text = \"\\\\\\\\\"; break;\n\t\tcase '\\\"': text = \"\\\\\\\"\"; break;\n\t\tcase '\\b': text = \"\\\\b\"; break;\n\t\tcase '\\f': text = \"\\\\f\"; break;\n\t\tcase '\\n': text = \"\\\\n\"; break;\n\t\tcase '\\r': text = \"\\\\r\"; break;\n\t\tcase '\\t': text = \"\\\\t\"; break;\n\t\tcase '/':  text = \"\\\\/\"; break;\n\t\tdefault:\n\t\t{\n\t\t\t/* codepoint is in BMP */\n\t\t\tif (codepoint < 0x10000)\n\t\t\t{\n\t\t\t\tsnprintf(seq, sizeof(seq), \"\\\\u%04X\", (unsigned int)codepoint);\n\t\t\t\tlength = 6;\n\t\t\t}\n\n\t\t\t/* not in BMP -> construct a UTF-16 surrogate pair */\n\t\t\telse\n\t\t\t{\n\t\t\t\tint32_t first, last;\n\n\t\t\t\tcodepoint -= 0x10000;\n\t\t\t\tfirst = 0xD800 | ((codepoint & 0xffc00) >> 10);\n\t\t\t\tlast = 0xDC00 | (codepoint & 0x003ff);\n\n\t\t\t\tsnprintf(seq, sizeof(seq), \"\\\\u%04X\\\\u%04X\", (unsigned int)first, (unsigned int)last);\n\t\t\t\tlength = 12;\n\t\t\t}\n\n\t\t\ttext = seq;\n\t\t\tbreak;\n\t\t}\n\t\t}\n\n\t\tif (dump(text, length, data))\n\t\t\treturn -1;\n\n\t\tstr = pos = end;\n\t}\n\n\treturn dump(\"\\\"\", 1, data);\n}\n\nstatic int compare_keys(const void *key1, const void *key2)\n{\n\treturn strcmp(*(const char **)key1, *(const char **)key2);\n}\n\nstatic int do_dump(const json_t *json, size_t flags, int depth,\n\tjson_dump_callback_t dump, void *data)\n{\n\tint embed = flags & JSON_EMBED;\n\n\tflags &= ~JSON_EMBED;\n\n\tif (!json)\n\t\treturn -1;\n\n\tswitch (json_typeof(json)) {\n\tcase JSON_NULL:\n\t\treturn dump(\"null\", 4, data);\n\n\tcase JSON_TRUE:\n\t\treturn dump(\"true\", 4, data);\n\n\tcase JSON_FALSE:\n\t\treturn dump(\"false\", 5, data);\n\n\tcase JSON_INTEGER:\n\t{\n\t\tchar buffer[MAX_INTEGER_STR_LENGTH];\n\t\tint size;\n\n\t\tsize = snprintf(buffer, MAX_INTEGER_STR_LENGTH,\n\t\t\t\"%\" JSON_INTEGER_FORMAT,\n\t\t\tjson_integer_value(json));\n\t\tif (size < 0 || size >= MAX_INTEGER_STR_LENGTH)\n\t\t\treturn -1;\n\n\t\treturn dump(buffer, size, data);\n\t}\n\n\tcase JSON_REAL:\n\t{\n\t\tchar buffer[MAX_REAL_STR_LENGTH];\n\t\tint size;\n\t\tdouble value = json_real_value(json);\n\n\t\tsize = jsonp_dtostr(buffer, MAX_REAL_STR_LENGTH, value,\n\t\t\tFLAGS_TO_PRECISION(flags));\n\t\tif (size < 0)\n\t\t\treturn -1;\n\n\t\treturn dump(buffer, size, data);\n\t}\n\n\tcase JSON_MEM:\n\t\treturn dump_mem(json_mem_value(json), json_mem_length(json), dump, data);\n\n\tcase JSON_STRING:\n\t\treturn dump_string(json_string_value(json), json_string_length(json), dump, data, flags);\n\n\tcase JSON_ARRAY:\n\t{\n\t\tsize_t n;\n\t\tsize_t i;\n\n\t\tjson_array_t *array;\n\n\t\t/* detect circular references */\n\t\tarray = json_to_array(json);\n\t\tif (array->visited)\n\t\t\tgoto array_error;\n\t\tarray->visited = 1;\n\n\t\tn = json_array_size(json);\n\n\t\tif (!embed && dump(\"[\", 1, data))\n\t\t\tgoto array_error;\n\t\tif (n == 0) {\n\t\t\tarray->visited = 0;\n\t\t\treturn embed ? 0 : dump(\"]\", 1, data);\n\t\t}\n\t\tif (dump_indent(flags, depth + 1, 0, dump, data))\n\t\t\tgoto array_error;\n\n\t\tfor (i = 0; i < n; ++i) {\n\t\t\tif (do_dump(json_array_get(json, i), flags, depth + 1,\n\t\t\t\tdump, data))\n\t\t\t\tgoto array_error;\n\n\t\t\tif (i < n - 1)\n\t\t\t{\n\t\t\t\tif (dump(\",\", 1, data) ||\n\t\t\t\t\tdump_indent(flags, depth + 1, 1, dump, data))\n\t\t\t\t\tgoto array_error;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (dump_indent(flags, depth, 0, dump, data))\n\t\t\t\t\tgoto array_error;\n\t\t\t}\n\t\t}\n\n\t\tarray->visited = 0;\n\t\treturn embed ? 0 : dump(\"]\", 1, data);\n\n\tarray_error:\n\t\tarray->visited = 0;\n\t\treturn -1;\n\t}\n\n\tcase JSON_OBJECT:\n\t{\n\t\tjson_object_t *object;\n\t\tvoid *iter;\n\t\tconst char *separator;\n\t\tint separator_length;\n\n\t\tif (flags & JSON_COMPACT) {\n\t\t\tseparator = \":\";\n\t\t\tseparator_length = 1;\n\t\t}\n\t\telse {\n\t\t\tseparator = \": \";\n\t\t\tseparator_length = 2;\n\t\t}\n\n\t\t/* detect circular references */\n\t\tobject = json_to_object(json);\n\t\tif (object->visited)\n\t\t\tgoto object_error;\n\t\tobject->visited = 1;\n\n\t\titer = json_object_iter((json_t *)json);\n\n\t\tif (!embed && dump(\"{\", 1, data))\n\t\t\tgoto object_error;\n\t\tif (!iter) {\n\t\t\tobject->visited = 0;\n\t\t\treturn embed ? 0 : dump(\"}\", 1, data);\n\t\t}\n\t\tif (dump_indent(flags, depth + 1, 0, dump, data))\n\t\t\tgoto object_error;\n\n\t\tif (flags & JSON_SORT_KEYS)\n\t\t{\n\t\t\tconst char **keys;\n\t\t\tsize_t size, i;\n\n\t\t\tsize = json_object_size(json);\n\t\t\tkeys = jsonp_malloc(size * sizeof(const char *));\n\t\t\tif (!keys)\n\t\t\t\tgoto object_error;\n\n\t\t\ti = 0;\n\t\t\twhile (iter)\n\t\t\t{\n\t\t\t\tkeys[i] = json_object_iter_key(iter);\n\t\t\t\titer = json_object_iter_next((json_t *)json, iter);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tassert(i == size);\n\n\t\t\tqsort(keys, size, sizeof(const char *), compare_keys);\n\n\t\t\tfor (i = 0; i < size; i++)\n\t\t\t{\n\t\t\t\tconst char *key;\n\t\t\t\tjson_t *value;\n\n\t\t\t\tkey = keys[i];\n\t\t\t\tvalue = json_object_get(json, key);\n\t\t\t\tassert(value);\n\n\t\t\t\tdump_string(key, strlen(key), dump, data, flags);\n\t\t\t\tif (dump(separator, separator_length, data) ||\n\t\t\t\t\tdo_dump(value, flags, depth + 1, dump, data))\n\t\t\t\t{\n\t\t\t\t\tjsonp_free(keys);\n\t\t\t\t\tgoto object_error;\n\t\t\t\t}\n\n\t\t\t\tif (i < size - 1)\n\t\t\t\t{\n\t\t\t\t\tif (dump(\",\", 1, data) ||\n\t\t\t\t\t\tdump_indent(flags, depth + 1, 1, dump, data))\n\t\t\t\t\t{\n\t\t\t\t\t\tjsonp_free(keys);\n\t\t\t\t\t\tgoto object_error;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (dump_indent(flags, depth, 0, dump, data))\n\t\t\t\t\t{\n\t\t\t\t\t\tjsonp_free(keys);\n\t\t\t\t\t\tgoto object_error;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tjsonp_free(keys);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Don't sort keys */\n\n\t\t\twhile (iter)\n\t\t\t{\n\t\t\t\tvoid *next = json_object_iter_next((json_t *)json, iter);\n\t\t\t\tconst char *key = json_object_iter_key(iter);\n\n\t\t\t\tdump_string(key, strlen(key), dump, data, flags);\n\t\t\t\tif (dump(separator, separator_length, data) ||\n\t\t\t\t\tdo_dump(json_object_iter_value(iter), flags, depth + 1,\n\t\t\t\t\t\tdump, data))\n\t\t\t\t\tgoto object_error;\n\n\t\t\t\tif (next)\n\t\t\t\t{\n\t\t\t\t\tif (dump(\",\", 1, data) ||\n\t\t\t\t\t\tdump_indent(flags, depth + 1, 1, dump, data))\n\t\t\t\t\t\tgoto object_error;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (dump_indent(flags, depth, 0, dump, data))\n\t\t\t\t\t\tgoto object_error;\n\t\t\t\t}\n\n\t\t\t\titer = next;\n\t\t\t}\n\t\t}\n\n\t\tobject->visited = 0;\n\t\treturn embed ? 0 : dump(\"}\", 1, data);\n\n\tobject_error:\n\t\tobject->visited = 0;\n\t\treturn -1;\n\t}\n\n\tdefault:\n\t\t/* not reached */\n\t\treturn -1;\n\t}\n}\n\nchar *json_dumps(const json_t *json, size_t flags)\n{\n\tstrbuffer_t strbuff;\n\tchar *result;\n\n\tif (strbuffer_init(&strbuff))\n\t\treturn NULL;\n\n\tif (json_dump_callback(json, dump_to_strbuffer, (void *)&strbuff, flags))\n\t\tresult = NULL;\n\telse\n\t\tresult = jsonp_strdup(strbuffer_value(&strbuff));\n\n\tstrbuffer_close(&strbuff);\n\treturn result;\n}\n\nsize_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags)\n{\n\tstruct buffer buf = { size, 0, buffer };\n\n\tif (json_dump_callback(json, dump_to_buffer, (void *)&buf, flags))\n\t\treturn 0;\n\n\treturn buf.used;\n}\n\nint json_dumpf(const json_t *json, FILE *output, size_t flags)\n{\n\treturn json_dump_callback(json, dump_to_file, (void *)output, flags);\n}\n\nint json_dumpfd(const json_t *json, int output, size_t flags)\n{\n\treturn json_dump_callback(json, dump_to_fd, (void *)&output, flags);\n}\n\nint json_dump_file(const json_t *json, const char *path, size_t flags)\n{\n\tint result;\n\n\tFILE *output = fopen(path, \"w\");\n\tif (!output)\n\t\treturn -1;\n\n\tresult = json_dumpf(json, output, flags);\n\n\tfclose(output);\n\treturn result;\n}\n\nint json_dump_callback(const json_t *json, json_dump_callback_t callback, void *data, size_t flags)\n{\n\tif (!(flags & JSON_ENCODE_ANY)) {\n\t\tif (!json_is_array(json) && !json_is_object(json))\n\t\t\treturn -1;\n\t}\n\n\treturn do_dump(json, flags, 0, callback, data);\n}\n"
  },
  {
    "path": "jansson/error.c",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n *\n * Jansson is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n */\n\n#include <string.h>\n#include \"jansson_private.h\"\n\nvoid jsonp_error_init(json_error_t *error, const char *source)\n{\n    if(error)\n    {\n        error->text[0] = '\\0';\n        error->line = -1;\n        error->column = -1;\n        error->position = 0;\n        if(source)\n            jsonp_error_set_source(error, source);\n        else\n            error->source[0] = '\\0';\n    }\n}\n\nvoid jsonp_error_set_source(json_error_t *error, const char *source)\n{\n    size_t length;\n\n    if(!error || !source)\n        return;\n\n    length = strlen(source);\n    if(length < JSON_ERROR_SOURCE_LENGTH)\n        strncpy(error->source, source, length + 1);\n    else {\n        size_t extra = length - JSON_ERROR_SOURCE_LENGTH + 4;\n        strncpy(error->source, \"...\", 3);\n        strncpy(error->source + 3, source + extra, length - extra + 1);\n    }\n}\n\nvoid jsonp_error_set(json_error_t *error, int line, int column,\n                     size_t position, const char *msg, ...)\n{\n    va_list ap;\n\n    va_start(ap, msg);\n    jsonp_error_vset(error, line, column, position, msg, ap);\n    va_end(ap);\n}\n\nvoid jsonp_error_vset(json_error_t *error, int line, int column,\n                      size_t position, const char *msg, va_list ap)\n{\n    if(!error)\n        return;\n\n    if(error->text[0] != '\\0') {\n        /* error already set */\n        return;\n    }\n\n    error->line = line;\n    error->column = column;\n    error->position = (int)position;\n\n    vsnprintf(error->text, JSON_ERROR_TEXT_LENGTH, msg, ap);\n    error->text[JSON_ERROR_TEXT_LENGTH - 1] = '\\0';\n}\n"
  },
  {
    "path": "jansson/hashtable.c",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n *\n * This library is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n */\n\n#if HAVE_CONFIG_H\n#include <jansson_private_config.h>\n#endif\n\n#include <stdlib.h>\n#include <string.h>\n\n#if HAVE_STDINT_H\n#include <stdint.h>\n#endif\n\n#include \"jansson_config.h\"   /* for JSON_INLINE */\n#include \"jansson_private.h\"  /* for container_of() */\n#include \"hashtable.h\"\n\n#ifndef INITIAL_HASHTABLE_ORDER\n#define INITIAL_HASHTABLE_ORDER 3\n#endif\n\ntypedef struct hashtable_list list_t;\ntypedef struct hashtable_pair pair_t;\ntypedef struct hashtable_bucket bucket_t;\n\nextern volatile uint32_t hashtable_seed;\n\n/* Implementation of the hash function */\n#include \"lookup3.h\"\n\n#define list_to_pair(list_)  container_of(list_, pair_t, list)\n#define ordered_list_to_pair(list_)  container_of(list_, pair_t, ordered_list)\n#define hash_str(key)        ((size_t)hashlittle((key), strlen(key), hashtable_seed))\n\nstatic JSON_INLINE void list_init(list_t *list)\n{\n    list->next = list;\n    list->prev = list;\n}\n\nstatic JSON_INLINE void list_insert(list_t *list, list_t *node)\n{\n    node->next = list;\n    node->prev = list->prev;\n    list->prev->next = node;\n    list->prev = node;\n}\n\nstatic JSON_INLINE void list_remove(list_t *list)\n{\n    list->prev->next = list->next;\n    list->next->prev = list->prev;\n}\n\nstatic JSON_INLINE int bucket_is_empty(hashtable_t *hashtable, bucket_t *bucket)\n{\n    return bucket->first == &hashtable->list && bucket->first == bucket->last;\n}\n\nstatic void insert_to_bucket(hashtable_t *hashtable, bucket_t *bucket,\n                             list_t *list)\n{\n    if(bucket_is_empty(hashtable, bucket))\n    {\n        list_insert(&hashtable->list, list);\n        bucket->first = bucket->last = list;\n    }\n    else\n    {\n        list_insert(bucket->first, list);\n        bucket->first = list;\n    }\n}\n\nstatic pair_t *hashtable_find_pair(hashtable_t *hashtable, bucket_t *bucket,\n                                   const char *key, size_t hash)\n{\n    list_t *list;\n    pair_t *pair;\n\n    if(bucket_is_empty(hashtable, bucket))\n        return NULL;\n\n    list = bucket->first;\n    while(1)\n    {\n        pair = list_to_pair(list);\n        if(pair->hash == hash && strcmp(pair->key, key) == 0)\n            return pair;\n\n        if(list == bucket->last)\n            break;\n\n        list = list->next;\n    }\n\n    return NULL;\n}\n\n/* returns 0 on success, -1 if key was not found */\nstatic int hashtable_do_del(hashtable_t *hashtable,\n                            const char *key, size_t hash)\n{\n    pair_t *pair;\n    bucket_t *bucket;\n    size_t index;\n\n    index = hash & hashmask(hashtable->order);\n    bucket = &hashtable->buckets[index];\n\n    pair = hashtable_find_pair(hashtable, bucket, key, hash);\n    if(!pair)\n        return -1;\n\n    if(&pair->list == bucket->first && &pair->list == bucket->last)\n        bucket->first = bucket->last = &hashtable->list;\n\n    else if(&pair->list == bucket->first)\n        bucket->first = pair->list.next;\n\n    else if(&pair->list == bucket->last)\n        bucket->last = pair->list.prev;\n\n    list_remove(&pair->list);\n    list_remove(&pair->ordered_list);\n    json_decref(pair->value);\n\n    jsonp_free(pair);\n    hashtable->size--;\n\n    return 0;\n}\n\nstatic void hashtable_do_clear(hashtable_t *hashtable)\n{\n    list_t *list, *next;\n    pair_t *pair;\n\n    for(list = hashtable->list.next; list != &hashtable->list; list = next)\n    {\n        next = list->next;\n        pair = list_to_pair(list);\n        json_decref(pair->value);\n        jsonp_free(pair);\n    }\n}\n\nstatic int hashtable_do_rehash(hashtable_t *hashtable)\n{\n    list_t *list, *next;\n    pair_t *pair;\n    size_t i, index, new_size, new_order;\n    struct hashtable_bucket *new_buckets;\n\n    new_order = hashtable->order + 1;\n    new_size = hashsize(new_order);\n\n    new_buckets = jsonp_malloc(new_size * sizeof(bucket_t));\n    if(!new_buckets)\n        return -1;\n\n    jsonp_free(hashtable->buckets);\n    hashtable->buckets = new_buckets;\n    hashtable->order = new_order;\n\n    for(i = 0; i < hashsize(hashtable->order); i++)\n    {\n        hashtable->buckets[i].first = hashtable->buckets[i].last =\n            &hashtable->list;\n    }\n\n    list = hashtable->list.next;\n    list_init(&hashtable->list);\n\n    for(; list != &hashtable->list; list = next) {\n        next = list->next;\n        pair = list_to_pair(list);\n        index = pair->hash % new_size;\n        insert_to_bucket(hashtable, &hashtable->buckets[index], &pair->list);\n    }\n\n    return 0;\n}\n\n\nint hashtable_init(hashtable_t *hashtable)\n{\n    size_t i;\n\n    hashtable->size = 0;\n    hashtable->order = INITIAL_HASHTABLE_ORDER;\n    hashtable->buckets = jsonp_malloc(hashsize(hashtable->order) * sizeof(bucket_t));\n    if(!hashtable->buckets)\n        return -1;\n\n    list_init(&hashtable->list);\n    list_init(&hashtable->ordered_list);\n\n    for(i = 0; i < hashsize(hashtable->order); i++)\n    {\n        hashtable->buckets[i].first = hashtable->buckets[i].last =\n            &hashtable->list;\n    }\n\n    return 0;\n}\n\nvoid hashtable_close(hashtable_t *hashtable)\n{\n    hashtable_do_clear(hashtable);\n    jsonp_free(hashtable->buckets);\n}\n\nint hashtable_set(hashtable_t *hashtable, const char *key, json_t *value)\n{\n    pair_t *pair;\n    bucket_t *bucket;\n    size_t hash, index;\n\n    /* rehash if the load ratio exceeds 1 */\n    if(hashtable->size >= hashsize(hashtable->order))\n        if(hashtable_do_rehash(hashtable))\n            return -1;\n\n    hash = hash_str(key);\n    index = hash & hashmask(hashtable->order);\n    bucket = &hashtable->buckets[index];\n    pair = hashtable_find_pair(hashtable, bucket, key, hash);\n\n    if(pair)\n    {\n        json_decref(pair->value);\n        pair->value = value;\n    }\n    else\n    {\n        /* offsetof(...) returns the size of pair_t without the last,\n           flexible member. This way, the correct amount is\n           allocated. */\n\n        size_t len = strlen(key);\n        if(len >= (size_t)-1 - offsetof(pair_t, key)) {\n            /* Avoid an overflow if the key is very long */\n            return -1;\n        }\n\n        pair = jsonp_malloc(offsetof(pair_t, key) + len + 1);\n        if(!pair)\n            return -1;\n\n        pair->hash = hash;\n        strncpy(pair->key, key, len + 1);\n        pair->value = value;\n        list_init(&pair->list);\n        list_init(&pair->ordered_list);\n\n        insert_to_bucket(hashtable, bucket, &pair->list);\n        list_insert(&hashtable->ordered_list, &pair->ordered_list);\n\n        hashtable->size++;\n    }\n    return 0;\n}\n\nvoid *hashtable_get(hashtable_t *hashtable, const char *key)\n{\n    pair_t *pair;\n    size_t hash;\n    bucket_t *bucket;\n\n    hash = hash_str(key);\n    bucket = &hashtable->buckets[hash & hashmask(hashtable->order)];\n\n    pair = hashtable_find_pair(hashtable, bucket, key, hash);\n    if(!pair)\n        return NULL;\n\n    return pair->value;\n}\n\nint hashtable_del(hashtable_t *hashtable, const char *key)\n{\n    size_t hash = hash_str(key);\n    return hashtable_do_del(hashtable, key, hash);\n}\n\nvoid hashtable_clear(hashtable_t *hashtable)\n{\n    size_t i;\n\n    hashtable_do_clear(hashtable);\n\n    for(i = 0; i < hashsize(hashtable->order); i++)\n    {\n        hashtable->buckets[i].first = hashtable->buckets[i].last =\n            &hashtable->list;\n    }\n\n    list_init(&hashtable->list);\n    list_init(&hashtable->ordered_list);\n    hashtable->size = 0;\n}\n\nvoid *hashtable_iter(hashtable_t *hashtable)\n{\n    return hashtable_iter_next(hashtable, &hashtable->ordered_list);\n}\n\nvoid *hashtable_iter_at(hashtable_t *hashtable, const char *key)\n{\n    pair_t *pair;\n    size_t hash;\n    bucket_t *bucket;\n\n    hash = hash_str(key);\n    bucket = &hashtable->buckets[hash & hashmask(hashtable->order)];\n\n    pair = hashtable_find_pair(hashtable, bucket, key, hash);\n    if(!pair)\n        return NULL;\n\n    return &pair->ordered_list;\n}\n\nvoid *hashtable_iter_next(hashtable_t *hashtable, void *iter)\n{\n    list_t *list = (list_t *)iter;\n    if(list->next == &hashtable->ordered_list)\n        return NULL;\n    return list->next;\n}\n\nvoid *hashtable_iter_key(void *iter)\n{\n    pair_t *pair = ordered_list_to_pair((list_t *)iter);\n    return pair->key;\n}\n\nvoid *hashtable_iter_value(void *iter)\n{\n    pair_t *pair = ordered_list_to_pair((list_t *)iter);\n    return pair->value;\n}\n\nvoid hashtable_iter_set(void *iter, json_t *value)\n{\n    pair_t *pair = ordered_list_to_pair((list_t *)iter);\n\n    json_decref(pair->value);\n    pair->value = value;\n}\n"
  },
  {
    "path": "jansson/hashtable.h",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n *\n * This library is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n */\n\n#ifndef HASHTABLE_H\n#define HASHTABLE_H\n\n#include <stdlib.h>\n#include \"jansson.h\"\n\nstruct hashtable_list {\n    struct hashtable_list *prev;\n    struct hashtable_list *next;\n};\n\n/* \"pair\" may be a bit confusing a name, but think of it as a\n   key-value pair. In this case, it just encodes some extra data,\n   too */\nstruct hashtable_pair {\n    struct hashtable_list list;\n    struct hashtable_list ordered_list;\n    size_t hash;\n    json_t *value;\n    char key[1];\n};\n\nstruct hashtable_bucket {\n    struct hashtable_list *first;\n    struct hashtable_list *last;\n};\n\ntypedef struct hashtable {\n    size_t size;\n    struct hashtable_bucket *buckets;\n    size_t order;  /* hashtable has pow(2, order) buckets */\n    struct hashtable_list list;\n    struct hashtable_list ordered_list;\n} hashtable_t;\n\n\n#define hashtable_key_to_iter(key_) \\\n    (&(container_of(key_, struct hashtable_pair, key)->ordered_list))\n\n\n/**\n * hashtable_init - Initialize a hashtable object\n *\n * @hashtable: The (statically allocated) hashtable object\n *\n * Initializes a statically allocated hashtable object. The object\n * should be cleared with hashtable_close when it's no longer used.\n *\n * Returns 0 on success, -1 on error (out of memory).\n */\nint hashtable_init(hashtable_t *hashtable);\n\n/**\n * hashtable_close - Release all resources used by a hashtable object\n *\n * @hashtable: The hashtable\n *\n * Destroys a statically allocated hashtable object.\n */\nvoid hashtable_close(hashtable_t *hashtable);\n\n/**\n * hashtable_set - Add/modify value in hashtable\n *\n * @hashtable: The hashtable object\n * @key: The key\n * @serial: For addition order of keys\n * @value: The value\n *\n * If a value with the given key already exists, its value is replaced\n * with the new value. Value is \"stealed\" in the sense that hashtable\n * doesn't increment its refcount but decreases the refcount when the\n * value is no longer needed.\n *\n * Returns 0 on success, -1 on failure (out of memory).\n */\nint hashtable_set(hashtable_t *hashtable, const char *key, json_t *value);\n\n/**\n * hashtable_get - Get a value associated with a key\n *\n * @hashtable: The hashtable object\n * @key: The key\n *\n * Returns value if it is found, or NULL otherwise.\n */\nvoid *hashtable_get(hashtable_t *hashtable, const char *key);\n\n/**\n * hashtable_del - Remove a value from the hashtable\n *\n * @hashtable: The hashtable object\n * @key: The key\n *\n * Returns 0 on success, or -1 if the key was not found.\n */\nint hashtable_del(hashtable_t *hashtable, const char *key);\n\n/**\n * hashtable_clear - Clear hashtable\n *\n * @hashtable: The hashtable object\n *\n * Removes all items from the hashtable.\n */\nvoid hashtable_clear(hashtable_t *hashtable);\n\n/**\n * hashtable_iter - Iterate over hashtable\n *\n * @hashtable: The hashtable object\n *\n * Returns an opaque iterator to the first element in the hashtable.\n * The iterator should be passed to hashtable_iter_* functions.\n * The hashtable items are not iterated over in any particular order.\n *\n * There's no need to free the iterator in any way. The iterator is\n * valid as long as the item that is referenced by the iterator is not\n * deleted. Other values may be added or deleted. In particular,\n * hashtable_iter_next() may be called on an iterator, and after that\n * the key/value pair pointed by the old iterator may be deleted.\n */\nvoid *hashtable_iter(hashtable_t *hashtable);\n\n/**\n * hashtable_iter_at - Return an iterator at a specific key\n *\n * @hashtable: The hashtable object\n * @key: The key that the iterator should point to\n *\n * Like hashtable_iter() but returns an iterator pointing to a\n * specific key.\n */\nvoid *hashtable_iter_at(hashtable_t *hashtable, const char *key);\n\n/**\n * hashtable_iter_next - Advance an iterator\n *\n * @hashtable: The hashtable object\n * @iter: The iterator\n *\n * Returns a new iterator pointing to the next element in the\n * hashtable or NULL if the whole hastable has been iterated over.\n */\nvoid *hashtable_iter_next(hashtable_t *hashtable, void *iter);\n\n/**\n * hashtable_iter_key - Retrieve the key pointed by an iterator\n *\n * @iter: The iterator\n */\nvoid *hashtable_iter_key(void *iter);\n\n/**\n * hashtable_iter_value - Retrieve the value pointed by an iterator\n *\n * @iter: The iterator\n */\nvoid *hashtable_iter_value(void *iter);\n\n/**\n * hashtable_iter_set - Set the value pointed by an iterator\n *\n * @iter: The iterator\n * @value: The value to set\n */\nvoid hashtable_iter_set(void *iter, json_t *value);\n\n#endif\n"
  },
  {
    "path": "jansson/hashtable_seed.c",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n *\n * This library is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n */\n\n/* Generate sizeof(uint32_t) bytes of as random data as possible to seed\n   the hash function.\n*/\n\n#ifdef HAVE_CONFIG_H\n#include <jansson_private_config.h>\n#endif\n\n#include <stdio.h>\n#include <time.h>\n\n#ifdef HAVE_STDINT_H\n#include <stdint.h>\n#endif\n\n#ifdef HAVE_FCNTL_H\n#include <fcntl.h>\n#endif\n\n#ifdef HAVE_SCHED_H\n#include <sched.h>\n#endif\n\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n\n#ifdef HAVE_SYS_STAT_H\n#include <sys/stat.h>\n#endif\n\n#ifdef HAVE_SYS_TIME_H\n#include <sys/time.h>\n#endif\n\n#ifdef HAVE_SYS_TYPES_H\n#include <sys/types.h>\n#endif\n\n#if defined(_WIN32)\n/* For GetModuleHandle(), GetProcAddress() and GetCurrentProcessId() */\n#include <windows.h>\n#endif\n\n#include \"jansson.h\"\n\n\nstatic uint32_t buf_to_uint32(char *data) {\n    size_t i;\n    uint32_t result = 0;\n\n    for (i = 0; i < sizeof(uint32_t); i++)\n        result = (result << 8) | (unsigned char)data[i];\n\n    return result;\n}\n\n\n\n/* /dev/urandom */\n#if !defined(_WIN32) && defined(USE_URANDOM)\nstatic int seed_from_urandom(uint32_t *seed) {\n    /* Use unbuffered I/O if we have open(), close() and read(). Otherwise\n       fall back to fopen() */\n\n    char data[sizeof(uint32_t)];\n    int ok;\n\n#if defined(HAVE_OPEN) && defined(HAVE_CLOSE) && defined(HAVE_READ)\n    int urandom;\n    urandom = open(\"/dev/urandom\", O_RDONLY);\n    if (urandom == -1)\n        return 1;\n\n    ok = read(urandom, data, sizeof(uint32_t)) == sizeof(uint32_t);\n    close(urandom);\n#else\n    FILE *urandom;\n\n    urandom = fopen(\"/dev/urandom\", \"rb\");\n    if (!urandom)\n        return 1;\n\n    ok = fread(data, 1, sizeof(uint32_t), urandom) == sizeof(uint32_t);\n    fclose(urandom);\n#endif\n\n    if (!ok)\n        return 1;\n\n    *seed = buf_to_uint32(data);\n    return 0;\n}\n#endif\n\n/* Windows Crypto API */\n#if defined(_WIN32) && defined(USE_WINDOWS_CRYPTOAPI)\n#include <wincrypt.h>\n\ntypedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv, LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags);\ntypedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer);\ntypedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv, DWORD dwFlags);\n\nstatic int seed_from_windows_cryptoapi(uint32_t *seed)\n{\n    HINSTANCE hAdvAPI32 = NULL;\n    CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;\n    CRYPTGENRANDOM pCryptGenRandom = NULL;\n    CRYPTRELEASECONTEXT pCryptReleaseContext = NULL;\n    HCRYPTPROV hCryptProv = 0;\n    BYTE data[sizeof(uint32_t)];\n    int ok;\n\n    hAdvAPI32 = GetModuleHandle(TEXT(\"advapi32.dll\"));\n    if(hAdvAPI32 == NULL)\n        return 1;\n\n    pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(hAdvAPI32, \"CryptAcquireContextA\");\n    if (!pCryptAcquireContext)\n        return 1;\n\n    pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(hAdvAPI32, \"CryptGenRandom\");\n    if (!pCryptGenRandom)\n        return 1;\n\n    pCryptReleaseContext = (CRYPTRELEASECONTEXT)GetProcAddress(hAdvAPI32, \"CryptReleaseContext\");\n    if (!pCryptReleaseContext)\n        return 1;\n\n    if (!pCryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))\n        return 1;\n\n    ok = pCryptGenRandom(hCryptProv, sizeof(uint32_t), data);\n    pCryptReleaseContext(hCryptProv, 0);\n\n    if (!ok)\n        return 1;\n\n    *seed = buf_to_uint32((char *)data);\n    return 0;\n}\n#endif\n\n/* gettimeofday() and getpid() */\nstatic int seed_from_timestamp_and_pid(uint32_t *seed) {\n#ifdef HAVE_GETTIMEOFDAY\n    /* XOR of seconds and microseconds */\n    struct timeval tv;\n    gettimeofday(&tv, NULL);\n    *seed = (uint32_t)tv.tv_sec ^ (uint32_t)tv.tv_usec;\n#else\n    /* Seconds only */\n    *seed = (uint32_t)time(NULL);\n#endif\n\n    /* XOR with PID for more randomness */\n#if defined(_WIN32)\n    *seed ^= (uint32_t)GetCurrentProcessId();\n#elif defined(HAVE_GETPID)\n    *seed ^= (uint32_t)getpid();\n#endif\n\n    return 0;\n}\n\nstatic uint32_t generate_seed() {\n    uint32_t seed;\n    int done = 0;\n\n#if !defined(_WIN32) && defined(USE_URANDOM)\n    if (seed_from_urandom(&seed) == 0)\n        done = 1;\n#endif\n\n#if defined(_WIN32) && defined(USE_WINDOWS_CRYPTOAPI)\n    if (seed_from_windows_cryptoapi(&seed) == 0)\n        done = 1;\n#endif\n\n    if (!done) {\n        /* Fall back to timestamp and PID if no better randomness is\n           available */\n        seed_from_timestamp_and_pid(&seed);\n    }\n\n    /* Make sure the seed is never zero */\n    if (seed == 0)\n        seed = 1;\n\n    return seed;\n}\n\n\nvolatile uint32_t hashtable_seed = 0;\n\n#if defined(HAVE_ATOMIC_BUILTINS) && (defined(HAVE_SCHED_YIELD) || !defined(_WIN32))\nstatic volatile char seed_initialized = 0;\n\nvoid json_object_seed(size_t seed) {\n    uint32_t new_seed = (uint32_t)seed;\n\n    if (hashtable_seed == 0) {\n        if (__atomic_test_and_set(&seed_initialized, __ATOMIC_RELAXED) == 0) {\n            /* Do the seeding ourselves */\n            if (new_seed == 0)\n                new_seed = generate_seed();\n\n            __atomic_store_n(&hashtable_seed, new_seed, __ATOMIC_RELEASE);\n        } else {\n            /* Wait for another thread to do the seeding */\n            do {\n#ifdef HAVE_SCHED_YIELD\n                sched_yield();\n#endif\n            } while(__atomic_load_n(&hashtable_seed, __ATOMIC_ACQUIRE) == 0);\n        }\n    }\n}\n#elif defined(HAVE_SYNC_BUILTINS) && (defined(HAVE_SCHED_YIELD) || !defined(_WIN32))\nvoid json_object_seed(size_t seed) {\n    uint32_t new_seed = (uint32_t)seed;\n\n    if (hashtable_seed == 0) {\n        if (new_seed == 0) {\n            /* Explicit synchronization fences are not supported by the\n               __sync builtins, so every thread getting here has to\n               generate the seed value.\n            */\n            new_seed = generate_seed();\n        }\n\n        do {\n            if (__sync_bool_compare_and_swap(&hashtable_seed, 0, new_seed)) {\n                /* We were the first to seed */\n                break;\n            } else {\n                /* Wait for another thread to do the seeding */\n#ifdef HAVE_SCHED_YIELD\n                sched_yield();\n#endif\n            }\n        } while(hashtable_seed == 0);\n    }\n}\n#elif defined(_WIN32)\nstatic long seed_initialized = 0;\nvoid json_object_seed(size_t seed) {\n    uint32_t new_seed = (uint32_t)seed;\n\n    if (hashtable_seed == 0) {\n        if (InterlockedIncrement(&seed_initialized) == 1) {\n            /* Do the seeding ourselves */\n            if (new_seed == 0)\n                new_seed = generate_seed();\n\n            hashtable_seed = new_seed;\n        } else {\n            /* Wait for another thread to do the seeding */\n            do {\n                SwitchToThread();\n            } while (hashtable_seed == 0);\n        }\n    }\n}\n#else\n/* Fall back to a thread-unsafe version */\nvoid json_object_seed(size_t seed) {\n    uint32_t new_seed = (uint32_t)seed;\n\n    if (hashtable_seed == 0) {\n        if (new_seed == 0)\n            new_seed = generate_seed();\n\n        hashtable_seed = new_seed;\n    }\n}\n#endif\n"
  },
  {
    "path": "jansson/jansson.h",
    "content": "/*\n* Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n*\n* Jansson is free software; you can redistribute it and/or modify\n* it under the terms of the MIT license. See MIT for details.\n*/\n\n#ifndef JANSSON_H\n#define JANSSON_H\n\n#include <stdio.h>\n#include <stdlib.h>  /* for size_t */\n#include <stdarg.h>\n\n#include \"jansson_config.h\"\n\n#ifdef _WIN32\n#if defined(JANSSON_EXPORTS)\n#define JANSSON_API __declspec(dllexport)\n#elif defined(JANSSON_NO_IMPORT)\n#define JANSSON_API\n#elif defined(__cplusplus)\n#define JANSSON_API extern \"C\" __declspec(dllimport)\n#else\n#define JANSSON_API __declspec(dllimport)\n#endif\n#else //_WIN32\n#define JANSSON_API\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\t/* version */\n\n#define JANSSON_MAJOR_VERSION  2\n#define JANSSON_MINOR_VERSION  10\n#define JANSSON_MICRO_VERSION  0\n\n\t/* Micro version is omitted if it's 0 */\n#define JANSSON_VERSION  \"2.10\"\n\n\t/* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this\n\tfor numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */\n#define JANSSON_VERSION_HEX  ((JANSSON_MAJOR_VERSION << 16) |   \\\n                              (JANSSON_MINOR_VERSION << 8)  |   \\\n                              (JANSSON_MICRO_VERSION << 0))\n\n\n\t/* types */\n\n\ttypedef enum {\n\t\tJSON_OBJECT,\n\t\tJSON_ARRAY,\n\t\tJSON_STRING,\n\t\tJSON_MEM,\n\t\tJSON_INTEGER,\n\t\tJSON_REAL,\n\t\tJSON_TRUE,\n\t\tJSON_FALSE,\n\t\tJSON_NULL\n\t} json_type;\n\n\ttypedef struct json_t {\n\t\tjson_type type;\n\t\tsize_t refcount;\n\t} json_t;\n\n#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */\n#if JSON_INTEGER_IS_LONG_LONG\n#ifdef _WIN32\n#define JSON_INTEGER_FORMAT \"I64d\"\n#else\n#define JSON_INTEGER_FORMAT \"lld\"\n#endif\n\ttypedef long long json_int_t;\n#else\n#define JSON_INTEGER_FORMAT \"ld\"\n\ttypedef long json_int_t;\n#endif /* JSON_INTEGER_IS_LONG_LONG */\n#endif\n\n#define json_typeof(json)      ((json)->type)\n#define json_is_object(json)   ((json) && json_typeof(json) == JSON_OBJECT)\n#define json_is_array(json)    ((json) && json_typeof(json) == JSON_ARRAY)\n#define json_is_string(json)   ((json) && json_typeof(json) == JSON_STRING)\n#define json_is_mem(json)      ((json) && json_typeof(json) == JSON_MEM)\n#define json_is_integer(json)  ((json) && json_typeof(json) == JSON_INTEGER)\n#define json_is_real(json)     ((json) && json_typeof(json) == JSON_REAL)\n#define json_is_number(json)   (json_is_integer(json) || json_is_real(json))\n#define json_is_true(json)     ((json) && json_typeof(json) == JSON_TRUE)\n#define json_is_false(json)    ((json) && json_typeof(json) == JSON_FALSE)\n#define json_boolean_value     json_is_true\n#define json_is_boolean(json)  (json_is_true(json) || json_is_false(json))\n#define json_is_null(json)     ((json) && json_typeof(json) == JSON_NULL)\n\n\t/* construction, destruction, reference counting */\n\n\tJANSSON_API json_t *json_object(void);\n\tJANSSON_API json_t *json_array(void);\n\tJANSSON_API json_t *json_string(const char *value);\n\tJANSSON_API json_t *json_stringn(const char *value, size_t len);\n\tJANSSON_API json_t *json_mem(const char *value, size_t len);\n\tJANSSON_API json_t *json_string_nocheck(const char *value);\n\tJANSSON_API json_t *json_stringn_nocheck(const char *value, size_t len);\n\tJANSSON_API json_t *json_integer(json_int_t value);\n\tJANSSON_API json_t *json_real(double value);\n\tJANSSON_API json_t *json_true(void);\n\tJANSSON_API json_t *json_false(void);\n#define json_boolean(val)      ((val) ? json_true() : json_false())\n\tJANSSON_API json_t *json_null(void);\n\n\tstatic JSON_INLINE\n\t\tjson_t *json_incref(json_t *json)\n\t{\n\t\tif (json && json->refcount != (size_t)-1)\n\t\t\t++json->refcount;\n\t\treturn json;\n\t}\n\n\t/* do not call json_delete directly */\n\tJANSSON_API void json_delete(json_t *json);\n\n\tstatic JSON_INLINE\n\t\tvoid json_decref(json_t *json)\n\t{\n\t\tif (json && json->refcount != (size_t)-1 && --json->refcount == 0)\n\t\t\tjson_delete(json);\n\t}\n\n#if defined(__GNUC__) || defined(__clang__)\n\tstatic JSON_INLINE\n\t\tvoid json_decrefp(json_t **json)\n\t{\n\t\tif (json) {\n\t\t\tjson_decref(*json);\n\t\t\t*json = NULL;\n\t\t}\n\t}\n\n#define json_auto_t json_t __attribute__((cleanup(json_decrefp)))\n#endif\n\n\n\t/* error reporting */\n\n#define JSON_ERROR_TEXT_LENGTH    160\n#define JSON_ERROR_SOURCE_LENGTH   80\n\n\ttypedef struct json_error_t {\n\t\tint line;\n\t\tint column;\n\t\tint position;\n\t\tchar source[JSON_ERROR_SOURCE_LENGTH];\n\t\tchar text[JSON_ERROR_TEXT_LENGTH];\n\t} json_error_t;\n\n\n\t/* getters, setters, manipulation */\n\n\tJANSSON_API void json_object_seed(size_t seed);\n\tJANSSON_API size_t json_object_size(const json_t *object);\n\tJANSSON_API json_t *json_object_get(const json_t *object, const char *key);\n\tJANSSON_API int json_object_set_new(json_t *object, const char *key, json_t *value);\n\tJANSSON_API int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value);\n\tJANSSON_API int json_object_del(json_t *object, const char *key);\n\tJANSSON_API int json_object_clear(json_t *object);\n\tJANSSON_API int json_object_update(json_t *object, json_t *other);\n\tJANSSON_API int json_object_update_existing(json_t *object, json_t *other);\n\tJANSSON_API int json_object_update_missing(json_t *object, json_t *other);\n\tJANSSON_API void *json_object_iter(json_t *object);\n\tJANSSON_API void *json_object_iter_at(json_t *object, const char *key);\n\tJANSSON_API void *json_object_key_to_iter(const char *key);\n\tJANSSON_API void *json_object_iter_next(json_t *object, void *iter);\n\tJANSSON_API const char *json_object_iter_key(void *iter);\n\tJANSSON_API json_t *json_object_iter_value(void *iter);\n\tJANSSON_API int json_object_iter_set_new(json_t *object, void *iter, json_t *value);\n\n#define json_object_foreach(object, key, value) \\\n    for(key = json_object_iter_key(json_object_iter(object)); \\\n        key && (value = json_object_iter_value(json_object_key_to_iter(key))); \\\n        key = json_object_iter_key(json_object_iter_next(object, json_object_key_to_iter(key))))\n\n#define json_object_foreach_safe(object, n, key, value)     \\\n    for(key = json_object_iter_key(json_object_iter(object)), \\\n            n = json_object_iter_next(object, json_object_key_to_iter(key)); \\\n        key && (value = json_object_iter_value(json_object_key_to_iter(key))); \\\n        key = json_object_iter_key(n), \\\n            n = json_object_iter_next(object, json_object_key_to_iter(key)))\n\n#define json_array_foreach(array, index, value) \\\n\tfor(index = 0; \\\n\t\tindex < json_array_size(array) && (value = json_array_get(array, index)); \\\n\t\tindex++)\n\n\tstatic JSON_INLINE\n\t\tint json_object_set(json_t *object, const char *key, json_t *value)\n\t{\n\t\treturn json_object_set_new(object, key, json_incref(value));\n\t}\n\n\tstatic JSON_INLINE\n\t\tint json_object_set_nocheck(json_t *object, const char *key, json_t *value)\n\t{\n\t\treturn json_object_set_new_nocheck(object, key, json_incref(value));\n\t}\n\n\tstatic JSON_INLINE\n\t\tint json_object_iter_set(json_t *object, void *iter, json_t *value)\n\t{\n\t\treturn json_object_iter_set_new(object, iter, json_incref(value));\n\t}\n\n\tJANSSON_API size_t json_array_size(const json_t *array);\n\tJANSSON_API json_t *json_array_get(const json_t *array, size_t index);\n\tJANSSON_API int json_array_set_new(json_t *array, size_t index, json_t *value);\n\tJANSSON_API int json_array_append_new(json_t *array, json_t *value);\n\tJANSSON_API int json_array_insert_new(json_t *array, size_t index, json_t *value);\n\tJANSSON_API int json_array_remove(json_t *array, size_t index);\n\tJANSSON_API int json_array_clear(json_t *array);\n\tJANSSON_API int json_array_extend(json_t *array, json_t *other);\n\n\tstatic JSON_INLINE\n\t\tint json_array_set(json_t *array, size_t ind, json_t *value)\n\t{\n\t\treturn json_array_set_new(array, ind, json_incref(value));\n\t}\n\n\tstatic JSON_INLINE\n\t\tint json_array_append(json_t *array, json_t *value)\n\t{\n\t\treturn json_array_append_new(array, json_incref(value));\n\t}\n\n\tstatic JSON_INLINE\n\t\tint json_array_insert(json_t *array, size_t ind, json_t *value)\n\t{\n\t\treturn json_array_insert_new(array, ind, json_incref(value));\n\t}\n\n\tJANSSON_API const char *json_string_value(const json_t *string);\n\tJANSSON_API size_t json_string_length(const json_t *string);\n\tJANSSON_API const char *json_mem_value(const json_t *mem);\n\tJANSSON_API size_t json_mem_length(const json_t *mem);\n\n\tJANSSON_API json_int_t json_integer_value(const json_t *integer);\n\tJANSSON_API double json_real_value(const json_t *real);\n\tJANSSON_API double json_number_value(const json_t *json);\n\n\tJANSSON_API int json_string_set(json_t *string, const char *value);\n\tJANSSON_API int json_string_setn(json_t *string, const char *value, size_t len);\n\tJANSSON_API int json_string_set_nocheck(json_t *string, const char *value);\n\tJANSSON_API int json_string_setn_nocheck(json_t *string, const char *value, size_t len);\n\tJANSSON_API int json_integer_set(json_t *integer, json_int_t value);\n\tJANSSON_API int json_real_set(json_t *real, double value);\n\n\t/* pack, unpack */\n\n\tJANSSON_API json_t *json_pack(const char *fmt, ...);\n\tJANSSON_API json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...);\n\tJANSSON_API json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap);\n\n#define JSON_VALIDATE_ONLY  0x1\n#define JSON_STRICT         0x2\n\n\tJANSSON_API int json_unpack(json_t *root, const char *fmt, ...);\n\tJANSSON_API int json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, ...);\n\tJANSSON_API int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, va_list ap);\n\n\n\t/* equality */\n\n\tJANSSON_API int json_equal(json_t *value1, json_t *value2);\n\n\n\t/* copying */\n\n\tJANSSON_API json_t *json_copy(json_t *value);\n\tJANSSON_API json_t *json_deep_copy(const json_t *value);\n\n\n\t/* decoding */\n\n#define JSON_REJECT_DUPLICATES  0x1\n#define JSON_DISABLE_EOF_CHECK  0x2\n#define JSON_DECODE_ANY         0x4\n#define JSON_DECODE_INT_AS_REAL 0x8\n#define JSON_ALLOW_NUL          0x10\n\n\ttypedef size_t(*json_load_callback_t)(void *buffer, size_t buflen, void *data);\n\n\tJANSSON_API json_t *json_loads(const char *input, size_t flags, json_error_t *error);\n\tJANSSON_API json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error);\n\tJANSSON_API json_t *json_loadf(FILE *input, size_t flags, json_error_t *error);\n\tJANSSON_API json_t *json_loadfd(int input, size_t flags, json_error_t *error);\n\tJANSSON_API json_t *json_load_file(const char *path, size_t flags, json_error_t *error);\n\tJANSSON_API json_t *json_load_callback(json_load_callback_t callback, void *data, size_t flags, json_error_t *error);\n\n\n\t/* encoding */\n\n#define JSON_MAX_INDENT         0x1F\n#define JSON_INDENT(n)          ((n) & JSON_MAX_INDENT)\n#define JSON_COMPACT            0x20\n#define JSON_ENSURE_ASCII       0x40\n#define JSON_SORT_KEYS          0x80\n#define JSON_PRESERVE_ORDER     0x100\n#define JSON_ENCODE_ANY         0x200\n#define JSON_ESCAPE_SLASH       0x400\n#define JSON_REAL_PRECISION(n)  (((n) & 0x1F) << 11)\n#define JSON_EMBED              0x10000\n\n\ttypedef int(*json_dump_callback_t)(const char *buffer, size_t size, void *data);\n\n\tJANSSON_API char *json_dumps(const json_t *json, size_t flags);\n\tJANSSON_API size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags);\n\tJANSSON_API int json_dumpf(const json_t *json, FILE *output, size_t flags);\n\tJANSSON_API int json_dumpfd(const json_t *json, int output, size_t flags);\n\tJANSSON_API int json_dump_file(const json_t *json, const char *path, size_t flags);\n\tJANSSON_API int json_dump_callback(const json_t *json, json_dump_callback_t callback, void *data, size_t flags);\n\n\t/* custom memory allocation */\n\n\ttypedef void *(*json_malloc_t)(size_t);\n\ttypedef void(*json_free_t)(void *);\n\n\tJANSSON_API void json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn);\n\tJANSSON_API void json_get_alloc_funcs(json_malloc_t *malloc_fn, json_free_t *free_fn);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "jansson/jansson_config.h",
    "content": "/*\n * Copyright (c) 2010-2016 Petri Lehtinen <petri@digip.org>\n *\n * Jansson is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n *\n *\n * This file specifies a part of the site-specific configuration for\n * Jansson, namely those things that affect the public API in\n * jansson.h.\n *\n * The CMake system will generate the jansson_config.h file and\n * copy it to the build and install directories.\n */\n\n#ifndef JANSSON_CONFIG_H\n#define JANSSON_CONFIG_H\n\n/* Define this so that we can disable scattered automake configuration in source files */\n#ifndef JANSSON_USING_CMAKE\n#define JANSSON_USING_CMAKE\n#endif\n\n/* Note: when using cmake, JSON_INTEGER_IS_LONG_LONG is not defined nor used,\n * as we will also check for __int64 etc types.\n * (the definition was used in the automake system) */\n\n/* Bring in the cmake-detected defines */\n#define HAVE_STDINT_H 1\n/* #undef HAVE_INTTYPES_H */\n/* #undef HAVE_SYS_TYPES_H */\n\n/* Include our standard type header for the integer typedef */\n\n#if defined(HAVE_STDINT_H)\n#  include <stdint.h>\n#elif defined(HAVE_INTTYPES_H)\n#  include <inttypes.h>\n#elif defined(HAVE_SYS_TYPES_H)\n#  include <sys/types.h>\n#endif\n\n\n/* If your compiler supports the inline keyword in C, JSON_INLINE is\n   defined to `inline', otherwise empty. In C++, the inline is always\n   supported. */\n#ifdef __cplusplus\n#define JSON_INLINE inline\n#else\n#define JSON_INLINE inline\n#endif\n\n\n#define json_int_t long long\n#define json_strtoint strtoll\n#ifdef _WIN32\n#define JSON_INTEGER_FORMAT \"I64d\"\n#else\n#define JSON_INTEGER_FORMAT \"lld\"\n#endif\n\n\n/* If locale.h and localeconv() are available, define to 1, otherwise to 0. */\n#define JSON_HAVE_LOCALECONV 1\n\n\n/* Maximum recursion depth for parsing JSON input.\n   This limits the depth of e.g. array-within-array constructions. */\n#define JSON_PARSER_MAX_DEPTH 2048\n\n\n#endif\n"
  },
  {
    "path": "jansson/jansson_helper.c",
    "content": "#include \"jansson.h\"\n#include \"jansson_helper.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n/**\n * This function parses the given JSON string and converts it into a json_t object\n * @param json_string - a JSON character buffer that should be converted into a json_t\n * @return - a json_t object on success, or NULL on failure\n */\njson_t * get_root_option_json_object(const char * json_string)\n{\n\tjson_t * root;\n\tjson_error_t error;\n\n\troot = json_loads(json_string, 0, &error);\n\tif (!root)\n\t{\n\t\tfprintf(stderr, \"json error in options: on line %d: %s\\n\", error.line, error.text);\n\t\treturn NULL;\n\t}\n\n\tif (!json_is_object(root))\n\t{\n\t\tfprintf(stderr, \"json error in options: root is not an object\\n\");\n\t\tjson_decref(root);\n\t\treturn NULL;\n\t}\n\n\treturn root;\n}\n\n/**\n * Gets a string attribute value from a json_t object\n * @param root - the json_t object to get the attribute from\n * @param option_name - the name of the attribute to get\n * @param result - a pointer to an integer to return the results of trying to get\n * the attribute value.  The value 0 is returned if the attribute isn't found, -1\n * if the attribute is found but not a string, and 1 if the attribute is found and\n * a string.\n * @param should_free - whether or not to free the root json_t parameter after finding\n * the attribute\n * @return - the string value of the specified attribute on success, or NULL if the attribute\n * wasn't found or the wrong type. The return value should be freed by the caller.\n */\nstatic char * get_string_options_inner(json_t * root, const char * option_name, int * result, int should_free)\n{\n\tjson_t *option_item;\n\tchar * option_value;\n\n\toption_item = json_object_get(root, option_name);\n\tif (!option_item)\n\t{\n\t\tif (should_free)\n\t\t\tjson_decref(root);\n\t\t*result = 0;\n\t\treturn NULL;\n\t}\n\n\tif (!json_is_string(option_item))\n\t{\n\t\t*result = -1;\n\t\tfprintf(stderr, \"error: option item %s is expected to be a string\\n\", option_name);\n\t\tif (should_free)\n\t\t\tjson_decref(root);\n\t\treturn NULL;\n\t}\n\n\toption_value = strdup(json_string_value(option_item));\n\t*result = 1;\n\tif (should_free)\n\t\tjson_decref(root);\n\treturn option_value;\n}\n\n/**\n * Gets a string attribute value from a JSON string\n * @param json_string - the JSON string to parse and obtain the attribute value from\n * @param option_name - the name of the attribute to get\n * @param result - a pointer to an integer to return the results of trying to get\n * the attribute value.  The value 0 is returned if the attribute isn't found, -1\n * if the attribute is found but not a string, and 1 if the attribute is found and\n * a string.\n * @return - the string value of the specified attribute on success, or NULL if the json\n * couldn't be parsed, the attribute wasn't found, or the attribute was the wrong type.\n * The return value should be freed by the caller.\n */\nchar * get_string_options(const char * json_string, const char * option_name, int * result)\n{\n\tjson_t * root;\n\n\t*result = -1;\n\troot = get_root_option_json_object(json_string);\n\tif (!root)\n\t\treturn NULL;\n\treturn get_string_options_inner(root, option_name, result, 1);\n}\n\n\n/**\n * Gets a string attribute value from a JSON string\n * @param root - the json_t object to get the attribute from\n * @param option_name - the name of the attribute to get\n * @param result - a pointer to an integer to return the results of trying to get\n * the attribute value.  The value 0 is returned if the attribute isn't found, -1\n * if the attribute is found but not a string, and 1 if the attribute is found and\n * a string.\n * @return - the string value of the specified attribute on success, or NULL if the\n * attribute wasn't found or the wrong type. The return value should be freed by the caller.\n */\nchar * get_string_options_from_json(json_t * root, const char * option_name, int * result)\n{\n\treturn get_string_options_inner(root, option_name, result, 0);\n}\n\n/**\n * Gets a mem attribute value from a json_t object\n * @param root - the json_t object to get the attribute from\n * @param option_name - the name of the attribute to get\n * @param result - a pointer to an integer to return the results of trying to get\n * the attribute value.  The value 0 is returned if the attribute isn't found, -1\n * if the attribute is found but not a mem, and 1 if the attribute is found and\n * a mem.\n * @param should_free - whether or not to free the root json_t parameter after finding\n * the attribute\n * @return - the mem value of the specified attribute on success, or NULL if the attribute\n * wasn't found or the wrong type.  The return value should be freed by the caller.\n */\nstatic char * get_mem_options_inner(json_t * root, const char * option_name, int * result, int should_free)\n{\n\tjson_t *option_item;\n\tchar * option_value;\n\tsize_t length;\n\n\toption_item = json_object_get(root, option_name);\n\tif (!option_item)\n\t{\n\t\tif (should_free)\n\t\t\tjson_decref(root);\n\t\t*result = 0;\n\t\treturn NULL;\n\t}\n\n\tif (!json_is_mem(option_item))\n\t{\n\t\t*result = -1;\n\t\tfprintf(stderr, \"error: option item %s is expected to be a mem\\n\", option_name);\n\t\tif (should_free)\n\t\t\tjson_decref(root);\n\t\treturn NULL;\n\t}\n\n\tlength = json_mem_length(option_item);\n\toption_value = malloc(length);\n\tmemcpy(option_value, json_mem_value(option_item), length);\n\t*result = 1;\n\tif (should_free)\n\t\tjson_decref(root);\n\treturn option_value;\n}\n\n/**\n * Gets a mem attribute value from a JSON string\n * @param json_string - the JSON string to parse and obtain the attribute value from\n * @param option_name - the name of the attribute to get\n * @param result - a pointer to an integer to return the results of trying to get\n * the attribute value.  The value 0 is returned if the attribute isn't found, -1\n * if the attribute is found but not a mem, and 1 if the attribute is found and\n * a mem.\n * @return - the mem value of the specified attribute on success, or NULL if the json\n * couldn't be parsed, the attribute wasn't found, or the attribute was the wrong type.\n * The return value should be freed by the caller.\n */\nchar * get_mem_options(const char * json_string, const char * option_name, int * result)\n{\n\tjson_t * root;\n\n\t*result = -1;\n\troot = get_root_option_json_object(json_string);\n\tif (!root)\n\t\treturn NULL;\n\treturn get_mem_options_inner(root, option_name, result, 1);\n}\n\n/**\n * Gets a mem attribute value from a json_t object\n * @param root - the json_t object to get the attribute from\n * @param option_name - the name of the attribute to get\n * @param result - a pointer to an integer to return the results of trying to get\n * the attribute value.  The value 0 is returned if the attribute isn't found, -1\n * if the attribute is found but not a mem, and 1 if the attribute is found and\n * a mem.\n * @return - the mem value of the specified attribute on success, or NULL if the attribute\n * wasn't found or the wrong type. The return value should be freed by the caller.\n */\nchar * get_mem_options_from_json(json_t * root, const char * option_name, int * result)\n{\n\treturn get_mem_options_inner(root, option_name, result, 0);\n}\n\n/**\n * Gets an integer attribute value from a json_t object\n * @param root - the json_t object to get the attribute from\n * @param option_name - the name of the attribute to get\n * @param result - a pointer to an integer to return the results of trying to get\n * the attribute value.  The value 0 is returned if the attribute isn't found, -1\n * if the attribute is found but not an integer, and 1 if the attribute is found and\n * an integer.\n * @param should_free - whether or not to free the root json_t parameter after finding\n * the attribute\n * @return - the integer value of the specified attribute on success, or -1 if the attribute\n * wasn't found or the wrong type.  Check the value of the result parameter to differentiate\n * between the attribute value of -1 or failure to get the value.\n */\nstatic long long get_int_options_inner(json_t * root, const char * option_name, int * result, int should_free)\n{\n\tjson_t *option_item;\n\tlong long option_value;\n\n\toption_item = json_object_get(root, option_name);\n\tif (!option_item)\n\t{\n\t\tif (should_free)\n\t\t\tjson_decref(root);\n\t\t*result = 0;\n\t\treturn -1;\n\t}\n\n\tif (!json_is_integer(option_item))\n\t{\n\t\t*result = -1;\n\t\tfprintf(stderr, \"error: option item %s is expected to be an integer\\n\", option_name);\n\t\tif (should_free)\n\t\t\tjson_decref(root);\n\t\treturn -1;\n\t}\n\n\toption_value = json_integer_value(option_item);\n\t*result = 1;\n\tif (should_free)\n\t\tjson_decref(root);\n\treturn option_value;\n}\n\n/**\n * Gets an integer attribute value from a JSON string\n * @param json_string - the JSON string to parse and obtain the attribute value from\n * @param option_name - the name of the attribute to get\n * @param result - a pointer to an integer to return the results of trying to get\n * the attribute value.  The value 0 is returned if the attribute isn't found, -1\n * if the attribute is found but not an integer, and 1 if the attribute is found and\n * an integer.\n * @return - the integer value of the specified attribute on success, or -1 if the json\n * couldn't be parsed, the attribute wasn't found, or the attribute was the wrong type.\n * Check the value of the result parameter to differentiate between the attribute value\n * of -1 or failure to get the value.\n */\nint get_int_options(const char * json_string, const char * option_name, int * result)\n{\n\tjson_t * root;\n\n\t*result = -1;\n\troot = get_root_option_json_object(json_string);\n\tif (!root)\n\t\treturn -1;\n\treturn (int)get_int_options_inner(root, option_name, result, 1);\n}\n\n/**\n* Gets an integer attribute value from a json_t object\n* @param root - the json_t object to get the attribute from\n* @param option_name - the name of the attribute to get\n* @param result - a pointer to an integer to return the results of trying to get\n* the attribute value.  The value 0 is returned if the attribute isn't found, -1\n* if the attribute is found but not an integer, and 1 if the attribute is found and\n* an integer.\n* @return - the integer value of the specified attribute on success, or -1 if the attribute\n* wasn't found or the wrong type.  Check the value of the result parameter to differentiate\n* between the attribute value of -1 or failure to get the value.\n*/\nint get_int_options_from_json(json_t * root, const char * option_name, int * result)\n{\n\treturn (int)get_int_options_inner(root, option_name, result, 0);\n}\n\n/**\n* Gets a uint64_t attribute value from a JSON string\n* @param json_string - the JSON string to parse and obtain the attribute value from\n* @param option_name - the name of the attribute to get\n* @param result - a pointer to an integer to return the results of trying to get\n* the attribute value.  The value 0 is returned if the attribute isn't found, -1\n* if the attribute is found but not an integer, and 1 if the attribute is found and\n* an integer.\n* @return - the uint64_t value of the specified attribute on success, or -1 if the json\n* couldn't be parsed, the attribute wasn't found, or the attribute was the wrong type.\n* Check the value of the result parameter to differentiate between the attribute value\n* of -1 or failure to get the value.s\n*/\nuint64_t get_uint64t_options(const char * json_string, const char * option_name, int * result)\n{\n\tjson_t * root;\n\n\t*result = -1;\n\troot = get_root_option_json_object(json_string);\n\tif (!root)\n\t\treturn -1;\n\treturn (uint64_t)get_int_options_inner(root, option_name, result, 1);\n}\n\n/**\n* Gets a uint64_t attribute value from a json_t object\n* @param root - the json_t object to get the attribute from\n* @param option_name - the name of the attribute to get\n* @param result - a pointer to an integer to return the results of trying to get\n* the attribute value.  The value 0 is returned if the attribute isn't found, -1\n* if the attribute is found but not an integer, and 1 if the attribute is found and\n* an integer.\n* @return - the uint64_t value of the specified attribute on success, or -1 if the attribute\n* wasn't found or the wrong type.  Check the value of the result parameter to differentiate\n* between the attribute value of -1 or failure to get the value.\n*/\nuint64_t get_uint64t_options_from_json(json_t * root, const char * option_name, int * result)\n{\n\treturn (uint64_t)get_int_options_inner(root, option_name, result, 0);\n}\n\n/**\n * Gets a double attribute value from a json_t object\n * @param root - the json_t object to get the attribute from\n * @param option_name - the name of the attribute to get\n * @param result - a pointer to an integer to return the results of trying to get\n * the attribute value.  The value 0 is returned if the attribute isn't found, -1\n * if the attribute is found but not a number, and 1 if the attribute is found and\n * a number.\n * @param should_free - whether or not to free the root json_t parameter after finding\n * the attribute\n * @return - the double value of the specified attribute on success, or -1 if the attribute\n * wasn't found or the wrong type.  Check the value of the result parameter to differentiate\n * between the attribute value of -1 or failure to get the value.\n */\nstatic double get_double_options_inner(json_t * root, const char * option_name, int * result, int should_free)\n{\n\tjson_t *option_item;\n\tdouble option_value;\n\n\toption_item = json_object_get(root, option_name);\n\tif (!option_item)\n\t{\n\t\tif (should_free)\n\t\t\tjson_decref(root);\n\t\t*result = 0;\n\t\treturn -1;\n\t}\n\n\tif (!json_is_real(option_item))\n\t{\n\t\t*result = -1;\n\t\tfprintf(stderr, \"error: option item %s is expected to be a real\\n\", option_name);\n\t\tif (should_free)\n\t\t\tjson_decref(root);\n\t\treturn -1;\n\t}\n\n\toption_value = json_real_value(option_item);\n\t*result = 1;\n\tif (should_free)\n\t\tjson_decref(root);\n\treturn option_value;\n}\n\n/**\n * Gets an double attribute value from a JSON string\n * @param json_string - the JSON string to parse and obtain the attribute value from\n * @param option_name - the name of the attribute to get\n * @param result - a pointer to an integer to return the results of trying to get\n * the attribute value.  The value 0 is returned if the attribute isn't found, -1\n * if the attribute is found but not an integer, and 1 if the attribute is found and\n * an double.\n * @return - the double value of the specified attribute on success, or -1 if the json\n * couldn't be parsed, the attribute wasn't found, or the attribute was the wrong type.\n * Check the value of the result parameter to differentiate between the attribute value\n * of -1 or failure to get the value.\n */\ndouble get_double_options(const char * json_string, const char * option_name, int * result)\n{\n\tjson_t * root;\n\n\t*result = -1;\n\troot = get_root_option_json_object(json_string);\n\tif (!root)\n\t\treturn -1;\n\treturn get_double_options_inner(root, option_name, result, 1);\n}\n\n/**\n * Gets an double attribute value from a json_t object\n * @param root - the json_t object to get the attribute from\n * @param option_name - the name of the attribute to get\n * @param result - a pointer to an integer to return the results of trying to get\n * the attribute value.  The value 0 is returned if the attribute isn't found, -1\n * if the attribute is found but not an integer, and 1 if the attribute is found and\n * an double.\n * @return - the double value of the specified attribute on success, or -1 if the attribute\n * wasn't found or the wrong type.  Check the value of the result parameter to differentiate\n * between the attribute value of -1 or failure to get the value.\n */\ndouble get_double_options_from_json(json_t * root, const char * option_name, int * result)\n{\n\treturn get_double_options_inner(root, option_name, result, 0);\n}\n\nstatic int get_array_options_inner(const char * json_string, const char * option_name, size_t * count, char *** string_array, int ** int_array, int is_string_array)\n{\n\tjson_t * root, *option_array, *option_item;\n\tchar ** option_strings;\n\tint * option_ints;\n\tsize_t i;\n\n\troot = get_root_option_json_object(json_string);\n\tif (!root)\n\t\treturn -1;\n\n\toption_array = json_object_get(root, option_name);\n\tif (!option_array)\n\t{\n\t\tjson_decref(root);\n\t\treturn 0;\n\t}\n\n\tif (!json_is_array(option_array))\n\t{\n\t\tfprintf(stderr, \"error: option item %s is expected to be a array\\n\", option_name);\n\t\tjson_decref(root);\n\t\treturn -1;\n\t}\n\n\t*count = json_array_size(option_array);\n\tif(is_string_array)\n\t\toption_strings = malloc(*count * sizeof(char *));\n\telse\n\t\toption_ints = malloc(*count * sizeof(int));\n\tif ((is_string_array && !option_strings) || (!is_string_array && !option_ints))\n\t{\n\t\tfprintf(stderr, \"error: couldn't allocate array for option %s (%zu items)\\n\", option_name, *count);\n\t\tjson_decref(root);\n\t\treturn -1;\n\t}\n\tfor (i = 0; i < *count; i++)\n\t{\n\t\toption_item = json_array_get(option_array, i);\n\t\tif ((is_string_array && !json_is_string(option_item)) || (!is_string_array && !json_is_integer(option_item)))\n\t\t{\n\t\t\tfprintf(stderr, \"error: option %zu in array %s is expected to be a %s\\n\", i, option_name, is_string_array ? \"string\" : \"integer\");\n\t\t\tjson_decref(root);\n\t\t\tfree(option_strings);\n\t\t\treturn -1;\n\t\t}\n\t\tif(is_string_array)\n\t\t\toption_strings[i] = strdup(json_string_value(option_item));\n\t\telse\n\t\t\toption_ints[i] = json_integer_value(option_item);\n\t}\n\n\tif (is_string_array)\n\t\t*string_array = option_strings;\n\telse\n\t\t*int_array = option_ints;\n\n\tjson_decref(root);\n\treturn 1;\n}\n\n\n/**\n * Gets a string array attribute value from a JSON string\n * @param json_string - the JSON string to parse and obtain the attribute value from\n * @param option_name - the name of the attribute to get\n * @param count - a pointer to a size_t object used to return the number of items found\n * in the array attribute value\n * @param result - a pointer to an integer to return the results of trying to get\n * the attribute value.  The value 0 is returned if the attribute isn't found; -1\n * if the attribute is found but not an array, contains elements that aren't strings, or\n * on allocation failures; and 1 if the attribute is found and a string array.\n * @return - the string array of the specified attribute on success, or NULL if the\n * attribute wasn't found or the wrong type.  The returned array and all of its elements should\n * be freed by the caller.\n */\nchar ** get_array_options(const char * json_string, const char * option_name, size_t * count, int * result)\n{\n\tchar **option_strings = NULL;\n\t*result = get_array_options_inner(json_string, option_name, count, &option_strings, NULL, 1);\n\treturn option_strings;\n}\n\n/**\n * Gets an integer array attribute value from a JSON string\n * @param json_string - the JSON string to parse and obtain the attribute value from\n * @param option_name - the name of the attribute to get\n * @param count - a pointer to a size_t object used to return the number of items found\n * in the array attribute value\n * @param result - a pointer to an integer to return the results of trying to get\n * the attribute value.  The value 0 is returned if the attribute isn't found; -1\n * if the attribute is found but not an array, contains elements that aren't integers, or\n * on allocation failures; and 1 if the attribute is found and an integer array.\n * @return - the integer array of the specified attribute on success, or NULL if the\n * attribute wasn't found or the wrong type.  The returned array should be freed by\n * the caller.\n */\nint * get_int_array_options(const char * json_string, const char * option_name, size_t * count, int * result)\n{\n\tint *option_ints = NULL;\n\t*result = get_array_options_inner(json_string, option_name, count, NULL, &option_ints, 0);\n\treturn option_ints;\n}\n\n/**\n * Adds a new attribute to an existing json string.\n * @param root_options - the JSON string to parse and add an attribute to\n * @param new_option_name - the name of the attribute to create\n * @param new_value_string - If specified, the new attribute has the type string\n * and is given the value of this parameter.\n * @param new_value_int - If new_value_string is NULL, the new attribute has the\n * type int and the value specified in this parameter.\n * @return - NULL on error, or the json string passed in the root_options parameter\n * with the added attribute as requested\n */\nstatic char * add_option_to_json(const char * root_options, const char * new_option_name, const char * new_value_string, int new_value_int)\n{\n\tjson_t * root, *temp;\n\tchar * ret;\n\n\troot = get_root_option_json_object(root_options);\n\tif (!root)\n\t\treturn NULL;\n\n\t//Add the new item\n\tif (new_value_string) {\n\t\tADD_STRING(temp, new_value_string, root, new_option_name);\n\t} else {\n\t\tADD_INT(temp, new_value_int, root, new_option_name);\n\t}\n\n\tret = json_dumps(root, 0);\n\tjson_decref(root);\n\treturn ret;\n}\n\n/**\n * Adds a new string attribute to an existing json string.\n * @param root_options - the JSON string to parse and add an attribute to\n * @param new_option_name - the name of the attribute to create\n * @param new_value - the new attribute's value\n * @return - NULL on error, or the json string passed in the root_options parameter\n * with the added attribute as requested\n */\nchar * add_string_option_to_json(const char * root_options, const char * new_option_name, const char * new_value)\n{\n\tif (!new_value)\n\t\treturn NULL;\n\treturn add_option_to_json(root_options, new_option_name, new_value, 0);\n}\n\n/**\n * Adds a new integer attribute to an existing json string.\n * @param root_options - the JSON string to parse and add an attribute to\n * @param new_option_name - the name of the attribute to create\n * @param new_value - the new attribute's value\n * @return - NULL on error, or the json string passed in the root_options parameter\n * with the added attribute as requested\n */\nchar * add_int_option_to_json(const char * root_options, const char * new_option_name, int new_value)\n{\n\treturn add_option_to_json(root_options, new_option_name, NULL, new_value);\n}\n\n/**\n * Gets an array of buffers out of a JSON string containing an array of\n * JSON mem items\n * @param json_string - the JSON string to parse and get the array items from\n * @param items - a pointer to an array of buffers.  This will be used to return\n * the array of items.\n * @param item_lengths - a pointer to a size_t array that will be used to return the\n * lengths of each item returned in the items parameter\n * @param items_count - a size_t pointer that will be used to return the number of items\n * returned in the items parameter\n * @return - non-zero on failure, 0 on success\n */\nint decode_mem_array(const char *json_string, char *** items, size_t ** item_lengths, size_t * items_count)\n{\n\tjson_t * items_jsons, *item_json;\n\tjson_error_t error;\n\tsize_t count, i, j;\n\tchar ** items_array;\n\tsize_t * items_lengths_array;\n\n\titems_jsons = json_loads(json_string, 0, &error);\n\tif (!items_jsons)\n\t\treturn 1;\n\n\tif (!json_is_array(items_jsons)) {\n\t\tjson_decref(items_jsons);\n\t\treturn 1;\n\t}\n\n\tcount = json_array_size(items_jsons);\n\tif (!count) {\n\t\tjson_decref(items_jsons);\n\t\t*items = NULL;\n\t\t*item_lengths = NULL;\n\t\t*items_count = 0;\n\t\treturn 0;\n\t}\n\n\titems_array = malloc(sizeof(char *) * count);\n\titems_lengths_array = malloc(sizeof(size_t) * count);\n\tif (!items_array || !items_lengths_array) {\n\t\tfree(items_array);\n\t\tfree(items_lengths_array);\n\t\tjson_decref(items_jsons);\n\t\treturn 1;\n\t}\n\tmemset(items_array, 0, sizeof(char *) * count);\n\n\tfor (i = 0; i < count; i++)\n\t{\n\t\titem_json = json_array_get(items_jsons, i);\n\t\tif (json_is_mem(item_json))\n\t\t{\n\t\t\titems_lengths_array[i] = json_mem_length(item_json);\n\t\t\titems_array[i] = malloc(items_lengths_array[i]);\n\t\t\tif (items_array[i])\n\t\t\t\tmemcpy(items_array[i], json_mem_value(item_json), items_lengths_array[i]);\n\t\t}\n\n\t\tif (!items_array[i])\n\t\t{\n\t\t\tfor (j = 0; j < i; j++)\n\t\t\t\tfree(items_array[j]);\n\t\t\tfree(items_array);\n\t\t\tfree(items_lengths_array);\n\t\t\tjson_decref(items_jsons);\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\t*items = items_array;\n\t*item_lengths = items_lengths_array;\n\t*items_count = count;\n\treturn 0;\n}\n\n/**\n * Transforms an array of buffers into a JSON string containing the array\n * @param items - an array of buffers that will be put into the returned JSON string\n * @param item_lengths - an array of integers that list the lengths of the buffers\n * in the items parameter\n * @param items_count - the number of items in the items and item_lengths parameters\n * @param output_length = the length of the returned JSON string\n * @return - a JSON string containing an array of mem items encoding the buffers on success, or NULL on failure\n */\nchar * encode_mem_array(char ** items, size_t * item_lengths, size_t items_count, int * output_length)\n{\n\tjson_t *items_obj, *item_obj;\n\tsize_t i;\n\tchar * ret;\n\n\titems_obj = json_array();\n\tif (!items_obj)\n\t\treturn NULL;\n\tfor (i = 0; i < items_count; i++)\n\t{\n\t\titem_obj = json_mem(items[i], item_lengths[i]);\n\t\tif (!item_obj) {\n\t\t\tjson_decref(items_obj);\n\t\t\treturn NULL;\n\t\t}\n\t\tjson_array_append_new(items_obj, item_obj);\n\t}\n\tret = json_dumps(items_obj, 0);\n\t*output_length = strlen(ret);\n\tjson_decref(items_obj);\n\treturn ret;\n}\n"
  },
  {
    "path": "jansson/jansson_helper.h",
    "content": "#pragma once\n\n#include \"jansson.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// Some macros to make parsing options easier\n\n#define PARSE_OPTION_INT_TEMP(state, options, name, name_literal, fail_func, temp_name)  \\\n\tint result_##temp_name = 0;                                                          \\\n\tint tempi_##temp_name = get_int_options(options, name_literal, &result_##temp_name); \\\n\tif (result_##temp_name < 0)                                                          \\\n\t{                                                                                    \\\n\t\tfail_func(state);                                                                \\\n\t\treturn NULL;                                                                     \\\n\t}                                                                                    \\\n\telse if (result_##temp_name > 0)                                                     \\\n\t{                                                                                    \\\n\t\tstate->name = tempi_##temp_name;                                                 \\\n\t}\n\n#define PARSE_OPTION_INT(state, options, name, name_literal, fail_func)                  \\\n\tPARSE_OPTION_INT_TEMP(state, options, name, name_literal, fail_func, name)\n\n#define PARSE_OPTION_UINT64T_TEMP(state, options, name, name_literal, fail_func, temp_name)       \\\n\tint result_##temp_name = 0;                                                                   \\\n\tuint64_t tempi_##temp_name = get_uint64t_options(options, name_literal, &result_##temp_name); \\\n\tif (result_##temp_name < 0)                                                                   \\\n\t{                                                                                             \\\n\t\tfail_func(state);                                                                         \\\n\t\treturn NULL;                                                                              \\\n\t}                                                                                             \\\n\telse if (result_##temp_name > 0)                                                              \\\n\t{                                                                                             \\\n\t\tstate->name = tempi_##temp_name;                                                          \\\n\t}\n\n#define PARSE_OPTION_UINT64T(state, options, name, name_literal, fail_func)                       \\\n\tPARSE_OPTION_UINT64T_TEMP(state, options, name, name_literal, fail_func, name)\n\n#define PARSE_OPTION_DOUBLE_TEMP(state, options, name, name_literal, fail_func, temp_name)     \\\n\tint result_##temp_name = 0;                                                                \\\n\tdouble tempi_##temp_name = get_double_options(options, name_literal, &result_##temp_name); \\\n\tif (result_##temp_name < 0)                                                                \\\n\t{                                                                                          \\\n\t\tfail_func(state);                                                                      \\\n\t\treturn NULL;                                                                           \\\n\t}                                                                                          \\\n\telse if (result_##temp_name > 0)                                                           \\\n\t{                                                                                          \\\n\t\tstate->name = tempi_##temp_name;                                                       \\\n\t}\n\n#define PARSE_OPTION_DOUBLE(state, options, name, name_literal, fail_func)                     \\\n\tPARSE_OPTION_DOUBLE_TEMP(state, options, name, name_literal, fail_func, name)\n\n#define PARSE_OPTION_STRING_TEMP(state, options, name, name_literal, fail_func, temp_name)     \\\n\tint result_##temp_name = 0;                                                                \\\n\tchar * temps_##temp_name = get_string_options(options, name_literal, &result_##temp_name); \\\n\tif (result_##temp_name < 0)                                                                \\\n\t{                                                                                          \\\n\t\tfail_func(state);                                                                      \\\n\t\treturn NULL;                                                                           \\\n\t}                                                                                          \\\n\telse if (result_##temp_name > 0)                                                           \\\n\t{                                                                                          \\\n\t\tif(state->name)                                                                        \\\n\t\t\tfree(state->name);                                                                 \\\n\t\tstate->name = temps_##temp_name;                                                       \\\n\t}\n\n#define PARSE_OPTION_STRING(state, options, name, name_literal, fail_func)                     \\\n\tPARSE_OPTION_STRING_TEMP(state, options, name, name_literal, fail_func, name)\n\n#define PARSE_OPTION_ARRAY_TEMP(state, options, name, count, name_literal, fail_func, temp_name)                   \\\n\tint result_##temp_name = 0;                                                                                    \\\n\tsize_t count_##temp_name = 0;                                                                                  \\\n\tchar ** temps_##temp_name = get_array_options(options, name_literal, &count_##temp_name, &result_##temp_name); \\\n\tif (result_##temp_name < 0)                                                                                    \\\n\t{                                                                                                              \\\n\t\tfail_func(state);                                                                                          \\\n\t\treturn NULL;                                                                                               \\\n\t}                                                                                                              \\\n\telse if (result_##temp_name > 0)                                                                               \\\n\t{                                                                                                              \\\n\t\tif(state->name)                                                                                            \\\n\t\t\tfree(state->name);                                                                                     \\\n\t\tstate->name = temps_##temp_name;                                                                           \\\n\t\tstate->count = count_##temp_name;                                                                          \\\n\t}                            \n\n#define PARSE_OPTION_ARRAY(state, options, name, count, name_literal, fail_func)                                   \\\n\tPARSE_OPTION_ARRAY_TEMP(state, options, name, count, name_literal, fail_func, name)\n\n#define PARSE_OPTION_INT_ARRAY_TEMP(state, options, name, count, name_literal, fail_func, temp_name)                 \\\n\tint result_##temp_name = 0;                                                                                      \\\n\tsize_t count_##temp_name = 0;                                                                                    \\\n\tint * temps_##temp_name = get_int_array_options(options, name_literal, &count_##temp_name, &result_##temp_name); \\\n\tif (result_##temp_name < 0)                                                                                      \\\n\t{                                                                                                                \\\n\t\tfail_func(state);                                                                                            \\\n\t\treturn NULL;                                                                                                 \\\n\t}                                                                                                                \\\n\telse if (result_##temp_name > 0)                                                                                 \\\n\t{                                                                                                                \\\n\t\tif(state->name)                                                                                              \\\n\t\t\tfree(state->name);                                                                                       \\\n\t\tstate->name = temps_##temp_name;                                                                             \\\n\t\tstate->count = count_##temp_name;                                                                            \\\n\t}\n\n#define PARSE_OPTION_INT_ARRAY(state, options, name, count, name_literal, fail_func)                                 \\\n\tPARSE_OPTION_INT_ARRAY_TEMP(state, options, name, count, name_literal, fail_func, name)\n\n\n// Some macros to make iterating json arrays easier\n\n#define FOREACH_OBJECT_JSON_ARRAY_ITEM_BEGIN(state, name, name_str, item, result)                    \\\n    do {                                                                                             \\\n\t\tjson_t * root##name, *option_array##name;                                                    \\\n\t\tsize_t i##name;                                                                              \\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \\\n\t\tresult = -1;                                                                                 \\\n\t\troot##name = get_root_option_json_object(state);                                             \\\n\t\tif (root##name)                                                                              \\\n\t\t{                                                                                            \\\n\t\t\toption_array##name = json_object_get(root##name, name_str);                              \\\n\t\t\tif (!option_array##name || !json_is_array(option_array##name))                           \\\n\t\t\t\tjson_decref(root##name);                                                             \\\n\t\t\telse                                                                                     \\\n\t\t\t{                                                                                        \\\n\t\t\t\tresult = 1;                                                                          \\\n\t\t\t\tfor (i##name = 0; i##name < json_array_size(option_array##name); i##name++)          \\\n\t\t\t\t{                                                                                    \\\n\t\t\t\t\titem = json_array_get(option_array##name, i##name);\n\n#define FOREACH_OBJECT_JSON_ARRAY_ITEM_END(name)                                                     \\\n\t\t\t\t}                                                                                    \\\n\t\t\t}                                                                                        \\\n\t\t\tjson_decref(root##name);                                                                 \\\n\t\t}                                                                                            \\\n\t} while (0);\n\n//If you want to end the macro early, such that the code won't hit the end of the loop, use this to\n//free the root object.\n#define FOREACH_OBJECT_JSON_ARRAY_ITEM_FREE(name)                                                    \\\n\tjson_decref(root##name);\n\n// Some macros to make generating objects easier\n\n#define ADD_ITEM1(temp, arg1, dest, func, name)       \\\n\ttemp = func(arg1);                                \\\n    if(!temp) return NULL;                            \\\n\tjson_object_set_new(dest, name, temp);\n\n#define ADD_ITEM2(temp, arg1, arg2, dest, func, name) \\\n\ttemp = func(arg1, arg2);                          \\\n    if(!temp) return NULL;                            \\\n\tjson_object_set_new(dest, name, temp);\n\n#define ADD_STRING(temp, arg1, dest, name)        ADD_ITEM1(temp, arg1, dest, json_string, name)\n#define ADD_INT(temp, arg1, dest, name)           ADD_ITEM1(temp, arg1, dest, json_integer, name)\n#define ADD_UINT64T                               ADD_INT //Internally they both use json_integer\n#define ADD_MEM(temp, arg1, arg2, dest, name)     ADD_ITEM2(temp, arg1, arg2, dest, json_mem, name)\n#define ADD_DOUBLE(temp, arg1, dest, name)        ADD_ITEM1(temp, arg1, dest, json_real, name)\n\n#define GET_ITEM(arg1, dest, temp, func, name, ret) \\\n    temp = func(arg1, name, &ret);                  \\\n    if (ret <= 0)                                   \\\n        return 1;                                   \\\n    dest = temp;\n\n#define GET_STRING(temp, arg1, dest, name, ret)   GET_ITEM(arg1, dest, temp, get_string_options, name, ret)\n#define GET_INT(temp, arg1, dest, name, ret)      GET_ITEM(arg1, dest, temp, get_int_options, name, ret)\n#define GET_UINT64T(temp, arg1, dest, name, ret)  GET_ITEM(arg1, dest, temp, get_uint64t_options, name, ret)\n#define GET_MEM(temp, arg1, dest, name, ret)      GET_ITEM(arg1, dest, temp, get_mem_options, name, ret)\n#define GET_DOUBLE(temp, arg1, dest, name, ret)   GET_ITEM(arg1, dest, temp, get_double_options, name, ret)\n\nJANSSON_API char * get_string_options(const char * options, const char * option_name, int * result);\nJANSSON_API char * get_string_options_from_json(json_t * root, const char * option_name, int * result);\n\nJANSSON_API char * get_mem_options(const char * options, const char * option_name, int * result);\nJANSSON_API char * get_mem_options_from_json(json_t * root, const char * option_name, int * result);\n\nJANSSON_API int get_int_options(const char * options, const char * option_name, int * result);\nJANSSON_API int get_int_options_from_json(json_t * root, const char * option_name, int * result);\n\nJANSSON_API uint64_t get_uint64t_options(const char * options, const char * option_name, int * result);\nJANSSON_API uint64_t get_uint64t_options_from_json(json_t * root, const char * option_name, int * result);\n\nJANSSON_API double get_double_options(const char * json_string, const char * option_name, int * result);\nJANSSON_API double get_double_options_from_json(json_t * root, const char * option_name, int * result);\n\nJANSSON_API char ** get_array_options(const char * options, const char * option_name, size_t * count, int * result);\nJANSSON_API int * get_int_array_options(const char * json_string, const char * option_name, size_t * count, int * result);\n\nJANSSON_API json_t * get_root_option_json_object(const char * options);\n\nJANSSON_API char * add_string_option_to_json(const char * root_options, const char * new_option_name, const char * new_value);\nJANSSON_API char * add_int_option_to_json(const char * root_options, const char * new_option_name, int new_value);\n\nJANSSON_API int decode_mem_array(const char *json_string, char *** items, size_t ** item_lengths, size_t * items_count);\nJANSSON_API char * encode_mem_array(char ** items, size_t * item_lengths, size_t items_count, int * output_length);\n\n#ifdef __cplusplus\n}\n#endif\n"
  },
  {
    "path": "jansson/jansson_private.h",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n *\n * Jansson is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n */\n\n#ifndef JANSSON_PRIVATE_H\n#define JANSSON_PRIVATE_H\n\n#include \"jansson_private_config.h\"\n#include <stddef.h>\n#include \"jansson.h\"\n#include \"hashtable.h\"\n#include \"strbuffer.h\"\n\n#define MEM_TOKEN \"::MEM::\"\n#define MEM_TOKEN_LEN strlen(\"::MEM::\")\n\n#define container_of(ptr_, type_, member_)  \\\n    ((type_ *)((char *)ptr_ - offsetof(type_, member_)))\n\n/* On some platforms, max() may already be defined */\n#ifndef max\n#define max(a, b)  ((a) > (b) ? (a) : (b))\n#endif\n\n/* va_copy is a C99 feature. In C89 implementations, it's sometimes\n   available as __va_copy. If not, memcpy() should do the trick. */\n#ifndef va_copy\n#ifdef __va_copy\n#define va_copy __va_copy\n#else\n#define va_copy(a, b)  memcpy(&(a), &(b), sizeof(va_list))\n#endif\n#endif\n\ntypedef struct {\n    json_t json;\n    hashtable_t hashtable;\n    int visited;\n} json_object_t;\n\ntypedef struct {\n    json_t json;\n    size_t size;\n    size_t entries;\n    json_t **table;\n    int visited;\n} json_array_t;\n\ntypedef struct {\n    json_t json;\n    char *value;\n    size_t length;\n} json_string_t;\n\ntypedef struct {\n\tjson_t json;\n\tchar *value;\n\tsize_t length;\n} json_mem_t;\n\ntypedef struct {\n    json_t json;\n    double value;\n} json_real_t;\n\ntypedef struct {\n    json_t json;\n    json_int_t value;\n} json_integer_t;\n\n#define json_to_object(json_)  container_of(json_, json_object_t, json)\n#define json_to_array(json_)   container_of(json_, json_array_t, json)\n#define json_to_string(json_)  container_of(json_, json_string_t, json)\n#define json_to_mem(json_)     container_of(json_, json_mem_t, json)\n#define json_to_real(json_)    container_of(json_, json_real_t, json)\n#define json_to_integer(json_) container_of(json_, json_integer_t, json)\n\n/* Create a string by taking ownership of an existing buffer */\njson_t *jsonp_stringn_nocheck_own(const char *value, size_t len);\n\n/* Create a mem object by taking ownership of an existing buffer */\njson_t *json_mem_own(const char *value, size_t len);\n\n/* Error message formatting */\nvoid jsonp_error_init(json_error_t *error, const char *source);\nvoid jsonp_error_set_source(json_error_t *error, const char *source);\nvoid jsonp_error_set(json_error_t *error, int line, int column,\n                     size_t position, const char *msg, ...);\nvoid jsonp_error_vset(json_error_t *error, int line, int column,\n                      size_t position, const char *msg, va_list ap);\n\n/* Locale independent string<->double conversions */\nint jsonp_strtod(strbuffer_t *strbuffer, double *out);\nint jsonp_dtostr(char *buffer, size_t size, double value, int prec);\n\n/* Wrappers for custom memory functions */\nvoid* jsonp_malloc(size_t size);\nvoid jsonp_free(void *ptr);\nchar *jsonp_strndup(const char *str, size_t length);\nchar *jsonp_strdup(const char *str);\nchar *jsonp_strndup(const char *str, size_t len);\n\n\n/* Windows compatibility */\n#if defined(_WIN32) || defined(WIN32)\n#  if defined(_MSC_VER)  /* MS compiller */\n#    if (_MSC_VER < 1900) && !defined(snprintf)  /* snprintf not defined yet & not introduced */\n#      define snprintf _snprintf\n#    endif\n#    if (_MSC_VER < 1500) && !defined(vsnprintf)  /* vsnprintf not defined yet & not introduced */\n#      define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a)\n#    endif\n#  else  /* Other Windows compiller, old definition */\n#    define snprintf _snprintf\n#    define vsnprintf _vsnprintf\n#  endif\n#endif\n\n#endif\n"
  },
  {
    "path": "jansson/jansson_private_config.h",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n *\n * Jansson is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n */\n\n/* #undef HAVE_ENDIAN_H */\n#define HAVE_FCNTL_H 1\n/* #undef HAVE_SCHED_H */\n/* #undef HAVE_UNISTD_H */\n/* #undef HAVE_SYS_PARAM_H */\n#define HAVE_SYS_STAT_H 1\n/* #undef HAVE_SYS_TIME_H */\n/* #undef HAVE_SYS_TYPES_H */\n#define HAVE_STDINT_H 1\n\n#define HAVE_CLOSE 1\n#define HAVE_GETPID 1\n/* #undef HAVE_GETTIMEOFDAY */\n#define HAVE_OPEN 1\n#define HAVE_READ 1\n/* #undef HAVE_SCHED_YIELD */\n\n/* #undef HAVE_SYNC_BUILTINS */\n/* #undef HAVE_ATOMIC_BUILTINS */\n\n#define HAVE_LOCALE_H 1\n#define HAVE_SETLOCALE 1\n\n#define HAVE_INT32_T 1\n#ifndef HAVE_INT32_T\n#  define int32_t int32_t\n#endif\n\n#define HAVE_UINT32_T 1\n#ifndef HAVE_UINT32_T\n#  define uint32_t uint32_t\n#endif\n\n#define HAVE_UINT16_T 1\n#ifndef HAVE_UINT16_T\n#  define uint16_t uint16_t\n#endif\n\n#define HAVE_UINT8_T 1\n#ifndef HAVE_UINT8_T\n#  define uint8_t uint8_t\n#endif\n\n#define USE_URANDOM 1\n#define USE_WINDOWS_CRYPTOAPI 1\n\n#define INITIAL_HASHTABLE_ORDER 3\n"
  },
  {
    "path": "jansson/load.c",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n *\n * Jansson is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n */\n\n#ifndef _GNU_SOURCE\n#define _GNU_SOURCE\n#endif\n\n#include \"jansson_private.h\"\n\n#include <errno.h>\n#include <limits.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n\n#include \"jansson.h\"\n#include \"strbuffer.h\"\n#include \"utf.h\"\n\n#define STREAM_STATE_OK        0\n#define STREAM_STATE_EOF      -1\n#define STREAM_STATE_ERROR    -2\n\n#define TOKEN_INVALID         -1\n#define TOKEN_EOF              0\n#define TOKEN_STRING         256\n#define TOKEN_INTEGER        257\n#define TOKEN_REAL           258\n#define TOKEN_TRUE           259\n#define TOKEN_FALSE          260\n#define TOKEN_NULL           261\n\n /* Locale independent versions of isxxx() functions */\n#define l_isupper(c)  ('A' <= (c) && (c) <= 'Z')\n#define l_islower(c)  ('a' <= (c) && (c) <= 'z')\n#define l_isalpha(c)  (l_isupper(c) || l_islower(c))\n#define l_isdigit(c)  ('0' <= (c) && (c) <= '9')\n#define l_isxdigit(c) \\\n    (l_isdigit(c) || ('A' <= (c) && (c) <= 'F') || ('a' <= (c) && (c) <= 'f'))\n\n/* Read one byte from stream, convert to unsigned char, then int, and\n   return. return EOF on end of file. This corresponds to the\n   behaviour of fgetc(). */\ntypedef int(*get_func)(void *data);\n\ntypedef struct {\n\tget_func get;\n\tvoid *data;\n\tchar buffer[5];\n\tsize_t buffer_pos;\n\tint state;\n\tint line;\n\tint column, last_column;\n\tsize_t position;\n} stream_t;\n\ntypedef struct {\n\tstream_t stream;\n\tstrbuffer_t saved_text;\n\tsize_t flags;\n\tsize_t depth;\n\tint token;\n\tunion {\n\t\tstruct {\n\t\t\tchar *val;\n\t\t\tsize_t len;\n\t\t} string;\n\t\tjson_int_t integer;\n\t\tdouble real;\n\t} value;\n} lex_t;\n\n#define stream_to_lex(stream) container_of(stream, lex_t, stream)\n\n\n/*** error reporting ***/\n\nstatic void error_set(json_error_t *error, const lex_t *lex,\n\tconst char *msg, ...)\n{\n\tva_list ap;\n\tchar msg_text[JSON_ERROR_TEXT_LENGTH];\n\tchar msg_with_context[JSON_ERROR_TEXT_LENGTH];\n\n\tint line = -1, col = -1;\n\tsize_t pos = 0;\n\tconst char *result = msg_text;\n\n\tif (!error)\n\t\treturn;\n\n\tva_start(ap, msg);\n\tvsnprintf(msg_text, JSON_ERROR_TEXT_LENGTH, msg, ap);\n\tmsg_text[JSON_ERROR_TEXT_LENGTH - 1] = '\\0';\n\tva_end(ap);\n\n\tif (lex)\n\t{\n\t\tconst char *saved_text = strbuffer_value(&lex->saved_text);\n\n\t\tline = lex->stream.line;\n\t\tcol = lex->stream.column;\n\t\tpos = lex->stream.position;\n\n\t\tif (saved_text && saved_text[0])\n\t\t{\n\t\t\tif (lex->saved_text.length <= 20) {\n\t\t\t\tsnprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH,\n\t\t\t\t\t\"%s near '%s'\", msg_text, saved_text);\n\t\t\t\tmsg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\\0';\n\t\t\t\tresult = msg_with_context;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (lex->stream.state == STREAM_STATE_ERROR) {\n\t\t\t\t/* No context for UTF-8 decoding errors */\n\t\t\t\tresult = msg_text;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tsnprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH,\n\t\t\t\t\t\"%s near end of file\", msg_text);\n\t\t\t\tmsg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\\0';\n\t\t\t\tresult = msg_with_context;\n\t\t\t}\n\t\t}\n\t}\n\n\tjsonp_error_set(error, line, col, pos, \"%s\", result);\n}\n\n\n/*** lexical analyzer ***/\n\nstatic void\nstream_init(stream_t *stream, get_func get, void *data)\n{\n\tstream->get = get;\n\tstream->data = data;\n\tstream->buffer[0] = '\\0';\n\tstream->buffer_pos = 0;\n\n\tstream->state = STREAM_STATE_OK;\n\tstream->line = 1;\n\tstream->column = 0;\n\tstream->position = 0;\n}\n\nstatic int stream_get(stream_t *stream, json_error_t *error)\n{\n\tint c;\n\n\tif (stream->state != STREAM_STATE_OK)\n\t\treturn stream->state;\n\n\tif (!stream->buffer[stream->buffer_pos])\n\t{\n\t\tc = stream->get(stream->data);\n\t\tif (c == EOF) {\n\t\t\tstream->state = STREAM_STATE_EOF;\n\t\t\treturn STREAM_STATE_EOF;\n\t\t}\n\n\t\tstream->buffer[0] = c;\n\t\tstream->buffer_pos = 0;\n\n\t\tif (0x80 <= c && c <= 0xFF)\n\t\t{\n\t\t\t/* multi-byte UTF-8 sequence */\n\t\t\tsize_t i, count;\n\n\t\t\tcount = utf8_check_first(c);\n\t\t\tif (!count)\n\t\t\t\tgoto out;\n\n\t\t\tassert(count >= 2);\n\n\t\t\tfor (i = 1; i < count; i++)\n\t\t\t\tstream->buffer[i] = stream->get(stream->data);\n\n\t\t\tif (!utf8_check_full(stream->buffer, count, NULL))\n\t\t\t\tgoto out;\n\n\t\t\tstream->buffer[count] = '\\0';\n\t\t}\n\t\telse\n\t\t\tstream->buffer[1] = '\\0';\n\t}\n\n\tc = stream->buffer[stream->buffer_pos++];\n\n\tstream->position++;\n\tif (c == '\\n') {\n\t\tstream->line++;\n\t\tstream->last_column = stream->column;\n\t\tstream->column = 0;\n\t}\n\telse if (utf8_check_first(c)) {\n\t\t/* track the Unicode character column, so increment only if\n\t\t   this is the first character of a UTF-8 sequence */\n\t\tstream->column++;\n\t}\n\n\treturn c;\n\nout:\n\tstream->state = STREAM_STATE_ERROR;\n\terror_set(error, stream_to_lex(stream), \"unable to decode byte 0x%x\", c);\n\treturn STREAM_STATE_ERROR;\n}\n\nstatic void stream_unget(stream_t *stream, int c)\n{\n\tif (c == STREAM_STATE_EOF || c == STREAM_STATE_ERROR)\n\t\treturn;\n\n\tstream->position--;\n\tif (c == '\\n') {\n\t\tstream->line--;\n\t\tstream->column = stream->last_column;\n\t}\n\telse if (utf8_check_first(c))\n\t\tstream->column--;\n\n\tassert(stream->buffer_pos > 0);\n\tstream->buffer_pos--;\n\tassert(stream->buffer[stream->buffer_pos] == c);\n}\n\n\nstatic int lex_get(lex_t *lex, json_error_t *error)\n{\n\treturn stream_get(&lex->stream, error);\n}\n\nstatic void lex_save(lex_t *lex, int c)\n{\n\tstrbuffer_append_byte(&lex->saved_text, c);\n}\n\nstatic int lex_get_save(lex_t *lex, json_error_t *error)\n{\n\tint c = stream_get(&lex->stream, error);\n\tif (c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR)\n\t\tlex_save(lex, c);\n\treturn c;\n}\n\nstatic void lex_unget(lex_t *lex, int c)\n{\n\tstream_unget(&lex->stream, c);\n}\n\nstatic void lex_unget_unsave(lex_t *lex, int c)\n{\n\tif (c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) {\n\t\t/* Since we treat warnings as errors, when assertions are turned\n\t\t * off the \"d\" variable would be set but never used. Which is\n\t\t * treated as an error by GCC.\n\t\t */\n#ifndef NDEBUG\n\t\tchar d;\n#endif\n\t\tstream_unget(&lex->stream, c);\n#ifndef NDEBUG\n\t\td =\n#endif\n\t\t\tstrbuffer_pop(&lex->saved_text);\n\t\tassert(c == d);\n\t}\n}\n\nstatic void lex_save_cached(lex_t *lex)\n{\n\twhile (lex->stream.buffer[lex->stream.buffer_pos] != '\\0')\n\t{\n\t\tlex_save(lex, lex->stream.buffer[lex->stream.buffer_pos]);\n\t\tlex->stream.buffer_pos++;\n\t\tlex->stream.position++;\n\t}\n}\n\nstatic void lex_free_string(lex_t *lex)\n{\n\tjsonp_free(lex->value.string.val);\n\tlex->value.string.val = NULL;\n\tlex->value.string.len = 0;\n}\n\n/* assumes that str points to 'u' plus at least 4 valid hex digits */\nstatic int32_t decode_unicode_escape(const char *str)\n{\n\tint i;\n\tint32_t value = 0;\n\n\tassert(str[0] == 'u');\n\n\tfor (i = 1; i <= 4; i++) {\n\t\tchar c = str[i];\n\t\tvalue <<= 4;\n\t\tif (l_isdigit(c))\n\t\t\tvalue += c - '0';\n\t\telse if (l_islower(c))\n\t\t\tvalue += c - 'a' + 10;\n\t\telse if (l_isupper(c))\n\t\t\tvalue += c - 'A' + 10;\n\t\telse\n\t\t\treturn -1;\n\t}\n\n\treturn value;\n}\n\nstatic void lex_scan_string(lex_t *lex, json_error_t *error)\n{\n\tint c;\n\tconst char *p;\n\tchar *t;\n\tint i;\n\n\tlex->value.string.val = NULL;\n\tlex->token = TOKEN_INVALID;\n\n\tc = lex_get_save(lex, error);\n\n\twhile (c != '\"') {\n\t\tif (c == STREAM_STATE_ERROR)\n\t\t\tgoto out;\n\n\t\telse if (c == STREAM_STATE_EOF) {\n\t\t\terror_set(error, lex, \"premature end of input\");\n\t\t\tgoto out;\n\t\t}\n\n\t\telse if (0 <= c && c <= 0x1F) {\n\t\t\t/* control character */\n\t\t\tlex_unget_unsave(lex, c);\n\t\t\tif (c == '\\n')\n\t\t\t\terror_set(error, lex, \"unexpected newline\");\n\t\t\telse\n\t\t\t\terror_set(error, lex, \"control character 0x%x\", c);\n\t\t\tgoto out;\n\t\t}\n\n\t\telse if (c == '\\\\') {\n\t\t\tc = lex_get_save(lex, error);\n\t\t\tif (c == 'u') {\n\t\t\t\tc = lex_get_save(lex, error);\n\t\t\t\tfor (i = 0; i < 4; i++) {\n\t\t\t\t\tif (!l_isxdigit(c)) {\n\t\t\t\t\t\terror_set(error, lex, \"invalid escape\");\n\t\t\t\t\t\tgoto out;\n\t\t\t\t\t}\n\t\t\t\t\tc = lex_get_save(lex, error);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (c == '\"' || c == '\\\\' || c == '/' || c == 'b' ||\n\t\t\t\tc == 'f' || c == 'n' || c == 'r' || c == 't')\n\t\t\t\tc = lex_get_save(lex, error);\n\t\t\telse {\n\t\t\t\terror_set(error, lex, \"invalid escape\");\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tc = lex_get_save(lex, error);\n\t}\n\n\t/* the actual value is at most of the same length as the source\n\t   string, because:\n\t\t - shortcut escapes (e.g. \"\\t\") (length 2) are converted to 1 byte\n\t\t - a single \\uXXXX escape (length 6) is converted to at most 3 bytes\n\t\t - two \\uXXXX escapes (length 12) forming an UTF-16 surrogate pair\n\t\t   are converted to 4 bytes\n\t*/\n\tt = jsonp_malloc(lex->saved_text.length + 1);\n\tif (!t) {\n\t\t/* this is not very nice, since TOKEN_INVALID is returned */\n\t\tgoto out;\n\t}\n\tlex->value.string.val = t;\n\n\t/* + 1 to skip the \" */\n\tp = strbuffer_value(&lex->saved_text) + 1;\n\n\twhile (*p != '\"') {\n\t\tif (*p == '\\\\') {\n\t\t\tp++;\n\t\t\tif (*p == 'u') {\n\t\t\t\tsize_t length;\n\t\t\t\tint32_t value;\n\n\t\t\t\tvalue = decode_unicode_escape(p);\n\t\t\t\tif (value < 0) {\n\t\t\t\t\terror_set(error, lex, \"invalid Unicode escape '%.6s'\", p - 1);\n\t\t\t\t\tgoto out;\n\t\t\t\t}\n\t\t\t\tp += 5;\n\n\t\t\t\tif (0xD800 <= value && value <= 0xDBFF) {\n\t\t\t\t\t/* surrogate pair */\n\t\t\t\t\tif (*p == '\\\\' && *(p + 1) == 'u') {\n\t\t\t\t\t\tint32_t value2 = decode_unicode_escape(++p);\n\t\t\t\t\t\tif (value2 < 0) {\n\t\t\t\t\t\t\terror_set(error, lex, \"invalid Unicode escape '%.6s'\", p - 1);\n\t\t\t\t\t\t\tgoto out;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp += 5;\n\n\t\t\t\t\t\tif (0xDC00 <= value2 && value2 <= 0xDFFF) {\n\t\t\t\t\t\t\t/* valid second surrogate */\n\t\t\t\t\t\t\tvalue =\n\t\t\t\t\t\t\t\t((value - 0xD800) << 10) +\n\t\t\t\t\t\t\t\t(value2 - 0xDC00) +\n\t\t\t\t\t\t\t\t0x10000;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t/* invalid second surrogate */\n\t\t\t\t\t\t\terror_set(error, lex,\n\t\t\t\t\t\t\t\t\"invalid Unicode '\\\\u%04X\\\\u%04X'\",\n\t\t\t\t\t\t\t\tvalue, value2);\n\t\t\t\t\t\t\tgoto out;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\t/* no second surrogate */\n\t\t\t\t\t\terror_set(error, lex, \"invalid Unicode '\\\\u%04X'\",\n\t\t\t\t\t\t\tvalue);\n\t\t\t\t\t\tgoto out;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (0xDC00 <= value && value <= 0xDFFF) {\n\t\t\t\t\terror_set(error, lex, \"invalid Unicode '\\\\u%04X'\", value);\n\t\t\t\t\tgoto out;\n\t\t\t\t}\n\n\t\t\t\tif (utf8_encode(value, t, &length))\n\t\t\t\t\tassert(0);\n\t\t\t\tt += length;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tswitch (*p) {\n\t\t\t\tcase '\"': case '\\\\': case '/':\n\t\t\t\t\t*t = *p; break;\n\t\t\t\tcase 'b': *t = '\\b'; break;\n\t\t\t\tcase 'f': *t = '\\f'; break;\n\t\t\t\tcase 'n': *t = '\\n'; break;\n\t\t\t\tcase 'r': *t = '\\r'; break;\n\t\t\t\tcase 't': *t = '\\t'; break;\n\t\t\t\tdefault: assert(0);\n\t\t\t\t}\n\t\t\t\tt++;\n\t\t\t\tp++;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\t*(t++) = *(p++);\n\t}\n\t*t = '\\0';\n\tlex->value.string.len = t - lex->value.string.val;\n\tlex->token = TOKEN_STRING;\n\treturn;\n\nout:\n\tlex_free_string(lex);\n}\n\n#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */\n#if JSON_INTEGER_IS_LONG_LONG\n#ifdef _MSC_VER  /* Microsoft Visual Studio */\n#define json_strtoint     _strtoi64\n#else\n#define json_strtoint     strtoll\n#endif\n#else\n#define json_strtoint     strtol\n#endif\n#endif\n\nstatic int lex_scan_number(lex_t *lex, int c, json_error_t *error)\n{\n\tconst char *saved_text;\n\tchar *end;\n\tdouble doubleval;\n\n\tlex->token = TOKEN_INVALID;\n\n\tif (c == '-')\n\t\tc = lex_get_save(lex, error);\n\n\tif (c == '0') {\n\t\tc = lex_get_save(lex, error);\n\t\tif (l_isdigit(c)) {\n\t\t\tlex_unget_unsave(lex, c);\n\t\t\tgoto out;\n\t\t}\n\t}\n\telse if (l_isdigit(c)) {\n\t\tdo\n\t\t\tc = lex_get_save(lex, error);\n\t\twhile (l_isdigit(c));\n\t}\n\telse {\n\t\tlex_unget_unsave(lex, c);\n\t\tgoto out;\n\t}\n\n\tif (!(lex->flags & JSON_DECODE_INT_AS_REAL) &&\n\t\tc != '.' && c != 'E' && c != 'e')\n\t{\n\t\tjson_int_t intval;\n\n\t\tlex_unget_unsave(lex, c);\n\n\t\tsaved_text = strbuffer_value(&lex->saved_text);\n\n\t\terrno = 0;\n\t\tintval = json_strtoint(saved_text, &end, 10);\n\t\tif (errno == ERANGE) {\n\t\t\tif (intval < 0)\n\t\t\t\terror_set(error, lex, \"too big negative integer\");\n\t\t\telse\n\t\t\t\terror_set(error, lex, \"too big integer\");\n\t\t\tgoto out;\n\t\t}\n\n\t\tassert(end == saved_text + lex->saved_text.length);\n\n\t\tlex->token = TOKEN_INTEGER;\n\t\tlex->value.integer = intval;\n\t\treturn 0;\n\t}\n\n\tif (c == '.') {\n\t\tc = lex_get(lex, error);\n\t\tif (!l_isdigit(c)) {\n\t\t\tlex_unget(lex, c);\n\t\t\tgoto out;\n\t\t}\n\t\tlex_save(lex, c);\n\n\t\tdo\n\t\t\tc = lex_get_save(lex, error);\n\t\twhile (l_isdigit(c));\n\t}\n\n\tif (c == 'E' || c == 'e') {\n\t\tc = lex_get_save(lex, error);\n\t\tif (c == '+' || c == '-')\n\t\t\tc = lex_get_save(lex, error);\n\n\t\tif (!l_isdigit(c)) {\n\t\t\tlex_unget_unsave(lex, c);\n\t\t\tgoto out;\n\t\t}\n\n\t\tdo\n\t\t\tc = lex_get_save(lex, error);\n\t\twhile (l_isdigit(c));\n\t}\n\n\tlex_unget_unsave(lex, c);\n\n\tif (jsonp_strtod(&lex->saved_text, &doubleval)) {\n\t\terror_set(error, lex, \"real number overflow\");\n\t\tgoto out;\n\t}\n\n\tlex->token = TOKEN_REAL;\n\tlex->value.real = doubleval;\n\treturn 0;\n\nout:\n\treturn -1;\n}\n\nstatic int lex_scan(lex_t *lex, json_error_t *error)\n{\n\tint c;\n\n\tstrbuffer_clear(&lex->saved_text);\n\n\tif (lex->token == TOKEN_STRING)\n\t\tlex_free_string(lex);\n\n\tdo\n\t\tc = lex_get(lex, error);\n\twhile (c == ' ' || c == '\\t' || c == '\\n' || c == '\\r');\n\n\tif (c == STREAM_STATE_EOF) {\n\t\tlex->token = TOKEN_EOF;\n\t\tgoto out;\n\t}\n\n\tif (c == STREAM_STATE_ERROR) {\n\t\tlex->token = TOKEN_INVALID;\n\t\tgoto out;\n\t}\n\n\tlex_save(lex, c);\n\n\tif (c == '{' || c == '}' || c == '[' || c == ']' || c == ':' || c == ',')\n\t\tlex->token = c;\n\n\telse if (c == '\"')\n\t\tlex_scan_string(lex, error);\n\n\telse if (l_isdigit(c) || c == '-') {\n\t\tif (lex_scan_number(lex, c, error))\n\t\t\tgoto out;\n\t}\n\n\telse if (l_isalpha(c)) {\n\t\t/* eat up the whole identifier for clearer error messages */\n\t\tconst char *saved_text;\n\n\t\tdo\n\t\t\tc = lex_get_save(lex, error);\n\t\twhile (l_isalpha(c));\n\t\tlex_unget_unsave(lex, c);\n\n\t\tsaved_text = strbuffer_value(&lex->saved_text);\n\n\t\tif (strcmp(saved_text, \"true\") == 0)\n\t\t\tlex->token = TOKEN_TRUE;\n\t\telse if (strcmp(saved_text, \"false\") == 0)\n\t\t\tlex->token = TOKEN_FALSE;\n\t\telse if (strcmp(saved_text, \"null\") == 0)\n\t\t\tlex->token = TOKEN_NULL;\n\t\telse\n\t\t\tlex->token = TOKEN_INVALID;\n\t}\n\n\telse {\n\t\t/* save the rest of the input UTF-8 sequence to get an error\n\t\t   message of valid UTF-8 */\n\t\tlex_save_cached(lex);\n\t\tlex->token = TOKEN_INVALID;\n\t}\n\nout:\n\treturn lex->token;\n}\n\nstatic char *lex_steal_string(lex_t *lex, size_t *out_len)\n{\n\tchar *result = NULL;\n\tif (lex->token == TOKEN_STRING) {\n\t\tresult = lex->value.string.val;\n\t\t*out_len = lex->value.string.len;\n\t\tlex->value.string.val = NULL;\n\t\tlex->value.string.len = 0;\n\t}\n\treturn result;\n}\n\nstatic int lex_init(lex_t *lex, get_func get, size_t flags, void *data)\n{\n\tstream_init(&lex->stream, get, data);\n\tif (strbuffer_init(&lex->saved_text))\n\t\treturn -1;\n\n\tlex->flags = flags;\n\tlex->token = TOKEN_INVALID;\n\treturn 0;\n}\n\nstatic void lex_close(lex_t *lex)\n{\n\tif (lex->token == TOKEN_STRING)\n\t\tlex_free_string(lex);\n\tstrbuffer_close(&lex->saved_text);\n}\n\n\n/*** parser ***/\n\nstatic json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error);\n\nstatic json_t *parse_object(lex_t *lex, size_t flags, json_error_t *error)\n{\n\tjson_t *object = json_object();\n\tif (!object)\n\t\treturn NULL;\n\n\tlex_scan(lex, error);\n\tif (lex->token == '}')\n\t\treturn object;\n\n\twhile (1) {\n\t\tchar *key;\n\t\tsize_t len;\n\t\tjson_t *value;\n\n\t\tif (lex->token != TOKEN_STRING) {\n\t\t\terror_set(error, lex, \"string or '}' expected\");\n\t\t\tgoto error;\n\t\t}\n\n\t\tkey = lex_steal_string(lex, &len);\n\t\tif (!key)\n\t\t\treturn NULL;\n\t\tif (memchr(key, '\\0', len)) {\n\t\t\tjsonp_free(key);\n\t\t\terror_set(error, lex, \"NUL byte in object key not supported\");\n\t\t\tgoto error;\n\t\t}\n\n\t\tif (flags & JSON_REJECT_DUPLICATES) {\n\t\t\tif (json_object_get(object, key)) {\n\t\t\t\tjsonp_free(key);\n\t\t\t\terror_set(error, lex, \"duplicate object key\");\n\t\t\t\tgoto error;\n\t\t\t}\n\t\t}\n\n\t\tlex_scan(lex, error);\n\t\tif (lex->token != ':') {\n\t\t\tjsonp_free(key);\n\t\t\terror_set(error, lex, \"':' expected\");\n\t\t\tgoto error;\n\t\t}\n\n\t\tlex_scan(lex, error);\n\t\tvalue = parse_value(lex, flags, error);\n\t\tif (!value) {\n\t\t\tjsonp_free(key);\n\t\t\tgoto error;\n\t\t}\n\n\t\tif (json_object_set_nocheck(object, key, value)) {\n\t\t\tjsonp_free(key);\n\t\t\tjson_decref(value);\n\t\t\tgoto error;\n\t\t}\n\n\t\tjson_decref(value);\n\t\tjsonp_free(key);\n\n\t\tlex_scan(lex, error);\n\t\tif (lex->token != ',')\n\t\t\tbreak;\n\n\t\tlex_scan(lex, error);\n\t}\n\n\tif (lex->token != '}') {\n\t\terror_set(error, lex, \"'}' expected\");\n\t\tgoto error;\n\t}\n\n\treturn object;\n\nerror:\n\tjson_decref(object);\n\treturn NULL;\n}\n\nstatic json_t *parse_array(lex_t *lex, size_t flags, json_error_t *error)\n{\n\tjson_t *array = json_array();\n\tif (!array)\n\t\treturn NULL;\n\n\tlex_scan(lex, error);\n\tif (lex->token == ']')\n\t\treturn array;\n\n\twhile (lex->token) {\n\t\tjson_t *elem = parse_value(lex, flags, error);\n\t\tif (!elem)\n\t\t\tgoto error;\n\n\t\tif (json_array_append(array, elem)) {\n\t\t\tjson_decref(elem);\n\t\t\tgoto error;\n\t\t}\n\t\tjson_decref(elem);\n\n\t\tlex_scan(lex, error);\n\t\tif (lex->token != ',')\n\t\t\tbreak;\n\n\t\tlex_scan(lex, error);\n\t}\n\n\tif (lex->token != ']') {\n\t\terror_set(error, lex, \"']' expected\");\n\t\tgoto error;\n\t}\n\n\treturn array;\n\nerror:\n\tjson_decref(array);\n\treturn NULL;\n}\n\nstatic json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error)\n{\n\tjson_t *json;\n\n\tlex->depth++;\n\tif (lex->depth > JSON_PARSER_MAX_DEPTH) {\n\t\terror_set(error, lex, \"maximum parsing depth reached\");\n\t\treturn NULL;\n\t}\n\n\tswitch (lex->token) {\n\tcase TOKEN_STRING: {\n\t\tconst char *value = lex->value.string.val;\n\t\tsize_t len = lex->value.string.len;\n\t\tunsigned char * temp, *mem;\n\t\tconst char *pos;\n\n\t\tif (len >= MEM_TOKEN_LEN && !memcmp(value, MEM_TOKEN, MEM_TOKEN_LEN))\n\t\t{\n\t\t\tlen = len - MEM_TOKEN_LEN;\n\t\t\tvalue = value + MEM_TOKEN_LEN;\n\t\t\tmem = temp = malloc(len / 2);\n\t\t\tif (!temp)\n\t\t\t\treturn NULL;\n\n\t\t\tsize_t num_read;\n\t\t\tfor (pos = value; pos < value + len; pos += num_read, temp += num_read / 2)\n\t\t\t{\n\t\t\t\tif (pos + 0x20 < value + len)\n\t\t\t\t{\n\t\t\t\t\tsscanf(pos, \n\t\t\t\t\t\t\"%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx\"\n\t\t\t\t\t\t\"%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx\",\n\t\t\t\t\t\ttemp, temp + 1, temp + 2, temp + 3, temp + 4, temp + 5, temp + 6, temp + 7,\n\t\t\t\t\t\ttemp + 8, temp + 9, temp + 10, temp + 11, temp + 12, temp + 13, temp + 14, temp + 15,\n\t\t\t\t\t\ttemp + 16, temp + 17, temp + 18, temp + 19, temp + 20, temp + 21, temp + 22, temp + 23,\n\t\t\t\t\t\ttemp + 24, temp + 25, temp + 26, temp + 27, temp + 28, temp + 29, temp + 30, temp + 31);\n\t\t\t\t\tnum_read = 0x40;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsscanf(pos, \"%02hhx\", temp);\n\t\t\t\t\tnum_read = 2;\n\t\t\t\t}\n\t\t\t}\n\t\t\tjson = json_mem_own(mem, len / 2);\n\t\t}\n\t\telse\n\t\t{\n\n\t\t\tif (!(flags & JSON_ALLOW_NUL)) {\n\t\t\t\tif (memchr(value, '\\0', len)) {\n\t\t\t\t\terror_set(error, lex, \"\\\\u0000 is not allowed without JSON_ALLOW_NUL\");\n\t\t\t\t\treturn NULL;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tjson = jsonp_stringn_nocheck_own(value, len);\n\t\t\tif (json) {\n\t\t\t\tlex->value.string.val = NULL;\n\t\t\t\tlex->value.string.len = 0;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n\n\tcase TOKEN_INTEGER: {\n\t\tjson = json_integer(lex->value.integer);\n\t\tbreak;\n\t}\n\n\tcase TOKEN_REAL: {\n\t\tjson = json_real(lex->value.real);\n\t\tbreak;\n\t}\n\n\tcase TOKEN_TRUE:\n\t\tjson = json_true();\n\t\tbreak;\n\n\tcase TOKEN_FALSE:\n\t\tjson = json_false();\n\t\tbreak;\n\n\tcase TOKEN_NULL:\n\t\tjson = json_null();\n\t\tbreak;\n\n\tcase '{':\n\t\tjson = parse_object(lex, flags, error);\n\t\tbreak;\n\n\tcase '[':\n\t\tjson = parse_array(lex, flags, error);\n\t\tbreak;\n\n\tcase TOKEN_INVALID:\n\t\terror_set(error, lex, \"invalid token\");\n\t\treturn NULL;\n\n\tdefault:\n\t\terror_set(error, lex, \"unexpected token\");\n\t\treturn NULL;\n\t}\n\n\tif (!json)\n\t\treturn NULL;\n\n\tlex->depth--;\n\treturn json;\n}\n\nstatic json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error)\n{\n\tjson_t *result;\n\n\tlex->depth = 0;\n\n\tlex_scan(lex, error);\n\tif (!(flags & JSON_DECODE_ANY)) {\n\t\tif (lex->token != '[' && lex->token != '{') {\n\t\t\terror_set(error, lex, \"'[' or '{' expected\");\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\tresult = parse_value(lex, flags, error);\n\tif (!result)\n\t\treturn NULL;\n\n\tif (!(flags & JSON_DISABLE_EOF_CHECK)) {\n\t\tlex_scan(lex, error);\n\t\tif (lex->token != TOKEN_EOF) {\n\t\t\terror_set(error, lex, \"end of file expected\");\n\t\t\tjson_decref(result);\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\tif (error) {\n\t\t/* Save the position even though there was no error */\n\t\terror->position = (int)lex->stream.position;\n\t}\n\n\treturn result;\n}\n\ntypedef struct\n{\n\tconst char *data;\n\tsize_t pos;\n} string_data_t;\n\nstatic int string_get(void *data)\n{\n\tchar c;\n\tstring_data_t *stream = (string_data_t *)data;\n\tc = stream->data[stream->pos];\n\tif (c == '\\0')\n\t\treturn EOF;\n\telse\n\t{\n\t\tstream->pos++;\n\t\treturn (unsigned char)c;\n\t}\n}\n\njson_t *json_loads(const char *string, size_t flags, json_error_t *error)\n{\n\tlex_t lex;\n\tjson_t *result;\n\tstring_data_t stream_data;\n\n\tjsonp_error_init(error, \"<string>\");\n\n\tif (string == NULL) {\n\t\terror_set(error, NULL, \"wrong arguments\");\n\t\treturn NULL;\n\t}\n\n\tstream_data.data = string;\n\tstream_data.pos = 0;\n\n\tif (lex_init(&lex, string_get, flags, (void *)&stream_data))\n\t\treturn NULL;\n\n\tresult = parse_json(&lex, flags, error);\n\n\tlex_close(&lex);\n\treturn result;\n}\n\ntypedef struct\n{\n\tconst char *data;\n\tsize_t len;\n\tsize_t pos;\n} buffer_data_t;\n\nstatic int buffer_get(void *data)\n{\n\tchar c;\n\tbuffer_data_t *stream = data;\n\tif (stream->pos >= stream->len)\n\t\treturn EOF;\n\n\tc = stream->data[stream->pos];\n\tstream->pos++;\n\treturn (unsigned char)c;\n}\n\njson_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error)\n{\n\tlex_t lex;\n\tjson_t *result;\n\tbuffer_data_t stream_data;\n\n\tjsonp_error_init(error, \"<buffer>\");\n\n\tif (buffer == NULL) {\n\t\terror_set(error, NULL, \"wrong arguments\");\n\t\treturn NULL;\n\t}\n\n\tstream_data.data = buffer;\n\tstream_data.pos = 0;\n\tstream_data.len = buflen;\n\n\tif (lex_init(&lex, buffer_get, flags, (void *)&stream_data))\n\t\treturn NULL;\n\n\tresult = parse_json(&lex, flags, error);\n\n\tlex_close(&lex);\n\treturn result;\n}\n\njson_t *json_loadf(FILE *input, size_t flags, json_error_t *error)\n{\n\tlex_t lex;\n\tconst char *source;\n\tjson_t *result;\n\n\tif (input == stdin)\n\t\tsource = \"<stdin>\";\n\telse\n\t\tsource = \"<stream>\";\n\n\tjsonp_error_init(error, source);\n\n\tif (input == NULL) {\n\t\terror_set(error, NULL, \"wrong arguments\");\n\t\treturn NULL;\n\t}\n\n\tif (lex_init(&lex, (get_func)fgetc, flags, input))\n\t\treturn NULL;\n\n\tresult = parse_json(&lex, flags, error);\n\n\tlex_close(&lex);\n\treturn result;\n}\n\nstatic int fd_get_func(int *fd)\n{\n\tuint8_t c;\n#ifdef HAVE_UNISTD_H\n\tif (read(*fd, &c, 1) == 1)\n\t\treturn c;\n#endif\n\treturn EOF;\n}\n\njson_t *json_loadfd(int input, size_t flags, json_error_t *error)\n{\n\tlex_t lex;\n\tconst char *source;\n\tjson_t *result;\n\n#ifdef HAVE_UNISTD_H\n\tif (input == STDIN_FILENO)\n\t\tsource = \"<stdin>\";\n\telse\n#endif\n\t\tsource = \"<stream>\";\n\n\tjsonp_error_init(error, source);\n\n\tif (input < 0) {\n\t\terror_set(error, NULL, \"wrong arguments\");\n\t\treturn NULL;\n\t}\n\n\tif (lex_init(&lex, (get_func)fd_get_func, flags, &input))\n\t\treturn NULL;\n\n\tresult = parse_json(&lex, flags, error);\n\n\tlex_close(&lex);\n\treturn result;\n}\n\njson_t *json_load_file(const char *path, size_t flags, json_error_t *error)\n{\n\tjson_t *result;\n\tFILE *fp;\n\n\tjsonp_error_init(error, path);\n\n\tif (path == NULL) {\n\t\terror_set(error, NULL, \"wrong arguments\");\n\t\treturn NULL;\n\t}\n\n\tfp = fopen(path, \"rb\");\n\tif (!fp)\n\t{\n\t\terror_set(error, NULL, \"unable to open %s: %s\",\n\t\t\tpath, strerror(errno));\n\t\treturn NULL;\n\t}\n\n\tresult = json_loadf(fp, flags, error);\n\n\tfclose(fp);\n\treturn result;\n}\n\n#define MAX_BUF_LEN 1024\n\ntypedef struct\n{\n\tchar data[MAX_BUF_LEN];\n\tsize_t len;\n\tsize_t pos;\n\tjson_load_callback_t callback;\n\tvoid *arg;\n} callback_data_t;\n\nstatic int callback_get(void *data)\n{\n\tchar c;\n\tcallback_data_t *stream = data;\n\n\tif (stream->pos >= stream->len) {\n\t\tstream->pos = 0;\n\t\tstream->len = stream->callback(stream->data, MAX_BUF_LEN, stream->arg);\n\t\tif (stream->len == 0 || stream->len == (size_t)-1)\n\t\t\treturn EOF;\n\t}\n\n\tc = stream->data[stream->pos];\n\tstream->pos++;\n\treturn (unsigned char)c;\n}\n\njson_t *json_load_callback(json_load_callback_t callback, void *arg, size_t flags, json_error_t *error)\n{\n\tlex_t lex;\n\tjson_t *result;\n\n\tcallback_data_t stream_data;\n\n\tmemset(&stream_data, 0, sizeof(stream_data));\n\tstream_data.callback = callback;\n\tstream_data.arg = arg;\n\n\tjsonp_error_init(error, \"<callback>\");\n\n\tif (callback == NULL) {\n\t\terror_set(error, NULL, \"wrong arguments\");\n\t\treturn NULL;\n\t}\n\n\tif (lex_init(&lex, (get_func)callback_get, flags, &stream_data))\n\t\treturn NULL;\n\n\tresult = parse_json(&lex, flags, error);\n\n\tlex_close(&lex);\n\treturn result;\n}\n"
  },
  {
    "path": "jansson/lookup3.h",
    "content": "/*\n-------------------------------------------------------------------------------\nlookup3.c, by Bob Jenkins, May 2006, Public Domain.\n\nThese are functions for producing 32-bit hashes for hash table lookup.\nhashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() \nare externally useful functions.  Routines to test the hash are included \nif SELF_TEST is defined.  You can use this free for any purpose.  It's in\nthe public domain.  It has no warranty.\n\nYou probably want to use hashlittle().  hashlittle() and hashbig()\nhash byte arrays.  hashlittle() is is faster than hashbig() on\nlittle-endian machines.  Intel and AMD are little-endian machines.\nOn second thought, you probably want hashlittle2(), which is identical to\nhashlittle() except it returns two 32-bit hashes for the price of one.  \nYou could implement hashbig2() if you wanted but I haven't bothered here.\n\nIf you want to find a hash of, say, exactly 7 integers, do\n  a = i1;  b = i2;  c = i3;\n  mix(a,b,c);\n  a += i4; b += i5; c += i6;\n  mix(a,b,c);\n  a += i7;\n  final(a,b,c);\nthen use c as the hash value.  If you have a variable length array of\n4-byte integers to hash, use hashword().  If you have a byte array (like\na character string), use hashlittle().  If you have several byte arrays, or\na mix of things, see the comments above hashlittle().  \n\nWhy is this so big?  I read 12 bytes at a time into 3 4-byte integers, \nthen mix those integers.  This is fast (you can do a lot more thorough\nmixing with 12*3 instructions on 3 integers than you can with 3 instructions\non 1 byte), but shoehorning those bytes into integers efficiently is messy.\n-------------------------------------------------------------------------------\n*/\n\n#include <stdlib.h>\n\n#ifdef HAVE_CONFIG_H\n#include <jansson_private_config.h>\n#endif\n\n#ifdef HAVE_STDINT_H\n#include <stdint.h>     /* defines uint32_t etc */\n#endif\n\n#ifdef HAVE_SYS_PARAM_H\n#include <sys/param.h>  /* attempt to define endianness */\n#endif\n\n#ifdef HAVE_ENDIAN_H\n# include <endian.h>    /* attempt to define endianness */\n#endif\n\n/*\n * My best guess at if you are big-endian or little-endian.  This may\n * need adjustment.\n */\n#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \\\n     __BYTE_ORDER == __LITTLE_ENDIAN) || \\\n    (defined(i386) || defined(__i386__) || defined(__i486__) || \\\n     defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL))\n# define HASH_LITTLE_ENDIAN 1\n# define HASH_BIG_ENDIAN 0\n#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \\\n       __BYTE_ORDER == __BIG_ENDIAN) || \\\n      (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel))\n# define HASH_LITTLE_ENDIAN 0\n# define HASH_BIG_ENDIAN 1\n#else\n# define HASH_LITTLE_ENDIAN 0\n# define HASH_BIG_ENDIAN 0\n#endif\n\n#define hashsize(n) ((uint32_t)1<<(n))\n#define hashmask(n) (hashsize(n)-1)\n#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))\n\n/*\n-------------------------------------------------------------------------------\nmix -- mix 3 32-bit values reversibly.\n\nThis is reversible, so any information in (a,b,c) before mix() is\nstill in (a,b,c) after mix().\n\nIf four pairs of (a,b,c) inputs are run through mix(), or through\nmix() in reverse, there are at least 32 bits of the output that\nare sometimes the same for one pair and different for another pair.\nThis was tested for:\n* pairs that differed by one bit, by two bits, in any combination\n  of top bits of (a,b,c), or in any combination of bottom bits of\n  (a,b,c).\n* \"differ\" is defined as +, -, ^, or ~^.  For + and -, I transformed\n  the output delta to a Gray code (a^(a>>1)) so a string of 1's (as\n  is commonly produced by subtraction) look like a single 1-bit\n  difference.\n* the base values were pseudorandom, all zero but one bit set, or \n  all zero plus a counter that starts at zero.\n\nSome k values for my \"a-=c; a^=rot(c,k); c+=b;\" arrangement that\nsatisfy this are\n    4  6  8 16 19  4\n    9 15  3 18 27 15\n   14  9  3  7 17  3\nWell, \"9 15 3 18 27 15\" didn't quite get 32 bits diffing\nfor \"differ\" defined as + with a one-bit base and a two-bit delta.  I\nused http://burtleburtle.net/bob/hash/avalanche.html to choose \nthe operations, constants, and arrangements of the variables.\n\nThis does not achieve avalanche.  There are input bits of (a,b,c)\nthat fail to affect some output bits of (a,b,c), especially of a.  The\nmost thoroughly mixed value is c, but it doesn't really even achieve\navalanche in c.\n\nThis allows some parallelism.  Read-after-writes are good at doubling\nthe number of bits affected, so the goal of mixing pulls in the opposite\ndirection as the goal of parallelism.  I did what I could.  Rotates\nseem to cost as much as shifts on every machine I could lay my hands\non, and rotates are much kinder to the top and bottom bits, so I used\nrotates.\n-------------------------------------------------------------------------------\n*/\n#define mix(a,b,c) \\\n{ \\\n  a -= c;  a ^= rot(c, 4);  c += b; \\\n  b -= a;  b ^= rot(a, 6);  a += c; \\\n  c -= b;  c ^= rot(b, 8);  b += a; \\\n  a -= c;  a ^= rot(c,16);  c += b; \\\n  b -= a;  b ^= rot(a,19);  a += c; \\\n  c -= b;  c ^= rot(b, 4);  b += a; \\\n}\n\n/*\n-------------------------------------------------------------------------------\nfinal -- final mixing of 3 32-bit values (a,b,c) into c\n\nPairs of (a,b,c) values differing in only a few bits will usually\nproduce values of c that look totally different.  This was tested for\n* pairs that differed by one bit, by two bits, in any combination\n  of top bits of (a,b,c), or in any combination of bottom bits of\n  (a,b,c).\n* \"differ\" is defined as +, -, ^, or ~^.  For + and -, I transformed\n  the output delta to a Gray code (a^(a>>1)) so a string of 1's (as\n  is commonly produced by subtraction) look like a single 1-bit\n  difference.\n* the base values were pseudorandom, all zero but one bit set, or \n  all zero plus a counter that starts at zero.\n\nThese constants passed:\n 14 11 25 16 4 14 24\n 12 14 25 16 4 14 24\nand these came close:\n  4  8 15 26 3 22 24\n 10  8 15 26 3 22 24\n 11  8 15 26 3 22 24\n-------------------------------------------------------------------------------\n*/\n#define final(a,b,c) \\\n{ \\\n  c ^= b; c -= rot(b,14); \\\n  a ^= c; a -= rot(c,11); \\\n  b ^= a; b -= rot(a,25); \\\n  c ^= b; c -= rot(b,16); \\\n  a ^= c; a -= rot(c,4);  \\\n  b ^= a; b -= rot(a,14); \\\n  c ^= b; c -= rot(b,24); \\\n}\n\n/*\n-------------------------------------------------------------------------------\nhashlittle() -- hash a variable-length key into a 32-bit value\n  k       : the key (the unaligned variable-length array of bytes)\n  length  : the length of the key, counting by bytes\n  initval : can be any 4-byte value\nReturns a 32-bit value.  Every bit of the key affects every bit of\nthe return value.  Two keys differing by one or two bits will have\ntotally different hash values.\n\nThe best hash table sizes are powers of 2.  There is no need to do\nmod a prime (mod is sooo slow!).  If you need less than 32 bits,\nuse a bitmask.  For example, if you need only 10 bits, do\n  h = (h & hashmask(10));\nIn which case, the hash table should have hashsize(10) elements.\n\nIf you are hashing n strings (uint8_t **)k, do it like this:\n  for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);\n\nBy Bob Jenkins, 2006.  bob_jenkins@burtleburtle.net.  You may use this\ncode any way you wish, private, educational, or commercial.  It's free.\n\nUse for hash table lookup, or anything where one collision in 2^^32 is\nacceptable.  Do NOT use for cryptographic purposes.\n-------------------------------------------------------------------------------\n*/\n\nstatic uint32_t hashlittle(const void *key, size_t length, uint32_t initval)\n{\n  uint32_t a,b,c;                                          /* internal state */\n  union { const void *ptr; size_t i; } u;     /* needed for Mac Powerbook G4 */\n\n  /* Set up the internal state */\n  a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;\n\n  u.ptr = key;\n  if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {\n    const uint32_t *k = (const uint32_t *)key;         /* read 32-bit chunks */\n\n/* Detect Valgrind or AddressSanitizer */\n#ifdef VALGRIND\n# define NO_MASKING_TRICK 1\n#else\n# if defined(__has_feature)  /* Clang */\n#  if __has_feature(address_sanitizer)  /* is ASAN enabled? */\n#   define NO_MASKING_TRICK 1\n#  endif\n# else\n#  if defined(__SANITIZE_ADDRESS__)  /* GCC 4.8.x, is ASAN enabled? */\n#   define NO_MASKING_TRICK 1\n#  endif\n# endif\n#endif\n\n#ifdef NO_MASKING_TRICK\n    const uint8_t  *k8;\n#endif\n\n    /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */\n    while (length > 12)\n    {\n      a += k[0];\n      b += k[1];\n      c += k[2];\n      mix(a,b,c);\n      length -= 12;\n      k += 3;\n    }\n\n    /*----------------------------- handle the last (probably partial) block */\n    /* \n     * \"k[2]&0xffffff\" actually reads beyond the end of the string, but\n     * then masks off the part it's not allowed to read.  Because the\n     * string is aligned, the masked-off tail is in the same word as the\n     * rest of the string.  Every machine with memory protection I've seen\n     * does it on word boundaries, so is OK with this.  But VALGRIND will\n     * still catch it and complain.  The masking trick does make the hash\n     * noticably faster for short strings (like English words).\n     */\n#ifndef NO_MASKING_TRICK\n\n    switch(length)\n    {\n    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;\n    case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;\n    case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;\n    case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;\n    case 8 : b+=k[1]; a+=k[0]; break;\n    case 7 : b+=k[1]&0xffffff; a+=k[0]; break;\n    case 6 : b+=k[1]&0xffff; a+=k[0]; break;\n    case 5 : b+=k[1]&0xff; a+=k[0]; break;\n    case 4 : a+=k[0]; break;\n    case 3 : a+=k[0]&0xffffff; break;\n    case 2 : a+=k[0]&0xffff; break;\n    case 1 : a+=k[0]&0xff; break;\n    case 0 : return c;              /* zero length strings require no mixing */\n    }\n\n#else /* make valgrind happy */\n\n    k8 = (const uint8_t *)k;\n    switch(length)\n    {\n    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;\n    case 11: c+=((uint32_t)k8[10])<<16;  /* fall through */\n    case 10: c+=((uint32_t)k8[9])<<8;    /* fall through */\n    case 9 : c+=k8[8];                   /* fall through */\n    case 8 : b+=k[1]; a+=k[0]; break;\n    case 7 : b+=((uint32_t)k8[6])<<16;   /* fall through */\n    case 6 : b+=((uint32_t)k8[5])<<8;    /* fall through */\n    case 5 : b+=k8[4];                   /* fall through */\n    case 4 : a+=k[0]; break;\n    case 3 : a+=((uint32_t)k8[2])<<16;   /* fall through */\n    case 2 : a+=((uint32_t)k8[1])<<8;    /* fall through */\n    case 1 : a+=k8[0]; break;\n    case 0 : return c;\n    }\n\n#endif /* !valgrind */\n\n  } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {\n    const uint16_t *k = (const uint16_t *)key;         /* read 16-bit chunks */\n    const uint8_t  *k8;\n\n    /*--------------- all but last block: aligned reads and different mixing */\n    while (length > 12)\n    {\n      a += k[0] + (((uint32_t)k[1])<<16);\n      b += k[2] + (((uint32_t)k[3])<<16);\n      c += k[4] + (((uint32_t)k[5])<<16);\n      mix(a,b,c);\n      length -= 12;\n      k += 6;\n    }\n\n    /*----------------------------- handle the last (probably partial) block */\n    k8 = (const uint8_t *)k;\n    switch(length)\n    {\n    case 12: c+=k[4]+(((uint32_t)k[5])<<16);\n             b+=k[2]+(((uint32_t)k[3])<<16);\n             a+=k[0]+(((uint32_t)k[1])<<16);\n             break;\n    case 11: c+=((uint32_t)k8[10])<<16;     /* fall through */\n    case 10: c+=k[4];\n             b+=k[2]+(((uint32_t)k[3])<<16);\n             a+=k[0]+(((uint32_t)k[1])<<16);\n             break;\n    case 9 : c+=k8[8];                      /* fall through */\n    case 8 : b+=k[2]+(((uint32_t)k[3])<<16);\n             a+=k[0]+(((uint32_t)k[1])<<16);\n             break;\n    case 7 : b+=((uint32_t)k8[6])<<16;      /* fall through */\n    case 6 : b+=k[2];\n             a+=k[0]+(((uint32_t)k[1])<<16);\n             break;\n    case 5 : b+=k8[4];                      /* fall through */\n    case 4 : a+=k[0]+(((uint32_t)k[1])<<16);\n             break;\n    case 3 : a+=((uint32_t)k8[2])<<16;      /* fall through */\n    case 2 : a+=k[0];\n             break;\n    case 1 : a+=k8[0];\n             break;\n    case 0 : return c;                     /* zero length requires no mixing */\n    }\n\n  } else {                        /* need to read the key one byte at a time */\n    const uint8_t *k = (const uint8_t *)key;\n\n    /*--------------- all but the last block: affect some 32 bits of (a,b,c) */\n    while (length > 12)\n    {\n      a += k[0];\n      a += ((uint32_t)k[1])<<8;\n      a += ((uint32_t)k[2])<<16;\n      a += ((uint32_t)k[3])<<24;\n      b += k[4];\n      b += ((uint32_t)k[5])<<8;\n      b += ((uint32_t)k[6])<<16;\n      b += ((uint32_t)k[7])<<24;\n      c += k[8];\n      c += ((uint32_t)k[9])<<8;\n      c += ((uint32_t)k[10])<<16;\n      c += ((uint32_t)k[11])<<24;\n      mix(a,b,c);\n      length -= 12;\n      k += 12;\n    }\n\n    /*-------------------------------- last block: affect all 32 bits of (c) */\n    switch(length)                   /* all the case statements fall through */\n    {\n    case 12: c+=((uint32_t)k[11])<<24;\n    case 11: c+=((uint32_t)k[10])<<16;\n    case 10: c+=((uint32_t)k[9])<<8;\n    case 9 : c+=k[8];\n    case 8 : b+=((uint32_t)k[7])<<24;\n    case 7 : b+=((uint32_t)k[6])<<16;\n    case 6 : b+=((uint32_t)k[5])<<8;\n    case 5 : b+=k[4];\n    case 4 : a+=((uint32_t)k[3])<<24;\n    case 3 : a+=((uint32_t)k[2])<<16;\n    case 2 : a+=((uint32_t)k[1])<<8;\n    case 1 : a+=k[0];\n             break;\n    case 0 : return c;\n    }\n  }\n\n  final(a,b,c);\n  return c;\n}\n"
  },
  {
    "path": "jansson/memory.c",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n * Copyright (c) 2011-2012 Basile Starynkevitch <basile@starynkevitch.net>\n *\n * Jansson is free software; you can redistribute it and/or modify it\n * under the terms of the MIT license. See MIT for details.\n */\n\n#include <stdlib.h>\n#include <string.h>\n\n#include \"jansson.h\"\n#include \"jansson_private.h\"\n\n/* C89 allows these to be macros */\n#undef malloc\n#undef free\n\n/* memory function pointers */\nstatic json_malloc_t do_malloc = malloc;\nstatic json_free_t do_free = free;\n\nvoid *jsonp_malloc(size_t size)\n{\n    if(!size)\n        return NULL;\n\n    return (*do_malloc)(size);\n}\n\nvoid jsonp_free(void *ptr)\n{\n    if(!ptr)\n        return;\n\n    (*do_free)(ptr);\n}\n\nchar *jsonp_strdup(const char *str)\n{\n    return jsonp_strndup(str, strlen(str));\n}\n\nchar *jsonp_strndup(const char *str, size_t len)\n{\n    char *new_str;\n\n    new_str = jsonp_malloc(len + 1);\n    if(!new_str)\n        return NULL;\n\n    memcpy(new_str, str, len);\n    new_str[len] = '\\0';\n    return new_str;\n}\n\nvoid json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn)\n{\n    do_malloc = malloc_fn;\n    do_free = free_fn;\n}\n\nvoid json_get_alloc_funcs(json_malloc_t *malloc_fn, json_free_t *free_fn)\n{\n    if (malloc_fn)\n        *malloc_fn = do_malloc;\n    if (free_fn)\n        *free_fn = do_free;\n}\n"
  },
  {
    "path": "jansson/pack_unpack.c",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n * Copyright (c) 2011-2012 Graeme Smecher <graeme.smecher@mail.mcgill.ca>\n *\n * Jansson is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n */\n\n#include <string.h>\n#include \"jansson.h\"\n#include \"jansson_private.h\"\n#include \"utf.h\"\n\ntypedef struct {\n    int line;\n    int column;\n    size_t pos;\n    char token;\n} token_t;\n\ntypedef struct {\n    const char *start;\n    const char *fmt;\n    token_t prev_token;\n    token_t token;\n    token_t next_token;\n    json_error_t *error;\n    size_t flags;\n    int line;\n    int column;\n    size_t pos;\n} scanner_t;\n\n#define token(scanner) ((scanner)->token.token)\n\nstatic const char * const type_names[] = {\n    \"object\",\n    \"array\",\n    \"string\",\n    \"mem\",\n    \"integer\",\n    \"real\",\n    \"true\",\n    \"false\",\n    \"null\"\n};\n\n#define type_name(x) type_names[json_typeof(x)]\n\nstatic const char unpack_value_starters[] = \"{[siIbfFOon\";\n\nstatic void scanner_init(scanner_t *s, json_error_t *error,\n                         size_t flags, const char *fmt)\n{\n    s->error = error;\n    s->flags = flags;\n    s->fmt = s->start = fmt;\n    memset(&s->prev_token, 0, sizeof(token_t));\n    memset(&s->token, 0, sizeof(token_t));\n    memset(&s->next_token, 0, sizeof(token_t));\n    s->line = 1;\n    s->column = 0;\n    s->pos = 0;\n}\n\nstatic void next_token(scanner_t *s)\n{\n    const char *t;\n    s->prev_token = s->token;\n\n    if(s->next_token.line) {\n        s->token = s->next_token;\n        s->next_token.line = 0;\n        return;\n    }\n\n    t = s->fmt;\n    s->column++;\n    s->pos++;\n\n    /* skip space and ignored chars */\n    while(*t == ' ' || *t == '\\t' || *t == '\\n' || *t == ',' || *t == ':') {\n        if(*t == '\\n') {\n            s->line++;\n            s->column = 1;\n        }\n        else\n            s->column++;\n\n        s->pos++;\n        t++;\n    }\n\n    s->token.token = *t;\n    s->token.line = s->line;\n    s->token.column = s->column;\n    s->token.pos = s->pos;\n\n    t++;\n    s->fmt = t;\n}\n\nstatic void prev_token(scanner_t *s)\n{\n    s->next_token = s->token;\n    s->token = s->prev_token;\n}\n\nstatic void set_error(scanner_t *s, const char *source, const char *fmt, ...)\n{\n    va_list ap;\n    va_start(ap, fmt);\n\n    jsonp_error_vset(s->error, s->token.line, s->token.column, s->token.pos,\n                     fmt, ap);\n\n    jsonp_error_set_source(s->error, source);\n\n    va_end(ap);\n}\n\nstatic json_t *pack(scanner_t *s, va_list *ap);\n\n\n/* ours will be set to 1 if jsonp_free() must be called for the result\n   afterwards */\nstatic char *read_string(scanner_t *s, va_list *ap,\n                         const char *purpose, size_t *out_len, int *ours)\n{\n    char t;\n    strbuffer_t strbuff;\n    const char *str;\n    size_t length;\n\n    next_token(s);\n    t = token(s);\n    prev_token(s);\n\n    if(t != '#' && t != '%' && t != '+') {\n        /* Optimize the simple case */\n        str = va_arg(*ap, const char *);\n\n        if(!str) {\n            set_error(s, \"<args>\", \"NULL string argument\");\n            return NULL;\n        }\n\n        length = strlen(str);\n\n        if(!utf8_check_string(str, length)) {\n            set_error(s, \"<args>\", \"Invalid UTF-8 %s\", purpose);\n            return NULL;\n        }\n\n        *out_len = length;\n        *ours = 0;\n        return (char *)str;\n    }\n\n    strbuffer_init(&strbuff);\n\n    while(1) {\n        str = va_arg(*ap, const char *);\n        if(!str) {\n            set_error(s, \"<args>\", \"NULL string argument\");\n            strbuffer_close(&strbuff);\n            return NULL;\n        }\n\n        next_token(s);\n\n        if(token(s) == '#') {\n            length = va_arg(*ap, int);\n        }\n        else if(token(s) == '%') {\n            length = va_arg(*ap, size_t);\n        }\n        else {\n            prev_token(s);\n            length = strlen(str);\n        }\n\n        if(strbuffer_append_bytes(&strbuff, str, length) == -1) {\n            set_error(s, \"<internal>\", \"Out of memory\");\n            strbuffer_close(&strbuff);\n            return NULL;\n        }\n\n        next_token(s);\n        if(token(s) != '+') {\n            prev_token(s);\n            break;\n        }\n    }\n\n    if(!utf8_check_string(strbuff.value, strbuff.length)) {\n        set_error(s, \"<args>\", \"Invalid UTF-8 %s\", purpose);\n        strbuffer_close(&strbuff);\n        return NULL;\n    }\n\n    *out_len = strbuff.length;\n    *ours = 1;\n    return strbuffer_steal_value(&strbuff);\n}\n\nstatic json_t *pack_object(scanner_t *s, va_list *ap)\n{\n    json_t *object = json_object();\n    next_token(s);\n\n    while(token(s) != '}') {\n        char *key;\n        size_t len;\n        int ours;\n        json_t *value;\n\n        if(!token(s)) {\n            set_error(s, \"<format>\", \"Unexpected end of format string\");\n            goto error;\n        }\n\n        if(token(s) != 's') {\n            set_error(s, \"<format>\", \"Expected format 's', got '%c'\", token(s));\n            goto error;\n        }\n\n        key = read_string(s, ap, \"object key\", &len, &ours);\n        if(!key)\n            goto error;\n\n        next_token(s);\n\n        value = pack(s, ap);\n        if(!value) {\n            if(ours)\n                jsonp_free(key);\n\n            if(strchr(\"soO\", token(s)) && s->next_token.token == '*') {\n                next_token(s);\n                next_token(s);\n                continue;\n            }\n\n            goto error;\n        }\n\n        if(json_object_set_new_nocheck(object, key, value)) {\n            set_error(s, \"<internal>\", \"Unable to add key \\\"%s\\\"\", key);\n            if(ours)\n                jsonp_free(key);\n\n            goto error;\n        }\n\n        if(ours)\n            jsonp_free(key);\n\n        if(strchr(\"soO\", token(s)) && s->next_token.token == '*')\n            next_token(s);\n        next_token(s);\n    }\n\n    return object;\n\nerror:\n    json_decref(object);\n    return NULL;\n}\n\nstatic json_t *pack_array(scanner_t *s, va_list *ap)\n{\n    json_t *array = json_array();\n    next_token(s);\n\n    while(token(s) != ']') {\n        json_t *value;\n\n        if(!token(s)) {\n            set_error(s, \"<format>\", \"Unexpected end of format string\");\n            goto error;\n        }\n\n        value = pack(s, ap);\n        if(!value) {\n            if(strchr(\"soO\", token(s)) && s->next_token.token == '*') {\n                next_token(s);\n                next_token(s);\n                continue;\n            }\n\n            goto error;\n        }\n\n        if(json_array_append_new(array, value)) {\n            set_error(s, \"<internal>\", \"Unable to append to array\");\n            goto error;\n        }\n\n        if(strchr(\"soO\", token(s)) && s->next_token.token == '*')\n            next_token(s);\n        next_token(s);\n    }\n    return array;\n\nerror:\n    json_decref(array);\n    return NULL;\n}\n\nstatic json_t *pack_string(scanner_t *s, va_list *ap)\n{\n    char *str;\n    size_t len;\n    int ours;\n    int nullable;\n\n    next_token(s);\n    nullable = token(s) == '?';\n    if (!nullable)\n        prev_token(s);\n\n    str = read_string(s, ap, \"string\", &len, &ours);\n    if (!str) {\n        return nullable ? json_null() : NULL;\n    } else if (ours) {\n        return jsonp_stringn_nocheck_own(str, len);\n    } else {\n        return json_stringn_nocheck(str, len);\n    }\n}\n\nstatic json_t *pack(scanner_t *s, va_list *ap)\n{\n    switch(token(s)) {\n        case '{':\n            return pack_object(s, ap);\n\n        case '[':\n            return pack_array(s, ap);\n\n        case 's': /* string */\n            return pack_string(s, ap);\n\n        case 'n': /* null */\n            return json_null();\n\n        case 'b': /* boolean */\n            return va_arg(*ap, int) ? json_true() : json_false();\n\n        case 'i': /* integer from int */\n            return json_integer(va_arg(*ap, int));\n\n        case 'I': /* integer from json_int_t */\n            return json_integer(va_arg(*ap, json_int_t));\n\n        case 'f': /* real */\n            return json_real(va_arg(*ap, double));\n\n        case 'O': /* a json_t object; increments refcount */\n        {\n            int nullable;\n            json_t *json;\n\n            next_token(s);\n            nullable = token(s) == '?';\n            if (!nullable)\n                prev_token(s);\n\n            json = va_arg(*ap, json_t *);\n            if (!json && nullable) {\n                return json_null();\n            } else {\n                return json_incref(json);\n            }\n        }\n\n        case 'o': /* a json_t object; doesn't increment refcount */\n        {\n            int nullable;\n            json_t *json;\n\n            next_token(s);\n            nullable = token(s) == '?';\n            if (!nullable)\n                prev_token(s);\n\n            json = va_arg(*ap, json_t *);\n            if (!json && nullable) {\n                return json_null();\n            } else {\n                return json;\n            }\n        }\n\n        default:\n            set_error(s, \"<format>\", \"Unexpected format character '%c'\",\n                      token(s));\n            return NULL;\n    }\n}\n\nstatic int unpack(scanner_t *s, json_t *root, va_list *ap);\n\nstatic int unpack_object(scanner_t *s, json_t *root, va_list *ap)\n{\n    int ret = -1;\n    int strict = 0;\n    int gotopt = 0;\n\n    /* Use a set (emulated by a hashtable) to check that all object\n       keys are accessed. Checking that the correct number of keys\n       were accessed is not enough, as the same key can be unpacked\n       multiple times.\n    */\n    hashtable_t key_set;\n\n    if(hashtable_init(&key_set)) {\n        set_error(s, \"<internal>\", \"Out of memory\");\n        return -1;\n    }\n\n    if(root && !json_is_object(root)) {\n        set_error(s, \"<validation>\", \"Expected object, got %s\",\n                  type_name(root));\n        goto out;\n    }\n    next_token(s);\n\n    while(token(s) != '}') {\n        const char *key;\n        json_t *value;\n        int opt = 0;\n\n        if(strict != 0) {\n            set_error(s, \"<format>\", \"Expected '}' after '%c', got '%c'\",\n                      (strict == 1 ? '!' : '*'), token(s));\n            goto out;\n        }\n\n        if(!token(s)) {\n            set_error(s, \"<format>\", \"Unexpected end of format string\");\n            goto out;\n        }\n\n        if(token(s) == '!' || token(s) == '*') {\n            strict = (token(s) == '!' ? 1 : -1);\n            next_token(s);\n            continue;\n        }\n\n        if(token(s) != 's') {\n            set_error(s, \"<format>\", \"Expected format 's', got '%c'\", token(s));\n            goto out;\n        }\n\n        key = va_arg(*ap, const char *);\n        if(!key) {\n            set_error(s, \"<args>\", \"NULL object key\");\n            goto out;\n        }\n\n        next_token(s);\n\n        if(token(s) == '?') {\n            opt = gotopt = 1;\n            next_token(s);\n        }\n\n        if(!root) {\n            /* skipping */\n            value = NULL;\n        }\n        else {\n            value = json_object_get(root, key);\n            if(!value && !opt) {\n                set_error(s, \"<validation>\", \"Object item not found: %s\", key);\n                goto out;\n            }\n        }\n\n        if(unpack(s, value, ap))\n            goto out;\n\n        hashtable_set(&key_set, key, json_null());\n        next_token(s);\n    }\n\n    if(strict == 0 && (s->flags & JSON_STRICT))\n        strict = 1;\n\n    if(root && strict == 1) {\n        /* We need to check that all non optional items have been parsed */\n        const char *key;\n        int have_unrecognized_keys = 0;\n        strbuffer_t unrecognized_keys;\n        json_t *value;\n        long unpacked = 0;\n        if (gotopt) {\n            /* We have optional keys, we need to iter on each key */\n            json_object_foreach(root, key, value) {\n                if(!hashtable_get(&key_set, key)) {\n                    unpacked++;\n\n                    /* Save unrecognized keys for the error message */\n                    if (!have_unrecognized_keys) {\n                        strbuffer_init(&unrecognized_keys);\n                        have_unrecognized_keys = 1;\n                    } else {\n                        strbuffer_append_bytes(&unrecognized_keys, \", \", 2);\n                    }\n                    strbuffer_append_bytes(&unrecognized_keys, key, strlen(key));\n                }\n            }\n        } else {\n            /* No optional keys, we can just compare the number of items */\n            unpacked = (long)json_object_size(root) - (long)key_set.size;\n        }\n        if (unpacked) {\n            if (!gotopt) {\n                /* Save unrecognized keys for the error message */\n                json_object_foreach(root, key, value) {\n                    if(!hashtable_get(&key_set, key)) {\n                        if (!have_unrecognized_keys) {\n                            strbuffer_init(&unrecognized_keys);\n                            have_unrecognized_keys = 1;\n                        } else {\n                            strbuffer_append_bytes(&unrecognized_keys, \", \", 2);\n                        }\n                        strbuffer_append_bytes(&unrecognized_keys, key, strlen(key));\n                    }\n                }\n            }\n            set_error(s, \"<validation>\",\n                      \"%li object item(s) left unpacked: %s\",\n                      unpacked, strbuffer_value(&unrecognized_keys));\n            strbuffer_close(&unrecognized_keys);\n            goto out;\n        }\n    }\n\n    ret = 0;\n\nout:\n    hashtable_close(&key_set);\n    return ret;\n}\n\nstatic int unpack_array(scanner_t *s, json_t *root, va_list *ap)\n{\n    size_t i = 0;\n    int strict = 0;\n\n    if(root && !json_is_array(root)) {\n        set_error(s, \"<validation>\", \"Expected array, got %s\", type_name(root));\n        return -1;\n    }\n    next_token(s);\n\n    while(token(s) != ']') {\n        json_t *value;\n\n        if(strict != 0) {\n            set_error(s, \"<format>\", \"Expected ']' after '%c', got '%c'\",\n                      (strict == 1 ? '!' : '*'),\n                      token(s));\n            return -1;\n        }\n\n        if(!token(s)) {\n            set_error(s, \"<format>\", \"Unexpected end of format string\");\n            return -1;\n        }\n\n        if(token(s) == '!' || token(s) == '*') {\n            strict = (token(s) == '!' ? 1 : -1);\n            next_token(s);\n            continue;\n        }\n\n        if(!strchr(unpack_value_starters, token(s))) {\n            set_error(s, \"<format>\", \"Unexpected format character '%c'\",\n                      token(s));\n            return -1;\n        }\n\n        if(!root) {\n            /* skipping */\n            value = NULL;\n        }\n        else {\n            value = json_array_get(root, i);\n            if(!value) {\n                set_error(s, \"<validation>\", \"Array index %lu out of range\",\n                          (unsigned long)i);\n                return -1;\n            }\n        }\n\n        if(unpack(s, value, ap))\n            return -1;\n\n        next_token(s);\n        i++;\n    }\n\n    if(strict == 0 && (s->flags & JSON_STRICT))\n        strict = 1;\n\n    if(root && strict == 1 && i != json_array_size(root)) {\n        long diff = (long)json_array_size(root) - (long)i;\n        set_error(s, \"<validation>\", \"%li array item(s) left unpacked\", diff);\n        return -1;\n    }\n\n    return 0;\n}\n\nstatic int unpack(scanner_t *s, json_t *root, va_list *ap)\n{\n    switch(token(s))\n    {\n        case '{':\n            return unpack_object(s, root, ap);\n\n        case '[':\n            return unpack_array(s, root, ap);\n\n        case 's':\n            if(root && !json_is_string(root)) {\n                set_error(s, \"<validation>\", \"Expected string, got %s\",\n                          type_name(root));\n                return -1;\n            }\n\n            if(!(s->flags & JSON_VALIDATE_ONLY)) {\n                const char **str_target;\n                size_t *len_target = NULL;\n\n                str_target = va_arg(*ap, const char **);\n                if(!str_target) {\n                    set_error(s, \"<args>\", \"NULL string argument\");\n                    return -1;\n                }\n\n                next_token(s);\n\n                if(token(s) == '%') {\n                    len_target = va_arg(*ap, size_t *);\n                    if(!len_target) {\n                        set_error(s, \"<args>\", \"NULL string length argument\");\n                        return -1;\n                    }\n                }\n                else\n                    prev_token(s);\n\n                if(root) {\n                    *str_target = json_string_value(root);\n                    if(len_target)\n                        *len_target = json_string_length(root);\n                }\n            }\n            return 0;\n\n        case 'i':\n            if(root && !json_is_integer(root)) {\n                set_error(s, \"<validation>\", \"Expected integer, got %s\",\n                          type_name(root));\n                return -1;\n            }\n\n            if(!(s->flags & JSON_VALIDATE_ONLY)) {\n                int *target = va_arg(*ap, int*);\n                if(root)\n                    *target = (int)json_integer_value(root);\n            }\n\n            return 0;\n\n        case 'I':\n            if(root && !json_is_integer(root)) {\n                set_error(s, \"<validation>\", \"Expected integer, got %s\",\n                          type_name(root));\n                return -1;\n            }\n\n            if(!(s->flags & JSON_VALIDATE_ONLY)) {\n                json_int_t *target = va_arg(*ap, json_int_t*);\n                if(root)\n                    *target = json_integer_value(root);\n            }\n\n            return 0;\n\n        case 'b':\n            if(root && !json_is_boolean(root)) {\n                set_error(s, \"<validation>\", \"Expected true or false, got %s\",\n                          type_name(root));\n                return -1;\n            }\n\n            if(!(s->flags & JSON_VALIDATE_ONLY)) {\n                int *target = va_arg(*ap, int*);\n                if(root)\n                    *target = json_is_true(root);\n            }\n\n            return 0;\n\n        case 'f':\n            if(root && !json_is_real(root)) {\n                set_error(s, \"<validation>\", \"Expected real, got %s\",\n                          type_name(root));\n                return -1;\n            }\n\n            if(!(s->flags & JSON_VALIDATE_ONLY)) {\n                double *target = va_arg(*ap, double*);\n                if(root)\n                    *target = json_real_value(root);\n            }\n\n            return 0;\n\n        case 'F':\n            if(root && !json_is_number(root)) {\n                set_error(s, \"<validation>\", \"Expected real or integer, got %s\",\n                          type_name(root));\n                return -1;\n            }\n\n            if(!(s->flags & JSON_VALIDATE_ONLY)) {\n                double *target = va_arg(*ap, double*);\n                if(root)\n                    *target = json_number_value(root);\n            }\n\n            return 0;\n\n        case 'O':\n            if(root && !(s->flags & JSON_VALIDATE_ONLY))\n                json_incref(root);\n            /* Fall through */\n\n        case 'o':\n            if(!(s->flags & JSON_VALIDATE_ONLY)) {\n                json_t **target = va_arg(*ap, json_t**);\n                if(root)\n                    *target = root;\n            }\n\n            return 0;\n\n        case 'n':\n            /* Never assign, just validate */\n            if(root && !json_is_null(root)) {\n                set_error(s, \"<validation>\", \"Expected null, got %s\",\n                          type_name(root));\n                return -1;\n            }\n            return 0;\n\n        default:\n            set_error(s, \"<format>\", \"Unexpected format character '%c'\",\n                      token(s));\n            return -1;\n    }\n}\n\njson_t *json_vpack_ex(json_error_t *error, size_t flags,\n                      const char *fmt, va_list ap)\n{\n    scanner_t s;\n    va_list ap_copy;\n    json_t *value;\n\n    if(!fmt || !*fmt) {\n        jsonp_error_init(error, \"<format>\");\n        jsonp_error_set(error, -1, -1, 0, \"NULL or empty format string\");\n        return NULL;\n    }\n    jsonp_error_init(error, NULL);\n\n    scanner_init(&s, error, flags, fmt);\n    next_token(&s);\n\n    va_copy(ap_copy, ap);\n    value = pack(&s, &ap_copy);\n    va_end(ap_copy);\n\n    if(!value)\n        return NULL;\n\n    next_token(&s);\n    if(token(&s)) {\n        json_decref(value);\n        set_error(&s, \"<format>\", \"Garbage after format string\");\n        return NULL;\n    }\n\n    return value;\n}\n\njson_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...)\n{\n    json_t *value;\n    va_list ap;\n\n    va_start(ap, fmt);\n    value = json_vpack_ex(error, flags, fmt, ap);\n    va_end(ap);\n\n    return value;\n}\n\njson_t *json_pack(const char *fmt, ...)\n{\n    json_t *value;\n    va_list ap;\n\n    va_start(ap, fmt);\n    value = json_vpack_ex(NULL, 0, fmt, ap);\n    va_end(ap);\n\n    return value;\n}\n\nint json_vunpack_ex(json_t *root, json_error_t *error, size_t flags,\n                    const char *fmt, va_list ap)\n{\n    scanner_t s;\n    va_list ap_copy;\n\n    if(!root) {\n        jsonp_error_init(error, \"<root>\");\n        jsonp_error_set(error, -1, -1, 0, \"NULL root value\");\n        return -1;\n    }\n\n    if(!fmt || !*fmt) {\n        jsonp_error_init(error, \"<format>\");\n        jsonp_error_set(error, -1, -1, 0, \"NULL or empty format string\");\n        return -1;\n    }\n    jsonp_error_init(error, NULL);\n\n    scanner_init(&s, error, flags, fmt);\n    next_token(&s);\n\n    va_copy(ap_copy, ap);\n    if(unpack(&s, root, &ap_copy)) {\n        va_end(ap_copy);\n        return -1;\n    }\n    va_end(ap_copy);\n\n    next_token(&s);\n    if(token(&s)) {\n        set_error(&s, \"<format>\", \"Garbage after format string\");\n        return -1;\n    }\n\n    return 0;\n}\n\nint json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, ...)\n{\n    int ret;\n    va_list ap;\n\n    va_start(ap, fmt);\n    ret = json_vunpack_ex(root, error, flags, fmt, ap);\n    va_end(ap);\n\n    return ret;\n}\n\nint json_unpack(json_t *root, const char *fmt, ...)\n{\n    int ret;\n    va_list ap;\n\n    va_start(ap, fmt);\n    ret = json_vunpack_ex(root, NULL, 0, fmt, ap);\n    va_end(ap);\n\n    return ret;\n}\n"
  },
  {
    "path": "jansson/strbuffer.c",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n *\n * Jansson is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n */\n\n#ifndef _GNU_SOURCE\n#define _GNU_SOURCE\n#endif\n\n#include <stdlib.h>\n#include <string.h>\n#include \"jansson_private.h\"\n#include \"strbuffer.h\"\n\n#define STRBUFFER_MIN_SIZE  16\n#define STRBUFFER_FACTOR    2\n#define STRBUFFER_SIZE_MAX  ((size_t)-1)\n\nint strbuffer_init(strbuffer_t *strbuff)\n{\n    strbuff->size = STRBUFFER_MIN_SIZE;\n    strbuff->length = 0;\n\n    strbuff->value = jsonp_malloc(strbuff->size);\n    if(!strbuff->value)\n        return -1;\n\n    /* initialize to empty */\n    strbuff->value[0] = '\\0';\n    return 0;\n}\n\nvoid strbuffer_close(strbuffer_t *strbuff)\n{\n    if(strbuff->value)\n        jsonp_free(strbuff->value);\n\n    strbuff->size = 0;\n    strbuff->length = 0;\n    strbuff->value = NULL;\n}\n\nvoid strbuffer_clear(strbuffer_t *strbuff)\n{\n    strbuff->length = 0;\n    strbuff->value[0] = '\\0';\n}\n\nconst char *strbuffer_value(const strbuffer_t *strbuff)\n{\n    return strbuff->value;\n}\n\nchar *strbuffer_steal_value(strbuffer_t *strbuff)\n{\n    char *result = strbuff->value;\n    strbuff->value = NULL;\n    return result;\n}\n\nint strbuffer_append_byte(strbuffer_t *strbuff, char byte)\n{\n    return strbuffer_append_bytes(strbuff, &byte, 1);\n}\n\nint strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, size_t size)\n{\n    if(size >= strbuff->size - strbuff->length)\n    {\n        size_t new_size;\n        char *new_value;\n\n        /* avoid integer overflow */\n        if (strbuff->size > STRBUFFER_SIZE_MAX / STRBUFFER_FACTOR\n            || size > STRBUFFER_SIZE_MAX - 1\n            || strbuff->length > STRBUFFER_SIZE_MAX - 1 - size)\n            return -1;\n\n        new_size = max(strbuff->size * STRBUFFER_FACTOR,\n                       strbuff->length + size + 1);\n\n        new_value = jsonp_malloc(new_size);\n        if(!new_value)\n            return -1;\n\n        memcpy(new_value, strbuff->value, strbuff->length);\n\n        jsonp_free(strbuff->value);\n        strbuff->value = new_value;\n        strbuff->size = new_size;\n    }\n\n    memcpy(strbuff->value + strbuff->length, data, size);\n    strbuff->length += size;\n    strbuff->value[strbuff->length] = '\\0';\n\n    return 0;\n}\n\nchar strbuffer_pop(strbuffer_t *strbuff)\n{\n    if(strbuff->length > 0) {\n        char c = strbuff->value[--strbuff->length];\n        strbuff->value[strbuff->length] = '\\0';\n        return c;\n    }\n    else\n        return '\\0';\n}\n"
  },
  {
    "path": "jansson/strbuffer.h",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n *\n * Jansson is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n */\n\n#ifndef STRBUFFER_H\n#define STRBUFFER_H\n\n#include <stdlib.h>\n\ntypedef struct {\n    char *value;\n    size_t length;   /* bytes used */\n    size_t size;     /* bytes allocated */\n} strbuffer_t;\n\nint strbuffer_init(strbuffer_t *strbuff);\nvoid strbuffer_close(strbuffer_t *strbuff);\n\nvoid strbuffer_clear(strbuffer_t *strbuff);\n\nconst char *strbuffer_value(const strbuffer_t *strbuff);\n\n/* Steal the value and close the strbuffer */\nchar *strbuffer_steal_value(strbuffer_t *strbuff);\n\nint strbuffer_append_byte(strbuffer_t *strbuff, char byte);\nint strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, size_t size);\n\nchar strbuffer_pop(strbuffer_t *strbuff);\n\n#endif\n"
  },
  {
    "path": "jansson/strconv.c",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n *\n * Jansson is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n */\n\n#include <assert.h>\n#include <errno.h>\n#include <stdio.h>\n#include <string.h>\n#include <math.h>\n#ifdef __MINGW32__\n#undef __NO_ISOCEXT /* ensure stdlib.h will declare prototypes for mingw own 'strtod' replacement, called '__strtod' */\n#endif\n#include \"jansson_private.h\"\n#include \"strbuffer.h\"\n\n/* need jansson_private_config.h to get the correct snprintf */\n#ifdef HAVE_CONFIG_H\n#include <jansson_private_config.h>\n#endif\n\n#ifdef __MINGW32__\n#define strtod __strtod\n#endif\n\n#if JSON_HAVE_LOCALECONV\n#include <locale.h>\n\n/*\n  - This code assumes that the decimal separator is exactly one\n    character.\n\n  - If setlocale() is called by another thread between the call to\n    localeconv() and the call to sprintf() or strtod(), the result may\n    be wrong. setlocale() is not thread-safe and should not be used\n    this way. Multi-threaded programs should use uselocale() instead.\n*/\n\nstatic void to_locale(strbuffer_t *strbuffer)\n{\n    const char *point;\n    char *pos;\n\n    point = localeconv()->decimal_point;\n    if(*point == '.') {\n        /* No conversion needed */\n        return;\n    }\n\n    pos = strchr(strbuffer->value, '.');\n    if(pos)\n        *pos = *point;\n}\n\nstatic void from_locale(char *buffer)\n{\n    const char *point;\n    char *pos;\n\n    point = localeconv()->decimal_point;\n    if(*point == '.') {\n        /* No conversion needed */\n        return;\n    }\n\n    pos = strchr(buffer, *point);\n    if(pos)\n        *pos = '.';\n}\n#endif\n\nint jsonp_strtod(strbuffer_t *strbuffer, double *out)\n{\n    double value;\n    char *end;\n\n#if JSON_HAVE_LOCALECONV\n    to_locale(strbuffer);\n#endif\n\n    errno = 0;\n    value = strtod(strbuffer->value, &end);\n    assert(end == strbuffer->value + strbuffer->length);\n\n    if((value == HUGE_VAL || value == -HUGE_VAL) && errno == ERANGE) {\n        /* Overflow */\n        return -1;\n    }\n\n    *out = value;\n    return 0;\n}\n\nint jsonp_dtostr(char *buffer, size_t size, double value, int precision)\n{\n    int ret;\n    char *start, *end;\n    size_t length;\n\n    if (precision == 0)\n        precision = 17;\n\n    ret = snprintf(buffer, size, \"%.*g\", precision, value);\n    if(ret < 0)\n        return -1;\n\n    length = (size_t)ret;\n    if(length >= size)\n        return -1;\n\n#if JSON_HAVE_LOCALECONV\n    from_locale(buffer);\n#endif\n\n    /* Make sure there's a dot or 'e' in the output. Otherwise\n       a real is converted to an integer when decoding */\n    if(strchr(buffer, '.') == NULL &&\n       strchr(buffer, 'e') == NULL)\n    {\n        if(length + 3 >= size) {\n            /* No space to append \".0\" */\n            return -1;\n        }\n        buffer[length] = '.';\n        buffer[length + 1] = '0';\n        buffer[length + 2] = '\\0';\n        length += 2;\n    }\n\n    /* Remove leading '+' from positive exponent. Also remove leading\n       zeros from exponents (added by some printf() implementations) */\n    start = strchr(buffer, 'e');\n    if(start) {\n        start++;\n        end = start + 1;\n\n        if(*start == '-')\n            start++;\n\n        while(*end == '0')\n            end++;\n\n        if(end != start) {\n            memmove(start, end, length - (size_t)(end - buffer));\n            length -= (size_t)(end - start);\n        }\n    }\n\n    return (int)length;\n}\n"
  },
  {
    "path": "jansson/utf.c",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n *\n * Jansson is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n */\n\n#include <string.h>\n#include \"utf.h\"\n\nint utf8_encode(int32_t codepoint, char *buffer, size_t *size)\n{\n    if(codepoint < 0)\n        return -1;\n    else if(codepoint < 0x80)\n    {\n        buffer[0] = (char)codepoint;\n        *size = 1;\n    }\n    else if(codepoint < 0x800)\n    {\n        buffer[0] = 0xC0 + ((codepoint & 0x7C0) >> 6);\n        buffer[1] = 0x80 + ((codepoint & 0x03F));\n        *size = 2;\n    }\n    else if(codepoint < 0x10000)\n    {\n        buffer[0] = 0xE0 + ((codepoint & 0xF000) >> 12);\n        buffer[1] = 0x80 + ((codepoint & 0x0FC0) >> 6);\n        buffer[2] = 0x80 + ((codepoint & 0x003F));\n        *size = 3;\n    }\n    else if(codepoint <= 0x10FFFF)\n    {\n        buffer[0] = 0xF0 + ((codepoint & 0x1C0000) >> 18);\n        buffer[1] = 0x80 + ((codepoint & 0x03F000) >> 12);\n        buffer[2] = 0x80 + ((codepoint & 0x000FC0) >> 6);\n        buffer[3] = 0x80 + ((codepoint & 0x00003F));\n        *size = 4;\n    }\n    else\n        return -1;\n\n    return 0;\n}\n\nsize_t utf8_check_first(char byte)\n{\n    unsigned char u = (unsigned char)byte;\n\n    if(u < 0x80)\n        return 1;\n\n    if(0x80 <= u && u <= 0xBF) {\n        /* second, third or fourth byte of a multi-byte\n           sequence, i.e. a \"continuation byte\" */\n        return 0;\n    }\n    else if(u == 0xC0 || u == 0xC1) {\n        /* overlong encoding of an ASCII byte */\n        return 0;\n    }\n    else if(0xC2 <= u && u <= 0xDF) {\n        /* 2-byte sequence */\n        return 2;\n    }\n\n    else if(0xE0 <= u && u <= 0xEF) {\n        /* 3-byte sequence */\n        return 3;\n    }\n    else if(0xF0 <= u && u <= 0xF4) {\n        /* 4-byte sequence */\n        return 4;\n    }\n    else { /* u >= 0xF5 */\n        /* Restricted (start of 4-, 5- or 6-byte sequence) or invalid\n           UTF-8 */\n        return 0;\n    }\n}\n\nsize_t utf8_check_full(const char *buffer, size_t size, int32_t *codepoint)\n{\n    size_t i;\n    int32_t value = 0;\n    unsigned char u = (unsigned char)buffer[0];\n\n    if(size == 2)\n    {\n        value = u & 0x1F;\n    }\n    else if(size == 3)\n    {\n        value = u & 0xF;\n    }\n    else if(size == 4)\n    {\n        value = u & 0x7;\n    }\n    else\n        return 0;\n\n    for(i = 1; i < size; i++)\n    {\n        u = (unsigned char)buffer[i];\n\n        if(u < 0x80 || u > 0xBF) {\n            /* not a continuation byte */\n            return 0;\n        }\n\n        value = (value << 6) + (u & 0x3F);\n    }\n\n    if(value > 0x10FFFF) {\n        /* not in Unicode range */\n        return 0;\n    }\n\n    else if(0xD800 <= value && value <= 0xDFFF) {\n        /* invalid code point (UTF-16 surrogate halves) */\n        return 0;\n    }\n\n    else if((size == 2 && value < 0x80) ||\n            (size == 3 && value < 0x800) ||\n            (size == 4 && value < 0x10000)) {\n        /* overlong encoding */\n        return 0;\n    }\n\n    if(codepoint)\n        *codepoint = value;\n\n    return 1;\n}\n\nconst char *utf8_iterate(const char *buffer, size_t bufsize, int32_t *codepoint)\n{\n    size_t count;\n    int32_t value;\n\n    if(!bufsize)\n        return buffer;\n\n    count = utf8_check_first(buffer[0]);\n    if(count <= 0)\n        return NULL;\n\n    if(count == 1)\n        value = (unsigned char)buffer[0];\n    else\n    {\n        if(count > bufsize || !utf8_check_full(buffer, count, &value))\n            return NULL;\n    }\n\n    if(codepoint)\n        *codepoint = value;\n\n    return buffer + count;\n}\n\nint utf8_check_string(const char *string, size_t length)\n{\n    size_t i;\n\n    for(i = 0; i < length; i++)\n    {\n        size_t count = utf8_check_first(string[i]);\n        if(count == 0)\n            return 0;\n        else if(count > 1)\n        {\n            if(count > length - i)\n                return 0;\n\n            if(!utf8_check_full(&string[i], count, NULL))\n                return 0;\n\n            i += count - 1;\n        }\n    }\n\n    return 1;\n}\n"
  },
  {
    "path": "jansson/utf.h",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n *\n * Jansson is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n */\n\n#ifndef UTF_H\n#define UTF_H\n\n#ifdef HAVE_CONFIG_H\n#include \"jansson_private_config.h\"\n#endif\n\n#include <stdint.h>\n\nint utf8_encode(int32_t codepoint, char *buffer, size_t *size);\n\nsize_t utf8_check_first(char byte);\nsize_t utf8_check_full(const char *buffer, size_t size, int32_t *codepoint);\nconst char *utf8_iterate(const char *buffer, size_t size, int32_t *codepoint);\n\nint utf8_check_string(const char *string, size_t length);\n\n#endif\n"
  },
  {
    "path": "jansson/value.c",
    "content": "/*\n * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n *\n * Jansson is free software; you can redistribute it and/or modify\n * it under the terms of the MIT license. See MIT for details.\n */\n\n#ifndef _GNU_SOURCE\n#define _GNU_SOURCE\n#endif\n\n#ifdef HAVE_CONFIG_H\n#include <jansson_private_config.h>\n#endif\n\n#include <stddef.h>\n#include <stdlib.h>\n#include <string.h>\n#include <math.h>\n\n#ifdef HAVE_STDINT_H\n#include <stdint.h>\n#endif\n\n#include \"jansson.h\"\n#include \"hashtable.h\"\n#include \"jansson_private.h\"\n#include \"utf.h\"\n\n /* Work around nonstandard isnan() and isinf() implementations */\n#ifndef isnan\n#ifndef __sun\nstatic JSON_INLINE int isnan(double x) { return x != x; }\n#endif\n#endif\n#ifndef isinf\nstatic JSON_INLINE int isinf(double x) { return !isnan(x) && isnan(x - x); }\n#endif\n\nstatic JSON_INLINE void json_init(json_t *json, json_type type)\n{\n\tjson->type = type;\n\tjson->refcount = 1;\n}\n\n\n/*** object ***/\n\nextern volatile uint32_t hashtable_seed;\n\njson_t *json_object(void)\n{\n\tjson_object_t *object = jsonp_malloc(sizeof(json_object_t));\n\tif (!object)\n\t\treturn NULL;\n\n\tif (!hashtable_seed) {\n\t\t/* Autoseed */\n\t\tjson_object_seed(0);\n\t}\n\n\tjson_init(&object->json, JSON_OBJECT);\n\n\tif (hashtable_init(&object->hashtable))\n\t{\n\t\tjsonp_free(object);\n\t\treturn NULL;\n\t}\n\n\tobject->visited = 0;\n\n\treturn &object->json;\n}\n\nstatic void json_delete_object(json_object_t *object)\n{\n\thashtable_close(&object->hashtable);\n\tjsonp_free(object);\n}\n\nsize_t json_object_size(const json_t *json)\n{\n\tjson_object_t *object;\n\n\tif (!json_is_object(json))\n\t\treturn 0;\n\n\tobject = json_to_object(json);\n\treturn object->hashtable.size;\n}\n\njson_t *json_object_get(const json_t *json, const char *key)\n{\n\tjson_object_t *object;\n\n\tif (!key || !json_is_object(json))\n\t\treturn NULL;\n\n\tobject = json_to_object(json);\n\treturn hashtable_get(&object->hashtable, key);\n}\n\nint json_object_set_new_nocheck(json_t *json, const char *key, json_t *value)\n{\n\tjson_object_t *object;\n\n\tif (!value)\n\t\treturn -1;\n\n\tif (!key || !json_is_object(json) || json == value)\n\t{\n\t\tjson_decref(value);\n\t\treturn -1;\n\t}\n\tobject = json_to_object(json);\n\n\tif (hashtable_set(&object->hashtable, key, value))\n\t{\n\t\tjson_decref(value);\n\t\treturn -1;\n\t}\n\n\treturn 0;\n}\n\nint json_object_set_new(json_t *json, const char *key, json_t *value)\n{\n\tif (!key || !utf8_check_string(key, strlen(key)))\n\t{\n\t\tjson_decref(value);\n\t\treturn -1;\n\t}\n\n\treturn json_object_set_new_nocheck(json, key, value);\n}\n\nint json_object_del(json_t *json, const char *key)\n{\n\tjson_object_t *object;\n\n\tif (!key || !json_is_object(json))\n\t\treturn -1;\n\n\tobject = json_to_object(json);\n\treturn hashtable_del(&object->hashtable, key);\n}\n\nint json_object_clear(json_t *json)\n{\n\tjson_object_t *object;\n\n\tif (!json_is_object(json))\n\t\treturn -1;\n\n\tobject = json_to_object(json);\n\thashtable_clear(&object->hashtable);\n\n\treturn 0;\n}\n\nint json_object_update(json_t *object, json_t *other)\n{\n\tconst char *key;\n\tjson_t *value;\n\n\tif (!json_is_object(object) || !json_is_object(other))\n\t\treturn -1;\n\n\tjson_object_foreach(other, key, value) {\n\t\tif (json_object_set_nocheck(object, key, value))\n\t\t\treturn -1;\n\t}\n\n\treturn 0;\n}\n\nint json_object_update_existing(json_t *object, json_t *other)\n{\n\tconst char *key;\n\tjson_t *value;\n\n\tif (!json_is_object(object) || !json_is_object(other))\n\t\treturn -1;\n\n\tjson_object_foreach(other, key, value) {\n\t\tif (json_object_get(object, key))\n\t\t\tjson_object_set_nocheck(object, key, value);\n\t}\n\n\treturn 0;\n}\n\nint json_object_update_missing(json_t *object, json_t *other)\n{\n\tconst char *key;\n\tjson_t *value;\n\n\tif (!json_is_object(object) || !json_is_object(other))\n\t\treturn -1;\n\n\tjson_object_foreach(other, key, value) {\n\t\tif (!json_object_get(object, key))\n\t\t\tjson_object_set_nocheck(object, key, value);\n\t}\n\n\treturn 0;\n}\n\nvoid *json_object_iter(json_t *json)\n{\n\tjson_object_t *object;\n\n\tif (!json_is_object(json))\n\t\treturn NULL;\n\n\tobject = json_to_object(json);\n\treturn hashtable_iter(&object->hashtable);\n}\n\nvoid *json_object_iter_at(json_t *json, const char *key)\n{\n\tjson_object_t *object;\n\n\tif (!key || !json_is_object(json))\n\t\treturn NULL;\n\n\tobject = json_to_object(json);\n\treturn hashtable_iter_at(&object->hashtable, key);\n}\n\nvoid *json_object_iter_next(json_t *json, void *iter)\n{\n\tjson_object_t *object;\n\n\tif (!json_is_object(json) || iter == NULL)\n\t\treturn NULL;\n\n\tobject = json_to_object(json);\n\treturn hashtable_iter_next(&object->hashtable, iter);\n}\n\nconst char *json_object_iter_key(void *iter)\n{\n\tif (!iter)\n\t\treturn NULL;\n\n\treturn hashtable_iter_key(iter);\n}\n\njson_t *json_object_iter_value(void *iter)\n{\n\tif (!iter)\n\t\treturn NULL;\n\n\treturn (json_t *)hashtable_iter_value(iter);\n}\n\nint json_object_iter_set_new(json_t *json, void *iter, json_t *value)\n{\n\tif (!json_is_object(json) || !iter || !value)\n\t\treturn -1;\n\n\thashtable_iter_set(iter, value);\n\treturn 0;\n}\n\nvoid *json_object_key_to_iter(const char *key)\n{\n\tif (!key)\n\t\treturn NULL;\n\n\treturn hashtable_key_to_iter(key);\n}\n\nstatic int json_object_equal(json_t *object1, json_t *object2)\n{\n\tconst char *key;\n\tjson_t *value1, *value2;\n\n\tif (json_object_size(object1) != json_object_size(object2))\n\t\treturn 0;\n\n\tjson_object_foreach(object1, key, value1) {\n\t\tvalue2 = json_object_get(object2, key);\n\n\t\tif (!json_equal(value1, value2))\n\t\t\treturn 0;\n\t}\n\n\treturn 1;\n}\n\nstatic json_t *json_object_copy(json_t *object)\n{\n\tjson_t *result;\n\n\tconst char *key;\n\tjson_t *value;\n\n\tresult = json_object();\n\tif (!result)\n\t\treturn NULL;\n\n\tjson_object_foreach(object, key, value)\n\t\tjson_object_set_nocheck(result, key, value);\n\n\treturn result;\n}\n\nstatic json_t *json_object_deep_copy(const json_t *object)\n{\n\tjson_t *result;\n\tvoid *iter;\n\n\tresult = json_object();\n\tif (!result)\n\t\treturn NULL;\n\n\t/* Cannot use json_object_foreach because object has to be cast\n\t   non-const */\n\titer = json_object_iter((json_t *)object);\n\twhile (iter) {\n\t\tconst char *key;\n\t\tconst json_t *value;\n\t\tkey = json_object_iter_key(iter);\n\t\tvalue = json_object_iter_value(iter);\n\n\t\tjson_object_set_new_nocheck(result, key, json_deep_copy(value));\n\t\titer = json_object_iter_next((json_t *)object, iter);\n\t}\n\n\treturn result;\n}\n\n\n/*** array ***/\n\njson_t *json_array(void)\n{\n\tjson_array_t *array = jsonp_malloc(sizeof(json_array_t));\n\tif (!array)\n\t\treturn NULL;\n\tjson_init(&array->json, JSON_ARRAY);\n\n\tarray->entries = 0;\n\tarray->size = 8;\n\n\tarray->table = jsonp_malloc(array->size * sizeof(json_t *));\n\tif (!array->table) {\n\t\tjsonp_free(array);\n\t\treturn NULL;\n\t}\n\n\tarray->visited = 0;\n\n\treturn &array->json;\n}\n\nstatic void json_delete_array(json_array_t *array)\n{\n\tsize_t i;\n\n\tfor (i = 0; i < array->entries; i++)\n\t\tjson_decref(array->table[i]);\n\n\tjsonp_free(array->table);\n\tjsonp_free(array);\n}\n\nsize_t json_array_size(const json_t *json)\n{\n\tif (!json_is_array(json))\n\t\treturn 0;\n\n\treturn json_to_array(json)->entries;\n}\n\njson_t *json_array_get(const json_t *json, size_t index)\n{\n\tjson_array_t *array;\n\tif (!json_is_array(json))\n\t\treturn NULL;\n\tarray = json_to_array(json);\n\n\tif (index >= array->entries)\n\t\treturn NULL;\n\n\treturn array->table[index];\n}\n\nint json_array_set_new(json_t *json, size_t index, json_t *value)\n{\n\tjson_array_t *array;\n\n\tif (!value)\n\t\treturn -1;\n\n\tif (!json_is_array(json) || json == value)\n\t{\n\t\tjson_decref(value);\n\t\treturn -1;\n\t}\n\tarray = json_to_array(json);\n\n\tif (index >= array->entries)\n\t{\n\t\tjson_decref(value);\n\t\treturn -1;\n\t}\n\n\tjson_decref(array->table[index]);\n\tarray->table[index] = value;\n\n\treturn 0;\n}\n\nstatic void array_move(json_array_t *array, size_t dest,\n\tsize_t src, size_t count)\n{\n\tmemmove(&array->table[dest], &array->table[src], count * sizeof(json_t *));\n}\n\nstatic void array_copy(json_t **dest, size_t dpos,\n\tjson_t **src, size_t spos,\n\tsize_t count)\n{\n\tmemcpy(&dest[dpos], &src[spos], count * sizeof(json_t *));\n}\n\nstatic json_t **json_array_grow(json_array_t *array,\n\tsize_t amount,\n\tint copy)\n{\n\tsize_t new_size;\n\tjson_t **old_table, **new_table;\n\n\tif (array->entries + amount <= array->size)\n\t\treturn array->table;\n\n\told_table = array->table;\n\n\tnew_size = max(array->size + amount, array->size * 2);\n\tnew_table = jsonp_malloc(new_size * sizeof(json_t *));\n\tif (!new_table)\n\t\treturn NULL;\n\n\tarray->size = new_size;\n\tarray->table = new_table;\n\n\tif (copy) {\n\t\tarray_copy(array->table, 0, old_table, 0, array->entries);\n\t\tjsonp_free(old_table);\n\t\treturn array->table;\n\t}\n\n\treturn old_table;\n}\n\nint json_array_append_new(json_t *json, json_t *value)\n{\n\tjson_array_t *array;\n\n\tif (!value)\n\t\treturn -1;\n\n\tif (!json_is_array(json) || json == value)\n\t{\n\t\tjson_decref(value);\n\t\treturn -1;\n\t}\n\tarray = json_to_array(json);\n\n\tif (!json_array_grow(array, 1, 1)) {\n\t\tjson_decref(value);\n\t\treturn -1;\n\t}\n\n\tarray->table[array->entries] = value;\n\tarray->entries++;\n\n\treturn 0;\n}\n\nint json_array_insert_new(json_t *json, size_t index, json_t *value)\n{\n\tjson_array_t *array;\n\tjson_t **old_table;\n\n\tif (!value)\n\t\treturn -1;\n\n\tif (!json_is_array(json) || json == value) {\n\t\tjson_decref(value);\n\t\treturn -1;\n\t}\n\tarray = json_to_array(json);\n\n\tif (index > array->entries) {\n\t\tjson_decref(value);\n\t\treturn -1;\n\t}\n\n\told_table = json_array_grow(array, 1, 0);\n\tif (!old_table) {\n\t\tjson_decref(value);\n\t\treturn -1;\n\t}\n\n\tif (old_table != array->table) {\n\t\tarray_copy(array->table, 0, old_table, 0, index);\n\t\tarray_copy(array->table, index + 1, old_table, index,\n\t\t\tarray->entries - index);\n\t\tjsonp_free(old_table);\n\t}\n\telse\n\t\tarray_move(array, index + 1, index, array->entries - index);\n\n\tarray->table[index] = value;\n\tarray->entries++;\n\n\treturn 0;\n}\n\nint json_array_remove(json_t *json, size_t index)\n{\n\tjson_array_t *array;\n\n\tif (!json_is_array(json))\n\t\treturn -1;\n\tarray = json_to_array(json);\n\n\tif (index >= array->entries)\n\t\treturn -1;\n\n\tjson_decref(array->table[index]);\n\n\t/* If we're removing the last element, nothing has to be moved */\n\tif (index < array->entries - 1)\n\t\tarray_move(array, index, index + 1, array->entries - index - 1);\n\n\tarray->entries--;\n\n\treturn 0;\n}\n\nint json_array_clear(json_t *json)\n{\n\tjson_array_t *array;\n\tsize_t i;\n\n\tif (!json_is_array(json))\n\t\treturn -1;\n\tarray = json_to_array(json);\n\n\tfor (i = 0; i < array->entries; i++)\n\t\tjson_decref(array->table[i]);\n\n\tarray->entries = 0;\n\treturn 0;\n}\n\nint json_array_extend(json_t *json, json_t *other_json)\n{\n\tjson_array_t *array, *other;\n\tsize_t i;\n\n\tif (!json_is_array(json) || !json_is_array(other_json))\n\t\treturn -1;\n\tarray = json_to_array(json);\n\tother = json_to_array(other_json);\n\n\tif (!json_array_grow(array, other->entries, 1))\n\t\treturn -1;\n\n\tfor (i = 0; i < other->entries; i++)\n\t\tjson_incref(other->table[i]);\n\n\tarray_copy(array->table, array->entries, other->table, 0, other->entries);\n\n\tarray->entries += other->entries;\n\treturn 0;\n}\n\nstatic int json_array_equal(json_t *array1, json_t *array2)\n{\n\tsize_t i, size;\n\n\tsize = json_array_size(array1);\n\tif (size != json_array_size(array2))\n\t\treturn 0;\n\n\tfor (i = 0; i < size; i++)\n\t{\n\t\tjson_t *value1, *value2;\n\n\t\tvalue1 = json_array_get(array1, i);\n\t\tvalue2 = json_array_get(array2, i);\n\n\t\tif (!json_equal(value1, value2))\n\t\t\treturn 0;\n\t}\n\n\treturn 1;\n}\n\nstatic json_t *json_array_copy(json_t *array)\n{\n\tjson_t *result;\n\tsize_t i;\n\n\tresult = json_array();\n\tif (!result)\n\t\treturn NULL;\n\n\tfor (i = 0; i < json_array_size(array); i++)\n\t\tjson_array_append(result, json_array_get(array, i));\n\n\treturn result;\n}\n\nstatic json_t *json_array_deep_copy(const json_t *array)\n{\n\tjson_t *result;\n\tsize_t i;\n\n\tresult = json_array();\n\tif (!result)\n\t\treturn NULL;\n\n\tfor (i = 0; i < json_array_size(array); i++)\n\t\tjson_array_append_new(result, json_deep_copy(json_array_get(array, i)));\n\n\treturn result;\n}\n\n/*** string ***/\n\nstatic json_t *string_create(const char *value, size_t len, int own)\n{\n\tchar *v;\n\tjson_string_t *string;\n\n\tif (!value)\n\t\treturn NULL;\n\n\tif (own)\n\t\tv = (char *)value;\n\telse {\n\t\tv = jsonp_strndup(value, len);\n\t\tif (!v)\n\t\t\treturn NULL;\n\t}\n\n\tstring = jsonp_malloc(sizeof(json_string_t));\n\tif (!string) {\n\t\tif (!own)\n\t\t\tjsonp_free(v);\n\t\treturn NULL;\n\t}\n\tjson_init(&string->json, JSON_STRING);\n\tstring->value = v;\n\tstring->length = len;\n\n\treturn &string->json;\n}\n\njson_t *json_string_nocheck(const char *value)\n{\n\tif (!value)\n\t\treturn NULL;\n\n\treturn string_create(value, strlen(value), 0);\n}\n\njson_t *json_stringn_nocheck(const char *value, size_t len)\n{\n\treturn string_create(value, len, 0);\n}\n\n/* this is private; \"steal\" is not a public API concept */\njson_t *jsonp_stringn_nocheck_own(const char *value, size_t len)\n{\n\treturn string_create(value, len, 1);\n}\n\njson_t *json_string(const char *value)\n{\n\tif (!value)\n\t\treturn NULL;\n\n\treturn json_stringn(value, strlen(value));\n}\n\n\njson_t *json_stringn(const char *value, size_t len)\n{\n\tif (!value || !utf8_check_string(value, len))\n\t\treturn NULL;\n\n\treturn json_stringn_nocheck(value, len);\n}\n\nconst char *json_string_value(const json_t *json)\n{\n\tif (!json_is_string(json))\n\t\treturn NULL;\n\n\treturn json_to_string(json)->value;\n}\n\nsize_t json_string_length(const json_t *json)\n{\n\tif (!json_is_string(json))\n\t\treturn 0;\n\n\treturn json_to_string(json)->length;\n}\n\n/*** mem ***/\n\nstatic json_t *mem_create(const char *value, size_t len, int own)\n{\n\tchar *v;\n\tjson_mem_t *mem;\n\n\tif (!value)\n\t\treturn NULL;\n\n\tif (own)\n\t\tv = (char *)value;\n\telse {\n\t\tv = malloc(len);\n\t\tif (!v)\n\t\t\treturn NULL;\n\t\tmemcpy(v, value, len);\n\t}\n\n\tmem = jsonp_malloc(sizeof(json_mem_t));\n\tif (!mem) {\n\t\tif (!own)\n\t\t\tjsonp_free(v);\n\t\treturn NULL;\n\t}\n\tjson_init(&mem->json, JSON_MEM);\n\tmem->value = v;\n\tmem->length = len;\n\n\treturn &mem->json;\n}\n\njson_t *json_mem(const char *value, size_t len)\n{\n\treturn mem_create(value, len, 0);\n}\n\njson_t *json_mem_own(const char *value, size_t len)\n{\n\treturn mem_create(value, len, 1);\n}\n\nconst char *json_mem_value(const json_t *json)\n{\n\tif (!json_is_mem(json))\n\t\treturn NULL;\n\n\treturn json_to_mem(json)->value;\n}\n\nsize_t json_mem_length(const json_t *json)\n{\n\tif (!json_is_mem(json))\n\t\treturn 0;\n\n\treturn json_to_mem(json)->length;\n}\n\nint json_string_set_nocheck(json_t *json, const char *value)\n{\n\tif (!value)\n\t\treturn -1;\n\n\treturn json_string_setn_nocheck(json, value, strlen(value));\n}\n\nint json_string_setn_nocheck(json_t *json, const char *value, size_t len)\n{\n\tchar *dup;\n\tjson_string_t *string;\n\n\tif (!json_is_string(json) || !value)\n\t\treturn -1;\n\n\tdup = jsonp_strndup(value, len);\n\tif (!dup)\n\t\treturn -1;\n\n\tstring = json_to_string(json);\n\tjsonp_free(string->value);\n\tstring->value = dup;\n\tstring->length = len;\n\n\treturn 0;\n}\n\nint json_string_set(json_t *json, const char *value)\n{\n\tif (!value)\n\t\treturn -1;\n\n\treturn json_string_setn(json, value, strlen(value));\n}\n\nint json_string_setn(json_t *json, const char *value, size_t len)\n{\n\tif (!value || !utf8_check_string(value, len))\n\t\treturn -1;\n\n\treturn json_string_setn_nocheck(json, value, len);\n}\n\nstatic void json_delete_string(json_string_t *string)\n{\n\tjsonp_free(string->value);\n\tjsonp_free(string);\n}\n\nstatic int json_string_equal(json_t *string1, json_t *string2)\n{\n\tjson_string_t *s1, *s2;\n\n\tif (!json_is_string(string1) || !json_is_string(string2))\n\t\treturn 0;\n\n\ts1 = json_to_string(string1);\n\ts2 = json_to_string(string2);\n\treturn s1->length == s2->length && !memcmp(s1->value, s2->value, s1->length);\n}\n\nstatic json_t *json_string_copy(const json_t *string)\n{\n\tjson_string_t *s;\n\n\tif (!json_is_string(string))\n\t\treturn NULL;\n\n\ts = json_to_string(string);\n\treturn json_stringn_nocheck(s->value, s->length);\n}\n\n\n/*** integer ***/\n\njson_t *json_integer(json_int_t value)\n{\n\tjson_integer_t *integer = jsonp_malloc(sizeof(json_integer_t));\n\tif (!integer)\n\t\treturn NULL;\n\tjson_init(&integer->json, JSON_INTEGER);\n\n\tinteger->value = value;\n\treturn &integer->json;\n}\n\njson_int_t json_integer_value(const json_t *json)\n{\n\tif (!json_is_integer(json))\n\t\treturn 0;\n\n\treturn json_to_integer(json)->value;\n}\n\nint json_integer_set(json_t *json, json_int_t value)\n{\n\tif (!json_is_integer(json))\n\t\treturn -1;\n\n\tjson_to_integer(json)->value = value;\n\n\treturn 0;\n}\n\nstatic void json_delete_integer(json_integer_t *integer)\n{\n\tjsonp_free(integer);\n}\n\nstatic int json_integer_equal(json_t *integer1, json_t *integer2)\n{\n\treturn json_integer_value(integer1) == json_integer_value(integer2);\n}\n\nstatic json_t *json_integer_copy(const json_t *integer)\n{\n\treturn json_integer(json_integer_value(integer));\n}\n\n\n/*** real ***/\n\njson_t *json_real(double value)\n{\n\tjson_real_t *real;\n\n\tif (isnan(value) || isinf(value))\n\t\treturn NULL;\n\n\treal = jsonp_malloc(sizeof(json_real_t));\n\tif (!real)\n\t\treturn NULL;\n\tjson_init(&real->json, JSON_REAL);\n\n\treal->value = value;\n\treturn &real->json;\n}\n\ndouble json_real_value(const json_t *json)\n{\n\tif (!json_is_real(json))\n\t\treturn 0;\n\n\treturn json_to_real(json)->value;\n}\n\nint json_real_set(json_t *json, double value)\n{\n\tif (!json_is_real(json) || isnan(value) || isinf(value))\n\t\treturn -1;\n\n\tjson_to_real(json)->value = value;\n\n\treturn 0;\n}\n\nstatic void json_delete_real(json_real_t *real)\n{\n\tjsonp_free(real);\n}\n\nstatic int json_real_equal(json_t *real1, json_t *real2)\n{\n\treturn json_real_value(real1) == json_real_value(real2);\n}\n\nstatic json_t *json_real_copy(const json_t *real)\n{\n\treturn json_real(json_real_value(real));\n}\n\n\n/*** number ***/\n\ndouble json_number_value(const json_t *json)\n{\n\tif (json_is_integer(json))\n\t\treturn (double)json_integer_value(json);\n\telse if (json_is_real(json))\n\t\treturn json_real_value(json);\n\telse\n\t\treturn 0.0;\n}\n\n\n/*** simple values ***/\n\njson_t *json_true(void)\n{\n\tstatic json_t the_true = { JSON_TRUE, (size_t)-1 };\n\treturn &the_true;\n}\n\n\njson_t *json_false(void)\n{\n\tstatic json_t the_false = { JSON_FALSE, (size_t)-1 };\n\treturn &the_false;\n}\n\n\njson_t *json_null(void)\n{\n\tstatic json_t the_null = { JSON_NULL, (size_t)-1 };\n\treturn &the_null;\n}\n\n\n/*** deletion ***/\n\nvoid json_delete(json_t *json)\n{\n\tif (!json)\n\t\treturn;\n\n\tswitch (json_typeof(json)) {\n\tcase JSON_OBJECT:\n\t\tjson_delete_object(json_to_object(json));\n\t\tbreak;\n\tcase JSON_ARRAY:\n\t\tjson_delete_array(json_to_array(json));\n\t\tbreak;\n\tcase JSON_STRING:\n\t\tjson_delete_string(json_to_string(json));\n\t\tbreak;\n\tcase JSON_INTEGER:\n\t\tjson_delete_integer(json_to_integer(json));\n\t\tbreak;\n\tcase JSON_REAL:\n\t\tjson_delete_real(json_to_real(json));\n\t\tbreak;\n\tdefault:\n\t\treturn;\n\t}\n\n\t/* json_delete is not called for true, false or null */\n}\n\n\n/*** equality ***/\n\nint json_equal(json_t *json1, json_t *json2)\n{\n\tif (!json1 || !json2)\n\t\treturn 0;\n\n\tif (json_typeof(json1) != json_typeof(json2))\n\t\treturn 0;\n\n\t/* this covers true, false and null as they are singletons */\n\tif (json1 == json2)\n\t\treturn 1;\n\n\tswitch (json_typeof(json1)) {\n\tcase JSON_OBJECT:\n\t\treturn json_object_equal(json1, json2);\n\tcase JSON_ARRAY:\n\t\treturn json_array_equal(json1, json2);\n\tcase JSON_STRING:\n\t\treturn json_string_equal(json1, json2);\n\tcase JSON_INTEGER:\n\t\treturn json_integer_equal(json1, json2);\n\tcase JSON_REAL:\n\t\treturn json_real_equal(json1, json2);\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\n\n/*** copying ***/\n\njson_t *json_copy(json_t *json)\n{\n\tif (!json)\n\t\treturn NULL;\n\n\tswitch (json_typeof(json)) {\n\tcase JSON_OBJECT:\n\t\treturn json_object_copy(json);\n\tcase JSON_ARRAY:\n\t\treturn json_array_copy(json);\n\tcase JSON_STRING:\n\t\treturn json_string_copy(json);\n\tcase JSON_INTEGER:\n\t\treturn json_integer_copy(json);\n\tcase JSON_REAL:\n\t\treturn json_real_copy(json);\n\tcase JSON_TRUE:\n\tcase JSON_FALSE:\n\tcase JSON_NULL:\n\t\treturn json;\n\tdefault:\n\t\treturn NULL;\n\t}\n\n\treturn NULL;\n}\n\njson_t *json_deep_copy(const json_t *json)\n{\n\tif (!json)\n\t\treturn NULL;\n\n\tswitch (json_typeof(json)) {\n\tcase JSON_OBJECT:\n\t\treturn json_object_deep_copy(json);\n\tcase JSON_ARRAY:\n\t\treturn json_array_deep_copy(json);\n\t\t/* for the rest of the types, deep copying doesn't differ from\n\t\t   shallow copying */\n\tcase JSON_STRING:\n\t\treturn json_string_copy(json);\n\tcase JSON_INTEGER:\n\t\treturn json_integer_copy(json);\n\tcase JSON_REAL:\n\t\treturn json_real_copy(json);\n\tcase JSON_TRUE:\n\tcase JSON_FALSE:\n\tcase JSON_NULL:\n\t\treturn (json_t *)json;\n\tdefault:\n\t\treturn NULL;\n\t}\n\n\treturn NULL;\n}\n"
  },
  {
    "path": "merger/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (merger)\n\ninclude_directories (${CMAKE_SOURCE_DIR}/instrumentation/)\n\nset(MERGER_SRC ${PROJECT_SOURCE_DIR}/merger.c)\nsource_group(\"Executable Sources\" FILES ${MERGER_SRC})\nadd_executable(merger ${MERGER_SRC} $<TARGET_OBJECTS:instrumentation>)\ntarget_compile_definitions(merger PUBLIC INSTRUMENTATION_NO_IMPORT)\n\ntarget_link_libraries(merger utils)\ntarget_link_libraries(merger jansson)\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(merger Shlwapi)\nendif (WIN32)\n"
  },
  {
    "path": "merger/merger.c",
    "content": "//This program merges multiple sets of instrumentation data into one\n//instrumentation state.  The resulting instrumentation state will include the\n//tracked coverage from all of the input instrumentation states. This allows\n//multiple instances of the fuzzer to share instrumentation data, and ignore\n//paths that the other fuzzer found.\n\n#include <instrumentation.h>\n#include <instrumentation_factory.h>\n#include <utils.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n\n/**\n* This function prints out the usage information for the merger and the available instrumentations.\n* @param program_name - the name of the program currently being run (for use in the outputted message)\n*/\nvoid usage(char * program_name)\n{\n\tchar * help_text;\n\tprintf(\n\t\t\"Usage: %s instrumentation_name [-i instrumentation_options] output_file input_file [input_file ...]\\n\"\n\t\t\"\\n\"\n\t\t\"Options:\\n\"\n\t\t\"\\t -i instrumentation_options   Set the options for the instrumentation\\n\"\n\t\t\"\\t output_file                  Set the file containing that the combined instrumentation state should dump to\\n\"\n\t\t\"\\t input_file                   Set the file containing that the instrumentation state should load from\\n\"\n\t\t\"\\n\",\n\t\tprogram_name\n\t);\n\n#define PRINT_HELP(x, y) \\\n\tx = y;               \\\n\tif(x) {              \\\n\t\tputs(x);         \\\n\t\tfree(x);         \\\n\t}\n\n\tPRINT_HELP(help_text, instrumentation_help());\n\texit(1);\n}\n\n\nint main(int argc, char ** argv)\n{\n\tinstrumentation_t * instrumentation;\n\tint instrumentation_length, argv_index;\n\tchar *instrumentation_options = NULL, *instrumentation_state_string = NULL, *instrumentation_state_dump_file = NULL;\n\tvoid * instrumentation_state = NULL, *new_instrumentation_state = NULL, *merged_instrumentation_state = NULL;\n\n\tif (argc < 3)\n\t\tusage(argv[0]);\n\n\tif (setup_logging(NULL))\n\t{\n\t\tprintf(\"Failed setting up logging, exitting\\n\");\n\t\treturn 1;\n\t}\n\n\tinstrumentation = instrumentation_factory(argv[1]);\n\tif (!instrumentation)\n\t\tFATAL_MSG(\"Unknown instrumentation (%s)\", argv[1]);\n\n\tif (strcmp(\"-i\", argv[2]))\n\t{\n\t\targv_index = 3;\n\t\tinstrumentation_state_dump_file = argv[2];\n\t}\n\telse\n\t{\n\t\tinstrumentation_options = argv[3];\n\t\targv_index = 5;\n\t\tinstrumentation_state_dump_file = argv[4];\n\t}\n\n\n\tfor (; argv_index < argc; argv_index++)\n\t{\n\t\t//Load the instrumentation state from disk\n\t\tinstrumentation_length = read_file(argv[argv_index], &instrumentation_state_string);\n\t\tif (instrumentation_length <= 0)\n\t\t\tFATAL_MSG(\"Could not read instrumentation file or empty instrumentation file: %s\", argv[argv_index]);\n\t\tnew_instrumentation_state = instrumentation->create(instrumentation_options, instrumentation_state_string);\n\t\tif (!instrumentation)\n\t\t\tFATAL_MSG(\"Bad options/state for instrumentation file %s\", argv[argv_index]);\n\t\tfree(instrumentation_state_string);\n\n\t\tif (!instrumentation_state)\n\t\t\tinstrumentation_state = new_instrumentation_state;\n\t\telse\n\t\t{\n\t\t\tmerged_instrumentation_state = instrumentation->merge(instrumentation_state, new_instrumentation_state);\n\t\t\tinstrumentation->cleanup(instrumentation_state);\n\t\t\tinstrumentation->cleanup(new_instrumentation_state);\n\t\t\tinstrumentation_state = merged_instrumentation_state;\n\t\t}\n\t}\n\n\tinstrumentation_state_string = instrumentation->get_state(instrumentation_state);\n\tif (instrumentation_state_string)\n\t{\n\t\twrite_buffer_to_file(instrumentation_state_dump_file, instrumentation_state_string, strlen(instrumentation_state_string));\n\t\tinstrumentation->free_state(instrumentation_state_string);\n\t}\n\telse\n\t\tWARNING_MSG(\"Couldn't dump instrumentation state to file %s\", instrumentation_state_dump_file);\n\n\t//Cleanup the objects and exit\n\tinstrumentation->cleanup(instrumentation_state);\n\tfree(instrumentation);\n\treturn 0;\n}\n"
  },
  {
    "path": "mutators/APLv2",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "mutators/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (mutators_repo)\n\nSET ( BUILD_DIRECTORY ${CMAKE_SOURCE_DIR}/build )\n\nif (WIN32)\n\tSET( WINDOWS_BUILD_PATH ${BUILD_DIRECTORY}/${CMAKE_C_COMPILER_ARCHITECTURE_ID}/${CMAKE_BUILD_TYPE} )\n\tSET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${WINDOWS_BUILD_PATH}/mutators/ )\n\tSET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${WINDOWS_BUILD_PATH}/mutators/ )\n\tSET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${WINDOWS_BUILD_PATH}/mutators/ )\n\tLINK_DIRECTORIES(${WINDOWS_BUILD_PATH}/killerbeez/)\n\tadd_definitions(-D_CRT_SECURE_NO_WARNINGS -D_DEPRECATION_DISABLE -D_CRT_NONSTDC_NO_DEPRECATE -DUTILS_NO_IMPORT -DJANSSON_NO_IMPORT)\nelse (WIN32)\n\tSET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/mutators/ )\n\tSET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/mutators/ )\n\tSET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/mutators/ )\n\tLINK_DIRECTORIES(${CMAKE_BINARY_DIR}/killerbeez/)\nendif (WIN32)\n\ninclude_directories (${CMAKE_SOURCE_DIR}/jansson/)\ninclude_directories (${CMAKE_SOURCE_DIR}/utils/)\n\n# The general mutator library with the common functionality\nadd_subdirectory(mutators)\n\n# The various mutators\nadd_subdirectory(afl_mutator)\nadd_subdirectory(bit_flip_mutator)\nadd_subdirectory(arithmetic_mutator)\nadd_subdirectory(dictionary_mutator)\nadd_subdirectory(havoc_mutator)\nadd_subdirectory(honggfuzz_mutator)\nadd_subdirectory(interesting_value_mutator)\nadd_subdirectory(multipart_mutator)\nadd_subdirectory(ni_mutator)\nadd_subdirectory(nop_mutator)\nadd_subdirectory(splice_mutator)\nadd_subdirectory(zzuf_mutator)\n\nif (NOT APPLE)\nadd_subdirectory(radamsa_mutator)\nendif (NOT APPLE)\n\n# The mutator test program, uncomment to build\n#add_subdirectory(mutator_tester)\n\n"
  },
  {
    "path": "mutators/LICENSE",
    "content": "Unless otherwise marked, this license applies to all code in this repository.\n\nUniversity of Illinois/NCSA Open Source License (UIUC license)\nCopyright (c) 2018 Grimm. All rights reserved.\n\n\nDeveloped by: Software Security Group\nGrimm\nhttps://grimm-co.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal with\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\n- Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimers.\n- Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimers in the documentation\n  and/or other materials provided with the distribution.\n- Neither the names of Grimm, nor the names of its contributors may be used to\n  endorse or promote products derived from this Software without specific prior\n  written permission.\n\n\nSOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\nPARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.\n"
  },
  {
    "path": "mutators/afl_mutator/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (afl_mutator)\n\ninclude_directories (${PROJECT_SOURCE_DIR}/../mutators/)\n\nset(AFL_SRC ${PROJECT_SOURCE_DIR}/afl_mutator.c)\nsource_group(\"Library Sources\" FILES ${AFL_SRC})\n\nadd_library(afl_mutator SHARED ${AFL_SRC}\n  $<TARGET_OBJECTS:mutators_object> $<TARGET_OBJECTS:jansson_object>)\ntarget_link_libraries(afl_mutator utils)\ntarget_compile_definitions(afl_mutator PUBLIC AFL_MUTATOR_EXPORTS)\ntarget_compile_definitions(afl_mutator PUBLIC MUTATORS_NO_IMPORT)\ntarget_compile_definitions(afl_mutator PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(afl_mutator PUBLIC JANSSON_NO_IMPORT)\n\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(afl_mutator Shlwapi)\nendif (WIN32)\n"
  },
  {
    "path": "mutators/afl_mutator/afl_mutator.c",
    "content": "#include <afl_config.h>\n#include <afl_helpers.h>\n#include <afl_types.h>\n#include <mutators.h>\n#include \"afl_mutator.h\"\n\n#include <global_types.h>\n#include <jansson_helper.h>\n#include <utils.h>\n\n#include <string.h>\n\nstruct afl_state\n{\n\tint skip_deterministic;\n\n\tchar * input;\n\tsize_t input_length;\n\tint iteration;\n\n\tmutate_info_t info;\n};\ntypedef struct afl_state afl_state_t;\n\nmutator_t afl_mutator = {\n\tFUNCNAME(create),\n\tFUNCNAME(cleanup),\n\tFUNCNAME(mutate),\n\tFUNCNAME(mutate_extended),\n\tFUNCNAME(get_state),\n\tafl_free_state,\n\tFUNCNAME(set_state),\n\tFUNCNAME(get_current_iteration),\n\tafl_get_total_iteration_count,\n\tFUNCNAME(get_input_info),\n\tFUNCNAME(set_input),\n\tFUNCNAME(help)\n};\n\nstatic int afl_havoc(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tif (info->stage_cur > MAX(HAVOC_MIN, (info->queue_cycle > 1 ? HAVOC_CYCLES : HAVOC_CYCLES_INIT) * (info->perf_score / info->havoc_div) / 100))\n\t\treturn MUTATOR_DONE;\n\treturn havoc(info, buf);\n}\n\nstatic int afl_splice(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tif (info->stage_cur > MAX(HAVOC_MIN, SPLICE_HAVOC * (info->perf_score / info->havoc_div) / 100))\n\t\treturn MUTATOR_DONE;\n\treturn splice_buffers(info, buf);\n}\n\nstatic int(*const mutate_funcs[])(mutate_info_t *, mutate_buffer_t *) = {\n\tsingle_walking_bit,\n\ttwo_walking_bit,\n\tfour_walking_bit,\n\twalking_byte,\n\ttwo_walking_byte,\n\tfour_walking_byte,\n\tone_byte_arithmetics,\n\ttwo_byte_arithmetics,\n\tfour_byte_arithmetics,\n\tinteresting_one_byte,\n\tinteresting_two_byte,\n\tinteresting_four_byte,\n\tdictionary_overwrite,\n\tdictionary_insert,\n\tafl_havoc,\n\tafl_splice,\n};\n\n/* Fuzzing stages */\nenum {\n\t/* 00 */ STAGE_FLIP1,\n\t/* 01 */ STAGE_FLIP2,\n\t/* 02 */ STAGE_FLIP4,\n\t/* 03 */ STAGE_FLIP8,\n\t/* 04 */ STAGE_FLIP16,\n\t/* 05 */ STAGE_FLIP32,\n\t/* 06 */ STAGE_ARITH8,\n\t/* 07 */ STAGE_ARITH16,\n\t/* 08 */ STAGE_ARITH32,\n\t/* 09 */ STAGE_INTEREST8,\n\t/* 10 */ STAGE_INTEREST16,\n\t/* 11 */ STAGE_INTEREST32,\n\t/* 12 */ STAGE_EXTRAS_UO,\n\t/* 13 */ STAGE_EXTRAS_UI,\n\t/* 14 */ STAGE_HAVOC,\n\t/* 15 */ STAGE_SPLICE,\n};\n\n\n////////////////////////////////////////////////////////////////////////////////////////////\n//// API methods ///////////////////////////////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////////////////////////\n\n#ifndef ALL_MUTATORS_IN_ONE\n\n/**\n * This function fills in m with all of the function pointers for this mutator.\n * @param m - a pointer to a mutator_t structure\n * @return none\n */\nAFL_MUTATOR_API void init(mutator_t * m)\n{\n\tmemcpy(m, &afl_mutator, sizeof(mutator_t));\n}\n\n#endif\n\n/**\n * This function creates and initializes a afl_state_t object based on the passed in JSON options.\n * @param options - a JSON of options for the afl mutator\n * @return the newly created afl_state_t object or NULL on failure\n */\nstatic afl_state_t * setup_options(char * options)\n{\n\tafl_state_t * state;\n\tstate = (afl_state_t *)malloc(sizeof(afl_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(afl_state_t));\n\n\t//Setup defaults\n\tif (reset_mutate_info(&state->info)) {\n\t\tfree(state);\n\t\treturn NULL;\n\t}\n\tstate->info.should_skip_previous = 1;\n\tif (!options || !strlen(options))\n\t\treturn state;\n\n\tPARSE_MUTATE_INFO_OPTIONS(state, options, FUNCNAME(cleanup), 0, 0);\n\tPARSE_OPTION_INT(state, options, skip_deterministic, \"skip_deterministic\", FUNCNAME(cleanup));\n\tif (state->skip_deterministic)\n\t\tstate->info.stage = STAGE_HAVOC;\n\treturn state;\n}\n\n/**\n * This function will allocate and initialize the mutator state used in the other Mutator API\n * functions.  \n * @param options - a json string that contains the mutator specific string of options.\n * @param state - Optionally, used to load a previously dumped state (with the get_state()\n * function), that defines the current iteration of the mutator.\n * @param input - used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size of the input buffer\n * @return a mutator specific structure or NULL on failure.\n */\nAFL_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length)\n{\n\tGENERIC_MUTATOR_CREATE(afl_state_t, setup_options, FUNCNAME(cleanup));\n}\n\n/**\n * This function will release any resources that the mutator has open \n * and free the mutator state structure.\n * @param mutator_state - a mutator specific structure previously created by \n * the create function.  This structure will be freed and should not be referenced afterwards.\n */\nAFL_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state)\n{\n\tcleanup_mutate_info(&((afl_state_t *)mutator_state)->info);\n\tGENERIC_MUTATOR_CLEANUP(afl_state_t)\n}\n\nstatic int mutate_inner(void * mutator_state, char * buffer, size_t buffer_length, int is_thread_safe)\n{\n\tafl_state_t * state = (afl_state_t *)mutator_state;\n\tmutate_buffer_t buf;\n\tint ret;\n\tif (buffer_length < state->input_length)\n\t\treturn -1;\n\n\tbuf.buffer = (uint8_t *)buffer;\n\tbuf.length = MIN(buffer_length, state->input_length);\n\tbuf.max_length = buffer_length;\n\tmemcpy(buf.buffer, state->input, buf.length);\n\n\tif(is_thread_safe && take_mutex(state->info.mutate_mutex))\n\t\treturn -1;\n\tstate->iteration++;\n\twhile (1) {\n\t\tret = mutate_one(&state->info, &buf, mutate_funcs, ARRAY_SIZE(mutate_funcs));\n\t\tif (ret != MUTATOR_DONE)\n\t\t\tbreak;\n\n\t\t//We've finished this cycle, reset back to havoc and continue\n\t\tstate->info.stage = STAGE_HAVOC;\n\t\tstate->skip_deterministic = 1;\n\t\tstate->info.queue_cycle++;\n\t}\n\tif (is_thread_safe && release_mutex(state->info.mutate_mutex))\n\t\treturn -1;\n\n\treturn ret;\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nAFL_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length)\n{\n\treturn mutate_inner(mutator_state, buffer, buffer_length, 0);\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * This function also accepts a set of flags which instruct it how to mutate the input.  See global_types.h\n * for the list of available flags.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @param flags - A set of mutate flags that modify how this mutator mutates the input.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nAFL_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags)\n{\n\tSINGLE_INPUT_MUTATE_EXTENDED(afl_state_t, state->info.mutate_mutex);\n}\n\n/**\n * This function will return the state of the mutator.  The returned value can be used to restart the\n * mutator at a later time, by passing it to the create or set_state function.  It is the caller's\n * responsibility to free the memory allocated here by calling the free_state function.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return - a buffer that defines the current state of the mutator.\n */\nAFL_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state)\n{\n\tafl_state_t * state = (afl_state_t *)mutator_state;\n\tjson_t *state_obj, *temp;\n\tchar * ret;\n\n\tstate_obj = json_object();\n\tADD_INT(temp, state->iteration, state_obj, \"iteration\");\n\tADD_INT(temp, state->skip_deterministic, state_obj, \"skip_deterministic\");\n\tif (!add_mutate_info_to_json(state_obj, &state->info))\n\t\treturn NULL;\n\tret = json_dumps(state_obj, 0);\n\tjson_decref(state_obj);\n\treturn ret;\n}\n\n/**\n * This function will set the current state of the mutator.\n * This can be used to restart a mutator once from a previous run.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param state - a previously dumped state buffer obtained by the get_state function.\n * @return 0 on success or non-zero on failure\n */\nAFL_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state)\n{\n\tafl_state_t * current_state = (afl_state_t *)mutator_state;\n\tint result, temp_int;\n\tif (!state)\n\t\treturn 1;\n\tGET_INT(temp_int, state, current_state->iteration, \"iteration\", result);\n\tGET_INT(temp_int, state, current_state->skip_deterministic, \"skip_deterministic\", result);\n\tif (get_mutate_info_from_json(state, &current_state->info))\n\t\treturn 1;\n\treturn 0;\n}\n\n/**\n * This function will return the current iteration count of the mutator, i.e.\n * how many mutations have been generated with it.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return value - the number of previously generated mutations\n */\nAFL_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state)\n{\n\tGENERIC_MUTATOR_GET_ITERATION(afl_state_t);\n}\n\n/**\n * This function will set the mutator's input to something new.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param new_input - The new input used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size in bytes of the input buffer.\n * @return 0 on success and -1 on failure\n */\nAFL_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length)\n{\n\tGENERIC_MUTATOR_SET_INPUT(afl_state_t);\n}\n\n/**\n * Obtains information about the inputs that were given to the mutator when it was created\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param num_inputs - a pointer to an integer used to return the number of inputs given to this mutator\n * when it was created.  This parameter is optional and can be NULL, if this information is not needed\n * @param input_sizes - a pointer to a size_t array used to return the sizes of the inputs given to this\n * mutator when it was created. This parameter is optional and can be NULL, if this information is not needed.\n */\nAFL_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes)\n{\n\tSINGLE_INPUT_GET_INFO(afl_state_t);\n}\n\n/**\n * This function sets a help message for the mutator.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nAFL_MUTATOR_API int FUNCNAME(help)(char ** help_str)\n{\n\tGENERIC_MUTATOR_HELP(\n\"afl - afl-based mutator\\n\"\n\"Options:\\n\"\n\"  dictionary            A file or directory containing dictionary to use while\\n\"\n\"                          mangling input\\n\"\n\"  havoc_div             A divisor for determining the number of rounds that\\n\"\n\"                          the havoc stage should run (typically 1, 2, 5, or 10)\\n\"\n\"  perf_score            A performance score used to determine how long to run\\n\"\n\"                          the havoc and splice stages.  Typically 100, higher\\n\"\n\"                          results in a larger number of mutations in these\\n\"\n\"                          stages before moving on.\\n\"\n\"  queue_cycle           The queue round counter.  Used in determining how to\\n\"\n\"                          mutate input.  Generally this shouldn't need to be set\\n\"\n\"  random_state0         The first half of the seed to afl's random number\\n\"\n\"                          generator\\n\"\n\"  random_state1         The second half of the seed to afl's random number\\n\"\n\"                          generator\\n\"\n\"  skip_deterministic    Instruct AFL to skip the deterministic mutations\\n\"\n\"  splice_filenames      An array of files to use during afl's splice stage,\\n\"\n\"                          for mixing with the input\\n\"\n\"\\n\"\n\t);\n}\n"
  },
  {
    "path": "mutators/afl_mutator/afl_mutator.h",
    "content": "#pragma once\n\n#include <global_types.h>\n#include <mutators.h>\n\n#ifdef _WIN32\n#ifdef AFL_MUTATOR_EXPORTS\n#define AFL_MUTATOR_API __declspec(dllexport)\n#else\n#define AFL_MUTATOR_API __declspec(dllimport)\n#endif\n#else //_WIN32\n#define AFL_MUTATOR_API\n#endif\n\n#define MUTATOR_NAME \"afl\"\n\nAFL_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length);\nAFL_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state);\nAFL_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length);\nAFL_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags);\nAFL_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state);\n#define afl_free_state default_free_state\nAFL_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state);\nAFL_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state);\n#define afl_get_total_iteration_count return_unknown_or_infinite_total_iterations\nAFL_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes);\nAFL_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length);\nAFL_MUTATOR_API int FUNCNAME(help)(char **help_str);\n\n#ifndef ALL_MUTATORS_IN_ONE\nAFL_MUTATOR_API void init(mutator_t * m);\n#endif\n"
  },
  {
    "path": "mutators/arithmetic_mutator/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (arithmetic_mutator)\n\ninclude_directories (${PROJECT_SOURCE_DIR}/../mutators/)\n\nset(ARITHMETIC_SRC ${PROJECT_SOURCE_DIR}/arithmetic_mutator.c)\nsource_group(\"Library Sources\" FILES ${ARITHMETIC_SRC})\n\nadd_library(arithmetic_mutator SHARED ${ARITHMETIC_SRC}\n  $<TARGET_OBJECTS:mutators_object> $<TARGET_OBJECTS:jansson_object>)\ntarget_link_libraries(arithmetic_mutator utils)\ntarget_compile_definitions(arithmetic_mutator PUBLIC ARITHMETIC_MUTATOR_EXPORTS)\ntarget_compile_definitions(arithmetic_mutator PUBLIC MUTATORS_NO_IMPORT)\ntarget_compile_definitions(arithmetic_mutator PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(arithmetic_mutator PUBLIC JANSSON_NO_IMPORT)\n\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(arithmetic_mutator Shlwapi)\nendif (WIN32)\n"
  },
  {
    "path": "mutators/arithmetic_mutator/arithmetic_mutator.c",
    "content": "#include \"arithmetic_mutator.h\"\n#include <mutators.h>\n#include <afl_helpers.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <utils.h>\n#include <jansson.h>\n#include <jansson_helper.h>\n\nstruct arithmetic_state\n{\n\tuint64_t num_bytes;\n\n\tchar * input;\n\tsize_t input_length;\n\tint iteration;\n\n\tmutate_info_t info;\n};\ntypedef struct arithmetic_state arithmetic_state_t;\n\nstatic int(*const mutate_funcs[])(mutate_info_t *, mutate_buffer_t *) = {\n\tone_byte_arithmetics,\n\ttwo_byte_arithmetics,\n\tfour_byte_arithmetics,\n};\n\nmutator_t arithmetic_mutator = {\n\tFUNCNAME(create),\n\tFUNCNAME(cleanup),\n\tFUNCNAME(mutate),\n\tFUNCNAME(mutate_extended),\n\tFUNCNAME(get_state),\n\tarithmetic_free_state,\n\tFUNCNAME(set_state),\n\tFUNCNAME(get_current_iteration),\n\tarithmetic_get_total_iteration_count,\n\tFUNCNAME(get_input_info),\n\tFUNCNAME(set_input),\n\tFUNCNAME(help)\n};\n\n/**\n * This function fills in m with all of the function pointers for this mutator.\n * @param m - a pointer to a mutator_t structure\n * @return none\n */\n#ifndef ALL_MUTATORS_IN_ONE\nARITHMETIC_MUTATOR_API void init(mutator_t * m)\n{\n\tmemcpy(m, &arithmetic_mutator, sizeof(mutator_t));\n}\n#endif\n\nstatic arithmetic_state_t * setup_options(char * options)\n{\n\tarithmetic_state_t * state;\n\tint bytes_per_stage[] = { 1, 2, 4 };\n\tint i;\n\n\tstate = (arithmetic_state_t *)malloc(sizeof(arithmetic_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(arithmetic_state_t));\n\n\t//Setup defaults\n\tif (reset_mutate_info(&state->info)) {\n\t\tfree(state);\n\t\treturn NULL;\n\t}\n\n\tif (!options || !strlen(options))\n\t\treturn state;\n\n\tPARSE_MUTATE_INFO_OPTIONS(state, options, FUNCNAME(cleanup), 0, 0);\n\tPARSE_OPTION_INT(state, options, num_bytes, \"num_bytes\", FUNCNAME(cleanup));\n\n\tif (state->num_bytes) {\n\t\tstate->info.stage = -1;\n\t\tfor (i = 0; i < ARRAY_SIZE(bytes_per_stage) && state->info.stage < 0; i++)\n\t\t{\n\t\t\tif (bytes_per_stage[i] == state->num_bytes)\n\t\t\t\tstate->info.stage = i;\n\t\t}\n\t\tif (state->info.stage < 0)\n\t\t{\n\t\t\tFUNCNAME(cleanup)(state);\n\t\t\treturn NULL;\n\t\t}\n\t\tstate->info.one_stage_only = 1;\n\t}\n\treturn state;\n}\n\n\n/**\n * This function will allocate and initialize the mutator state used in the other Mutator API\n * functions.  \n * @param options - a json string that contains the mutator specific string of options.\n * @param state - Optionally, used to load a previously dumped state (with the get_state()\n * function), that defines the current iteration of the mutator.\n * @param input - used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size of the input buffer\n * @return a mutator specific structure or NULL on failure.\n */\nARITHMETIC_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length)\n{\n\tGENERIC_MUTATOR_CREATE(arithmetic_state_t, setup_options, FUNCNAME(cleanup));\n}\n\n/**\n * This function will release any resources that the mutator has open \n * and free the mutator state structure.\n * @param mutator_state - a mutator specific structure previously created by \n * the create function.  This structure will be freed and should not be referenced afterwards.\n */\nARITHMETIC_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state)\n{\n\tcleanup_mutate_info(&((arithmetic_state_t *)mutator_state)->info);\n\tGENERIC_MUTATOR_CLEANUP(arithmetic_state_t)\n}\n\nstatic int mutate_inner(void * mutator_state, char * buffer, size_t buffer_length, int is_thread_safe)\n{\n\tarithmetic_state_t * state = (arithmetic_state_t *)mutator_state;\n\tmutate_buffer_t buf;\n\tint ret;\n\tif (buffer_length < state->input_length)\n\t\treturn -1;\n\n\tbuf.buffer = (uint8_t *)buffer;\n\tbuf.length = MIN(buffer_length, state->input_length);\n\tbuf.max_length = buffer_length;\n\tmemcpy(buf.buffer, state->input, buf.length);\n\n\tif(is_thread_safe && take_mutex(state->info.mutate_mutex))\n\t\treturn -1;\n\tstate->iteration++;\n\tret = mutate_one(&state->info, &buf, mutate_funcs, ARRAY_SIZE(mutate_funcs));\n\tif (is_thread_safe && release_mutex(state->info.mutate_mutex))\n\t\treturn -1;\n\treturn ret;\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nARITHMETIC_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length)\n{\n\treturn mutate_inner(mutator_state, buffer, buffer_length, 0);\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * This function also accepts a set of flags which instruct it how to mutate the input.  See global_types.h\n * for the list of available flags.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @param flags - A set of mutate flags that modify how this mutator mutates the input.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nARITHMETIC_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags)\n{\n\tSINGLE_INPUT_MUTATE_EXTENDED(arithmetic_state_t, state->info.mutate_mutex);\n}\n\n/**\n * This function will return the state of the mutator.  The returned value can be used to restart the\n * mutator at a later time, by passing it to the create or set_state function.  It is the caller's\n * responsibility to free the memory allocated here by calling the free_state function.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return - a buffer that defines the current state of the mutator.\n */\nARITHMETIC_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state)\n{\n\tarithmetic_state_t * state = (arithmetic_state_t *)mutator_state;\n\tjson_t *state_obj, *temp;\n\tchar * ret;\n\n\tstate_obj = json_object();\n\tADD_INT(temp, state->iteration, state_obj, \"iteration\");\n\tif (!add_mutate_info_to_json(state_obj, &state->info))\n\t\treturn NULL;\n\n\tret = json_dumps(state_obj, 0);\n\tjson_decref(state_obj);\n\treturn ret;\n}\n\n/**\n * This function will set the current state of the mutator.\n * This can be used to restart a mutator once from a previous run.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param state - a previously dumped state buffer obtained by the get_state function.\n * @return 0 on success or non-zero on failure\n */\nARITHMETIC_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state)\n{\n\tarithmetic_state_t * current_state = (arithmetic_state_t *)mutator_state;\n\tint result, temp_int;\n\tif (!state)\n\t\treturn 1;\n\tGET_INT(temp_int, state, current_state->iteration, \"iteration\", result);\n\tif (get_mutate_info_from_json(state, &current_state->info))\n\t\treturn 1;\n\treturn 0;\n}\n\n/**\n * This function will return the current iteration count of the mutator, i.e.\n * how many mutations have been generated with it.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return value - the number of previously generated mutations\n */\nARITHMETIC_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state)\n{\n\tGENERIC_MUTATOR_GET_ITERATION(arithmetic_state_t);\n}\n\n/**\n * This function will set the mutator's input to something new.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param new_input - The new input used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size in bytes of the input buffer.\n * @return 0 on success and -1 on failure\n */\nARITHMETIC_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length)\n{\n\tGENERIC_MUTATOR_SET_INPUT(arithmetic_state_t);\n}\n\n/**\n * Obtains information about the inputs that were given to the mutator when it was created\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param num_inputs - a pointer to an integer used to return the number of inputs given to this mutator\n * when it was created.  This parameter is optional and can be NULL, if this information is not needed\n * @param input_sizes - a pointer to a size_t array used to return the sizes of the inputs given to this\n * mutator when it was created. This parameter is optional and can be NULL, if this information is not needed.\n */\nARITHMETIC_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes)\n{\n\tSINGLE_INPUT_GET_INFO(arithmetic_state_t);\n}\n\n/**\n * This function sets a help message for the mutator.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nARITHMETIC_MUTATOR_API int FUNCNAME(help)(char **help_str)\n{\n\tGENERIC_MUTATOR_HELP(\n\"arithmetic - afl-based arithmetic mutator\\n\"\n\"Options:\\n\"\n\"  num_bytes             The number of bytes to operate on; either 1, 2, or 4.\\n\"\n\"                          The default option is to do all three of the\\n\"\n\"                          options, one after another.\\n\"\n\"  skip_previous_stages  Whether the mutation outputs should skip any output\\n\"\n\"                          that would match the output of the bit_flip or\\n\"\n\"                          previous rounds of the arithmetic mutator. Useful\\n\"\n\"                          when using multiple mutators\\n\"\n\"\\n\"\n\t);\n}\n"
  },
  {
    "path": "mutators/arithmetic_mutator/arithmetic_mutator.h",
    "content": "#pragma once\n\n#include <global_types.h>\n#include <mutators.h>\n\n#ifdef _WIN32\n#ifdef ARITHMETIC_MUTATOR_EXPORTS\n#define ARITHMETIC_MUTATOR_API __declspec(dllexport)\n#else\n#define ARITHMETIC_MUTATOR_API __declspec(dllimport)\n#endif\n#else //_WIN32\n#define ARITHMETIC_MUTATOR_API\n#endif\n\n#define MUTATOR_NAME \"arithmetic\"\n\nARITHMETIC_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length);\nARITHMETIC_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state);\nARITHMETIC_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length);\nARITHMETIC_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags);\nARITHMETIC_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state);\n#define arithmetic_free_state default_free_state\nARITHMETIC_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state);\nARITHMETIC_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state);\n#define arithmetic_get_total_iteration_count return_unknown_or_infinite_total_iterations\nARITHMETIC_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes);\nARITHMETIC_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length);\nARITHMETIC_MUTATOR_API int FUNCNAME(help)(char **help_str);\n\n#ifndef ALL_MUTATORS_IN_ONE\nARITHMETIC_MUTATOR_API void init(mutator_t * m);\n#endif\n"
  },
  {
    "path": "mutators/bit_flip_mutator/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (bit_flip_mutator)\n\ninclude_directories (${PROJECT_SOURCE_DIR}/../mutators/)\n\nset(BIT_FLIP_SRC ${PROJECT_SOURCE_DIR}/bit_flip_mutator.c)\nsource_group(\"Library Sources\" FILES ${BIT_FLIP_SRC})\n\nadd_library(bit_flip_mutator SHARED ${BIT_FLIP_SRC}\n  $<TARGET_OBJECTS:mutators_object> $<TARGET_OBJECTS:jansson_object>)\ntarget_link_libraries(bit_flip_mutator utils)\ntarget_compile_definitions(bit_flip_mutator PUBLIC BF_MUTATOR_EXPORTS)\ntarget_compile_definitions(bit_flip_mutator PUBLIC MUTATORS_NO_IMPORT)\ntarget_compile_definitions(bit_flip_mutator PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(bit_flip_mutator PUBLIC JANSSON_NO_IMPORT)\n\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(bit_flip_mutator Shlwapi)\nendif (WIN32)\n"
  },
  {
    "path": "mutators/bit_flip_mutator/bit_flip_mutator.c",
    "content": "#include \"bit_flip_mutator.h\"\n#include <mutators.h>\n#include <afl_helpers.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <utils.h>\n#include <jansson.h>\n#include <jansson_helper.h>\n\nstruct bit_flip_state\n{\n\tuint64_t num_bits;\n\n\tchar * input;\n\tsize_t input_length;\n\tint iteration;\n\n\tmutate_info_t info;\n};\ntypedef struct bit_flip_state bit_flip_state_t;\n\nstatic int(*const mutate_funcs[])(mutate_info_t *, mutate_buffer_t *) = {\n\tsingle_walking_bit,\n\ttwo_walking_bit,\n\tfour_walking_bit,\n\twalking_byte,\n\ttwo_walking_byte,\n\tfour_walking_byte,\n};\n\nmutator_t arithmetic_mutator = {\n\tFUNCNAME(create),\n\tFUNCNAME(cleanup),\n\tFUNCNAME(mutate),\n\tFUNCNAME(mutate_extended),\n\tFUNCNAME(get_state),\n\tbit_flip_free_state,\n\tFUNCNAME(set_state),\n\tFUNCNAME(get_current_iteration),\n\tFUNCNAME(get_total_iteration_count),\n\tFUNCNAME(get_input_info),\n\tFUNCNAME(set_input),\n\tFUNCNAME(help)\n};\n\n/**\n * This function fills in m with all of the function pointers for this mutator.\n * @param m - a pointer to a mutator_t structure\n * @return none\n */\n#ifndef ALL_MUTATORS_IN_ONE\nBF_MUTATOR_API void init(mutator_t * m)\n{\n\tmemcpy(m, &arithmetic_mutator, sizeof(mutator_t));\n}\n#endif\n\nstatic bit_flip_state_t * setup_options(char * options)\n{\n\tbit_flip_state_t * state;\n\tint bits_per_stage[] = { 1, 2, 4, 8, 16, 32 };\n\tint i;\n\n\tstate = (bit_flip_state_t *)malloc(sizeof(bit_flip_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(bit_flip_state_t));\n\n\t//Setup defaults\n\tif (reset_mutate_info(&state->info)) {\n\t\tfree(state);\n\t\treturn NULL;\n\t}\n\n\tif (!options || !strlen(options))\n\t\treturn state;\n\n\tPARSE_MUTATE_INFO_OPTIONS(state, options, FUNCNAME(cleanup), 0, 0);\n\tPARSE_OPTION_INT(state, options, num_bits, \"num_bits\", FUNCNAME(cleanup));\n\n\tif (state->num_bits) {\n\t\tstate->info.stage = -1;\n\t\tfor (i = 0; i < ARRAY_SIZE(bits_per_stage) && state->info.stage < 0; i++)\n\t\t{\n\t\t\tif (bits_per_stage[i] == state->num_bits)\n\t\t\t\tstate->info.stage = i;\n\t\t}\n\t\tif (state->info.stage < 0)\n\t\t{\n\t\t\tFUNCNAME(cleanup)(state);\n\t\t\treturn NULL;\n\t\t}\n\t\tstate->info.one_stage_only = 1;\n\t}\n\treturn state;\n}\n\n\n/**\n * This function will allocate and initialize the mutator state used in the other Mutator API\n * functions.  \n * @param options - a json string that contains the mutator specific string of options.\n * @param state - Optionally, used to load a previously dumped state (with the get_state()\n * function), that defines the current iteration of the mutator.\n * @param input - used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size of the input buffer\n * @return a mutator specific structure or NULL on failure.\n */\nBF_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length)\n{\n\tGENERIC_MUTATOR_CREATE(bit_flip_state_t, setup_options, FUNCNAME(cleanup));\n}\n\n/**\n * This function will release any resources that the mutator has open \n * and free the mutator state structure.\n * @param mutator_state - a mutator specific structure previously created by \n * the create function.  This structure will be freed and should not be referenced afterwards.\n */\nBF_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state)\n{\n\tcleanup_mutate_info(&((bit_flip_state_t *)mutator_state)->info);\n\tGENERIC_MUTATOR_CLEANUP(bit_flip_state_t)\n}\n\nstatic int mutate_inner(void * mutator_state, char * buffer, size_t buffer_length, int is_thread_safe)\n{\n\tbit_flip_state_t * state = (bit_flip_state_t *)mutator_state;\n\tmutate_buffer_t buf;\n\tint ret;\n\tif (buffer_length < state->input_length)\n\t\treturn -1;\n\n\tbuf.buffer = (uint8_t *)buffer;\n\tbuf.length = MIN(buffer_length, state->input_length);\n\tbuf.max_length = buffer_length;\n\tmemcpy(buf.buffer, state->input, buf.length);\n\n\tif(is_thread_safe && take_mutex(state->info.mutate_mutex))\n\t\treturn -1;\n\tstate->iteration++;\n\tret = mutate_one(&state->info, &buf, mutate_funcs, ARRAY_SIZE(mutate_funcs));\n\tif (is_thread_safe && release_mutex(state->info.mutate_mutex))\n\t\treturn -1;\n\treturn ret;\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nBF_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length)\n{\n\treturn mutate_inner(mutator_state, buffer, buffer_length, 0);\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * This function also accepts a set of flags which instruct it how to mutate the input.  See global_types.h\n * for the list of available flags.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @param flags - A set of mutate flags that modify how this mutator mutates the input.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nBF_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags)\n{\n\tSINGLE_INPUT_MUTATE_EXTENDED(bit_flip_state_t, state->info.mutate_mutex);\n}\n\n/**\n * This function will return the state of the mutator.  The returned value can be used to restart the\n * mutator at a later time, by passing it to the create or set_state function.  It is the caller's\n * responsibility to free the memory allocated here by calling the free_state function.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return - a buffer that defines the current state of the mutator.\n */\nBF_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state)\n{\n\tbit_flip_state_t * state = (bit_flip_state_t *)mutator_state;\n\tjson_t *state_obj, *temp;\n\tchar * ret;\n\n\tstate_obj = json_object();\n\tADD_INT(temp, state->iteration, state_obj, \"iteration\");\n\tADD_INT(temp, state->num_bits, state_obj, \"num_bits\");\n\tif (!add_mutate_info_to_json(state_obj, &state->info))\n\t\treturn NULL;\n\n\tret = json_dumps(state_obj, 0);\n\tjson_decref(state_obj);\n\treturn ret;\n}\n\n/**\n * This function will set the current state of the mutator.\n * This can be used to restart a mutator once from a previous run.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param state - a previously dumped state buffer obtained by the get_state function.\n * @return 0 on success or non-zero on failure\n */\nBF_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state)\n{\n\tbit_flip_state_t * current_state = (bit_flip_state_t *)mutator_state;\n\tint result, temp_int;\n\tif (!state)\n\t\treturn 1;\n\tGET_INT(temp_int, state, current_state->iteration, \"iteration\", result);\n\tGET_INT(temp_int, state, current_state->num_bits, \"num_bits\", result);\n\tif (get_mutate_info_from_json(state, &current_state->info))\n\t\treturn 1;\n\treturn 0;\n}\n\n/**\n * This function will return the current iteration count of the mutator, i.e.\n * how many mutations have been generated with it.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return value - the number of previously generated mutations\n */\nBF_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state)\n{\n\tGENERIC_MUTATOR_GET_ITERATION(bit_flip_state_t);\n}\n\n/**\n * Returns the total number of mutations possible with this mutator and the current options.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return the number of possible mutations with this mutator, or -1 if infinite or the number\n * cannot be determined.\n */\nBF_MUTATOR_API int FUNCNAME(get_total_iteration_count)(void * mutator_state)\n{\n\tbit_flip_state_t * state = (bit_flip_state_t *)mutator_state;\n\tif (state->info.one_stage_only)\n\t{\n\t\tif(state->num_bits < 8) //1, 2, 4\n\t\t\treturn (state->input_length << 3) - (state->num_bits - 1);\n\t\treturn state->input_length - ((state->num_bits >> 3) - 1); //8, 16, 32\n\t}\n\t//Add up all rounds\n\treturn ((state->input_length << 3) //1\n\t\t+ ((state->input_length << 3) - 1) //2\n\t\t+ ((state->input_length << 3) - 3) //4\n\t\t+ state->input_length //8\n\t\t+ (state->input_length - 1) //16\n\t\t+ (state->input_length - 3)); //32\n}\n\n/**\n * Obtains information about the inputs that were given to the mutator when it was created\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param num_inputs - a pointer to an integer used to return the number of inputs given to this mutator\n * when it was created.  This parameter is optional and can be NULL, if this information is not needed\n * @param input_sizes - a pointer to a size_t array used to return the sizes of the inputs given to this\n * mutator when it was created. This parameter is optional and can be NULL, if this information is not needed.\n */\nBF_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes)\n{\n\tSINGLE_INPUT_GET_INFO(bit_flip_state_t);\n}\n\n/**\n * This function will set the mutator's input to something new.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param new_input - The new input used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size in bytes of the input buffer.\n * @return 0 on success and -1 on failure\n */\nBF_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length)\n{\n\tGENERIC_MUTATOR_SET_INPUT(bit_flip_state_t);\n}\n\n/**\n * This function sets a help message for the mutator.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nBF_MUTATOR_API int FUNCNAME(help)(char **help_str)\n{\n\tGENERIC_MUTATOR_HELP(\n\"bit_flip - afl-based bit flip mutator\\n\"\n\"Options:\\n\"\n\"  num_bits              The number of bits to operate on; either 1, 2, 4, 8,\\n\"\n\"                          16, or 32. The default option is to do all six of\\n\"\n\"                          the options, one after another.\\n\"\n\"\\n\"\n\t);\n}\n"
  },
  {
    "path": "mutators/bit_flip_mutator/bit_flip_mutator.h",
    "content": "#pragma once\n\n#include <global_types.h>\n#include <mutators.h>\n\n#ifdef _WIN32\n#ifdef BF_MUTATOR_EXPORTS\n#define BF_MUTATOR_API __declspec(dllexport)\n#else\n#define BF_MUTATOR_API __declspec(dllimport)\n#endif\n#else //_WIN32\n#define BF_MUTATOR_API\n#endif\n\n#define MUTATOR_NAME \"bit_flip\"\n\nBF_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length);\nBF_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state);\nBF_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length);\nBF_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags);\nBF_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state);\n#define bit_flip_free_state default_free_state\nBF_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state);\nBF_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state);\nBF_MUTATOR_API int FUNCNAME(get_total_iteration_count)(void * mutator_state);\nBF_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes);\nBF_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length);\nBF_MUTATOR_API int FUNCNAME(help)(char **help_str);\n\n#ifndef ALL_MUTATORS_IN_ONE\nBF_MUTATOR_API void init(mutator_t * m);\n#endif\n"
  },
  {
    "path": "mutators/dictionary_mutator/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (dictionary_mutator)\n\ninclude_directories (${PROJECT_SOURCE_DIR}/../mutators/)\n\nset(DICTIONARY_SRC ${PROJECT_SOURCE_DIR}/dictionary_mutator.c)\nsource_group(\"Library Sources\" FILES ${DICTIONARY_SRC})\n\nadd_library(dictionary_mutator SHARED ${DICTIONARY_SRC}\n  $<TARGET_OBJECTS:mutators_object> $<TARGET_OBJECTS:jansson_object>)\ntarget_link_libraries(dictionary_mutator utils)\ntarget_compile_definitions(dictionary_mutator PUBLIC DICTIONARY_MUTATOR_EXPORTS)\ntarget_compile_definitions(dictionary_mutator PUBLIC MUTATORS_NO_IMPORT)\ntarget_compile_definitions(dictionary_mutator PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(dictionary_mutator PUBLIC JANSSON_NO_IMPORT)\n\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(dictionary_mutator Shlwapi)\nendif (WIN32)\n"
  },
  {
    "path": "mutators/dictionary_mutator/dictionary_mutator.c",
    "content": "#include \"dictionary_mutator.h\"\n#include <mutators.h>\n#include <afl_helpers.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <utils.h>\n#include <jansson.h>\n#include <jansson_helper.h>\n\nstruct dictionary_state\n{\n\tchar * operation;\n\n\tchar * input;\n\tsize_t input_length;\n\tint iteration;\n\n\tmutate_info_t info;\n};\ntypedef struct dictionary_state dictionary_state_t;\n\nstatic int(*const mutate_funcs[])(mutate_info_t *, mutate_buffer_t *) = {\n\tdictionary_overwrite,\n\tdictionary_insert,\n};\n\nmutator_t dictionary_mutator = {\n\tFUNCNAME(create),\n\tFUNCNAME(cleanup),\n\tFUNCNAME(mutate),\n\tFUNCNAME(mutate_extended),\n\tFUNCNAME(get_state),\n\tdictionary_free_state,\n\tFUNCNAME(set_state),\n\tFUNCNAME(get_current_iteration),\n\tdictionary_get_total_iteration_count,\n\tFUNCNAME(get_input_info),\n\tFUNCNAME(set_input),\n\tFUNCNAME(help)\n};\n\n/**\n * This function fills in m with all of the function pointers for this mutator.\n * @param m - a pointer to a mutator_t structure\n * @return none\n */\n#ifndef ALL_MUTATORS_IN_ONE\nDICTIONARY_MUTATOR_API void init(mutator_t * m)\n{\n\tmemcpy(m, &dictionary_mutator, sizeof(mutator_t));\n}\n#endif\n\nstatic dictionary_state_t * setup_options(char * options)\n{\n\tdictionary_state_t * state;\n\tchar * operation_per_stage[] = { \"overwrite\", \"insert\" };\n\tint i;\n\n\tstate = (dictionary_state_t *)malloc(sizeof(dictionary_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(dictionary_state_t));\n\n\t//Setup defaults\n\tif (reset_mutate_info(&state->info)) {\n\t\tfree(state);\n\t\treturn NULL;\n\t}\n\n\tif (!options || !strlen(options))\n\t\treturn state;\n\n\tPARSE_MUTATE_INFO_OPTIONS(state, options, FUNCNAME(cleanup), 1, 0);\n\tPARSE_OPTION_STRING(state, options, operation, \"operation\", FUNCNAME(cleanup));\n\n\tif (state->operation) {\n\t\tstate->info.stage = -1;\n\t\tfor (i = 0; i < ARRAY_SIZE(operation_per_stage) && state->info.stage < 0; i++)\n\t\t{\n\t\t\tif (!strcmp(operation_per_stage[i], state->operation))\n\t\t\t\tstate->info.stage = i;\n\t\t}\n\t\tif (state->info.stage < 0)\n\t\t{\n\t\t\tFUNCNAME(cleanup)(state);\n\t\t\treturn NULL;\n\t\t}\n\t\tstate->info.one_stage_only = 1;\n\t}\n\treturn state;\n}\n\n/**\n * This function will allocate and initialize the mutator state used in the other Mutator API\n * functions.  \n * @param options - a json string that contains the mutator specific string of options.\n * @param state - Optionally, used to load a previously dumped state (with the get_state()\n * function), that defines the current iteration of the mutator.\n * @param input - used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size of the input buffer\n * @return a mutator specific structure or NULL on failure.\n */\nDICTIONARY_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length)\n{\n\tGENERIC_MUTATOR_CREATE(dictionary_state_t, setup_options, FUNCNAME(cleanup));\n}\n\n/**\n * This function will release any resources that the mutator has open \n * and free the mutator state structure.\n * @param mutator_state - a mutator specific structure previously created by \n * the create function.  This structure will be freed and should not be referenced afterwards.\n */\nDICTIONARY_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state)\n{\n\tcleanup_mutate_info(&((dictionary_state_t *)mutator_state)->info);\n\tGENERIC_MUTATOR_CLEANUP(dictionary_state_t)\n}\n\nstatic int mutate_inner(void * mutator_state, char * buffer, size_t buffer_length, int is_thread_safe)\n{\n\tdictionary_state_t * state = (dictionary_state_t *)mutator_state;\n\tmutate_buffer_t buf;\n\tint ret;\n\tif (buffer_length < state->input_length)\n\t\treturn -1;\n\n\tbuf.buffer = (uint8_t *)buffer;\n\tbuf.length = MIN(buffer_length, state->input_length);\n\tbuf.max_length = buffer_length;\n\tmemcpy(buf.buffer, state->input, buf.length);\n\n\tif(is_thread_safe && take_mutex(state->info.mutate_mutex))\n\t\treturn -1;\n\tstate->iteration++;\n\tret = mutate_one(&state->info, &buf, mutate_funcs, ARRAY_SIZE(mutate_funcs));\n\tif (is_thread_safe && release_mutex(state->info.mutate_mutex))\n\t\treturn -1;\n\treturn ret;\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nDICTIONARY_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length)\n{\n\treturn mutate_inner(mutator_state, buffer, buffer_length, 0);\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * This function also accepts a set of flags which instruct it how to mutate the input.  See global_types.h\n * for the list of available flags.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @param flags - A set of mutate flags that modify how this mutator mutates the input.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nDICTIONARY_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags)\n{\n\tSINGLE_INPUT_MUTATE_EXTENDED(dictionary_state_t, state->info.mutate_mutex);\n}\n\n/**\n * This function will return the state of the mutator.  The returned value can be used to restart the\n * mutator at a later time, by passing it to the create or set_state function.  It is the caller's\n * responsibility to free the memory allocated here by calling the free_state function.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return - a buffer that defines the current state of the mutator.\n */\nDICTIONARY_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state)\n{\n\tdictionary_state_t * state = (dictionary_state_t *)mutator_state;\n\tjson_t *state_obj, *temp;\n\tchar * ret;\n\n\tstate_obj = json_object();\n\tADD_INT(temp, state->iteration, state_obj, \"iteration\");\n\tif (!add_mutate_info_to_json(state_obj, &state->info))\n\t\treturn NULL;\n\tret = json_dumps(state_obj, 0);\n\tjson_decref(state_obj);\n\treturn ret;\n}\n\n/**\n * This function will set the current state of the mutator.\n * This can be used to restart a mutator once from a previous run.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param state - a previously dumped state buffer obtained by the get_state function.\n * @return 0 on success or non-zero on failure\n */\nDICTIONARY_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state)\n{\n\tdictionary_state_t * current_state = (dictionary_state_t *)mutator_state;\n\tint result, temp_int;\n\tif (!state)\n\t\treturn 1;\n\tGET_INT(temp_int, state, current_state->iteration, \"iteration\", result);\n\tif (get_mutate_info_from_json(state, &current_state->info))\n\t\treturn 1;\n\treturn 0;\n}\n\n/**\n * This function will return the current iteration count of the mutator, i.e.\n * how many mutations have been generated with it.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return value - the number of previously generated mutations\n */\nDICTIONARY_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state)\n{\n\tGENERIC_MUTATOR_GET_ITERATION(dictionary_state_t);\n}\n\n/**\n * This function will set the mutator's input to something new.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param new_input - The new input used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size in bytes of the input buffer.\n * @return 0 on success and -1 on failure\n */\nDICTIONARY_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length)\n{\n\tGENERIC_MUTATOR_SET_INPUT(dictionary_state_t);\n}\n\n/**\n * Obtains information about the inputs that were given to the mutator when it was created\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param num_inputs - a pointer to an integer used to return the number of inputs given to this mutator\n * when it was created.  This parameter is optional and can be NULL, if this information is not needed\n * @param input_sizes - a pointer to a size_t array used to return the sizes of the inputs given to this\n * mutator when it was created. This parameter is optional and can be NULL, if this information is not needed.\n */\nDICTIONARY_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes)\n{\n\tSINGLE_INPUT_GET_INFO(dictionary_state_t);\n}\n\n/**\n * This function sets a help message for the mutator.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nDICTIONARY_MUTATOR_API int FUNCNAME(help)(char **help_str)\n{\n\tGENERIC_MUTATOR_HELP(\n\"dictionary - afl-based dictionary mutator\\n\"\n\"Options:\\n\"\n\"  dictionary            A file or directory containing dictionary to use while\\n\"\n\"                          mangling input\\n\"\n\"  operation             The operation to perform with each dictionary item.\\n\"\n\"                          Either, overwrite or insert.  Default option is both.\\n\"\n\"  random_state0         The first half of the seed to afl's random number\\n\"\n\"                          generator\\n\"\n\"  random_state1         The second half of the seed to afl's random number\\n\"\n\"                          generator\\n\"\n\"\\n\"\n\t);\n}\n"
  },
  {
    "path": "mutators/dictionary_mutator/dictionary_mutator.h",
    "content": "#pragma once\n\n#include <global_types.h>\n#include <mutators.h>\n\n#ifdef _WIN32\n#ifdef DICTIONARY_MUTATOR_EXPORTS\n#define DICTIONARY_MUTATOR_API __declspec(dllexport)\n#else\n#define DICTIONARY_MUTATOR_API __declspec(dllimport)\n#endif\n#else //_WIN32\n#define DICTIONARY_MUTATOR_API\n#endif\n\n#define MUTATOR_NAME \"dictionary\"\n\nDICTIONARY_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length);\nDICTIONARY_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state);\nDICTIONARY_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length);\nDICTIONARY_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags);\nDICTIONARY_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state);\n#define dictionary_free_state default_free_state\nDICTIONARY_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state);\nDICTIONARY_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state);\n#define dictionary_get_total_iteration_count return_unknown_or_infinite_total_iterations\nDICTIONARY_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes);\nDICTIONARY_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length);\nDICTIONARY_MUTATOR_API int FUNCNAME(help)(char **help_str);\n\n#ifndef ALL_MUTATORS_IN_ONE\nDICTIONARY_MUTATOR_API void init(mutator_t * m);\n#endif\n"
  },
  {
    "path": "mutators/havoc_mutator/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (havoc_mutator)\n\ninclude_directories (${PROJECT_SOURCE_DIR}/../mutators/)\n\nset(HAVOC_SRC ${PROJECT_SOURCE_DIR}/havoc_mutator.c)\nsource_group(\"Library Sources\" FILES ${HAVOC_SRC})\n\nadd_library(havoc_mutator SHARED ${HAVOC_SRC}\n  $<TARGET_OBJECTS:mutators_object> $<TARGET_OBJECTS:jansson_object>)\ntarget_link_libraries(havoc_mutator utils)\ntarget_compile_definitions(havoc_mutator PUBLIC HAVOC_MUTATOR_EXPORTS)\ntarget_compile_definitions(havoc_mutator PUBLIC MUTATORS_NO_IMPORT)\ntarget_compile_definitions(havoc_mutator PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(havoc_mutator PUBLIC JANSSON_NO_IMPORT)\n\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(havoc_mutator Shlwapi)\nendif (WIN32)\n"
  },
  {
    "path": "mutators/havoc_mutator/havoc_mutator.c",
    "content": "#include \"havoc_mutator.h\"\n#include <mutators.h>\n#include <afl_helpers.h>\n#include <afl_config.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <utils.h>\n#include <jansson.h>\n#include <jansson_helper.h>\n\nstruct havoc_state\n{\n\tchar * input;\n\tsize_t input_length;\n\tint iteration;\n\n\tmutate_info_t info;\n};\ntypedef struct havoc_state havoc_state_t;\n\nstatic int(*const mutate_funcs[])(mutate_info_t *, mutate_buffer_t *) = {\n\thavoc,\n};\n\nmutator_t havoc_mutator = {\n\tFUNCNAME(create),\n\tFUNCNAME(cleanup),\n\tFUNCNAME(mutate),\n\tFUNCNAME(mutate_extended),\n\tFUNCNAME(get_state),\n\thavoc_free_state,\n\tFUNCNAME(set_state),\n\tFUNCNAME(get_current_iteration),\n\thavoc_get_total_iteration_count,\n\tFUNCNAME(get_input_info),\n\tFUNCNAME(set_input),\n\tFUNCNAME(help)\n};\n\n/**\n * This function fills in m with all of the function pointers for this mutator.\n * @param m - a pointer to a mutator_t structure\n * @return none\n */\n#ifndef ALL_MUTATORS_IN_ONE\nHAVOC_MUTATOR_API void init(mutator_t * m)\n{\n\tmemcpy(m, &havoc_mutator, sizeof(mutator_t));\n}\n#endif\n\nstatic havoc_state_t * setup_options(char * options)\n{\n\thavoc_state_t * state = (havoc_state_t *)malloc(sizeof(havoc_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(havoc_state_t));\n\n\t//Setup defaults\n\tif (reset_mutate_info(&state->info)) {\n\t\tfree(state);\n\t\treturn NULL;\n\t}\n\tif (!options || !strlen(options))\n\t\treturn state;\n\n\tPARSE_MUTATE_INFO_OPTIONS(state, options, FUNCNAME(cleanup), 0, 0);\n\treturn state;\n}\n\n/**\n * This function will allocate and initialize the mutator state used in the other Mutator API\n * functions.  \n * @param options - a json string that contains the mutator specific string of options.\n * @param state - Optionally, used to load a previously dumped state (with the get_state()\n * function), that defines the current iteration of the mutator.\n * @param input - used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size of the input buffer\n * @return a mutator specific structure or NULL on failure.\n */\nHAVOC_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length)\n{\n\tGENERIC_MUTATOR_CREATE(havoc_state_t, setup_options, FUNCNAME(cleanup));\n}\n\n/**\n * This function will release any resources that the mutator has open \n * and free the mutator state structure.\n * @param mutator_state - a mutator specific structure previously created by \n * the create function.  This structure will be freed and should not be referenced afterwards.\n */\nHAVOC_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state)\n{\n\tcleanup_mutate_info(&((havoc_state_t *)mutator_state)->info);\n\tGENERIC_MUTATOR_CLEANUP(havoc_state_t)\n}\n\nstatic int mutate_inner(void * mutator_state, char * buffer, size_t buffer_length, int is_thread_safe)\n{\n\thavoc_state_t * state = (havoc_state_t *)mutator_state;\n\tmutate_buffer_t buf;\n\tint ret;\n\tif (buffer_length < state->input_length)\n\t\treturn -1;\n\n\tbuf.buffer = (uint8_t *)buffer;\n\tbuf.length = MIN(buffer_length, state->input_length);\n\tbuf.max_length = buffer_length;\n\tmemcpy(buf.buffer, state->input, buf.length);\n\n\tif(is_thread_safe && take_mutex(state->info.mutate_mutex))\n\t\treturn -1;\n\tif (state->info.stage_cur > MAX(HAVOC_MIN, HAVOC_CYCLES * (state->info.perf_score / state->info.havoc_div) / 100))\n\t{\n\t\tstate->info.stage = 0;\n\t\tstate->info.stage_cur = 0;\n\t\tstate->info.queue_cycle++;\n\t}\n\tstate->iteration++;\n\tret = mutate_one(&state->info, &buf, mutate_funcs, ARRAY_SIZE(mutate_funcs));\n\tif (is_thread_safe && release_mutex(state->info.mutate_mutex))\n\t\treturn -1;\n\treturn ret;\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nHAVOC_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length)\n{\n\treturn mutate_inner(mutator_state, buffer, buffer_length, 0);\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * This function also accepts a set of flags which instruct it how to mutate the input.  See global_types.h\n * for the list of available flags.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @param flags - A set of mutate flags that modify how this mutator mutates the input.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nHAVOC_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags)\n{\n\tSINGLE_INPUT_MUTATE_EXTENDED(havoc_state_t, state->info.mutate_mutex);\n}\n\n/**\n * This function will return the state of the mutator.  The returned value can be used to restart the\n * mutator at a later time, by passing it to the create or set_state function.  It is the caller's\n * responsibility to free the memory allocated here by calling the free_state function.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return - a buffer that defines the current state of the mutator.\n */\nHAVOC_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state)\n{\n\thavoc_state_t * state = (havoc_state_t *)mutator_state;\n\tjson_t *state_obj, *temp;\n\tchar * ret;\n\n\tstate_obj = json_object();\n\tADD_INT(temp, state->iteration, state_obj, \"iteration\");\n\tif (!add_mutate_info_to_json(state_obj, &state->info))\n\t\treturn NULL;\n\tret = json_dumps(state_obj, 0);\n\tjson_decref(state_obj);\n\treturn ret;\n}\n\n/**\n * This function will set the current state of the mutator.\n * This can be used to restart a mutator once from a previous run.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param state - a previously dumped state buffer obtained by the get_state function.\n * @return 0 on success or non-zero on failure\n */\nHAVOC_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state)\n{\n\thavoc_state_t * current_state = (havoc_state_t *)mutator_state;\n\tint result, temp_int;\n\tif (!state)\n\t\treturn 1;\n\tGET_INT(temp_int, state, current_state->iteration, \"iteration\", result);\n\tif (get_mutate_info_from_json(state, &current_state->info))\n\t\treturn 1;\n\treturn 0;\n}\n\n/**\n * This function will return the current iteration count of the mutator, i.e.\n * how many mutations have been generated with it.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return value - the number of previously generated mutations\n */\nHAVOC_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state)\n{\n\tGENERIC_MUTATOR_GET_ITERATION(havoc_state_t);\n}\n\n/**\n * This function will set the mutator's input to something new.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param new_input - The new input used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size in bytes of the input buffer.\n * @return 0 on success and -1 on failure\n */\nHAVOC_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length)\n{\n\tGENERIC_MUTATOR_SET_INPUT(havoc_state_t);\n}\n\n/**\n * Obtains information about the inputs that were given to the mutator when it was created\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param num_inputs - a pointer to an integer used to return the number of inputs given to this mutator\n * when it was created.  This parameter is optional and can be NULL, if this information is not needed\n * @param input_sizes - a pointer to a size_t array used to return the sizes of the inputs given to this\n * mutator when it was created. This parameter is optional and can be NULL, if this information is not needed.\n */\nHAVOC_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes)\n{\n\tSINGLE_INPUT_GET_INFO(havoc_state_t);\n}\n\n/**\n * This function sets a help message for the mutator.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nHAVOC_MUTATOR_API int FUNCNAME(help)(char **help_str)\n{\n\tGENERIC_MUTATOR_HELP(\n\"havoc - afl-based havoc mutator\\n\"\n\"Options:\\n\"\n\"  dictionary            A file or directory containing dictionary to use while\\n\"\n\"                          mangling input\\n\"\n\"  havoc_div             A divisor for determining the number of rounds that\\n\"\n\"                          the havoc stage should run (typically 1, 2, 5, or 10)\\n\"\n\"  perf_score            A performance score used to determine how long a havoc\\n\"\n\"                          round lasts.  Typically 100, higher results in a\\n\"\n\"                          larger number of mutations in these stages before\\n\"\n\"                          moving on.\\n\"\n\"  queue_cycle           The queue round counter.  Used in determining how to\\n\"\n\"                          mutate input.  Generally this shouldn't need to be set\\n\"\n\"  random_state0         The first half of the seed to afl's random number\\n\"\n\"                          generator\\n\"\n\"  random_state1         The second half of the seed to afl's random number\\n\"\n\"                          generator\\n\"\n\"\\n\"\n\t);\n}\n"
  },
  {
    "path": "mutators/havoc_mutator/havoc_mutator.h",
    "content": "#pragma once\n\n#include <global_types.h>\n#include <mutators.h>\n\n#ifdef _WIN32\n#ifdef HAVOC_MUTATOR_EXPORTS\n#define HAVOC_MUTATOR_API __declspec(dllexport)\n#else\n#define HAVOC_MUTATOR_API __declspec(dllimport)\n#endif\n#else //_WIN32\n#define HAVOC_MUTATOR_API\n#endif\n\n#define MUTATOR_NAME \"havoc\"\n\nHAVOC_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length);\nHAVOC_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state);\nHAVOC_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length);\nHAVOC_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags);\nHAVOC_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state);\n#define havoc_free_state default_free_state\nHAVOC_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state);\nHAVOC_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state);\n#define havoc_get_total_iteration_count return_unknown_or_infinite_total_iterations\nHAVOC_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes);\nHAVOC_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length);\nHAVOC_MUTATOR_API int FUNCNAME(help)(char **help_str);\n\n#ifndef ALL_MUTATORS_IN_ONE\nHAVOC_MUTATOR_API void init(mutator_t * m);\n#endif\n"
  },
  {
    "path": "mutators/honggfuzz_mutator/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (honggfuzz_mutator)\n\ninclude_directories (${PROJECT_SOURCE_DIR}/../mutators/)\n\nset(HONGGFUZZ_SRC ${PROJECT_SOURCE_DIR}/honggfuzz_mutator.c)\nsource_group(\"Library Sources\" FILES ${HONGGFUZZ_SRC})\n\nadd_library(honggfuzz_mutator SHARED ${HONGGFUZZ_SRC}\n  $<TARGET_OBJECTS:mutators_object> $<TARGET_OBJECTS:jansson_object>)\ntarget_link_libraries(honggfuzz_mutator utils)\ntarget_compile_definitions(honggfuzz_mutator PUBLIC HONGGFUZZ_MUTATOR_EXPORTS)\ntarget_compile_definitions(honggfuzz_mutator PUBLIC MUTATORS_NO_IMPORT)\ntarget_compile_definitions(honggfuzz_mutator PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(honggfuzz_mutator PUBLIC JANSSON_NO_IMPORT)\n\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(honggfuzz_mutator Shlwapi)\nendif (WIN32)\n"
  },
  {
    "path": "mutators/honggfuzz_mutator/honggfuzz_mutator.c",
    "content": "#include \"honggfuzz_mutator.h\"\n#include <mutators.h>\n\n#include <utils.h>\n#include <jansson.h>\n#include <jansson_helper.h>\n#include <global_types.h>\n\n#include <assert.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n#include <inttypes.h>\n#include <math.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n\ntypedef struct {\n\tchar* s;\n\tsize_t len;\n} string_t;\n\nstruct honggfuzz_state\n{\n\tint mutations_per_run;\n\tchar * dictionary_file;\n\tuint64_t dictionary_count;\n\tstring_t ** dictq;\n\n\tchar * input;\n\tsize_t input_length;\n\n\t//Protects the fields below, i.e. the iteration count, mutate buffer information, and random state\n\tmutex_t mutate_mutex;\n\n\tint iteration;\n\tuint8_t * mutated_buffer;\n\tuint64_t mutated_buffer_length;\n\tuint64_t max_mutated_buffer_length;\n\tuint64_t random_state[2];\n};\ntypedef struct honggfuzz_state honggfuzz_state_t;\n\nmutator_t honggfuzz_mutator = {\n\tFUNCNAME(create),\n\tFUNCNAME(cleanup),\n\tFUNCNAME(mutate),\n\tFUNCNAME(mutate_extended),\n\tFUNCNAME(get_state),\n\thonggfuzz_free_state,\n\tFUNCNAME(set_state),\n\tFUNCNAME(get_current_iteration),\n\thonggfuzz_get_total_iteration_count,\n\tFUNCNAME(get_input_info),\n\tFUNCNAME(set_input),\n\tFUNCNAME(help)\n};\n\n////////////////////////////////////////////////////////////////////////////////////////////\n//// Honggfuzz mutator methods /////////////////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////////////////////////\n\n/*\n * The code in this section (Honggfuzz mutator methods) was taken\n * from honggfuzz and falls under the following license:\n *\n * honggfuzz - run->dynamicFilefer mangling routines\n * -----------------------------------------\n *\n * Author:\n * Robert Swiecki <swiecki@google.com>\n *\n * Copyright 2010-2015 by Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n * not use this file except in compliance with the License. You may obtain\n * a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n * implied. See the License for the specific language governing\n * permissions and limitations under the License.\n *\n * The code in this section has been modified from the original to suit the\n * purposes of this project.\n */\n\n//The following functions are taken from honggfuzz, see:\n//https://github.com/google/honggfuzz/blob/master/mangle.c\n//https://github.com/google/honggfuzz/blob/master/libcommon/util.c\n\n/*\n * xoroshiro128plus by David Blackman and Sebastiano Vigna\n */\nstatic inline uint64_t util_RotL(const uint64_t x, int k)\n{\n\treturn (x << k) | (x >> (64 - k));\n}\n\nstatic inline uint64_t util_InternalRnd64(honggfuzz_state_t * state) {\n\tconst uint64_t s0 = state->random_state[0];\n\tuint64_t s1 = state->random_state[1];\n\tconst uint64_t result = s0 + s1;\n\ts1 ^= s0;\n\tstate->random_state[0] = util_RotL(s0, 55) ^ s1 ^ (s1 << 14);\n\tstate->random_state[1] = util_RotL(s1, 36);\n\treturn result;\n}\n\nuint64_t util_rnd64(honggfuzz_state_t * state) {\n\treturn util_InternalRnd64(state);\n}\n\nuint64_t util_rndGet(honggfuzz_state_t * state, uint64_t min, uint64_t max) {\n\tassert(min <= max);\n\tif (max == UINT64_MAX) {\n\t\treturn util_rnd64(state);\n\t}\n\n\treturn ((util_rnd64(state) % (max - min + 1)) + min);\n}\n\nvoid util_rndBuf(honggfuzz_state_t * state, uint8_t* buf, uint64_t sz) {\n\tif (sz == 0) {\n\t\treturn;\n\t}\n\tfor (uint64_t i = 0; i < sz; i++) {\n\t\tbuf[i] = (uint8_t)util_InternalRnd64(state);\n\t}\n}\n\nstatic inline void mangle_Overwrite(honggfuzz_state_t * state, const uint8_t* src, uint64_t off, uint64_t sz) {\n\tuint64_t maxToCopy = state->mutated_buffer_length - off;\n\tif (sz > maxToCopy) {\n\t\tsz = maxToCopy;\n\t}\n\n\tmemmove(&state->mutated_buffer[off], src, (size_t)sz);\n}\n\nstatic inline void mangle_Move(honggfuzz_state_t * state, uint64_t off_from, uint64_t off_to, uint64_t len) {\n\tif (off_from >= state->mutated_buffer_length) {\n\t\treturn;\n\t}\n\tif (off_to >= state->mutated_buffer_length) {\n\t\treturn;\n\t}\n\n\tint64_t len_from = (int64_t)state->mutated_buffer_length - off_from - 1;\n\tint64_t len_to = (int64_t)state->mutated_buffer_length - off_to - 1;\n\n\tif ((int64_t)len > len_from) {\n\t\tlen = len_from;\n\t}\n\tif ((int64_t)len > len_to) {\n\t\tlen = len_to;\n\t}\n\n\tmemmove(&state->mutated_buffer[off_to], &state->mutated_buffer[off_from], (size_t)len);\n}\n\nstatic void mangle_Inflate(honggfuzz_state_t * state, uint64_t off, uint64_t len) {\n\tif (state->mutated_buffer_length >= state->max_mutated_buffer_length) {\n\t\treturn;\n\t}\n\tif (len > (state->max_mutated_buffer_length - state->mutated_buffer_length)) {\n\t\tlen = state->max_mutated_buffer_length - state->mutated_buffer_length;\n\t}\n\n\tstate->mutated_buffer_length += len;\n\tmangle_Move(state, off, off + len, state->mutated_buffer_length);\n}\n\nstatic void mangle_MemMove(honggfuzz_state_t * state) {\n\tuint64_t off_from = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tuint64_t off_to = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tuint64_t len = util_rndGet(state, 0, state->mutated_buffer_length);\n\n\tmangle_Move(state, off_from, off_to, len);\n}\n\nstatic void mangle_Byte(honggfuzz_state_t * state) {\n\tuint64_t off = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tstate->mutated_buffer[off] = (uint8_t)util_rnd64(state);\n}\n\nstatic void mangle_Bytes(honggfuzz_state_t * state) {\n\tuint64_t off = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tuint32_t val = (uint32_t)util_rnd64(state);\n\n\t/* Overwrite with random 2,3,4-byte values */\n\tuint64_t toCopy = util_rndGet(state, 2, 4);\n\tmangle_Overwrite(state, (uint8_t*)&val, off, toCopy);\n}\n\nstatic void mangle_Bit(honggfuzz_state_t * state) {\n\tuint64_t off = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tstate->mutated_buffer[off] ^= (uint8_t)(1U << util_rndGet(state, 0, 7));\n}\n\nstatic void mangle_DictionaryInsert(honggfuzz_state_t * state) {\n\tif (state->dictionary_count == 0) {\n\t\tmangle_Bit(state);\n\t\treturn;\n\t}\n\n\tuint64_t choice = util_rndGet(state, 0, state->dictionary_count - 1);\n\tstring_t* str = state->dictq[choice];\n\tuint64_t off = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tmangle_Inflate(state, off, str->len);\n\tmangle_Move(state, off, off + str->len, str->len);\n\tmangle_Overwrite(state, (uint8_t*)str->s, off, str->len);\n}\n\nstatic void mangle_Dictionary(honggfuzz_state_t * state) {\n\tif (state->dictionary_count == 0) {\n\t\tmangle_Bit(state);\n\t\treturn;\n\t}\n\n\tuint64_t choice = util_rndGet(state, 0, state->dictionary_count - 1);\n\tstring_t* str = state->dictq[choice];\n\tuint64_t off = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tmangle_Overwrite(state, (uint8_t*)str->s, off, str->len);\n}\n\nstatic void mangle_Magic(honggfuzz_state_t * state) {\n\tstruct magic_values\n\t{\n\t\t//ugh.  Visual studio insists on strings being null terminated\n\t\tuint8_t val[9];//so we need to use 9 bytes instead of 8 for the value\n\t\tuint64_t size;\n\t};\n\tstatic const struct magic_values mangleMagicVals[] = {\n\t\t// 1B - No endianness\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x05\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x06\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x07\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x09\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x0A\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x0B\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x0C\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x0D\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x0E\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x0F\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x10\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x20\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x40\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x7E\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x7F\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\x81\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\xC0\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\xFE\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t{ \"\\xFF\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 1 },\n\t\t// 2B - NE\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x80\\x80\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\xFF\\xFF\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t// 2B - BE\n\t\t{ \"\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x02\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x03\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x05\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x06\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x07\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x08\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x09\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x0A\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x0B\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x0C\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x0D\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x0E\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x0F\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x10\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x20\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x40\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x7E\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x7F\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x80\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x81\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\xC0\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\xFE\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\xFF\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x7E\\xFF\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x7F\\xFF\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x80\\x01\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\xFF\\xFE\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t// 2B - LE\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x05\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x06\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x07\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x09\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x0A\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x0B\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x0C\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x0D\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x0E\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x0F\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x10\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x20\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x40\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x7E\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x7F\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x81\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\xC0\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\xFE\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\xFF\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\xFF\\x7E\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\xFF\\x7F\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x00\\x80\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\x01\\x80\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t{ \"\\xFE\\xFF\\x00\\x00\\x00\\x00\\x00\\x00\", 2 },\n\t\t// 4B - NE\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x01\\x01\\x01\\x01\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x80\\x80\\x80\\x80\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\xFF\\xFF\\xFF\\xFF\\x00\\x00\\x00\\x00\", 4 },\n\t\t// 4B - BE\n\t\t{ \"\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x04\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x05\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x06\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x07\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x08\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x09\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x0A\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x0B\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x0C\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x0D\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x0E\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x0F\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x10\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x20\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x40\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x7E\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x7F\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x80\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x81\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\xC0\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\xFE\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\xFF\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x7E\\xFF\\xFF\\xFF\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x7F\\xFF\\xFF\\xFF\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x80\\x00\\x00\\x01\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\xFF\\xFF\\xFF\\xFE\\x00\\x00\\x00\\x00\", 4 },\n\t\t// 4B - LE\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x05\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x06\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x07\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x09\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x0A\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x0B\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x0C\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x0D\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x0E\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x0F\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x10\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x20\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x40\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x7E\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x7F\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x81\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\xC0\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\xFE\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\xFF\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\xFF\\xFF\\xFF\\x7E\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\xFF\\xFF\\xFF\\x7F\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x00\\x00\\x00\\x80\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\x01\\x00\\x00\\x80\\x00\\x00\\x00\\x00\", 4 },\n\t\t{ \"\\xFE\\xFF\\xFF\\xFF\\x00\\x00\\x00\\x00\", 4 },\n\t\t// 8B - NE\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\", 8 },\n\t\t{ \"\\x80\\x80\\x80\\x80\\x80\\x80\\x80\\x80\", 8 },\n\t\t{ \"\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\", 8 },\n\t\t// 8B - BE\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x03\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x04\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x05\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x06\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x07\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x08\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x09\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0A\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0B\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0C\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0D\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0E\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0F\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x10\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x20\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x40\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x7E\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x7F\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x80\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x81\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xC0\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xFE\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xFF\", 8 },\n\t\t{ \"\\x7E\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\", 8 },\n\t\t{ \"\\x7F\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\", 8 },\n\t\t{ \"\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x01\", 8 },\n\t\t{ \"\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\\xFE\", 8 },\n\t\t// 8B - LE\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x05\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x06\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x07\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x09\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x0A\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x0B\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x0C\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x0D\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x0E\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x0F\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x10\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x20\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x40\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x7E\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x7F\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\x81\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\xC0\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\xFE\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\xFF\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8 },\n\t\t{ \"\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\\x7E\", 8 },\n\t\t{ \"\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\\x7F\", 8 },\n\t\t{ \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x80\", 8 },\n\t\t{ \"\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x80\", 8 },\n\t\t{ \"\\xFE\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\\xFF\", 8 },\n\t};\n\n\tuint64_t off = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tuint64_t choice = util_rndGet(state, 0, ARRAY_SIZE(mangleMagicVals) - 1);\n\tmangle_Overwrite(state, mangleMagicVals[choice].val, off, mangleMagicVals[choice].size);\n}\n\nstatic void mangle_MemSet(honggfuzz_state_t * state) {\n\tuint64_t off = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tuint64_t sz = util_rndGet(state, 1, state->mutated_buffer_length - off);\n\tint val = (int)util_rndGet(state, 0, UINT8_MAX);\n\n\tmemset(&state->mutated_buffer[off], val, (size_t)sz);\n}\n\nstatic void mangle_Random(honggfuzz_state_t * state) {\n\tuint64_t off = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tuint64_t len = util_rndGet(state, 1, state->mutated_buffer_length - off);\n\tutil_rndBuf(state, &state->mutated_buffer[off], len);\n}\n\nstatic void mangle_AddSub(honggfuzz_state_t * state) {\n\tuint64_t off = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\n\t/* 1,2,4,8 */\n\tuint64_t varLen = 1ULL << util_rndGet(state, 0, 3);\n\tif ((state->mutated_buffer_length - off) < varLen) {\n\t\tvarLen = 1;\n\t}\n\n\tint delta = (int)util_rndGet(state, 0, 8192);\n\tdelta -= 4096;\n\n\tassert(varLen == 1 || varLen == 2 || varLen == 4 || varLen == 8);\n\tswitch (varLen) {\n\t\tcase 1: {\n\t\t\tstate->mutated_buffer[off] += delta;\n\t\t\tbreak;\n\t\t}\n\t\tcase 2: {\n\t\t\tint16_t val;\n\t\t\tmemcpy(&val, &state->mutated_buffer[off], sizeof(val));\n\t\t\tif (util_rnd64(state) & 0x1) {\n\t\t\t\tval += delta;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t/* Foreign endianess */\n\t\t\t\tval = SWAP16(val);\n\t\t\t\tval += delta;\n\t\t\t\tval = SWAP16(val);\n\t\t\t}\n\t\t\tmangle_Overwrite(state, (uint8_t*)&val, off, varLen);\n\t\t\tbreak;\n\t\t}\n\t\tcase 4: {\n\t\t\tint32_t val;\n\t\t\tmemcpy(&val, &state->mutated_buffer[off], sizeof(val));\n\t\t\tif (util_rnd64(state) & 0x1) {\n\t\t\t\tval += delta;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t/* Foreign endianess */\n\t\t\t\tval = SWAP32(val);\n\t\t\t\tval += delta;\n\t\t\t\tval = SWAP32(val);\n\t\t\t}\n\t\t\tmangle_Overwrite(state, (uint8_t*)&val, off, varLen);\n\t\t\tbreak;\n\t\t}\n\t\tcase 8: {\n\t\t\tint64_t val;\n\t\t\tmemcpy(&val, &state->mutated_buffer[off], sizeof(val));\n\t\t\tif (util_rnd64(state) & 0x1) {\n\t\t\t\tval += delta;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t/* Foreign endianess */\n\t\t\t\tval = SWAP64(val);\n\t\t\t\tval += delta;\n\t\t\t\tval = SWAP64(val);\n\t\t\t}\n\t\t\tmangle_Overwrite(state, (uint8_t*)&val, off, varLen);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nstatic void mangle_IncByte(honggfuzz_state_t * state) {\n\tuint64_t off = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tstate->mutated_buffer[off] += (uint8_t)1UL;\n}\n\nstatic void mangle_DecByte(honggfuzz_state_t * state) {\n\tuint64_t off = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tstate->mutated_buffer[off] -= (uint8_t)1UL;\n}\n\nstatic void mangle_NegByte(honggfuzz_state_t * state) {\n\tuint64_t off = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tstate->mutated_buffer[off] = ~(state->mutated_buffer[off]);\n}\n\nstatic void mangle_CloneByte(honggfuzz_state_t * state) {\n\tuint64_t off1 = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tuint64_t off2 = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\n\tuint8_t tmp = state->mutated_buffer[off1];\n\tstate->mutated_buffer[off1] = state->mutated_buffer[off2];\n\tstate->mutated_buffer[off2] = tmp;\n}\n\nstatic void mangle_Resize(honggfuzz_state_t * state) {\n\tstate->mutated_buffer_length = util_rndGet(state, 1, state->max_mutated_buffer_length);\n}\n\nstatic void mangle_Expand(honggfuzz_state_t * state) {\n\tuint64_t off = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tuint64_t len = util_rndGet(state, 1, state->mutated_buffer_length - off);\n\n\tmangle_Inflate(state, off, len);\n\tmangle_Move(state, off, off + len, state->mutated_buffer_length);\n}\n\nstatic void mangle_Shrink(honggfuzz_state_t * state) {\n\tif (state->mutated_buffer_length <= 1U) {\n\t\treturn;\n\t}\n\n\tuint64_t len = util_rndGet(state, 1, state->mutated_buffer_length - 1);\n\tuint64_t off = util_rndGet(state, 0, len);\n\n\tstate->mutated_buffer_length -= len;\n\tmangle_Move(state, off + len, off, state->mutated_buffer_length);\n}\n\nstatic void mangle_InsertRnd(honggfuzz_state_t * state) {\n\tuint64_t off = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\tuint64_t len = util_rndGet(state, 1, state->mutated_buffer_length - off);\n\n\tmangle_Inflate(state, off, len);\n\tmangle_Move(state, off, off + len, state->mutated_buffer_length);\n\tutil_rndBuf(state, &state->mutated_buffer[off], len);\n}\n\nstatic void mangle_ASCIIVal(honggfuzz_state_t * state) {\n\tchar buf[32];\n\tsnprintf(buf, sizeof(buf), \"%\" PRId64, (int64_t)util_rnd64(state));\n\tsize_t off = util_rndGet(state, 0, state->mutated_buffer_length - 1);\n\n\tmangle_Overwrite(state, (uint8_t*)buf, off, strlen(buf));\n}\n\nstatic void mangle_mangleContent(honggfuzz_state_t* state) {\n\tif (state->mutations_per_run == 0U) {\n\t\treturn;\n\t}\n\n\t/* Minimum support file size for mangling is 1 */\n\tif (state->mutated_buffer_length == 0UL) {\n\t\tstate->mutated_buffer_length = 1UL;\n\t\tstate->mutated_buffer[0] = '\\0';\n\t}\n\n\tstatic void(*const mangleFuncs[])(honggfuzz_state_t * state) = {\n\t\tmangle_Resize,\n\t\tmangle_Byte,\n\t\tmangle_Bit,\n\t\tmangle_Bytes,\n\t\tmangle_Magic,\n\t\tmangle_IncByte,\n\t\tmangle_DecByte,\n\t\tmangle_NegByte,\n\t\tmangle_AddSub,\n\t\tmangle_Dictionary,\n\t\tmangle_DictionaryInsert,\n\t\tmangle_MemMove,\n\t\tmangle_MemSet,\n\t\tmangle_Random,\n\t\tmangle_CloneByte,\n\t\tmangle_Expand,\n\t\tmangle_Shrink,\n\t\tmangle_InsertRnd,\n\t\tmangle_ASCIIVal,\n\t};\n\n\tuint64_t changesCnt = util_rndGet(state, 1, state->mutations_per_run);\n\tfor (uint64_t x = 0; x < changesCnt; x++) {\n\t\tuint64_t choice = util_rndGet(state, 0, ARRAY_SIZE(mangleFuncs) - 1);\n\t\tmangleFuncs[choice](state);\n\t}\n}\n\nstatic size_t util_decodeCString(char* s) {\n\tsize_t o = 0;\n\tfor (size_t i = 0; s[i] != '\\0' && s[i] != '\"'; i++, o++) {\n\t\tswitch (s[i]) {\n\t\tcase '\\\\': {\n\t\t\ti++;\n\t\t\tif (!s[i]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tswitch (s[i]) {\n\t\t\tcase 'a':\n\t\t\t\ts[o] = '\\a';\n\t\t\t\tbreak;\n\t\t\tcase 'r':\n\t\t\t\ts[o] = '\\r';\n\t\t\t\tbreak;\n\t\t\tcase 'n':\n\t\t\t\ts[o] = '\\n';\n\t\t\t\tbreak;\n\t\t\tcase 't':\n\t\t\t\ts[o] = '\\t';\n\t\t\t\tbreak;\n\t\t\tcase '0':\n\t\t\t\ts[o] = '\\0';\n\t\t\t\tbreak;\n\t\t\tcase 'x': {\n\t\t\t\tif (s[i + 1] && s[i + 2]) {\n\t\t\t\t\tchar hex[] = { s[i + 1], s[i + 2], 0 };\n\t\t\t\t\ts[o] = (char) strtoul(hex, NULL, 16);\n\t\t\t\t\ti += 2;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ts[o] = s[i];\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\ts[o] = s[i];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\ts[o] = s[i];\n\t\t\tbreak;\n\t\t}\n\t\t}\n\t}\n\ts[o] = '\\0';\n\treturn o;\n}\n\nstatic int input_parseDictionary(honggfuzz_state_t * state) {\n\tchar * contents;\n\tchar lineptr[2100];\n\tint start, pos = 0, length, ret = 0;\n\tsize_t len;\n\n\tlength = read_file(state->dictionary_file, &contents);\n\tif (length < 0) {\n\t\tprintf(\"Couldn't open '%s'\", state->dictionary_file);\n\t\treturn 1;\n\t}\n\n\tfor (;;) {\n\t\t//Find the end of the line\n\t\tlen = 0;\n\t\tmemset(lineptr, 0, sizeof(lineptr));\n\t\tfor (start = pos; pos < length; pos++)\n\t\t{\n\t\t\tif (contents[pos] == '\\n')\n\t\t\t{\n\t\t\t\tlen = pos - start;\n\t\t\t\tmemcpy(lineptr, &contents[start], len);\n\t\t\t\tpos++;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (len == 0) {\n\t\t\tif(start == pos) //end of the file with no left over content\n\t\t\t\tbreak;\n\n\t\t\tlen = pos - start;\n\t\t\tmemcpy(lineptr, &contents[start], len);\n\t\t}\n\n\t\t//Remove the \\r\\n\n\t\tif (len > 1 && lineptr[len - 1] == '\\n') {\n\t\t\tlineptr[len - 1] = '\\0';\n\t\t\tlen--;\n\t\t}\n\t\tif (len > 1 && lineptr[len - 1] == '\\r') {\n\t\t\tlineptr[len - 1] = '\\0';\n\t\t\tlen--;\n\t\t}\n\n\t\t//if the line is empty, skip it\n\t\tif (lineptr[0] == '#' || lineptr[0] == '\\r' || lineptr[0] == '\\n' || lineptr[0] == '\\0') {\n\t\t\tcontinue;\n\t\t}\n\n\t\t//Parse the dictionary line\n\t\tchar bufn[1025];\n\t\tchar bufv[1025];\n\t\tif (sscanf(lineptr, \"\\\"%1024s\", bufv) != 1 &&\n\t\t\tsscanf(lineptr, \"%1024[^=]=\\\"%1024s\", bufn, bufv) != 2) {\n\t\t\tprintf(\"Incorrect dictionary entry: '%s'.\\n\", lineptr);\n\t\t\tret = 1;\n\t\t\tbreak;\n\t\t}\n\n\t\tchar* s = strdup(bufv);\n\t\tstring_t* str = (string_t*)malloc(sizeof(string_t));\n\t\tstr->len = util_decodeCString(s);\n\t\tstr->s = s;\n\n\t\tstate->dictq = (string_t **)realloc(state->dictq, (state->dictionary_count + 1) * sizeof(string_t));\n\t\tstate->dictq[state->dictionary_count] = str;\n\t\tstate->dictionary_count++;\n\t}\n\n\treturn ret;\n}\n\n////////////////////////////////////////////////////////////////////////////////////////////\n//// API methods ///////////////////////////////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////////////////////////\n\n#ifndef ALL_MUTATORS_IN_ONE\n\n/**\n * This function filled in the supplied mutator_t with all of the function\n * pointers for this mutator.\n * @param m - a pointer to a mutator_t structure\n * @return none\n */\nHONGGFUZZ_MUTATOR_API void init(mutator_t * m)\n{\n\tmemcpy(m, &honggfuzz_mutator, sizeof(mutator_t));\n}\n\n#endif\n\n/**\n * This function creates and initializes a honggfuzz_state_t object based on the passed in JSON options.\n * @return the newly created honggfuzz_state_t object or NULL on failure\n */\nstatic honggfuzz_state_t * setup_options(char * options)\n{\n\thonggfuzz_state_t * state;\n\tstate = (honggfuzz_state_t *)malloc(sizeof(honggfuzz_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(honggfuzz_state_t));\n\n\t//Setup defaults\n\tstate->mutations_per_run = 6;\n\tstate->random_state[0] = (((uint64_t)rand()) << 32) | rand();\n\tstate->random_state[1] = (((uint64_t)rand()) << 32) | rand();\n\tstate->mutate_mutex = create_mutex();\n\tif (!state->mutate_mutex) {\n\t\tfree(state);\n\t\treturn NULL;\n\t}\n\n\tif (!options || !strlen(options))\n\t\treturn state;\n\n\tPARSE_OPTION_INT(state, options, mutations_per_run, \"mutations_per_run\", FUNCNAME(cleanup));\n\tPARSE_OPTION_UINT64T_TEMP(state, options, random_state[0], \"random_state0\", FUNCNAME(cleanup), temp1);\n\tPARSE_OPTION_UINT64T_TEMP(state, options, random_state[1], \"random_state1\", FUNCNAME(cleanup), temp2);\n\tPARSE_OPTION_STRING(state, options, dictionary_file, \"dictionary\", FUNCNAME(cleanup));\n\n\tif (state->dictionary_file && input_parseDictionary(state))\n\t{\n\t\tFUNCNAME(cleanup)(state);\n\t\treturn NULL;\n\t}\n\n\treturn state;\n}\n\n/**\n * This function will allocate and initialize the mutator state.  The mutator state should be\n * freed by calling the cleanup function.\n * @param options - a json string that contains the honggfuzz specific  options.\n * @param state - optionally, a previously dumped state (with the get_state() function) to load\n * @param input - The input that this mutator will later be mutating\n * @param input_length - the size of the input parameter\n * @return a mutator specific structure or NULL on failure.  The returned value should\n * not be used for anything other than passing to the various Mutator API functions.\n */\nHONGGFUZZ_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length)\n{\n\thonggfuzz_state_t * honggfuzz_state = setup_options(options);\n\tif (!honggfuzz_state)\n\t\treturn NULL;\n\n\thonggfuzz_state->input = (char *)malloc(input_length);\n\tif (!honggfuzz_state->input || !input_length)\n\t{\n\t\tFUNCNAME(cleanup)(honggfuzz_state);\n\t\treturn NULL;\n\t}\n\tmemcpy(honggfuzz_state->input, input, input_length);\n\thonggfuzz_state->input_length = input_length;\n\tif (state && FUNCNAME(set_state)(honggfuzz_state, state)) {\n\t\tFUNCNAME(cleanup)(honggfuzz_state);\n\t\treturn NULL;\n\t}\n\treturn honggfuzz_state;\n}\n\n/**\n * This function clears out the dictionary related information inside a honggfuzz_state object\n * @param honggfuzz_state - a previously created honggfuzz specific state structure\n */\nstatic void clear_dictionary(honggfuzz_state_t * honggfuzz_state)\n{\n\tuint64_t i;\n\tfor (i = 0; i < honggfuzz_state->dictionary_count; i++)\n\t{\n\t\tfree(honggfuzz_state->dictq[i]->s);\n\t\tfree(honggfuzz_state->dictq[i]);\n\t}\n\tfree(honggfuzz_state->dictionary_file);\n\tfree(honggfuzz_state->dictq);\n\n\thonggfuzz_state->dictq = NULL;\n\thonggfuzz_state->dictionary_count = 0;\n\thonggfuzz_state->dictionary_file = NULL;\n}\n\n/**\n * This function will release any resources that the mutator has open\n * and free the mutator state structure.\n * @param mutator_state - a mutator specific structure previously created by\n * the create function.  This structure will be freed and should not be referenced afterwards.\n */\nHONGGFUZZ_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state)\n{\n\thonggfuzz_state_t * honggfuzz_state = (honggfuzz_state_t *)mutator_state;\n\tclear_dictionary(honggfuzz_state);\n\tdestroy_mutex(honggfuzz_state->mutate_mutex);\n\tfree(honggfuzz_state->input);\n\thonggfuzz_state->input = NULL;\n\tfree(honggfuzz_state);\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nHONGGFUZZ_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length)\n{\n\thonggfuzz_state_t * honggfuzz_state = (honggfuzz_state_t *)mutator_state;\n\t//Can't mutate an empty buffer\n\tif (buffer_length == 0)\n\t\treturn -1;\n\n\t//Setup the mutated buffer\n\thonggfuzz_state->mutated_buffer = (uint8_t *)buffer;\n\thonggfuzz_state->mutated_buffer_length = MIN(buffer_length, honggfuzz_state->input_length);\n\tmemcpy(honggfuzz_state->mutated_buffer, honggfuzz_state->input, (size_t)honggfuzz_state->mutated_buffer_length);\n\thonggfuzz_state->max_mutated_buffer_length = buffer_length;\n\n\t//Now mutate the buffer\n\thonggfuzz_state->iteration++;\n\tmangle_mangleContent(honggfuzz_state);\n\treturn (int)honggfuzz_state->mutated_buffer_length;\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * This function also accepts a set of flags which instruct it how to mutate the input.  See global_types.h\n * for the list of available flags.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @param flags - A set of mutate flags that modify how this mutator mutates the input.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nHONGGFUZZ_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags)\n{\n  SINGLE_INPUT_MUTATE_EXTENDED(honggfuzz_state_t, state->mutate_mutex);\n}\n\n/**\n * This function will return the state of the mutator.  The returned value can be used to restart the\n * mutator at a later time, by passing it to the create or set_state function.  It is the caller's\n * responsibility to free the memory allocated here by calling the free_state function.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return - a buffer that defines the current state of the mutator.  This will be a mutator specific JSON string.\n */\nHONGGFUZZ_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state)\n{\n\thonggfuzz_state_t * honggfuzz_state = (honggfuzz_state_t *)mutator_state;\n\tjson_t *obj, *temp, *dictionary_file, *dictionary_list, *dictionary_obj;\n\tuint64_t i;\n\tchar * ret;\n\n\tobj = json_object();\n\tADD_INT(temp, honggfuzz_state->iteration, obj, \"iteration\");\n\tADD_UINT64T(temp, honggfuzz_state->random_state[0], obj, \"random_state0\");\n\tADD_UINT64T(temp, honggfuzz_state->random_state[1], obj, \"random_state1\");\n\tif (honggfuzz_state->dictionary_file)\n\t{\n\t\tdictionary_file = json_string(honggfuzz_state->dictionary_file);\n\t\tif(!dictionary_file)\n\t\t\treturn NULL;\n\t\tjson_object_set_new(obj, \"dictionary_file\", dictionary_file);\n\n\t\t//Add the dictionary list to the json object\n\t\tdictionary_list = json_array();\n\t\tif (!dictionary_list)\n\t\t\treturn NULL;\n\t\tfor (i = 0; i < honggfuzz_state->dictionary_count; i++)\n\t\t{\n\t\t\tdictionary_obj = json_object();\n\t\t\tif (!dictionary_obj)\n\t\t\t\treturn NULL;\n\t\t\tADD_MEM(temp, honggfuzz_state->dictq[i]->s, honggfuzz_state->dictq[i]->len, dictionary_obj, \"s\");\n\t\t\tADD_UINT64T(temp, honggfuzz_state->dictq[i]->len, dictionary_obj, \"len\");\n\t\t\tjson_array_append_new(dictionary_list, dictionary_obj);\n\t\t}\n\t\tjson_object_set_new(obj, \"dictionary\", dictionary_list);\n\t}\n\n\tret = json_dumps(obj, 0);\n\tjson_decref(obj);\n\treturn ret;\n}\n\n/**\n * This function will set the current state of the mutator.\n * This can be used to restart a mutator once from a previous run.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param state - a previously dumped state buffer obtained by the get_state function.\n * @return 0 on success or non-zero on failure\n */\nHONGGFUZZ_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state)\n{\n\thonggfuzz_state_t * honggfuzz_state = (honggfuzz_state_t *)mutator_state;\n\tint result, inner_result, temp_int;\n\tuint64_t temp_uint64t;\n\tchar * temp_str;\n\tjson_t * dictionary_obj;\n\tstring_t * dictionary_item;\n\n\tif (!state)\n\t\treturn 1;\n\n\tGET_INT(temp_int, state, honggfuzz_state->iteration, \"iteration\", result);\n\tGET_UINT64T(temp_uint64t, state, honggfuzz_state->random_state[0], \"random_state0\", result);\n\tGET_UINT64T(temp_uint64t, state, honggfuzz_state->random_state[1], \"random_state1\", result);\n\n\tclear_dictionary(honggfuzz_state);\n\ttemp_str = get_string_options(state, \"dictionary_file\", &result);\n\tif (result > 0)\n\t{\n\t\thonggfuzz_state->dictionary_file = temp_str;\n\t\tFOREACH_OBJECT_JSON_ARRAY_ITEM_BEGIN(state, dictionary, \"dictionary\", dictionary_obj, result)\n\n\t\t\t//Create the new dictionary item\n\t\t\tdictionary_item = (string_t *)malloc(sizeof(string_t));\n\t\t\tGET_ITEM(dictionary_obj, dictionary_item->s, temp_str, get_mem_options_from_json, \"s\", inner_result);\n\t\t\tGET_ITEM(dictionary_obj, dictionary_item->len, temp_int, get_int_options_from_json, \"len\", inner_result);\n\n\t\t\t//Add the dictionary item to the dictionary linked list\n\t\t\thonggfuzz_state->dictq = (string_t **)realloc(honggfuzz_state->dictq, (honggfuzz_state->dictionary_count + 1) * sizeof(string_t));\n\t\t\thonggfuzz_state->dictq[honggfuzz_state->dictionary_count] = dictionary_item;\n\t\t\thonggfuzz_state->dictionary_count++;\n\n\t\tFOREACH_OBJECT_JSON_ARRAY_ITEM_END(dictionary);\n\n\t\tif (result < 0)\n\t\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n/**\n * This function will return the current iteration count of the mutator, i.e.\n * how many mutations have been generated with it.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return value - the number of previously generated mutations\n */\nHONGGFUZZ_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state)\n{\n\tGENERIC_MUTATOR_GET_ITERATION(honggfuzz_state_t);\n}\n\n/**\n * Obtains information about the inputs that were given to the mutator when it was created\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param num_inputs - a pointer to an integer used to return the number of inputs given to this mutator\n * when it was created.  This parameter is optional and can be NULL, if this information is not needed\n * @param input_sizes - a pointer to a size_t array used to return the sizes of the inputs given to this\n * mutator when it was created. This parameter is optional and can be NULL, if this information is not needed.\n */\nHONGGFUZZ_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes)\n{\n\tSINGLE_INPUT_GET_INFO(honggfuzz_state_t);\n}\n\n/**\n * This function will set the input(saved in the mutators state) to something new.\n * This can be used to reinitialize a mutator with new data, without reallocating the entire state struct.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param new_input - The new input used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size in bytes of the input buffer.\n * @return 0 on success and -1 on failure\n */\nHONGGFUZZ_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length)\n{\n\tGENERIC_MUTATOR_SET_INPUT(honggfuzz_state_t);\n}\n\n/**\n * This function sets a help message for the mutator.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nHONGGFUZZ_MUTATOR_API int FUNCNAME(help)(char ** help_str)\n{\n\tGENERIC_MUTATOR_HELP(\n\"honggfuzz - honggfuzz-based mutator\\n\"\n\"Options:\\n\"\n\"  dictionary_file       A file containing dictionary words to use while\\n\"\n\"                          mangling input\\n\"\n\"  mutations_per_run     The number of different mangle functions to apply per\\n\"\n\"                          single round of mutating the input\\n\"\n\"  random_state0         The first half of the seed to honggfuzz's random\\n\"\n\"                          number generator\\n\"\n\"  random_state1         The second half of the seed to honggfuzz's random\\n\"\n\"                          number generator\\n\"\n\"\\n\"\n\t);\n}\n"
  },
  {
    "path": "mutators/honggfuzz_mutator/honggfuzz_mutator.h",
    "content": "#pragma once\n\n#include <global_types.h>\n#include <mutators.h>\n#include <afl_types.h> //grab the definition of MIN/MAX\n\n#ifdef _WIN32\n#ifdef HONGGFUZZ_MUTATOR_EXPORTS\n#define HONGGFUZZ_MUTATOR_API __declspec(dllexport)\n#else\n#define HONGGFUZZ_MUTATOR_API __declspec(dllimport)\n#endif\n#else //_WIN32\n#define HONGGFUZZ_MUTATOR_API\n#endif\n\n#define MUTATOR_NAME \"honggfuzz\"\n\nHONGGFUZZ_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length);\nHONGGFUZZ_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state);\nHONGGFUZZ_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length);\nHONGGFUZZ_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags);\nHONGGFUZZ_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state);\n#define honggfuzz_free_state default_free_state\nHONGGFUZZ_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state);\nHONGGFUZZ_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state);\n#define honggfuzz_get_total_iteration_count return_unknown_or_infinite_total_iterations\nHONGGFUZZ_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes);\nHONGGFUZZ_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length);\nHONGGFUZZ_MUTATOR_API int FUNCNAME(help)(char ** help_str);\n\n#ifndef ALL_MUTATORS_IN_ONE\nHONGGFUZZ_MUTATOR_API void init(mutator_t * m);\n#endif\n"
  },
  {
    "path": "mutators/interesting_value_mutator/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (interesting_value_mutator)\n\ninclude_directories (${PROJECT_SOURCE_DIR}/../mutators/)\n\nset(INTERESTING_VALUE_SRC ${PROJECT_SOURCE_DIR}/interesting_value_mutator.c)\nsource_group(\"Library Sources\" FILES ${INTERESTING_VALUE_SRC})\n\nadd_library(interesting_value_mutator SHARED ${INTERESTING_VALUE_SRC}\n  $<TARGET_OBJECTS:mutators_object> $<TARGET_OBJECTS:jansson_object>)\ntarget_link_libraries(interesting_value_mutator utils)\ntarget_compile_definitions(interesting_value_mutator PUBLIC INTERESTING_VALUE_MUTATOR_EXPORTS)\ntarget_compile_definitions(interesting_value_mutator PUBLIC MUTATORS_NO_IMPORT)\ntarget_compile_definitions(interesting_value_mutator PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(interesting_value_mutator PUBLIC JANSSON_NO_IMPORT)\n\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(interesting_value_mutator Shlwapi)\nendif (WIN32)\n"
  },
  {
    "path": "mutators/interesting_value_mutator/interesting_value_mutator.c",
    "content": "#include \"interesting_value_mutator.h\"\n#include <mutators.h>\n#include <afl_helpers.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <utils.h>\n#include <jansson.h>\n#include <jansson_helper.h>\n\nstruct interesting_value_state\n{\n\tuint64_t num_bytes;\n\n\tchar * input;\n\tsize_t input_length;\n\tint iteration;\n\n\tmutate_info_t info;\n};\ntypedef struct interesting_value_state interesting_value_state_t;\n\nstatic int(*const mutate_funcs[])(mutate_info_t *, mutate_buffer_t *) = {\n\tinteresting_one_byte,\n\tinteresting_two_byte,\n\tinteresting_four_byte,\n};\n\nmutator_t interesting_value_mutator = {\n\tFUNCNAME(create),\n\tFUNCNAME(cleanup),\n\tFUNCNAME(mutate),\n\tFUNCNAME(mutate_extended),\n\tFUNCNAME(get_state),\n\tinteresting_value_free_state,\n\tFUNCNAME(set_state),\n\tFUNCNAME(get_current_iteration),\n\tinteresting_value_get_total_iteration_count,\n\tFUNCNAME(get_input_info),\n\tFUNCNAME(set_input),\n\tFUNCNAME(help)\n};\n\n/**\n * This function fills in m with all of the function pointers for this mutator.\n * @param m - a pointer to a mutator_t structure\n * @return none\n */\n#ifndef ALL_MUTATORS_IN_ONE\nINTERESTING_VALUE_MUTATOR_API void init(mutator_t * m)\n{\n\tmemcpy(m, &interesting_value_mutator, sizeof(mutator_t));\n}\n#endif\n\nstatic interesting_value_state_t * setup_options(char * options)\n{\n\tinteresting_value_state_t * state;\n\tint bytes_per_stage[] = { 1, 2, 4 };\n\tint i;\n\n\tstate = (interesting_value_state_t *)malloc(sizeof(interesting_value_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(interesting_value_state_t));\n\n\t//Setup defaults\n\tif (reset_mutate_info(&state->info)) {\n\t\tfree(state);\n\t\treturn NULL;\n\t}\n\n\tif (!options || !strlen(options))\n\t\treturn state;\n\n\tPARSE_MUTATE_INFO_OPTIONS(state, options, FUNCNAME(cleanup), 0, 0);\n\tPARSE_OPTION_INT(state, options, num_bytes, \"num_bytes\", FUNCNAME(cleanup));\n\n\tif (state->num_bytes) {\n\t\tstate->info.stage = -1;\n\t\tfor (i = 0; i < ARRAY_SIZE(bytes_per_stage) && state->info.stage < 0; i++)\n\t\t{\n\t\t\tif (bytes_per_stage[i] == state->num_bytes)\n\t\t\t\tstate->info.stage = i;\n\t\t}\n\t\tif (state->info.stage < 0)\n\t\t{\n\t\t\tFUNCNAME(cleanup)(state);\n\t\t\treturn NULL;\n\t\t}\n\t\tstate->info.one_stage_only = 1;\n\t}\n\treturn state;\n}\n\n/**\n * This function will allocate and initialize the mutator state used in the other Mutator API\n * functions.  \n * @param options - a json string that contains the mutator specific string of options.\n * @param state - Optionally, used to load a previously dumped state (with the get_state()\n * function), that defines the current iteration of the mutator.\n * @param input - used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size of the input buffer\n * @return a mutator specific structure or NULL on failure.\n */\nINTERESTING_VALUE_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length)\n{\n\tGENERIC_MUTATOR_CREATE(interesting_value_state_t, setup_options, FUNCNAME(cleanup));\n}\n\n/**\n * This function will release any resources that the mutator has open \n * and free the mutator state structure.\n * @param mutator_state - a mutator specific structure previously created by \n * the create function.  This structure will be freed and should not be referenced afterwards.\n */\nINTERESTING_VALUE_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state)\n{\n\tcleanup_mutate_info(&((interesting_value_state_t *)mutator_state)->info);\n\tGENERIC_MUTATOR_CLEANUP(interesting_value_state_t)\n}\n\nstatic int mutate_inner(void * mutator_state, char * buffer, size_t buffer_length, int is_thread_safe)\n{\n\tinteresting_value_state_t * state = (interesting_value_state_t *)mutator_state;\n\tmutate_buffer_t buf;\n\tint ret;\n\tif (buffer_length < state->input_length)\n\t\treturn -1;\n\n\tbuf.buffer = (uint8_t *)buffer;\n\tbuf.length = MIN(buffer_length, state->input_length);\n\tbuf.max_length = buffer_length;\n\tmemcpy(buf.buffer, state->input, buf.length);\n\n\tif(is_thread_safe && take_mutex(state->info.mutate_mutex))\n\t\treturn -1;\n\tstate->iteration++;\n\tret = mutate_one(&state->info, &buf, mutate_funcs, ARRAY_SIZE(mutate_funcs));\n\tif (is_thread_safe && release_mutex(state->info.mutate_mutex))\n\t\treturn -1;\n\treturn ret;\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nINTERESTING_VALUE_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length)\n{\n\treturn mutate_inner(mutator_state, buffer, buffer_length, 0);\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * This function also accepts a set of flags which instruct it how to mutate the input.  See global_types.h\n * for the list of available flags.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @param flags - A set of mutate flags that modify how this mutator mutates the input.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nINTERESTING_VALUE_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags)\n{\n\tSINGLE_INPUT_MUTATE_EXTENDED(interesting_value_state_t, state->info.mutate_mutex);\n}\n\n/**\n * This function will return the state of the mutator.  The returned value can be used to restart the\n * mutator at a later time, by passing it to the create or set_state function.  It is the caller's\n * responsibility to free the memory allocated here by calling the free_state function.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return - a buffer that defines the current state of the mutator.\n */\nINTERESTING_VALUE_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state)\n{\n\tinteresting_value_state_t * state = (interesting_value_state_t *)mutator_state;\n\tjson_t *state_obj, *temp;\n\tchar * ret;\n\n\tstate_obj = json_object();\n\tADD_INT(temp, state->iteration, state_obj, \"iteration\");\n\tif (!add_mutate_info_to_json(state_obj, &state->info))\n\t\treturn NULL;\n\n\tret = json_dumps(state_obj, 0);\n\tjson_decref(state_obj);\n\treturn ret;\n}\n\n/**\n * This function will set the current state of the mutator.\n * This can be used to restart a mutator once from a previous run.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param state - a previously dumped state buffer obtained by the get_state function.\n * @return 0 on success or non-zero on failure\n */\nINTERESTING_VALUE_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state)\n{\n\tinteresting_value_state_t * current_state = (interesting_value_state_t *)mutator_state;\n\tint result, temp_int;\n\tif (!state)\n\t\treturn 1;\n\tGET_INT(temp_int, state, current_state->iteration, \"iteration\", result);\n\tif (get_mutate_info_from_json(state, &current_state->info))\n\t\treturn 1;\n\treturn 0;\n}\n\n/**\n * This function will return the current iteration count of the mutator, i.e.\n * how many mutations have been generated with it.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return value - the number of previously generated mutations\n */\nINTERESTING_VALUE_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state)\n{\n\tGENERIC_MUTATOR_GET_ITERATION(interesting_value_state_t);\n}\n\n/**\n * This function will set the mutator's input to something new.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param new_input - The new input used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size in bytes of the input buffer.\n * @return 0 on success and -1 on failure\n */\nINTERESTING_VALUE_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length)\n{\n\tGENERIC_MUTATOR_SET_INPUT(interesting_value_state_t);\n}\n\n/**\n * Obtains information about the inputs that were given to the mutator when it was created\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param num_inputs - a pointer to an integer used to return the number of inputs given to this mutator\n * when it was created.  This parameter is optional and can be NULL, if this information is not needed\n * @param input_sizes - a pointer to a size_t array used to return the sizes of the inputs given to this\n * mutator when it was created. This parameter is optional and can be NULL, if this information is not needed.\n */\nINTERESTING_VALUE_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes)\n{\n\tSINGLE_INPUT_GET_INFO(interesting_value_state_t);\n}\n\n/**\n * This function sets a help message for the mutator.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nINTERESTING_VALUE_MUTATOR_API int FUNCNAME(help)(char **help_str)\n{\n\tGENERIC_MUTATOR_HELP(\n\"interesting_value - afl-based interesting value mutator\\n\"\n\"Options:\\n\"\n\"  num_bytes             The number of bytes to operate on; either 1, 2, or 4.\\n\"\n\"                          The default option is to do all three of the\\n\"\n\"                          options, one after another.\\n\"\n\"  skip_previous_stages  Whether the mutation outputs should skip any output\\n\"\n\"                          that would match the output of the bit_flip or\\n\"\n\"                          arithmetic mutator.  Useful when using multiple\\n\"\n\"                          mutators\\n\"\n\"\\n\"\n\t);\n}\n"
  },
  {
    "path": "mutators/interesting_value_mutator/interesting_value_mutator.h",
    "content": "#pragma once\n\n#include <global_types.h>\n#include <mutators.h>\n\n#ifdef _WIN32\n#ifdef INTERESTING_VALUE_MUTATOR_EXPORTS\n#define INTERESTING_VALUE_MUTATOR_API __declspec(dllexport)\n#else\n#define INTERESTING_VALUE_MUTATOR_API __declspec(dllimport)\n#endif\n#else //_WIN32\n#define INTERESTING_VALUE_MUTATOR_API\n#endif\n\n#define MUTATOR_NAME \"interesting_value\"\n\nINTERESTING_VALUE_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length);\nINTERESTING_VALUE_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state);\nINTERESTING_VALUE_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length);\nINTERESTING_VALUE_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags);\nINTERESTING_VALUE_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state);\n#define interesting_value_free_state default_free_state\nINTERESTING_VALUE_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state);\nINTERESTING_VALUE_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state);\n#define interesting_value_get_total_iteration_count return_unknown_or_infinite_total_iterations\nINTERESTING_VALUE_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes);\nINTERESTING_VALUE_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length);\nINTERESTING_VALUE_MUTATOR_API int FUNCNAME(help)(char **help_str);\n\n#ifndef ALL_MUTATORS_IN_ONE\nINTERESTING_VALUE_MUTATOR_API void init(mutator_t * m);\n#endif\n"
  },
  {
    "path": "mutators/multipart_mutator/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (multipart_mutator)\n\ninclude_directories (${PROJECT_SOURCE_DIR}/../mutators/)\n\nset(MULTIPART_SRC ${PROJECT_SOURCE_DIR}/multipart_mutator.c)\nsource_group(\"Library Sources\" FILES ${MULTIPART_SRC})\n\nadd_library(multipart_mutator SHARED ${MULTIPART_SRC}\n  $<TARGET_OBJECTS:mutators_object> $<TARGET_OBJECTS:jansson_object>)\ntarget_link_libraries(multipart_mutator utils)\ntarget_compile_definitions(multipart_mutator PUBLIC MULTIPART_MUTATOR_EXPORTS)\ntarget_compile_definitions(multipart_mutator PUBLIC MUTATORS_NO_IMPORT)\ntarget_compile_definitions(multipart_mutator PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(multipart_mutator PUBLIC JANSSON_NO_IMPORT)\n\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(multipart_mutator Shlwapi)\nendif (WIN32)\n"
  },
  {
    "path": "mutators/multipart_mutator/multipart_mutator.c",
    "content": "#include \"multipart_mutator.h\"\n#include <mutators.h>\n\n#ifdef _WIN32\n#include <Shlwapi.h>\n#else\n#include <libgen.h>\n#include <unistd.h>\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <utils.h>\n#include <mutator_factory.h>\n#include <jansson.h>\n#include <jansson_helper.h>\n\ntypedef struct\n{\n\tchar ** mutator_names;\n\tchar * mutator_directory;\n\n\tmutator_t ** mutators;\n\tvoid ** mutator_states;\n\tsize_t mutator_count;\n} multipart_state_t;\n\n///////////////////////////////////////////////////////////////////////////////////////////\n// Helper functions ///////////////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////////////////\n\nstatic int get_json_items(char * json_text, char * attribute_name, char *** output_array, int *all_use_same)\n{\n\tjson_error_t error;\n\tjson_t * root, *json_array, *item;\n\tchar ** dumped_array = NULL;\n\tint i, num_items;\n\n\t*output_array = NULL;\n\t*all_use_same = 0;\n\n\tif (!json_text)\n\t\treturn 0;\n\n\troot = json_loads(json_text, 0, &error);\n\tif (!root)\n\t\treturn -1;\n\n\tif (attribute_name) {\n\t\tjson_array = json_object_get(root, attribute_name);\n\t\tif (!json_array) { //Couldn't find the attribute\n\t\t\tjson_decref(root);\n\t\t\treturn 0;\n\t\t}\n\t}\n\telse\n\t\tjson_array = root;\n\n\t//if options isn't an array, then we want all the mutators to use the same options\n\tif(!json_is_array(json_array)) {\n\t\tdumped_array = malloc(sizeof(char *));\n\t\tdumped_array[0] = json_dumps(json_array, 0);\n\t\t*output_array = dumped_array;\n\t\t*all_use_same = 1;;\n\t\tjson_decref(root);\n\t\treturn 1;\n\t}\n\n\t//options is an empty array\n\tnum_items = json_array_size(json_array);\n\tif (!num_items) {\n\t\tjson_decref(root);\n\t\treturn 0;\n\t}\n\n\tdumped_array = calloc(num_items, sizeof(char *));\n\tfor (i = 0; i < num_items; i++)\n\t{\n\t\titem = json_array_get(json_array, i);\n\t\tif (!json_is_null(item))\n\t\t\tdumped_array[i] = json_dumps(item, 0);\n\t}\n\n\tjson_decref(root);\n\t*output_array = dumped_array;\n\treturn num_items;\n}\n\nstatic void free_mutator_arrays(char ** inputs, size_t * input_lengths, size_t inputs_count,\n\tchar ** options, size_t num_options, char ** states, size_t num_states)\n{\n\tsize_t i;\n\tfor (i = 0; i < inputs_count; i++)\n\t\tfree(inputs[i]);\n\tfor (i = 0; i < num_options; i++)\n\t\tfree(options[i]);\n\tfor (i = 0; i < num_states; i++)\n\t\tfree(states[i]);\n\tfree(inputs);\n\tfree(options);\n\tfree(states);\n\tfree(input_lengths);\n}\n\nstatic int setup_mutators(multipart_state_t * multipart_state, char * mutator_options, char * mutator_states, char * mutator_inputs)\n{\n\tsize_t inputs_count, i;\n\tchar **inputs = NULL, **options = NULL, **states = NULL, *option, *state;\n\tint num_options, num_states, all_use_same_options, all_use_same_states;\n\tsize_t * input_lengths;\n\tDEBUG_MSG(\"Setting up mutators\");\n\n\tif (decode_mem_array(mutator_inputs, &inputs, &input_lengths, &inputs_count)) {\n\t\tFATAL_MSG(\"Error parsing input data, is it in multipart format?\");\n\t\treturn 1;\n\t}\n\n\tif (!inputs_count) { //No inputs were found\n\t\tERROR_MSG(\"No inputs found\");\n\t\tfree_mutator_arrays(inputs, input_lengths, inputs_count, NULL, 0, NULL, 0);\n\t\treturn 1;\n\t}\n\n\tnum_options = get_json_items(mutator_options, \"options\", &options, &all_use_same_options);\n\tnum_states = get_json_items(mutator_states, NULL, &states, &all_use_same_states);\n\n\tif (inputs_count != multipart_state->mutator_count\n\t\t|| (num_options != 0 && !all_use_same_options && num_options != inputs_count)\n\t\t|| (num_states != 0 && !all_use_same_states && num_states != inputs_count))\n\t{\n\t\tfree_mutator_arrays(inputs, input_lengths, inputs_count, options, num_options, states, num_states);\n\t\treturn 1;\n\t}\n\n\tmultipart_state->mutators = calloc(inputs_count, sizeof(mutator_t *));\n\tmultipart_state->mutator_states = calloc(inputs_count, sizeof(void *));\n\tif(!multipart_state->mutators || !multipart_state->mutator_states) {\n\t\tfree(multipart_state->mutators);\n\t\tfree(multipart_state->mutator_states);\n\t\tmultipart_state->mutators = NULL;\n\t\tmultipart_state->mutator_states = NULL;\n\t\tfree_mutator_arrays(inputs, input_lengths, inputs_count, options, num_options, states, num_states);\n\t\treturn 1;\n\t}\n\n\tfor (i = 0; i < inputs_count; i++)\n\t{\n\t\tDEBUG_MSG(\"Setting up mutator %d\", i);\n\t\t//Create the mutator and get its state\n\t\tmultipart_state->mutators[i] = mutator_factory_directory(multipart_state->mutator_directory, multipart_state->mutator_names[i]);\n\t\tif (multipart_state->mutators[i]) {\n\t\t\toption = NULL;\n\t\t\tif (all_use_same_options)\n\t\t\t\toption = options[0];\n\t\t\telse if(num_options != 0)\n\t\t\t\toption = options[i];\n\t\t\tstate = NULL;\n\t\t\tif (all_use_same_states)\n\t\t\t\tstate = states[0];\n\t\t\telse if (num_states != 0)\n\t\t\t\tstate = states[i];\n\n\t\t\tmultipart_state->mutator_states[i] = multipart_state->mutators[i]->create(option, state, inputs[i], input_lengths[i]);\n\t\t}\n\n\t\tif (!multipart_state->mutator_states[i] || !multipart_state->mutators[i])\n\t\t{\n\t\t\tprintf(\"Unknown mutator %s, bad mutator options, or bad saved state for mutator %lu\\n\", multipart_state->mutator_names[i], i);\n\t\t\tfree(multipart_state->mutators[i]); //free the one that failed, if it did\n\t\t\tmultipart_state->mutators[i] = NULL;\n\t\t\tfree_mutator_arrays(inputs, input_lengths, inputs_count, options, num_options, states, num_states);\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\tfree_mutator_arrays(inputs, input_lengths, inputs_count, options, num_options, states, num_states);\n\treturn 0;\n}\n\n///////////////////////////////////////////////////////////////////////////////////////////\n// Mutator Functions //////////////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////////////////\n\nmutator_t multipart_mutator = {\n\tFUNCNAME(create),\n\tFUNCNAME(cleanup),\n\tFUNCNAME(mutate),\n\tFUNCNAME(mutate_extended),\n\tFUNCNAME(get_state),\n\tmultipart_free_state,\n\tFUNCNAME(set_state),\n\tFUNCNAME(get_current_iteration),\n\tFUNCNAME(get_total_iteration_count),\n\tFUNCNAME(get_input_info),\n\tFUNCNAME(set_input),\n\tFUNCNAME(help)\n};\n\n/**\n * This function fills in m with all of the function pointers for this mutator.\n * @param m - a pointer to a mutator_t structure\n * @return none\n */\n#ifndef ALL_MUTATORS_IN_ONE\nMULTIPART_MUTATOR_API void init(mutator_t * m)\n{\n\tmemcpy(m, &multipart_mutator, sizeof(mutator_t));\n}\n#endif\n\n/**\n * This function tries to determine the location of the currently executing library\n * to use as the default mutator directory.\n * @return either a string with the directory that contains the currently executing\n * library path, or NULL if it can't be determined.\n */\nstatic char * get_default_mutator_directory()\n{\n#ifdef _WIN32\n\tHANDLE handle;\n\tchar filename[MAX_PATH];\n\n\t//Find the path of the current library\n\tif (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |\n\t\tGET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,\n\t\t(LPCSTR)&get_default_mutator_directory,\n\t\t(HMODULE *)&handle))\n\t{\n\t\t//Trim the filename off, and look for other mutators in the same directory\n\t\tmemset(filename, 0, sizeof(filename));\n\t\tGetModuleFileName(handle, filename, sizeof(filename));\n\t\tPathRemoveFileSpec(filename);\n\t\treturn strdup(filename);\n\t}\n#else //!_WIN32\n\tFILE * fp;\n\tint notdone = 1, found = 0;\n\tchar path[256];\n\tchar * buffer = NULL;\n\tsize_t length = 0;\n\n#ifdef __APPLE__\n\t//Run vmmap on our process and locate this mutator's library on disk\n\tchar command[64];\n\tsnprintf(command, sizeof(command), \"vmmap %d\", getpid());\n\tfp = popen(command, \"r\");\n#else\n\t//Parse /proc/self/maps to try to locate this mutator's library on disk\n\tfp = fopen(\"/proc/self/maps\", \"r\");\n#endif\n\tif(fp) {\n\t\twhile(notdone > 0 && !found)\n\t\t{\n\t\t\tnotdone = getline(&buffer, &length, fp);\n\t\t\tif(notdone > 0) {\n\t\t\t\tmemset(path, 0, sizeof(path));\n#ifdef __APPLE__\n\t\t\t\tif(strncmp(buffer, \"__TEXT\", 6)) //if the line didn't start with __TEXT\n\t\t\t\t\tcontinue; //then skip it\n\t\t\t\tnotdone = sscanf(buffer, \"%*s %*x-%*x [ %*s %*s %*s %*s %*s %*s %255s\\n\", path);\n#else\n\t\t\t\tnotdone = sscanf(buffer, \"%*x-%*x %*c%*c%*c%*c %*x %*x:%*x %*u %255s\\n\", path);\n#endif\n\t\t\t\tif(strstr(path, MUTATOR_NAME \"_mutator\")) {\n\t\t\t\t\tfound = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfree(buffer);\n\t\tfclose(fp);\n\t\tif(found)\n\t\t\treturn strdup(dirname(path));\n\t}\n#endif\n\treturn NULL; //Couldn't figure out a reasonable default, search the normal library paths instead\n}\n\nstatic multipart_state_t * setup_options(char * options, char * input, size_t input_length)\n{\n\tmultipart_state_t * state;\n\n\tif (!options || !strlen(options)) //The multipart needs options\n\t\treturn NULL; //so error out if they weren't provided\n\n\tstate = (multipart_state_t *)malloc(sizeof(multipart_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(multipart_state_t));\n\n\tPARSE_OPTION_STRING(state, options, mutator_directory, \"mutator_directory\", FUNCNAME(cleanup));\n\tPARSE_OPTION_ARRAY(state, options, mutator_names, mutator_count, \"mutators\", FUNCNAME(cleanup));\n\n\tif(!state->mutator_directory)\n\t\tstate->mutator_directory = get_default_mutator_directory();\n\n\tif (state->mutator_count == 0) {\n\t\tFUNCNAME(cleanup)(state);\n\t\treturn NULL;\n\t}\n\n\treturn state;\n}\n\n/**\n * This function will allocate and initialize the mutator state used in the other Mutator API\n * functions.\n * @param options - a json string that contains the mutator specific string of options.\n * @param state - Optionally, used to load a previously dumped state (with the get_state()\n * function), that defines the current iteration of the mutator.\n * @param input - the input used to produce new mutated inputs later when the mutate function is called\n * This parameter must be a string containing a JSON array of JSON mem items of the individual inputs\n * @param input_length - the size of the input buffer\n * @return a mutator specific structure or NULL on failure.\n */\nMULTIPART_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length)\n{\n\tDEBUG_MSG(\"Creating multipart mutator\");\n\tmultipart_state_t * new_state;\n\tnew_state = setup_options(options, input, input_length);\n\tif (!new_state)\n\t\treturn NULL;\n\n\tif (setup_mutators(new_state, options, state, input)) {\n\t\tFUNCNAME(cleanup)(new_state);\n\t\treturn NULL;\n\t}\n\n\treturn new_state;\n}\n\n/**\n * This function will release any resources that the mutator has open\n * and free the mutator state structure.\n * @param mutator_state - a mutator specific structure previously created by\n * the create function.  This structure will be freed and should not be referenced afterwards.\n */\nMULTIPART_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state)\n{\n\tmultipart_state_t * state = (multipart_state_t *)mutator_state;\n\tsize_t i;\n\n\tfor (i = 0; i < state->mutator_count; i++)\n\t{\n\t\tfree(state->mutator_names[i]);\n\t\tif (state->mutators && state->mutators[i])\n\t\t{\n\t\t\tstate->mutators[i]->cleanup(state->mutator_states[i]);\n\t\t\tfree(state->mutators[i]);\n\t\t}\n\t}\n\n\tfree(state->mutator_directory);\n\tfree(state->mutators);\n\tfree(state->mutator_states);\n\tfree(state);\n}\n\n/**\n * The multipart mutator does not implement the mutate function, and thus this function always\n * returns an error (-1).\n * @return - -1 to indicate an error\n */\nMULTIPART_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length)\n{\n\treturn -1;\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * This function also accepts a set of flags which instruct it how to mutate the input.  See global_types.h\n * for the list of available flags.  The multipart mutator does not support mutating all of the inputs given\n * during create at once, so the MUTATE_MULTIPLE_INPUTS flag must be set.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @param flags - A set of mutate flags that modify how this mutator mutates the input.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nMULTIPART_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags)\n{\n\tmultipart_state_t * state = (multipart_state_t *)mutator_state;\n\tunsigned short input_part = flags & MUTATE_MULTIPLE_INPUTS_MASK;\n\tuint64_t inner_flags;\n\tif (!(flags & MUTATE_MULTIPLE_INPUTS) || input_part < 0 || input_part >= state->mutator_count)\n\t\treturn -1;\n\n\tinner_flags = flags & ~(MUTATE_MULTIPLE_INPUTS | MUTATE_MULTIPLE_INPUTS_MASK);\n\treturn state->mutators[input_part]->mutate_extended(state->mutator_states[input_part], buffer, buffer_length, inner_flags);\n}\n\n/**\n * This function will return the state of the mutator.  The returned value can be used to restart the\n * mutator at a later time, by passing it to the create or set_state function.  It is the caller's\n * responsibility to free the memory allocated here by calling the free_state function.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return - a buffer that defines the current state of the mutator.\n */\nMULTIPART_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state)\n{\n\tmultipart_state_t * state = (multipart_state_t *)mutator_state;\n\tjson_t *states_array, *temp;\n\tjson_error_t error;\n\tchar * ret, *single_state;\n\tsize_t i;\n\n\tstates_array = json_array();\n\tfor (i = 0; i < state->mutator_count; i++)\n\t{\n\t\tsingle_state = state->mutators[i]->get_state(state->mutator_states[i]);\n\t\ttemp = json_loads(single_state, 0, &error);\n\t\tstate->mutators[i]->free_state(single_state);\n\t\tjson_array_append_new(states_array, temp);\n\t}\n\n\tret = json_dumps(states_array, 0);\n\tjson_decref(states_array);\n\treturn ret;\n}\n\n/**\n * This function will set the current state of the mutator.\n * This can be used to restart a mutator once from a previous run.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param state - a previously dumped state buffer obtained by the get_state function.\n * @return 0 on success or non-zero on failure\n */\nMULTIPART_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state)\n{\n\tmultipart_state_t * current_state = (multipart_state_t *)mutator_state;\n\tjson_t *states_array, *temp;\n\tjson_error_t error;\n\tchar *single_state;\n\tsize_t i;\n\n\tif (!state)\n\t\treturn 1;\n\tstates_array = json_loads(state, 0, &error);\n\tif (!states_array || !json_is_array(states_array) || json_array_size(states_array) != current_state->mutator_count)\n\t{\n\t\tif(states_array)\n\t\t\tjson_decref(states_array);\n\t\treturn 1;\n\t}\n\n\tfor (i = 0; i < current_state->mutator_count; i++)\n\t{\n\t\ttemp = json_array_get(states_array, i);\n\t\tsingle_state = json_dumps(temp, 0);\n\t\tcurrent_state->mutators[i]->set_state(current_state->mutator_states[i], single_state);\n\t\tfree(single_state);\n\t}\n\n\tjson_decref(states_array);\n\treturn 0;\n}\n\n/**\n * This function will return the current iteration count of the mutator, i.e.\n * how many mutations have been generated with it.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return value - the number of previously generated mutations\n */\nMULTIPART_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state)\n{\n\tmultipart_state_t * state = (multipart_state_t *)mutator_state;\n\tint lowest = -1, temp;\n\tsize_t i;\n\tfor (i = 0; i < state->mutator_count; i++) {\n\t\ttemp = state->mutators[i]->get_current_iteration(state->mutator_states[i]);\n\t\tif (lowest == -1 || lowest > temp)\n\t\t\tlowest = temp;\n\t}\n\treturn lowest;\n}\n\n/**\n * Returns the total number of mutations possible with this mutator and the current options.\n * For the multipart mutator, it will determine the number of mutations possible from all of\n * the mutators and return the lowest value\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return the number of possible mutations with this mutator, or -1 if infinite or the number\n * cannot be determined.\n */\nMULTIPART_MUTATOR_API int FUNCNAME(get_total_iteration_count)(void * mutator_state)\n{\n\tmultipart_state_t * state = (multipart_state_t *)mutator_state;\n\tint lowest = -1, temp;\n\tsize_t i;\n\tfor (i = 0; i < state->mutator_count; i++) {\n\t\ttemp = state->mutators[i]->get_total_iteration_count(state->mutator_states[i]);\n\t\tif (lowest == -1 || (temp != -1 && lowest > temp))\n\t\t\tlowest = temp;\n\t}\n\treturn lowest;\n}\n\n/**\n * Obtains information about the inputs that were given to the mutator when it was created\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param num_inputs - a pointer to an integer used to return the number of inputs given to this mutator\n * when it was created.  This parameter is optional and can be NULL, if this information is not needed\n * @param input_sizes - a pointer to a size_t array used to return the sizes of the inputs given to this\n * mutator when it was created. This parameter is optional and can be NULL, if this information is not needed.\n */\nMULTIPART_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes)\n{\n\tmultipart_state_t * state = (multipart_state_t *)mutator_state;\n\tsize_t i;\n\tsize_t * sizes;\n\tif (num_inputs)\n\t\t*num_inputs = state->mutator_count;\n\tif (input_sizes) {\n\t\t*input_sizes = malloc(sizeof(size_t) * state->mutator_count);\n\t\tfor (i = 0; i < state->mutator_count; i++)\n\t\t{\n\t\t\tstate->mutators[i]->get_input_info(state->mutator_states[i], NULL, &sizes);\n\t\t\t(*input_sizes)[i] = sizes[0];\n\t\t\tfree(sizes);\n\t\t}\n\t}\n}\n\n/**\n * This function will set the mutator's input to something new.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param new_input - The new input used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size in bytes of the input buffer.\n * @return 0 on success and -1 on failure\n */\nMULTIPART_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length)\n{\n\tmultipart_state_t * state = (multipart_state_t *)mutator_state;\n\tsize_t inputs_count, i;\n\tchar **inputs = NULL;\n\tsize_t * input_lengths;\n\tint ret = 0;\n\n\tif (decode_mem_array(new_input, &inputs, &input_lengths, &inputs_count))\n\t\treturn -1;\n\tif (inputs_count != state->mutator_count) {\n\t\tfree_mutator_arrays(inputs, input_lengths, inputs_count, NULL, 0, NULL, 0);\n\t\treturn -1;\n\t}\n\n\tfor (i = 0; ret == 0 && i < state->mutator_count; i++)\n\t\tret = state->mutators[i]->set_input(state->mutator_states[i], inputs[i], input_lengths[i]);\n\tfree_mutator_arrays(inputs, input_lengths, inputs_count, NULL, 0, NULL, 0);\n\treturn ret;\n}\n\n/**\n * This function sets a help message for the mutator.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nMULTIPART_MUTATOR_API int FUNCNAME(help)(char **help_str)\n{\n\tGENERIC_MUTATOR_HELP(\n\"multipart - a mutator to manage multiple mutators\\n\"\n\"Required Options:\\n\"\n\"  mutators              An array of mutator names or library filenames that\\n\"\n\"                          the multipart mutator should use to mutate the input.\\n\"\n\"Optional Options:\\n\"\n\"  mutator_directory     The directory to look for other mutator libraries in\\n\"\n\"  options               An array of mutator options to pass to each mutator used\\n\"\n\"\\n\"\n\t);\n}\n"
  },
  {
    "path": "mutators/multipart_mutator/multipart_mutator.h",
    "content": "#pragma once\n\n#include <global_types.h>\n#include <mutators.h>\n\n#ifdef _WIN32\n#ifdef MULTIPART_MUTATOR_EXPORTS\n#define MULTIPART_MUTATOR_API __declspec(dllexport)\n#else\n#define MULTIPART_MUTATOR_API __declspec(dllimport)\n#endif\n#else //_WIN32\n#define MULTIPART_MUTATOR_API\n#endif\n\n#define MUTATOR_NAME \"multipart\"\n\nMULTIPART_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length);\nMULTIPART_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state);\nMULTIPART_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length);\nMULTIPART_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags);\nMULTIPART_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state);\n#define multipart_free_state default_free_state\nMULTIPART_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state);\nMULTIPART_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state);\nMULTIPART_MUTATOR_API int FUNCNAME(get_total_iteration_count)(void * mutator_state);\nMULTIPART_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes);\nMULTIPART_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length);\nMULTIPART_MUTATOR_API int FUNCNAME(help)(char **help_str);\n\n#ifndef ALL_MUTATORS_IN_ONE\nMULTIPART_MUTATOR_API void init(mutator_t * m);\n#endif\n"
  },
  {
    "path": "mutators/mutator_tester/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (mutator_tester)\nset(MUTATOR_TESTER_SRC ${PROJECT_SOURCE_DIR}/mutator_tester.c)\nadd_executable(mutator_tester ${MUTATOR_TESTER_SRC} $<TARGET_OBJECTS:jansson_object>)\n\ntarget_link_libraries(mutator_tester utils)\nsource_group(\"Executable Sources\" FILES ${MUTATOR_TESTER_SRC})\ntarget_compile_definitions(mutator_tester PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(mutator_tester PUBLIC JANSSON_NO_IMPORT)\n\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(mutator_tester Shlwapi)\nelse (WIN32)\n  target_link_libraries(mutator_tester dl)\n  target_link_libraries(mutator_tester pthread)\nendif (WIN32)\n"
  },
  {
    "path": "mutators/mutator_tester/mutator_tester.c",
    "content": "#include \"mutator_tester.h\"\n\n#include <global_types.h>\n#include <jansson.h>\n#include <jansson_helper.h>\n#include <mutator_factory.h>\n#include <utils.h>\n\n#include <string.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <time.h>\n\n#ifdef _WIN32\n#include <windows.h>\n#else\n#include <dlfcn.h>\n#include <unistd.h>\n#endif\n\n//The list of test functions\nstatic test_info_t test_info[NUM_TESTS] =\n{\n\t{ test_all,    \"Run all tests!\" }, //test_all MUST be the first entry in the test_info array\n\t{ test_mutate, \"Test the mutate() function, this will print each iteration of mutation\" },\n\t{ test_state,  \"Test the get_state() and set_state() functions.\" },\n\t{ test_thread_mutate, \"Test the thread safe mutate function. Only non-repeating mutators will pass this test\" },\n\t{ test_run_forever, \"Test the mutate() function by mutating the given buffer endlessly.\" },\n\t{ test_mutate_parts, \"Test the mutate_input_part() function.\" },\n\t{ test_mutate_once, \"Call the mutate() function once and print the output\" },\n};\n\nstatic test_function test_all_tests[] =\n{\n\ttest_mutate,\n\ttest_state,\n\ttest_thread_mutate,\n\ttest_mutate_parts,\n\ttest_mutate_once\n};\n\n/** This function sets up the mutator for testing. This test program is designed\n * To aid in the debugging of a mutator DLL. The dll is loaded like it would be in the \n * full blown fuzzer and a series of tests are run against it to find common errors.\n * @return - if the process fails, it will return 1, if a test fails, the error code \n * returned will be its test number + 100. For example if test 1 fails main will return 101\n * 0 is returned on success!\n */\nint main(int argc, char *argv[])\n{\n\t//Args\n\tchar *test_type_to_convert = NULL, *mutator_path = NULL, *mutator_options = NULL, *seed_file = NULL; //args\n\tchar *seed_buffer = NULL;\n\tchar *test_string = NULL;\n\tchar *help = NULL;\n\tint ret;\n\tunsigned long test_num;\n\tsize_t seed_length;\n\tmutator_t * mutator;\n\tvoid * mutator_state;\n\n\tif (argc == 3 && !strcmp(argv[1], \"help\"))\n\t{\n\t\thelp = mutator_help(argv[2]);\n\t\tif(help)\n\t\t\tputs(help);\n\t\tfree(help);\n\t\treturn 0;\n\t}\n\telse if (argc < 3)\n\t{\n\t\tprint_usage(argv[0]);\n\t\treturn 0;\n\t}\n\n\ttest_type_to_convert = argv[1];\n\tmutator_path = argv[2];\n\tif(argc > 3)\n\t\tmutator_options = argv[3];\n\n\tsrand(time(NULL));\n\n\t//Convert the test type to int\n\ttest_num = strtoul(test_type_to_convert, &test_string, 10);\n\tif (test_string == test_type_to_convert || test_num >= NUM_TESTS || *test_string != '\\0') { //Check for empty str, and overflow\n\t\tprintf(\"Invalid test number!\");\n\t\treturn 1;\n\t}\n\n\tif (argc < 5) {\n\t\tseed_length = 8;\n\t\tseed_buffer = (char *)malloc(seed_length);\n\t\tmemset(seed_buffer, 0, seed_length);\n\t}\n\telse\n\t{\n\t\t//Load the seed buffer from a file\n\t\tseed_file = argv[4];\n\t\tseed_length = read_file(seed_file, &seed_buffer);\n\t\tif (seed_length <= 0)\n\t\t{\n\t\t\tprintf(\"Could not read seed file or empty seed file: %s\\n\", seed_file);\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\t//Load the DLL\n\tmutator = mutator_factory(mutator_path);\n\tif (mutator == NULL) {\n\t\tprintf(\"Load mutator returned a NULL pointer\\n\");\n\t\treturn 1;\n\t}\n\t//Setup the mutator\n\tmutator_state = setup_mutator(mutator, mutator_options, seed_buffer, seed_length);\n\tif (!mutator_state) {\n\t\tprintf(\"setup_mutator() failed\\n\");\n\t\treturn 1;\n\t}\n\n\t//Everything is setup, now do the tests.\n\tret = test_info[test_num].func(mutator, mutator_state, mutator_options, seed_buffer, seed_length);\n\tif (ret)\n\t\tret = 100 + test_num;\n\n\tmutator->cleanup(mutator_state);\n\tfree(mutator);\n\tfree(seed_buffer);\n\treturn ret;\n}\n\n/**\n * This function initinalizes the mutator. It calls its create function to setup \n * the mutators state struct, and returns it. This struct is required for all other\n * mutator spicific function calls.\n * \n * @param mutator - a mutator_t struct with the API function pointers for the mutator to setup\n * @param mutator_options - a JSON string that contains the mutator options\n * @param seed_buffer - The data buffer used to seed the mutator\n * @param seed_length - The length of the seed_buffer in bytes\n * @return mutator_state - the state struct for a spicific mutator\n */\nvoid * setup_mutator(mutator_t * mutator, char * mutator_options, char * seed_buffer, size_t seed_length)\n{\n\tvoid * mutator_state;\n\n\tmutator_state = mutator->create(mutator_options, NULL, seed_buffer, seed_length);\n\tif (!mutator_state)\n\t{\n\t\tprintf(\"Bad mutator options or saved state\\n\");\n\t\treturn NULL;\n\t}\n\treturn mutator_state;\n}\n\n/**\n * This function prints the usage statment for the program.\n *\n * @param argv - The array of command line arguments\n * @return none\n */\nvoid print_usage(char *executable_name)\n{\n\tint i;\n\tprintf(\"\\nUsage:\\n\");\n\tprintf(\"\\n%s help \\\"/path/to/mutator/directory\\\"\\n\", executable_name);\n\tprintf(\"\\tPrint mutator help.\\n\");\n\tprintf(\"\\n%s test_type \\\"/path/to/mutator.dll\\\" [\\\"JSON Mutator Options String\\\" [path/to/input/data]]\\n\", executable_name);\n\tprintf(\"\\tRun a mutator test. Valid Test Types:\\n\");\n\tfor (i = 0; i < NUM_TESTS; i++)\n\t\tprintf(\"\\t\\t %d - %s\\n\", i, test_info[i].usage_info);\n}\n\n/**\n * This function runs all other tests in the test_info struct.\n *\n * @param mutator - the mutator struct representing the mutator to be tested, returned by load_mutator\n * @param mutator_state - the state struct for the mutator being tested.  Currently unused for this test.\n * @param mutator_options - a JSON string that contains the mutator options\n * @param seed_buffer - The data buffer used to seed the mutator\n * @param seed_length - The length of the seed_buffer in bytes\n * @return int - the results of the tests. 0 for success and nonzero for fail\n */\nint test_all(mutator_t * mutator, void * mutator_state, char * mutator_options, char * seed_buffer, size_t seed_length) {\n\tint test_num, ret = 0;\n\tvoid * single_test_mutator_state;\n\n\tfor (test_num = 0; test_num < sizeof(test_all_tests)/sizeof(test_all_tests[0]) && !ret; test_num++)\n\t{\n\t\tsingle_test_mutator_state = setup_mutator(mutator, mutator_options, seed_buffer, seed_length);\n\t\tif (!single_test_mutator_state) {\n\t\t\tprintf(\"setup_mutator() failed\\n\");\n\t\t\treturn 1;\n\t\t}\n\n\t\tprintf(\"+---------+\\n\");\n\t\tprintf(\"| TEST %2d |\\n\", test_num);\n\t\tprintf(\"+---------+\\n\\n\");\n\n\t\tret = test_all_tests[test_num](mutator, single_test_mutator_state, mutator_options, seed_buffer, seed_length);\n\t\tmutator->cleanup(single_test_mutator_state);\n\t}\n\treturn ret;\n}\n\n/**\n * This function tests several testcases around the mutators mutate() function.\n * This allows the user to see if the data is being mutated in the expected manner.\n * It also ensures that each iteration of mutation is being tracked appropriately.\n * \n * @param mutator - the mutator struct representing the mutator to be tested, returned by load_mutator\n * @param mutator_state - the state struct for the mutator being tested, This state should\n * be at the starting state for the mutator (iteration 0)\n * @param mutator_options - a JSON string that contains the mutator options\n * @param seed_buffer - The data buffer used to seed the mutator\n * @param seed_length - The length of the seed_buffer in bytes\n * @return int - the results of the tests. 0 for success and 1 for fail\n */\nint test_mutate(mutator_t * mutator, void * mutator_state, char * mutator_options, char * seed_buffer, size_t seed_length) {\n\n\tint total_iterations, mut_iter, i, limit;\n\tchar * mutate_buffer = (char *)malloc(2 * seed_length);\n\tint ret;\n\n\ttotal_iterations = mutator->get_total_iteration_count(mutator_state);\n\tprintf(\"The mutator reported %d required iterations.\\n\\n\", total_iterations);\n\tprintf(\"=== Original Data ===\\n\");\n\tprint_hex(seed_buffer, seed_length);\n\tprintf(\"\\n\\n\\n\");\n\n\tlimit = total_iterations;\n\tif (total_iterations == -1)\n\t\tlimit = 64;\n\n\tfor (i = 0; i <= limit; i++) {\n\t\tprintf(\"=== Iteration %d ===\\n\", i);\n\t\tmut_iter = mutator->get_current_iteration(mutator_state);\n\t\tif (i != mut_iter) {\n\t\t\tprintf(\"ERROR: The mutator reports that it is on iteration %d but the real iteration is %d\\n\", mut_iter, i);\n\t\t\treturn 1;\n\t\t}\n\t\tret = mutator->mutate(mutator_state, mutate_buffer, 2 * seed_length);\n\t\tprintf(\"mutated buffer, %3d bytes:\\n\", ret);\n\t\tif (ret != -1 && ret != 0) {\n\t\t\tprint_hex(mutate_buffer, ret);\n\t\t}\n\t\tprintf(\"\\n\\n\");\n\n\t\tif (ret == 0 && i == total_iterations) {\n\t\t\tprintf(\"The mutator reported that everything has been mutated on iteration %d of %d\\n\", i, total_iterations);\n\t\t\tbreak;\n\t\t} else if (ret == 0 && total_iterations == -1) { //undeterminable number of outputs, it's not really a bug\n\t\t\tprintf(\"The mutator reported that everything has been mutated on iteration %d\\n\", i);\n\t\t\tbreak;\n\t\t} else if (ret == -1) {\n\t\t\tprintf(\"ERROR: the mutator reported an error!\\n\");\n\t\t\treturn 1;\n\t\t} else if (i == limit && total_iterations != -1) {\n\t\t\tprintf(\"ERROR: The expected number of mutations were performed (%d), but the mutator did not return 0\\n\", total_iterations);\n\t\t}\n\t}\n\n\tif (total_iterations != -1 && ret != 0)\n\t{\n\t\tfor (i = 1; i < 100 && ret != 0; i++)\n\t\t\tret = mutator->mutate(mutator_state, mutate_buffer, 2 * seed_length);\n\n\t\tif (ret == 0 && total_iterations != -1)\n\t\t\tprintf(\"ERROR: it took %d extra iterations for the mutator to return 0\", i-1);\n\t\telse\n\t\t\tprintf(\"ERROR: the mutator did not return 0 even after %d extra iterations\", i-1);\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n/**\n * This function tests several testcases around the mutators get_state() and set_state functions.\n * This allows the user to check if the state of a mutator is being correctly saved and restored.\n *\n * @param mutator - the mutator struct returned by load_mutator\n * @param mutator_state - the state struct for a spicific mutator\n * @param mutator_options - a JSON string that contains the mutator options\n * @param seed_buffer - The data buffer used to seed the mutator\n * @param seed_length - The length of the seed_buffer in bytes\n * @return int - the results of the tests. 0 for success and 1 for fail\n */\nint test_state(mutator_t * mutator, void * mutator_state, char * mutator_options, char * seed_buffer, size_t seed_length) {\n\n\tsize_t total_iterations, i;\n\tchar * mutate_buffer = (char *)malloc(2 * seed_length);\n\tchar * new_mutate_buffer = (char *)malloc(2 * seed_length);\n\tchar * old_saved_state_buffer;\n\tchar * new_saved_state_buffer;\n\tjson_t * old_JSON_state;\n\tjson_t * new_JSON_state;\n\tint ret, old_iter, new_iter, old_mutate_length, new_mutate_length;\n\tvoid * new_mutator_state;\n\n\tif (!mutate_buffer || !new_mutate_buffer)\n\t{\n\t\tprintf(\"Malloc failed\\n\");\n\t\tfree(mutate_buffer);\n\t\tfree(new_mutate_buffer);\n\t\treturn 1;\n\t}\n\n\ttotal_iterations = mutator->get_total_iteration_count(mutator_state);\n\tif (total_iterations == -1) {\n\t\ttotal_iterations = 64;\n\t}\n\tprintf(\"Mutating the data %zi times\\n\", total_iterations / 2 );\n\tfor (i = 0; i <= total_iterations / 2; i++) {\n\t\tret = mutator->mutate(mutator_state, mutate_buffer, 2 * seed_length);\n\t\tif (ret <= 0) {\n\t\t\tif (ret < 0)\n\t\t\t\tprintf(\"ERROR: The mutate() function returned an error or finished pre-maturely. Run test 1 for more info\\n\");\n\t\t\telse\n\t\t\t\tprintf(\"Mutator finished mutations early\\n\");\n\t\t\tbreak;\n\t\t}\n\t}\n\tprintf(\"Mutation stopped on iteration %zi\\n\", i);\n\tprintf(\"Saving the mutators state...\\n\");\n\told_saved_state_buffer = (char *)mutator->get_state(mutator_state);\n\tprintf(\"Here is the OLD JSON string:\\n%s\\n\", old_saved_state_buffer);\n\n\t//Setup a new mutator to restore the state into\n\tnew_mutator_state = setup_mutator(mutator, mutator_options, seed_buffer, seed_length);\n\tif (!new_mutator_state) {\n\t\tprintf(\"setup_mutator() failed\\n\");\n\t\tfree(mutate_buffer);\n\t\tfree(new_mutate_buffer);\n\t\tmutator->free_state(old_saved_state_buffer);\n\t\treturn 1;\n\t}\n\n\t//set the state from the old -> new\n\tprintf(\"Restoring the mutators state...\\n\");\n\tret = mutator->set_state(new_mutator_state, old_saved_state_buffer);\n\tif (ret) {\n\t\tprintf(\"set_state() returned error code %i\\n\", ret);\n\t}\n\tnew_saved_state_buffer = (char *)mutator->get_state(new_mutator_state);\n\tprintf(\"Here is the NEW JSON string:\\n%s\\n\", new_saved_state_buffer);\n\n\t//Compare JSON states to see if they were saved and restored correctly\n\told_JSON_state = json_string(old_saved_state_buffer);\n\tmutator->free_state(old_saved_state_buffer);\n\tif (old_JSON_state == NULL) {\n\t\tprintf(\"Failed to convert old JSON string to JSON object\\n\");\n\t\tfree(mutate_buffer);\n\t\tfree(new_mutate_buffer);\n\t\tmutator->free_state(new_saved_state_buffer);\n\t\tmutator->cleanup(new_mutator_state);\n\t\treturn 1;\n\t}\n\tnew_JSON_state = json_string(new_saved_state_buffer);\n\tmutator->free_state(new_saved_state_buffer);\n\tif (new_JSON_state == NULL) {\n\t\tprintf(\"Failed to convert new JSON string to JSON object\\n\");\n\t\tjson_decref(old_JSON_state);\n\t\tfree(mutate_buffer);\n\t\tfree(new_mutate_buffer);\n\t\tmutator->cleanup(new_mutator_state);\n\t\treturn 1;\n\t}\n\tif (!json_equal(old_JSON_state, new_JSON_state)) {\n\t\tprintf(\"The mutator failed to restore state properly\\n\");\n\t\tjson_decref(old_JSON_state);\n\t\tjson_decref(new_JSON_state);\n\t\tfree(mutate_buffer);\n\t\tfree(new_mutate_buffer);\n\t\tmutator->cleanup(new_mutator_state);\n\t\treturn 1;\n\t}\n\tjson_decref(old_JSON_state);\n\tjson_decref(new_JSON_state);\n\tprintf(\"The saved states are equal, this is expected\\n\");\n\n\t//Get the iteration count and call mutate once, just to make sure that they work\n\told_iter = mutator->get_current_iteration(mutator_state);\n\tnew_iter = mutator->get_current_iteration(new_mutator_state);\n\n\told_mutate_length = mutator->mutate(mutator_state, mutate_buffer, 2 * seed_length);\n\tnew_mutate_length = mutator->mutate(new_mutator_state, new_mutate_buffer, 2 * seed_length);\n\n\tif (old_iter == new_iter\n\t\t&& old_mutate_length == new_mutate_length && old_mutate_length >= 0\n\t\t&& !memcmp(mutate_buffer, new_mutate_buffer, old_mutate_length)) {\n\t\tprintf(\"Success! The mutator has restored its state\\n\");\n\t\tret = 0;\n\t} else {\n\t\tprintf(\"The mutator failed to mutate properly after restoring the state\\n\"\n\t\t\t\"Original mutator iteration count %d New mutator iteration count %d\\n\"\n\t\t\t\"Original mutator output length %d new mutator output length %d\\n\", old_iter, new_iter, old_mutate_length, new_mutate_length);\n\t\tprintf(\"old (%d bytes): \", old_mutate_length);\n\t\tif(old_mutate_length > 0)\n\t\t\tprint_hex(mutate_buffer, old_mutate_length);\n\t\tprintf(\"\\nnew (%d bytes): \", new_mutate_length);\n\t\tif(new_mutate_length > 0)\n\t\t\tprint_hex(new_mutate_buffer, new_mutate_length);\n\t\tprintf(\"\\n\");\n\t\tret = 1;\n\t}\n\n\tfree(mutate_buffer);\n\tfree(new_mutate_buffer);\n\tmutator->cleanup(new_mutator_state);\n\treturn ret;\n}\n\n#define RACER_IS_THREAD_SAFE\n#define NUM_RACER_THREADS 10\n#define NUM_RACER_SAVED_BUFFERS 256\n#define NUM_RACER_ROUNDS 50\n\nstatic int racer_buffers_count;\nstatic int racer_saved_buffer_lengths[NUM_RACER_SAVED_BUFFERS];\nstatic char * racer_saved_buffers[NUM_RACER_SAVED_BUFFERS];\nstatic char * racer_seed_buffer;\nstatic size_t racer_seed_length;\nstatic mutator_t * racer_mutator;\n\n#ifdef _WIN32\nDWORD WINAPI mutate_racer(LPVOID mutator_state)\n#else\nvoid * mutate_racer(void * mutator_state)\n#endif\n{\n\tint index = 0;\n\tsize_t mutate_buffer_length = 2 * racer_seed_length;\n\n\twhile (index < NUM_RACER_SAVED_BUFFERS)\n\t{\n#ifdef _WIN32\n\t\tindex = InterlockedIncrement(&racer_buffers_count) - 1;\n#else\n\t\tindex = __sync_fetch_and_add(&racer_buffers_count, 1) - 1;\n#endif\n\t\tif (index >= NUM_RACER_SAVED_BUFFERS)\n\t\t\tbreak;\n\t\tracer_saved_buffers[index] = malloc(mutate_buffer_length);\n\t\tmemcpy(racer_saved_buffers[index], racer_seed_buffer, racer_seed_length);\n#ifdef RACER_IS_THREAD_SAFE\n\t\tracer_saved_buffer_lengths[index] = racer_mutator->mutate_extended(mutator_state, racer_saved_buffers[index], mutate_buffer_length, MUTATE_THREAD_SAFE);\n#else\n\t\tracer_saved_buffer_lengths[index] = racer_mutator->mutate(mutator_state, racer_saved_buffers[index], mutate_buffer_length);\n#endif\n\t\tif (racer_saved_buffer_lengths[index] <= 0)\n\t\t\tbreak;\n\t}\n\n#ifdef _WIN32\n\treturn index;\n#else\n\treturn NULL;\n#endif\n}\n\n/**\n * This function tests the thread safe mutate function.\n *\n * @param mutator - the mutator struct returned by load_mutator\n * @param mutator_state - the state struct for a spicific mutator\n * @param mutator_options - a JSON string that contains the mutator options\n * @param seed_buffer - The data buffer used to seed the mutator\n * @param seed_length - The length of the seed_buffer in bytes\n * @return int - the results of the tests. 0 for success and 1 for fail\n */\nint test_thread_mutate(mutator_t * mutator, void * mutator_state, char * mutator_options, char * seed_buffer, size_t seed_length) {\n\tint round, i, j, found_duplicate = 0;\n\n\tracer_seed_buffer = seed_buffer;\n\tracer_seed_length = seed_length;\n\tracer_mutator = mutator;\n\n\tfor (round = 0; !found_duplicate && round < NUM_RACER_ROUNDS; round++)\n\t{\n\t\tmemset(racer_saved_buffers, 0, sizeof(racer_saved_buffers));\n\t\tmemset(racer_saved_buffer_lengths, 0, sizeof(racer_saved_buffer_lengths));\n\t\tracer_buffers_count = 0;\n\n\t\tmutator_state = setup_mutator(mutator, mutator_options, seed_buffer, seed_length);\n\t\tif (!mutator_state) {\n\t\t\tprintf(\"setup_mutator() failed\\n\");\n\t\t\treturn 1;\n\t\t}\n\n\t\t//Run the racer threads\n#ifdef _WIN32\n\t\tHANDLE threads[NUM_RACER_THREADS];\n\t\tfor(i = 0; i < NUM_RACER_THREADS; i++)\n\t\t\tthreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)mutate_racer, mutator_state, 0, NULL);\n\t\tWaitForMultipleObjects(NUM_RACER_THREADS, threads, TRUE, INFINITE);\n\t\tfor (i = 0; i < NUM_RACER_THREADS; i++)\n\t\t\tCloseHandle(threads[i]);\n#else\n\t\tpthread_t threads[NUM_RACER_THREADS];\n\t\tfor(i = 0; i < NUM_RACER_THREADS; i++)\n\t\t\tpthread_create(&threads[i], NULL, mutate_racer, mutator_state);\n\t\tfor (i = 0; i < NUM_RACER_THREADS; i++)\n\t\t\tpthread_join(threads[i], NULL);\n#endif\n\n\t\tfor (i = 0; !found_duplicate && i < NUM_RACER_SAVED_BUFFERS; i++)\n\t\t{\n\t\t\tif (racer_saved_buffer_lengths[i] <= 0 || racer_saved_buffers[i] == NULL)\n\t\t\t\tcontinue;\n\n\t\t\tfor (j = i + 1; !found_duplicate && j < NUM_RACER_SAVED_BUFFERS; j++)\n\t\t\t{\n\t\t\t\tif (racer_saved_buffer_lengths[j] <= 0 || racer_saved_buffers[j] == NULL)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (racer_saved_buffer_lengths[i] == racer_saved_buffer_lengths[j] && !memcmp(racer_saved_buffers[i], racer_saved_buffers[j], racer_saved_buffer_lengths[i]))\n\t\t\t\t{\n\t\t\t\t\tprintf(\"Found duplicate in round %d: %d and %d\\n\", round, i, j);\n\t\t\t\t\tprint_hex(racer_saved_buffers[i], racer_saved_buffer_lengths[i]);\n\t\t\t\t\tprintf(\"\\n\");\n\t\t\t\t\tprint_hex(racer_saved_buffers[j], racer_saved_buffer_lengths[j]);\n\t\t\t\t\tprintf(\"\\n\\n\");\n\t\t\t\t\tfound_duplicate = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < NUM_RACER_SAVED_BUFFERS; i++)\n\t\t\tfree(racer_saved_buffers[i]);\n\t\tmutator->cleanup(mutator_state);\n\t}\n\n\treturn found_duplicate;\n}\n\n/**\n* This function tests the provided mutator by mutating a buffer endlessly\n*\n* @param mutator - a mutator_t struct to test\n* @param mutator_state - the state struct for a spicific mutator\n* @param mutator_options - a JSON string that contains the mutator options\n* @param seed_buffer - The data buffer used to seed the mutator\n* @param seed_length - The length of the seed_buffer in bytes\n* @return int - the results of the tests. 0 for success and 1 for fail\n*/\nint test_run_forever(mutator_t * mutator, void * mutator_state, char * mutator_options, char * seed_buffer, size_t seed_length) {\n\tsize_t i;\n\tint ret;\n\tchar * mutate_buffer = (char *)malloc(2 * seed_length);\n\n\tif (!mutate_buffer)\n\t{\n\t\tprintf(\"Malloc failed\\n\");\n\t\treturn 1;\n\t}\n\n\tret = 1;\n\tfor (i = 0; ret != 0 && ret != -1; i++) {\n\t\tret = mutator->mutate(mutator_state, mutate_buffer, 2 * seed_length);\n\t\tif (ret == -1) {\n\t\t\tprintf(\"%4lu: The mutate() function returned an error.\\n\", i);\n\t\t} else if(ret == 0) {\n\t\t\tprintf(\"%4lu: The mutate() function returned 0 (i.e. there are no more mutations).\\n\", i);\n\t\t} else if(ret > 0) {\n\t\t\tprintf(\"%4lu: \", i);\n\t\t\tprint_hex(mutate_buffer, ret);\n\t\t\tprintf(\"\\n\");\n\t\t}\n\t}\n\n\tfree(mutate_buffer);\n\treturn ret;\n}\n\nint test_mutate_parts(mutator_t * mutator, void * mutator_state, char * mutator_options, char * seed_buffer, size_t seed_length) {\n\tsize_t * input_sizes;\n\tint i, j, num_bytes, num_inputs, total_iteration_count;\n\tchar * mutate_buffer;\n\n\tmutate_buffer = (char *)malloc(2 * seed_length);\n\tif (!mutate_buffer) {\n\t\tprintf(\"Malloc failed\\n\");\n\t\treturn 1;\n\t}\n\n\ttotal_iteration_count = mutator->get_total_iteration_count(mutator_state);\n\tmutator->get_input_info(mutator_state, &num_inputs, &input_sizes);\n\tprintf(\"mutator started with %d inputs and has %d iterations total\\n\", num_inputs, total_iteration_count);\n\tfor (i = 0; i < num_inputs; i++)\n\t\tprintf(\"Input %d was %lu bytes\\n\", i, input_sizes[i]);\n\tfree(input_sizes);\n\n\tfor (i = 0; i < 10; i++)\n\t{\n\t\tnum_bytes = 1;\n\t\tfor (j = 0; j < num_inputs && num_bytes > 0; j++) {\n\t\t\tnum_bytes = mutator->mutate_extended(mutator_state, mutate_buffer, 2 * seed_length, MUTATE_MULTIPLE_INPUTS | j);\n\t\t\tif (num_bytes > 0) {\n\t\t\t\tprintf(\"%4d %4d: \", i, j);\n\t\t\t\tprint_hex(mutate_buffer, num_bytes);\n\t\t\t\tprintf(\"\\n\");\n\t\t\t}\n\t\t}\n\t}\n\tfree(mutate_buffer);\n\treturn 0;\n}\n\nint test_mutate_once(mutator_t * mutator, void * mutator_state, char * mutator_options, char * seed_buffer, size_t seed_length) {\n\tsize_t max_length = 5 * 1024 * 1024; //Allow for very large mutations\n\tchar * mutate_buffer;\n\tint mutate_length;\n\n\tmutate_buffer = (char *)malloc(max_length);\n\tmemset(mutate_buffer, 0, max_length);\n\n\tmutate_length = mutator->mutate(mutator_state, mutate_buffer, max_length);\n\tif(mutate_length < 0)\n\t\treturn -1;\n\twrite(1, mutate_buffer, mutate_length);\n\tfree(mutate_buffer);\n\treturn 0;\n}\n\n"
  },
  {
    "path": "mutators/mutator_tester/mutator_tester.h",
    "content": "#pragma once\n#include <global_types.h>\n\n//Helper functions\nvoid * setup_mutator(mutator_t * mutator, char * mutator_options, char * seed_buffer, size_t seed_length);\nvoid print_usage(char * executable_name);\n\n//Test functions\n#define NUM_TESTS 7\nint test_all(mutator_t * mutator, void * mutator_state, char * mutator_options, char * seed_buffer, size_t seed_length);\nint test_mutate(mutator_t * mutator, void * mutator_state, char * mutator_options, char * seed_buffer, size_t seed_length);\nint test_state(mutator_t * mutator, void * mutator_state, char * mutator_options, char * seed_buffer, size_t seed_length);\nint test_thread_mutate(mutator_t * mutator, void * mutator_state, char * mutator_options, char * seed_buffer, size_t seed_length);\nint test_run_forever(mutator_t * mutator, void * mutator_state, char * mutator_options, char * seed_buffer, size_t seed_length);\nint test_mutate_parts(mutator_t * mutator, void * mutator_state, char * mutator_options, char * seed_buffer, size_t seed_length);\nint test_mutate_once(mutator_t * mutator, void * mutator_state, char * mutator_options, char * seed_buffer, size_t seed_length);\n\n//Test types\ntypedef int(*test_function)(mutator_t * mutator, void * mutator_state, char * mutator_options, char * seed_buffer, size_t seed_length);\ntypedef struct test_info\n{\n\ttest_function func;\n\tconst char * usage_info;\n} test_info_t;\n"
  },
  {
    "path": "mutators/mutators/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (mutators)\n\nset(MUTATORS_SRC\n\t${PROJECT_SOURCE_DIR}/mutators.c\n\t${PROJECT_SOURCE_DIR}/afl_helpers.c\n)\nsource_group(\"Library Sources\" FILES ${MUTATORS_SRC})\n\nadd_library(mutators SHARED ${MUTATORS_SRC} $<TARGET_OBJECTS:jansson_object>)\ntarget_link_libraries(mutators utils)\ntarget_compile_definitions(mutators PUBLIC MUTATORS_EXPORTS)\ntarget_compile_definitions(mutators PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(mutators PUBLIC JANSSON_NO_IMPORT)\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(mutators Shlwapi)\nendif (WIN32)\n\nadd_library(mutators_object OBJECT ${MUTATORS_SRC})\nif (NOT WIN32)\n  set_target_properties(mutators_object PROPERTIES COMPILE_FLAGS \"-fPIC\")\nendif (NOT WIN32)\ntarget_compile_definitions(mutators_object PUBLIC MUTATORS_NO_IMPORT)\ntarget_compile_definitions(mutators_object PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(mutators_object PUBLIC JANSSON_NO_IMPORT)\n\nadd_library(mutators_static STATIC ${MUTATORS_SRC})\ntarget_compile_definitions(mutators_static PUBLIC MUTATORS_NO_IMPORT)\ntarget_link_libraries(mutators_static utils_static)\ntarget_link_libraries(mutators_static jansson_static)\n"
  },
  {
    "path": "mutators/mutators/afl_config.h",
    "content": "/*\n   american fuzzy lop - vaguely configurable bits\n   ----------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015, 2016 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This file has been modified from the original to suit the purposes of this\n   project.\n */\n\n#ifndef _HAVE_CONFIG_H\n#define _HAVE_CONFIG_H\n\n#include \"afl_types.h\"\n\n/* Version string: */\n\n#define VERSION             \"2.52b\"\n\n/******************************************************\n *                                                    *\n *  Settings that may be of interest to power users:  *\n *                                                    *\n ******************************************************/\n\n/* Comment out to disable terminal colors (note that this makes afl-analyze\n   a lot less nice): */\n\n//#define USE_COLOR\n\n/* Comment out to disable fancy ANSI boxes and use poor man's 7-bit UI: */\n\n#define FANCY_BOXES\n\n/* Default timeout for fuzzed code (milliseconds). This is the upper bound,\n   also used for detecting hangs; the actual value is auto-scaled: */\n\n#define EXEC_TIMEOUT        1000\n\n/* Timeout rounding factor when auto-scaling (milliseconds): */\n\n#define EXEC_TM_ROUND       20\n\n/* Default memory limit for child process (MB): */\n\n#ifndef __x86_64__ \n#  define MEM_LIMIT         25\n#else\n#  define MEM_LIMIT         50\n#endif /* ^!__x86_64__ */\n\n/* Default memory limit when running in QEMU mode (MB): */\n\n#define MEM_LIMIT_QEMU      200\n\n/* Number of calibration cycles per every new test case (and for test\n   cases that show variable behavior): */\n\n#define CAL_CYCLES          8\n#define CAL_CYCLES_LONG     40\n\n/* Number of subsequent timeouts before abandoning an input file: */\n\n#define TMOUT_LIMIT         250\n\n/* Maximum number of unique hangs or crashes to record: */\n\n#define KEEP_UNIQUE_HANG    500\n#define KEEP_UNIQUE_CRASH   5000\n\n/* Baseline number of random tweaks during a single 'havoc' stage: */\n\n#define HAVOC_CYCLES        256\n#define HAVOC_CYCLES_INIT   1024\n\n/* Maximum multiplier for the above (should be a power of two, beware\n   of 32-bit int overflows): */\n\n#define HAVOC_MAX_MULT      16\n\n/* Absolute minimum number of havoc cycles (after all adjustments): */\n\n#define HAVOC_MIN           16\n\n/* Maximum stacking for havoc-stage tweaks. The actual value is calculated\n   like this: \n\n   n = random between 1 and HAVOC_STACK_POW2\n   stacking = 2^n\n\n   In other words, the default (n = 7) produces 2, 4, 8, 16, 32, 64, or\n   128 stacked tweaks: */\n\n#define HAVOC_STACK_POW2    7\n\n/* Caps on block sizes for cloning and deletion operations. Each of these\n   ranges has a 33% probability of getting picked, except for the first\n   two cycles where smaller blocks are favored: */\n\n#define HAVOC_BLK_SMALL     32\n#define HAVOC_BLK_MEDIUM    128\n#define HAVOC_BLK_LARGE     1500\n\n/* Extra-large blocks, selected very rarely (<5% of the time): */\n\n#define HAVOC_BLK_XL        32768\n\n/* Probabilities of skipping non-favored entries in the queue, expressed as\n   percentages: */\n\n#define SKIP_TO_NEW_PROB    99 /* ...when there are new, pending favorites */\n#define SKIP_NFAV_OLD_PROB  95 /* ...no new favs, cur entry already fuzzed */\n#define SKIP_NFAV_NEW_PROB  75 /* ...no new favs, cur entry not fuzzed yet */\n\n/* Splicing cycle count: */\n\n#define SPLICE_CYCLES       15\n\n/* Nominal per-splice havoc cycle length: */\n\n#define SPLICE_HAVOC        32\n\n/* Maximum offset for integer addition / subtraction stages: */\n\n#define ARITH_MAX           35\n\n/* Limits for the test case trimmer. The absolute minimum chunk size; and\n   the starting and ending divisors for chopping up the input file: */\n\n#define TRIM_MIN_BYTES      4\n#define TRIM_START_STEPS    16\n#define TRIM_END_STEPS      1024\n\n/* Maximum size of input file, in bytes (keep under 100MB): */\n\n#define MAX_FILE            (1 * 1024 * 1024)\n\n/* The same, for the test case minimizer: */\n\n#define TMIN_MAX_FILE       (10 * 1024 * 1024)\n\n/* Block normalization steps for afl-tmin: */\n\n#define TMIN_SET_MIN_SIZE   4\n#define TMIN_SET_STEPS      128\n\n/* Maximum dictionary token size (-x), in bytes: */\n\n#define MAX_DICT_FILE       128\n\n/* Length limits for auto-detected dictionary tokens: */\n\n#define MIN_AUTO_EXTRA      3\n#define MAX_AUTO_EXTRA      32\n\n/* Maximum number of user-specified dictionary tokens to use in deterministic\n   steps; past this point, the \"extras/user\" step will be still carried out,\n   but with proportionally lower odds: */\n\n#define MAX_DET_EXTRAS      200\n\n/* Maximum number of auto-extracted dictionary tokens to actually use in fuzzing\n   (first value), and to keep in memory as candidates. The latter should be much\n   higher than the former. */\n\n#define USE_AUTO_EXTRAS     50\n#define MAX_AUTO_EXTRAS     (USE_AUTO_EXTRAS * 10)\n\n/* Scaling factor for the effector map used to skip some of the more\n   expensive deterministic steps. The actual divisor is set to\n   2^EFF_MAP_SCALE2 bytes: */\n\n#define EFF_MAP_SCALE2      3\n\n/* Minimum input file length at which the effector logic kicks in: */\n\n#define EFF_MIN_LEN         128\n\n/* Maximum effector density past which everything is just fuzzed\n   unconditionally (%): */\n\n#define EFF_MAX_PERC        90\n\n/* UI refresh frequency (Hz): */\n\n#define UI_TARGET_HZ        5\n\n/* Fuzzer stats file and plot update intervals (sec): */\n\n#define STATS_UPDATE_SEC    60\n#define PLOT_UPDATE_SEC     5\n\n/* Smoothing divisor for CPU load and exec speed stats (1 - no smoothing). */\n\n#define AVG_SMOOTHING       16\n\n/* Sync interval (every n havoc cycles): */\n\n#define SYNC_INTERVAL       5\n\n/* Output directory reuse grace period (minutes): */\n\n#define OUTPUT_GRACE        25\n\n/* Uncomment to use simple file names (id_NNNNNN): */\n\n// #define SIMPLE_FILES\n\n/* List of interesting values to use in fuzzing. */\n\n#define INTERESTING_8 \\\n  -128,          /* Overflow signed 8-bit when decremented  */ \\\n  -1,            /*                                         */ \\\n   0,            /*                                         */ \\\n   1,            /*                                         */ \\\n   16,           /* One-off with common buffer size         */ \\\n   32,           /* One-off with common buffer size         */ \\\n   64,           /* One-off with common buffer size         */ \\\n   100,          /* One-off with common buffer size         */ \\\n   127           /* Overflow signed 8-bit when incremented  */\n\n#define INTERESTING_16 \\\n  -32768,        /* Overflow signed 16-bit when decremented */ \\\n  -129,          /* Overflow signed 8-bit                   */ \\\n   128,          /* Overflow signed 8-bit                   */ \\\n   255,          /* Overflow unsig 8-bit when incremented   */ \\\n   256,          /* Overflow unsig 8-bit                    */ \\\n   512,          /* One-off with common buffer size         */ \\\n   1000,         /* One-off with common buffer size         */ \\\n   1024,         /* One-off with common buffer size         */ \\\n   4096,         /* One-off with common buffer size         */ \\\n   32767         /* Overflow signed 16-bit when incremented */\n\n#define INTERESTING_32 \\\n  -2147483648LL, /* Overflow signed 32-bit when decremented */ \\\n  -100663046,    /* Large negative number (endian-agnostic) */ \\\n  -32769,        /* Overflow signed 16-bit                  */ \\\n   32768,        /* Overflow signed 16-bit                  */ \\\n   65535,        /* Overflow unsig 16-bit when incremented  */ \\\n   65536,        /* Overflow unsig 16 bit                   */ \\\n   100663045,    /* Large positive number (endian-agnostic) */ \\\n   2147483647    /* Overflow signed 32-bit when incremented */\n\n/***********************************************************\n *                                                         *\n *  Really exotic stuff you probably don't want to touch:  *\n *                                                         *\n ***********************************************************/\n\n/* Call count interval between reseeding the libc PRNG from /dev/urandom: */\n\n#define RESEED_RNG          10000\n\n/* Maximum line length passed from GCC to 'as' and used for parsing\n   configuration files: */\n\n#define MAX_LINE            8192\n\n/* Environment variable used to pass SHM ID to the called program. */\n\n#define SHM_ENV_VAR         \"__AFL_SHM_ID\"\n\n/* Other less interesting, internal-only variables. */\n\n#define CLANG_ENV_VAR       \"__AFL_CLANG_MODE\"\n#define AS_LOOP_ENV_VAR     \"__AFL_AS_LOOPCHECK\"\n#define PERSIST_ENV_VAR     \"__AFL_PERSISTENT\"\n#define DEFER_ENV_VAR       \"__AFL_DEFER_FORKSRV\"\n\n/* In-code signatures for deferred and persistent mode. */\n\n#define PERSIST_SIG         \"##SIG_AFL_PERSISTENT##\"\n#define DEFER_SIG           \"##SIG_AFL_DEFER_FORKSRV##\"\n\n/* Distinctive bitmap signature used to indicate failed execution: */\n\n#define EXEC_FAIL_SIG       0xfee1dead\n\n/* Distinctive exit code used to indicate MSAN trip condition: */\n\n#define MSAN_ERROR          86\n\n/* Designated file descriptors for forkserver commands (the application will\n   use FORKSRV_FD and FORKSRV_FD + 1): */\n\n#define FORKSRV_FD          198\n\n/* Fork server init timeout multiplier: we'll wait the user-selected\n   timeout plus this much for the fork server to spin up. */\n\n#define FORK_WAIT_MULT      10\n\n/* Calibration timeout adjustments, to be a bit more generous when resuming\n   fuzzing sessions or trying to calibrate already-added internal finds.\n   The first value is a percentage, the other is in milliseconds: */\n\n#define CAL_TMOUT_PERC      125\n#define CAL_TMOUT_ADD       50\n\n/* Number of chances to calibrate a case before giving up: */\n\n#define CAL_CHANCES         3\n\n/* Map size for the traced binary (2^MAP_SIZE_POW2). Must be greater than\n   2; you probably want to keep it under 18 or so for performance reasons\n   (adjusting AFL_INST_RATIO when compiling is probably a better way to solve\n   problems with complex programs). You need to recompile the target binary\n   after changing this - otherwise, SEGVs may ensue. */\n\n#define MAP_SIZE_POW2       16\n#define MAP_SIZE            (1 << MAP_SIZE_POW2)\n\n/* Maximum allocator request size (keep well under INT_MAX): */\n\n#define MAX_ALLOC           0x40000000\n\n/* A made-up hashing seed: */\n\n#define HASH_CONST          0xa5b35705\n\n/* Constants for afl-gotcpu to control busy loop timing: */\n\n#define  CTEST_TARGET_MS    5000\n#define  CTEST_CORE_TRG_MS  1000\n#define  CTEST_BUSY_CYCLES  (10 * 1000 * 1000)\n\n/* Uncomment this to use inferior block-coverage-based instrumentation. Note\n   that you need to recompile the target binary for this to have any effect: */\n\n// #define COVERAGE_ONLY\n\n/* Uncomment this to ignore hit counts and output just one bit per tuple.\n   As with the previous setting, you will need to recompile the target\n   binary: */\n\n// #define SKIP_COUNTS\n\n/* Uncomment this to use instrumentation data to record newly discovered paths,\n   but do not use them as seeds for fuzzing. This is useful for conveniently\n   measuring coverage that could be attained by a \"dumb\" fuzzing algorithm: */\n\n// #define IGNORE_FINDS\n\n#endif /* ! _HAVE_CONFIG_H */\n"
  },
  {
    "path": "mutators/mutators/afl_debug.h",
    "content": "/*\n   american fuzzy lop - debug / error handling macros\n   --------------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015, 2016 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This file has been modified from the original to suit the purposes of this\n   project.\n */\n\n#ifndef _HAVE_DEBUG_H\n#define _HAVE_DEBUG_H\n\n#include <errno.h>\n\n#include \"afl_types.h\"\n#include \"afl_config.h\"\n\n/*******************\n * Terminal colors *\n *******************/\n\n#ifdef USE_COLOR\n\n#  define cBLK \"\\x1b[0;30m\"\n#  define cRED \"\\x1b[0;31m\"\n#  define cGRN \"\\x1b[0;32m\"\n#  define cBRN \"\\x1b[0;33m\"\n#  define cBLU \"\\x1b[0;34m\"\n#  define cMGN \"\\x1b[0;35m\"\n#  define cCYA \"\\x1b[0;36m\"\n#  define cLGR \"\\x1b[0;37m\"\n#  define cGRA \"\\x1b[1;90m\"\n#  define cLRD \"\\x1b[1;91m\"\n#  define cLGN \"\\x1b[1;92m\"\n#  define cYEL \"\\x1b[1;93m\"\n#  define cLBL \"\\x1b[1;94m\"\n#  define cPIN \"\\x1b[1;95m\"\n#  define cLCY \"\\x1b[1;96m\"\n#  define cBRI \"\\x1b[1;97m\"\n#  define cRST \"\\x1b[0m\"\n\n#  define bgBLK \"\\x1b[40m\"\n#  define bgRED \"\\x1b[41m\"\n#  define bgGRN \"\\x1b[42m\"\n#  define bgBRN \"\\x1b[43m\"\n#  define bgBLU \"\\x1b[44m\"\n#  define bgMGN \"\\x1b[45m\"\n#  define bgCYA \"\\x1b[46m\"\n#  define bgLGR \"\\x1b[47m\"\n#  define bgGRA \"\\x1b[100m\"\n#  define bgLRD \"\\x1b[101m\"\n#  define bgLGN \"\\x1b[102m\"\n#  define bgYEL \"\\x1b[103m\"\n#  define bgLBL \"\\x1b[104m\"\n#  define bgPIN \"\\x1b[105m\"\n#  define bgLCY \"\\x1b[106m\"\n#  define bgBRI \"\\x1b[107m\"\n\n#else\n\n#  define cBLK \"\"\n#  define cRED \"\"\n#  define cGRN \"\"\n#  define cBRN \"\"\n#  define cBLU \"\"\n#  define cMGN \"\"\n#  define cCYA \"\"\n#  define cLGR \"\"\n#  define cGRA \"\"\n#  define cLRD \"\"\n#  define cLGN \"\"\n#  define cYEL \"\"\n#  define cLBL \"\"\n#  define cPIN \"\"\n#  define cLCY \"\"\n#  define cBRI \"\"\n#  define cRST \"\"\n\n#  define bgBLK \"\"\n#  define bgRED \"\"\n#  define bgGRN \"\"\n#  define bgBRN \"\"\n#  define bgBLU \"\"\n#  define bgMGN \"\"\n#  define bgCYA \"\"\n#  define bgLGR \"\"\n#  define bgGRA \"\"\n#  define bgLRD \"\"\n#  define bgLGN \"\"\n#  define bgYEL \"\"\n#  define bgLBL \"\"\n#  define bgPIN \"\"\n#  define bgLCY \"\"\n#  define bgBRI \"\"\n\n#endif /* ^USE_COLOR */\n\n/*************************\n * Box drawing sequences *\n *************************/\n\n#ifdef FANCY_BOXES\n\n#  define SET_G1   \"\\x1b)0\"       /* Set G1 for box drawing    */\n#  define RESET_G1 \"\\x1b)B\"       /* Reset G1 to ASCII         */\n#  define bSTART   \"\\x0e\"         /* Enter G1 drawing mode     */\n#  define bSTOP    \"\\x0f\"         /* Leave G1 drawing mode     */\n#  define bH       \"q\"            /* Horizontal line           */\n#  define bV       \"x\"            /* Vertical line             */\n#  define bLT      \"l\"            /* Left top corner           */\n#  define bRT      \"k\"            /* Right top corner          */\n#  define bLB      \"m\"            /* Left bottom corner        */\n#  define bRB      \"j\"            /* Right bottom corner       */\n#  define bX       \"n\"            /* Cross                     */\n#  define bVR      \"t\"            /* Vertical, branch right    */\n#  define bVL      \"u\"            /* Vertical, branch left     */\n#  define bHT      \"v\"            /* Horizontal, branch top    */\n#  define bHB      \"w\"            /* Horizontal, branch bottom */\n\n#else\n\n#  define SET_G1   \"\"\n#  define RESET_G1 \"\"\n#  define bSTART   \"\"\n#  define bSTOP    \"\"\n#  define bH       \"-\"\n#  define bV       \"|\"\n#  define bLT      \"+\"\n#  define bRT      \"+\"\n#  define bLB      \"+\"\n#  define bRB      \"+\"\n#  define bX       \"+\"\n#  define bVR      \"+\"\n#  define bVL      \"+\"\n#  define bHT      \"+\"\n#  define bHB      \"+\"\n\n#endif /* ^FANCY_BOXES */\n\n/***********************\n * Misc terminal codes *\n ***********************/\n\n#define TERM_HOME     \"\\x1b[H\"\n#define TERM_CLEAR    TERM_HOME \"\\x1b[2J\"\n#define cEOL          \"\\x1b[0K\"\n#define CURSOR_HIDE   \"\\x1b[?25l\"\n#define CURSOR_SHOW   \"\\x1b[?25h\"\n\n/************************\n * Debug & error macros *\n ************************/\n\n/* Just print stuff to the appropriate stream. */\n\n#ifdef MESSAGES_TO_STDOUT\n#ifdef _WIN32\n#  define SAYF(x, ...)    printf(x, __VA_ARGS__)\n#else\n#  define SAYF(x...)    printf(x)\n#endif\n#else \n#ifdef _WIN32\n#  define SAYF(x, ...)    fprintf(stderr, x, __VA_ARGS__)\n#else\n#  define SAYF(x...)    fprintf(stderr, x)\n#endif\n#endif /* ^MESSAGES_TO_STDOUT */\n\n/* Show a prefixed warning. */\n\n#define WARNF(x, ...) do { \\\n    SAYF(cYEL \"[!] \" cBRI \"WARNING: \" cRST x, __VA_ARGS__); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Show a prefixed \"doing something\" message. */\n\n#define ACTF(x, ...) do { \\\n    SAYF(cLBL \"[*] \" cRST x, __VA_ARGS__); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Show a prefixed \"success\" message. */\n\n#define OKF(x, ...) do { \\\n    SAYF(cLGN \"[+] \" cRST x, __VA_ARGS__); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Show a prefixed fatal error message (not used in afl). */\n\n#define BADF(x, ...) do { \\\n    SAYF(cLRD \"\\n[-] \" cRST x, __VA_ARGS__); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Die with a verbose non-OS fatal error message. */\n\n#define FATAL(x, ...) do { \\\n    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \"\\n[-] PROGRAM ABORT : \" \\\n         cBRI x, __VA_ARGS__); \\\n    SAYF(cLRD \"\\n         Location : \" cRST \"%s(), %s:%u\\n\\n\", \\\n         __FUNCTION__, __FILE__, __LINE__); \\\n    exit(1); \\\n  } while (0)\n\n/* Die by calling abort() to provide a core dump. */\n\n#define ABORT(x, ...) do { \\\n    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \"\\n[-] PROGRAM ABORT : \" \\\n         cBRI x, __VA_ARGS__); \\\n    SAYF(cLRD \"\\n    Stop location : \" cRST \"%s(), %s:%u\\n\\n\", \\\n         __FUNCTION__, __FILE__, __LINE__); \\\n    abort(); \\\n  } while (0)\n\n/* Die while also including the output of perror(). */\n\n#define PFATAL(x, ...) do { \\\n    fflush(stdout); \\\n    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \"\\n[-]  SYSTEM ERROR : \" \\\n         cBRI x, __VA_ARGS__); \\\n    SAYF(cLRD \"\\n    Stop location : \" cRST \"%s(), %s:%u\\n\", \\\n         __FUNCTION__, __FILE__, __LINE__); \\\n    SAYF(cLRD \"       OS message : \" cRST \"%s\\n\", strerror(errno)); \\\n    exit(1); \\\n  } while (0)\n\n/* Die with FAULT() or PFAULT() depending on the value of res (used to\n   interpret different failure modes for read(), write(), etc). */\n\n#define RPFATAL(res, x, ...) do { \\\n    if (res < 0) PFATAL(x, __VA_ARGS__); else FATAL(x, __VA_ARGS__); \\\n  } while (0)\n\n/* Error-checking versions of read() and write() that call RPFATAL() as\n   appropriate. */\n\n#define ck_write(fd, buf, len, fn) do { \\\n    u32 _len = (len); \\\n    s32 _res = write(fd, buf, _len); \\\n    if (_res != _len) RPFATAL(_res, \"Short write to %s\", fn); \\\n  } while (0)\n\n#define ck_read(fd, buf, len, fn) do { \\\n    u32 _len = (len); \\\n    s32 _res = read(fd, buf, _len); \\\n    if (_res != _len) RPFATAL(_res, \"Short read from %s\", fn); \\\n  } while (0)\n\n#endif /* ! _HAVE_DEBUG_H */\n"
  },
  {
    "path": "mutators/mutators/afl_helpers.c",
    "content": "#include \"mutators.h\"\n#include \"afl_helpers.h\"\n#include \"afl_config.h\"\n#include \"afl_debug.h\"\n#include \"afl_types.h\"\n\n#include <utils.h>\n\n#include <ctype.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n\n#ifdef _WIN32\n#include <io.h>\n#include <windows.h>\n#else\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <dirent.h>\n#include <unistd.h>\n#endif\n\nstatic inline uint64_t rotl(const uint64_t x, int k) {\n\treturn (x << k) | (x >> (64 - k));\n}\n\n/**\n * xoroshiro128plus by David Blackman and Sebastiano Vigna\n * @param info - an mutate_info_t that holds the current random generator state\n * @return - a random uint64_t\n */\nstatic inline uint64_t rnd64(mutate_info_t * info) {\n\tconst uint64_t s0 = info->random_state[0];\n\tuint64_t s1 = info->random_state[1];\n\tconst uint64_t result = s0 + s1;\n\ts1 ^= s0;\n\tinfo->random_state[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14);\n\tinfo->random_state[1] = rotl(s1, 36);\n\treturn result;\n}\n\n/* Generate a random number (from 0 to limit - 1). This may have slight bias. */\nMUTATORS_API u32 UR(mutate_info_t * info, u32 limit) {\n\treturn rnd64(info) % limit;\n}\n\n//Mutates a buffer, running through each of the passed in mutate functions, updating the mutate_info_t\n//with the current progress through the mutation functions\nMUTATORS_API int mutate_one(mutate_info_t * info, mutate_buffer_t * buf, int(*const*mutate_funcs)(mutate_info_t *, mutate_buffer_t *), size_t num_funcs) {\n\tint length = MUTATOR_DONE;\n\twhile ((length == MUTATOR_DONE || length == MUTATOR_TRY_AGAIN) && info->stage < num_funcs)\n\t{\n\t\tlength = mutate_funcs[info->stage](info, buf);\n\t\tif (length == MUTATOR_TRY_AGAIN)\n\t\t\tinfo->stage_cur++;\n\t\telse if (length == MUTATOR_DONE)\n\t\t{\n\t\t\tinfo->stage++;\n\t\t\tinfo->stage_cur = 0;\n\t\t\tif (info->one_stage_only) { //if we're only doing one stage, set the stage to the end\n\t\t\t\tinfo->stage = num_funcs; //so the next call to mutate_one doesn't return a mutated buffer\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tinfo->stage_cur++;\n\tif (length == MUTATOR_DONE && info->stage == num_funcs) //If we've reached\n\t\tinfo->stage_cur = 0; //the end of the mutators cycle, reset the stage to 0\n\treturn length;\n}\n\nstatic void clear_splice_files(mutate_info_t * info)\n{\n\tsize_t i;\n\tif (info->splice_files)\n\t{\n\t\tfor (i = 0; i < info->splice_files_count; i++) {\n\t\t\tfree(info->splice_files[i]->s);\n\t\t\tfree(info->splice_files[i]);\n\t\t}\n\t\tfree(info->splice_files);\n\t\tinfo->splice_files = NULL;\n\t\tinfo->splice_files_count = 0;\n\t}\n}\n\n/**\n * Loads the splice files into the given afl state\n * @param info - the mutate_info_t to load the splice files for\n * @return - 0 on success, nonzero on failure\n */\nMUTATORS_API int load_splice_files(mutate_info_t * info, char ** splice_filenames, size_t splice_filenames_count)\n{\n\tchar * contents;\n\tint length;\n\tsize_t i;\n\tstring_t * splice_file;\n\n\tclear_splice_files(info);\n\tfor (i = 0; i < splice_filenames_count; i++)\n\t{\n\t\tlength = read_file(splice_filenames[i], &contents);\n\t\tif (length < 0)\n\t\t{\n\t\t\tprintf(\"Could not read file %s\\n\", splice_filenames[i]);\n\t\t\tclear_splice_files(info);\n\t\t\treturn 1;\n\t\t}\n\n\t\tsplice_file = (string_t *)malloc(sizeof(string_t));\n\t\tinfo->splice_files = (string_t **)realloc(info->splice_files, sizeof(string_t *) * (info->splice_files_count + 1));\n\t\tif (!info->splice_files || !splice_file)\n\t\t{\n\t\t\tprintf(\"Memory error while allocating splice files\\n\");\n\t\t\tfree(contents);\n\t\t\tfree(splice_file);\n\t\t\tclear_splice_files(info);\n\t\t\treturn 1;\n\t\t}\n\t\tsplice_file->len = length;\n\t\tsplice_file->s = (u8 *)contents;\n\t\tinfo->splice_files[info->splice_files_count] = splice_file;\n\t\tinfo->splice_files_count++;\n\t}\n\treturn 0;\n}\n\nstatic void clear_dictionary_files(mutate_info_t * info)\n{\n\tsize_t i;\n\tif (info->dictq)\n\t{\n\t\tfor (i = 0; i < info->dictionary_count; i++) {\n\t\t\tfree(info->dictq[i]->s);\n\t\t\tfree(info->dictq[i]);\n\t\t}\n\t\tfree(info->dictq);\n\t\tinfo->dictq = NULL;\n\t\tinfo->dictionary_count = 0;\n\t}\n}\n\nMUTATORS_API void cleanup_mutate_info(mutate_info_t * info)\n{\n\t//Free any dictionary/splice files that were loaded\n\tclear_dictionary_files(info);\n\tclear_splice_files(info);\n\tdestroy_mutex(info->mutate_mutex);\n\tinfo->mutate_mutex = NULL;\n}\n\n/**\n * Cleans up the old mutate_info_t struct and reinitializes it back to defaults\n * @param info - the mutate_info_t struct to reset\n * @return - 0 on success, nonzero on failure\n */\nMUTATORS_API int reset_mutate_info(mutate_info_t * info)\n{\n\tcleanup_mutate_info(info);\n\n\t//Setup the default options\n\tinfo->random_state[0] = (((uint64_t)rand()) << 32) | rand();\n\tinfo->random_state[1] = (((uint64_t)rand()) << 32) | rand();\n\tinfo->queue_cycle = 1;\n\tinfo->havoc_div = 1;\n\tinfo->perf_score = 100;\n\tinfo->mutate_mutex = create_mutex();\n\treturn info->mutate_mutex == NULL; //1 if the mutex creation failed, 0 otherwise\n}\n\nMUTATORS_API int add_mutate_info_to_json(json_t * obj, mutate_info_t * info)\n{\n\tjson_t *temp, *temp2, *dictionary_list, *dictionary_item;\n\tuint64_t i;\n\n\tADD_UINT64T(temp, info->random_state[0], obj, \"random_state0\");\n\tADD_UINT64T(temp, info->random_state[1], obj, \"random_state1\");\n\tADD_INT(temp, info->stage_cur, obj, \"stage_cur\");\n\tADD_INT(temp, info->stage, obj, \"stage\");\n\tADD_INT(temp, info->should_skip_previous, obj, \"should_skip_previous\");\n\tADD_INT(temp, info->one_stage_only, obj, \"one_stage_only\");\n\tADD_INT(temp, info->queue_cycle, obj, \"queue_cycle\");\n\tADD_INT(temp, info->havoc_div, obj, \"havoc_div\");\n\tADD_INT(temp, info->perf_score, obj, \"perf_score\");\n\n\tdictionary_list = json_array();\n\tif (!dictionary_list)\n\t\treturn 0;\n\tfor(i = 0; i < info->dictionary_count; i++)\n\t{\n\t\tdictionary_item = json_object();\n\t\ttemp = json_mem((const char *)info->dictq[i]->s, info->dictq[i]->len);\n\t\ttemp2 = json_integer(info->dictq[i]->len);\n\n\t\tif (!temp || !temp2 || !dictionary_item) {\n\t\t\tif(dictionary_item)\n\t\t\t\tjson_decref(dictionary_list);\n\t\t\tif (temp)\n\t\t\t\tjson_decref(temp);\n\t\t\tif (temp2)\n\t\t\t\tjson_decref(temp2);\n\t\t\treturn 0;\n\t\t}\n\t\tif (json_object_set_new(dictionary_item, \"s\", temp))\n\t\t{\n\t\t\tjson_decref(dictionary_list);\n\t\t\tjson_decref(dictionary_item);\n\t\t\tjson_decref(temp2);\n\t\t\treturn 0;\n\t\t}\n\t\tif (json_object_set_new(dictionary_item, \"len\", temp2))\n\t\t{\n\t\t\tjson_decref(dictionary_list);\n\t\t\tjson_decref(dictionary_item);\n\t\t\treturn 0;\n\t\t}\n\t\tjson_array_append_new(dictionary_list, dictionary_item);\n\t}\n\tif (json_object_set_new(obj, \"dictionary\", dictionary_list))\n\t\tjson_decref(dictionary_list);\n\n\treturn 1;\n}\n\nMUTATORS_API int get_mutate_info_from_json(char * state, mutate_info_t * info)\n{\n\tint temp_int, result, inner_result;\n\tuint64_t temp_uint64t;\n\tchar * tempstr;\n\tjson_t *dictionary_obj;\n\n\tclear_splice_files(info);\n\tclear_dictionary_files(info);\n\n\tGET_UINT64T(temp_uint64t, state, info->random_state[0], \"random_state0\", result);\n\tGET_UINT64T(temp_uint64t, state, info->random_state[1], \"random_state1\", result);\n\tGET_INT(temp_int, state, info->stage_cur, \"stage_cur\", result);\n\tGET_INT(temp_int, state, info->stage, \"stage\", result);\n\tGET_INT(temp_int, state, info->should_skip_previous, \"should_skip_previous\", result);\n\tGET_INT(temp_int, state, info->one_stage_only, \"one_stage_only\", result);\n\tGET_INT(temp_int, state, info->queue_cycle, \"queue_cycle\", result);\n\tGET_INT(temp_int, state, info->havoc_div, \"havoc_div\", result);\n\tGET_INT(temp_int, state, info->perf_score, \"perf_score\", result);\n\n\tFOREACH_OBJECT_JSON_ARRAY_ITEM_BEGIN(state, modules, \"dictionary\", dictionary_obj, result)\n\n\t\tGET_ITEM(dictionary_obj, temp_uint64t, temp_uint64t, get_uint64t_options_from_json, \"len\", inner_result);\n\t\ttempstr = get_mem_options_from_json(dictionary_obj, \"s\", &inner_result);\n\t\tif (inner_result <= 0) {\n\t\t\tFOREACH_OBJECT_JSON_ARRAY_ITEM_FREE(modules);\n\t\t\treturn 1;\n\t\t}\n\n\t\tinfo->dictq = (string_t **)realloc(info->dictq, (info->dictionary_count + 1) * sizeof(string_t *));\n\t\tif (!info->dictq) {\n\t\t\tfree(tempstr);\n\t\t\tFOREACH_OBJECT_JSON_ARRAY_ITEM_FREE(modules);\n\t\t\treturn 1;\n\t\t}\n\t\tinfo->dictq[info->dictionary_count] = (string_t *)malloc(sizeof(string_t));\n\t\tif (!info->dictq[info->dictionary_count]) {\n\t\t\tfree(tempstr);\n\t\t\tFOREACH_OBJECT_JSON_ARRAY_ITEM_FREE(modules);\n\t\t\treturn 1;\n\t\t}\n\n\t\tinfo->dictq[info->dictionary_count]->len = temp_uint64t;\n\t\tinfo->dictq[info->dictionary_count]->s = (u8*)tempstr;\n\t\tinfo->dictionary_count++;\n\n\tFOREACH_OBJECT_JSON_ARRAY_ITEM_END(modules);\n\tif (result < 0)\n\t\treturn 1;\n\n\treturn 0;\n}\n\n\n////////////////////////////////////////////////////////////////////////////////////////////\n//// AFL Mutation Functions ////////////////////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////////////////////////\n\n/*\n   The code in this section (AFL Mutation Functions) is taken from and/or based\n   on AFL and falls under the following license:\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n   The code in this section has been modified from the original to suit the\n   purposes of this project.\n*/\n\n/* Interesting values, as per config.h */\nstatic s8  interesting_8[] = { INTERESTING_8 };\nstatic s16 interesting_16[] = { INTERESTING_8, INTERESTING_16 };\nstatic s32 interesting_32[] = { INTERESTING_8, INTERESTING_16, INTERESTING_32 };\n\n/* Helper to choose random block len for block operations in fuzz_one().\nDoesn't return zero, provided that max_len is > 0. */\nstatic u32 choose_block_len(mutate_info_t * info, u32 limit) {\n\n\tu32 min_value, max_value;\n\tu32 rlim = MIN(info->queue_cycle, 3);\n\n\tswitch (UR(info, rlim)) {\n\n\tcase 0:\n\t\tmin_value = 1;\n\t\tmax_value = HAVOC_BLK_SMALL;\n\t\tbreak;\n\n\tcase 1:\n\t\tmin_value = HAVOC_BLK_SMALL;\n\t\tmax_value = HAVOC_BLK_MEDIUM;\n\t\tbreak;\n\n\tdefault:\n\t\tif (UR(info, 10)) {\n\t\t\tmin_value = HAVOC_BLK_MEDIUM;\n\t\t\tmax_value = HAVOC_BLK_LARGE;\n\t\t}\n\t\telse {\n\t\t\tmin_value = HAVOC_BLK_LARGE;\n\t\t\tmax_value = HAVOC_BLK_XL;\n\t\t}\n\t}\n\n\tif (min_value >= limit)\n\t\tmin_value = 1;\n\n\treturn min_value + UR(info, MIN(max_value, limit) - min_value + 1);\n}\n\n/* Helper function to compare buffers; returns first and last differing offset. We\nuse this to find reasonable locations for splicing two files. */\nstatic void locate_diffs(u8* ptr1, u8* ptr2, u32 len, s32* first, s32* last) {\n\n\ts32 f_loc = -1;\n\ts32 l_loc = -1;\n\tu32 pos;\n\n\tfor (pos = 0; pos < len; pos++) {\n\n\t\tif (*(ptr1++) != *(ptr2++)) {\n\n\t\t\tif (f_loc == -1) f_loc = pos;\n\t\t\tl_loc = pos;\n\n\t\t}\n\n\t}\n\n\t*first = f_loc;\n\t*last = l_loc;\n\n\treturn;\n}\n\n/* Helper function to see if a particular change (xor_val = old ^ new) could\nbe a product of deterministic bit flips with the lengths and stepovers\nattempted by afl-fuzz. This is used to avoid dupes in some of the\ndeterministic fuzzing operations that follow bit flips. We also\nreturn 1 if xor_val is zero, which implies that the old and attempted new\nvalues are identical and the exec would be a waste of time. */\nstatic u8 could_be_bitflip(u32 xor_val) {\n\n\tu32 sh = 0;\n\n\tif (!xor_val) return 1;\n\n\t/* Shift left until first bit set. */\n\n\twhile (!(xor_val & 1)) { sh++; xor_val >>= 1; }\n\n\t/* 1-, 2-, and 4-bit patterns are OK anywhere. */\n\n\tif (xor_val == 1 || xor_val == 3 || xor_val == 15) return 1;\n\n\t/* 8-, 16-, and 32-bit patterns are OK only if shift factor is\n\tdivisible by 8, since that's the stepover for these ops. */\n\n\tif (sh & 7) return 0;\n\n\tif (xor_val == 0xff || xor_val == 0xffff || xor_val == 0xffffffff)\n\t\treturn 1;\n\n\treturn 0;\n\n}\n\n/* Helper function to see if a particular value is reachable through\narithmetic operations. Used for similar purposes. */\nstatic u8 could_be_arith(u32 old_val, u32 new_val, u8 blen) {\n\n\tu32 i, ov = 0, nv = 0, diffs = 0;\n\n\tif (old_val == new_val) return 1;\n\n\t/* See if one-byte adjustments to any byte could produce this result. */\n\n\tfor (i = 0; i < blen; i++) {\n\n\t\tu8 a = old_val >> (8 * i),\n\t\t\tb = new_val >> (8 * i);\n\n\t\tif (a != b) { diffs++; ov = a; nv = b; }\n\n\t}\n\n\t/* If only one byte differs and the values are within range, return 1. */\n\n\tif (diffs == 1) {\n\n\t\tif ((u8)(ov - nv) <= ARITH_MAX ||\n\t\t\t(u8)(nv - ov) <= ARITH_MAX) return 1;\n\n\t}\n\n\tif (blen == 1) return 0;\n\n\t/* See if two-byte adjustments to any byte would produce this result. */\n\n\tdiffs = 0;\n\n\tfor (i = 0; i < blen / 2U; i++) {\n\n\t\tu16 a = old_val >> (16 * i),\n\t\t\tb = new_val >> (16 * i);\n\n\t\tif (a != b) { diffs++; ov = a; nv = b; }\n\n\t}\n\n\t/* If only one word differs and the values are within range, return 1. */\n\n\tif (diffs == 1) {\n\n\t\tif ((u16)(ov - nv) <= ARITH_MAX ||\n\t\t\t(u16)(nv - ov) <= ARITH_MAX) return 1;\n\n\t\tov = SWAP16(ov); nv = SWAP16(nv);\n\n\t\tif ((u16)(ov - nv) <= ARITH_MAX ||\n\t\t\t(u16)(nv - ov) <= ARITH_MAX) return 1;\n\n\t}\n\n\t/* Finally, let's do the same thing for dwords. */\n\n\tif (blen == 4) {\n\n\t\tif ((u32)(old_val - new_val) <= ARITH_MAX ||\n\t\t\t(u32)(new_val - old_val) <= ARITH_MAX) return 1;\n\n\t\tnew_val = SWAP32(new_val);\n\t\told_val = SWAP32(old_val);\n\n\t\tif ((u32)(old_val - new_val) <= ARITH_MAX ||\n\t\t\t(u32)(new_val - old_val) <= ARITH_MAX) return 1;\n\n\t}\n\n\treturn 0;\n\n}\n\n/* Describe integer as memory size. */\n\n#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) do { \\\n    if (val < (_divisor) * (_limit_mult)) { \\\n      snprintf((char *)tmp[cur], sizeof(tmp[cur]), _fmt, ((_cast)val) / (_divisor)); \\\n      return tmp[cur]; \\\n    } \\\n  } while (0)\n\nstatic u8* DMS(u64 val) {\n\n\tstatic u8 tmp[12][16];\n\tstatic u8 cur;\n\n\tcur = (cur + 1) % 12;\n\n\t/* 0-9999 */\n\tCHK_FORMAT(1, 10000, \"%llu B\", u64);\n\n\t/* 10.0k - 99.9k */\n\tCHK_FORMAT(1024, 99.95, \"%0.01f kB\", double);\n\n\t/* 100k - 999k */\n\tCHK_FORMAT(1024, 1000, \"%llu kB\", u64);\n\n\t/* 1.00M - 9.99M */\n\tCHK_FORMAT(1024 * 1024, 9.995, \"%0.02f MB\", double);\n\n\t/* 10.0M - 99.9M */\n\tCHK_FORMAT(1024 * 1024, 99.95, \"%0.01f MB\", double);\n\n\t/* 100M - 999M */\n\tCHK_FORMAT(1024 * 1024, 1000, \"%llu MB\", u64);\n\n\t/* 1.00G - 9.99G */\n\tCHK_FORMAT(1024LL * 1024 * 1024, 9.995, \"%0.02f GB\", double);\n\n\t/* 10.0G - 99.9G */\n\tCHK_FORMAT(1024LL * 1024 * 1024, 99.95, \"%0.01f GB\", double);\n\n\t/* 100G - 999G */\n\tCHK_FORMAT(1024LL * 1024 * 1024, 1000, \"%llu GB\", u64);\n\n\t/* 1.00T - 9.99G */\n\tCHK_FORMAT(1024LL * 1024 * 1024 * 1024, 9.995, \"%0.02f TB\", double);\n\n\t/* 10.0T - 99.9T */\n\tCHK_FORMAT(1024LL * 1024 * 1024 * 1024, 99.95, \"%0.01f TB\", double);\n\n#undef CHK_FORMAT\n\n\t/* 100T+ */\n\tstrncpy((char *)tmp[cur], \"infty\", sizeof(tmp[cur]));\n\treturn tmp[cur];\n}\n\n/* Last but not least, a similar helper to see if insertion of an\ninteresting integer is redundant given the insertions done for\nshorter blen. The last param (check_le) is set if the caller\nalready executed LE insertion for current blen and wants to see\nif BE variant passed in new_val is unique. */\nstatic u8 could_be_interest(u32 old_val, u32 new_val, u8 blen, u8 check_le) {\n\n\tu32 i, j;\n\n\tif (old_val == new_val) return 1;\n\n\t/* See if one-byte insertions from interesting_8 over old_val could\n\tproduce new_val. */\n\n\tfor (i = 0; i < blen; i++) {\n\n\t\tfor (j = 0; j < sizeof(interesting_8); j++) {\n\n\t\t\tu32 tval = (old_val & ~(0xff << (i * 8))) |\n\t\t\t\t(((u8)interesting_8[j]) << (i * 8));\n\n\t\t\tif (new_val == tval) return 1;\n\n\t\t}\n\n\t}\n\n\t/* Bail out unless we're also asked to examine two-byte LE insertions\n\tas a preparation for BE attempts. */\n\n\tif (blen == 2 && !check_le) return 0;\n\n\t/* See if two-byte insertions over old_val could give us new_val. */\n\n\tfor (i = 0; i < blen - 1; i++) {\n\n\t\tfor (j = 0; j < sizeof(interesting_16) / 2; j++) {\n\n\t\t\tu32 tval = (old_val & ~(0xffff << (i * 8))) |\n\t\t\t\t(((u16)interesting_16[j]) << (i * 8));\n\n\t\t\tif (new_val == tval) return 1;\n\n\t\t\t/* Continue here only if blen > 2. */\n\n\t\t\tif (blen > 2) {\n\n\t\t\t\ttval = (old_val & ~(0xffff << (i * 8))) |\n\t\t\t\t\t(SWAP16(interesting_16[j]) << (i * 8));\n\n\t\t\t\tif (new_val == tval) return 1;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tif (blen == 4 && check_le) {\n\n\t\t/* See if four-byte insertions could produce the same result\n\t\t(LE only). */\n\n\t\tfor (j = 0; j < sizeof(interesting_32) / 4; j++)\n\t\t\tif (new_val == (u32)interesting_32[j]) return 1;\n\n\t}\n\n\treturn 0;\n\n}\n\n/* Read the dictionary from a file */\nstatic int load_dictionary_file(mutate_info_t * info, char * fname, u32* min_len, u32* max_len, u32 dict_level) {\n\n\tFILE* fp;\n\tchar buf[MAX_LINE];\n\tu8 *lptr;\n\tu32 cur_line = 0;\n\tchar* hexdigits = \"0123456789abcdef\";\n\tstring_t ** temp_dictq;\n\n\tfp = fopen(fname, \"r\");\n\tif (!fp) {\n\t\tprintf(\"Unable to open dictionary file '%s'\", fname);\n\t\treturn 1;\n\t}\n\n\twhile ((lptr = (u8 *)fgets(buf, MAX_LINE, fp))) {\n\n\t\tu8 *rptr, *wptr, *new_item;\n\t\tu32 klen = 0;\n\n\t\tcur_line++;\n\n\t\t// Trim on left and right.\n\t\twhile (isspace(*lptr)) lptr++;\n\t\trptr = lptr + strlen((char *)lptr) - 1;\n\t\twhile (rptr >= lptr && isspace(*rptr)) rptr--;\n\t\trptr++;\n\t\t*rptr = 0;\n\n\t\t// Skip empty lines and comments.\n\t\tif (!*lptr || *lptr == '#') continue;\n\n\t\t// All other lines must end with '\"', which we can consume.\n\t\trptr--;\n\t\tif (rptr < lptr || *rptr != '\"') {\n\t\t\tprintf(\"Malformed name=\\\"value\\\" pair in dictionary file %s on line %u.\", fname, cur_line);\n\t\t\tfclose(fp);\n\t\t\treturn 1;\n\t\t}\n\t\t*rptr = 0;\n\n\t\t// Skip alphanumerics and dashes (label).\n\t\twhile (isalnum(*lptr) || *lptr == '_') lptr++;\n\n\t\t// If @number follows, parse that.\n\t\tif (*lptr == '@') {\n\t\t\tlptr++;\n\t\t\tif (atoi((char *)lptr) > dict_level) continue;\n\t\t\twhile (isdigit(*lptr)) lptr++;\n\t\t}\n\n\t\t// Skip whitespace and = signs.\n\t\twhile (isspace(*lptr) || *lptr == '=') lptr++;\n\n\t\t// Consume opening '\"'.\n\t\tif (*lptr != '\"') {\n\t\t\tprintf(\"Malformed name=\\\"keyword\\\" pair in dictionary file %s on line %u.\", fname, cur_line);\n\t\t\tfclose(fp);\n\t\t\treturn 1;\n\t\t}\n\n\t\tlptr++;\n\t\tif (!*lptr) {\n\t\t\tprintf(\"Empty keyword in dictionary file %s on line %u.\", fname, cur_line);\n\t\t\tfclose(fp);\n\t\t\treturn 1;\n\t\t}\n\n\n\t\t// Okay, let's allocate memory and copy data between \"...\", handling\n\t\t// \\xNN escaping, \\\\, and \\\".\n\t\twptr = new_item = (u8 *)malloc(rptr - lptr);\n\t\tif (!new_item) {\n\t\t\tprintf(\"Failed allocating memory while parsing dictionary file %s, line %u.\", fname, cur_line);\n\t\t\tfclose(fp);\n\t\t\treturn 1;\n\t\t}\n\n\t\twhile (*lptr) {\n\t\t\tif ((*lptr >= 1 && *lptr <= 31) || (*lptr >= 128 && *lptr <= 255)) {\n\t\t\t\tprintf(\"Non-printable characters in dictionary file %s on line %u.\", fname, cur_line);\n\t\t\t\tfree(new_item);\n\t\t\t\tfclose(fp);\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tif (*lptr == '\\\\') {\n\t\t\t\tlptr++;\n\n\t\t\t\tif (*lptr == '\\\\' || *lptr == '\"') {\n\t\t\t\t\t*(wptr++) = *(lptr++);\n\t\t\t\t\tklen++;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tif (*lptr != 'x' || !isxdigit(lptr[1]) || !isxdigit(lptr[2])) {\n\t\t\t\t\t\tprintf(\"Invalid escaping (not \\\\xNN) in dictionary file %s on line %u.\", fname, cur_line);\n\t\t\t\t\t\tfree(new_item);\n\t\t\t\t\t\tfclose(fp);\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\n\t\t\t\t\t*(wptr++) =\n\t\t\t\t\t\t((strchr(hexdigits, tolower(lptr[1])) - hexdigits) << 4) |\n\t\t\t\t\t\t(strchr(hexdigits, tolower(lptr[2])) - hexdigits);\n\t\t\t\t\tlptr += 3;\n\t\t\t\t\tklen++;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\t*(wptr++) = *(lptr++);\n\t\t\t\tklen++;\n\t\t\t}\n\t\t}\n\n\t\tif (klen > MAX_DICT_FILE) {\n\t\t\tprintf(\"Keyword too big in line %u (%s, limit is %s)\", cur_line, DMS(klen), DMS(MAX_DICT_FILE));\n\t\t\tfree(new_item);\n\t\t\tfclose(fp);\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (*min_len > klen) *min_len = klen;\n\t\tif (*max_len < klen) *max_len = klen;\n\n\t\ttemp_dictq = (string_t **)realloc(info->dictq, (info->dictionary_count + 1) * sizeof(string_t *));\n\t\tif (!temp_dictq) {\n\t\t\tprintf(\"Failed allocating memory while parsing dictionary file %s, line %u.\", fname, cur_line);\n\t\t\tfree(new_item);\n\t\t\tfclose(fp);\n\t\t\treturn 1;\n\t\t}\n\t\tinfo->dictq = temp_dictq;\n\n\t\tinfo->dictq[info->dictionary_count] = (string_t *)malloc(sizeof(string_t));\n\t\tif (!info->dictq[info->dictionary_count]) {\n\t\t\tprintf(\"Failed allocating memory while parsing dictionary file %s, line %u.\", fname, cur_line);\n\t\t\tfree(new_item);\n\t\t\tfclose(fp);\n\t\t\treturn 1;\n\t\t}\n\n\t\tinfo->dictq[info->dictionary_count]->s = new_item;\n\t\tinfo->dictq[info->dictionary_count]->len = klen;\n\t\tinfo->dictionary_count++;\n\t}\n\tfclose(fp);\n\treturn 0;\n}\n\n/* Read the dictionary from the dictionary directory */\nMUTATORS_API int load_dictionary(mutate_info_t * info, char * path) {\n\tu32 min_len = MAX_DICT_FILE, max_len = 0, dict_level = 0;\n\tchar * x, * file_contents;\n\tchar filename[MAX_PATH];\n\tint length, ret;\n\tstring_t ** temp_dictq;\n\n\t/* If the name ends with @, extract level and continue. */\n\tif ((x = strchr(path, '@'))) {\n\t\t*x = 0;\n\t\tdict_level = atoi(x + 1);\n\t}\n\n\tACTF(\"Loading extra dictionary from '%s' (level %u)...\", path, dict_level);\n\n#ifdef _WIN32\n\tWIN32_FIND_DATA fdata;\n\tHANDLE h;\n\twchar_t * wide_pattern;\n\n\tif (path[strlen(path) - 1] == '\\\\')\n\t\tsnprintf(filename, sizeof(filename), \"%s*\", path);\n\telse\n\t\tsnprintf(filename, sizeof(filename), \"%s\\\\*\", path);\n\twide_pattern = convert_char_array_to_wchar(filename, NULL);\n\th = FindFirstFile(wide_pattern, &fdata);\n\tfree(wide_pattern);\n\n\tif (h == INVALID_HANDLE_VALUE) {\n\t\tret = load_dictionary_file(info, path, &min_len, &max_len, dict_level);\n\t\tif (ret)\n\t\t\treturn ret;\n\t\tgoto check_dictionary;\n\t}\n\n\tif (x) {\n\t\tprintf(\"Dictionary levels not supported for directories.\");\n\t\tFindClose(h);\n\t\treturn 1;\n\t}\n\n\tdo {\n\t\tif (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)\n\t\t\tcontinue;\n\n\t\tsnprintf(filename, sizeof(filename), \"%s\\\\%s\", path, fdata.cFileName);\n\t\tif (_access(filename, 0)) {\n\t\t\tprintf(\"Unable to access dictionary file '%s'\", filename);\n\t\t\tFindClose(h);\n\t\t\treturn 1;\n\t\t}\n\t\tif ((fdata.nFileSizeHigh > 0) || (fdata.nFileSizeLow > MAX_DICT_FILE)) {\n\t\t\tprintf(\"Dictionary item '%s' is too big (%s, limit is %s)\", filename, DMS(fdata.nFileSizeLow), DMS(MAX_DICT_FILE));\n\t\t\tFindClose(h);\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (min_len > fdata.nFileSizeLow) min_len = fdata.nFileSizeLow;\n\t\tif (max_len < fdata.nFileSizeLow) max_len = fdata.nFileSizeLow;\n\n\t\tlength = read_file(filename, &file_contents);\n\t\tif (length < 0) {\n\t\t\tprintf(\"Unable to open dictionary file '%s'\", filename);\n\t\t\tFindClose(h);\n\t\t\treturn 1;\n\t\t}\n\n\t\ttemp_dictq = (string_t **)realloc(info->dictq, (info->dictionary_count + 1) * sizeof(string_t *));\n\t\tif (!temp_dictq) {\n\t\t\tprintf(\"Failed allocating memory while parsing dictionary file %s.\", filename);\n\t\t\tfree(file_contents);\n\t\t\tFindClose(h);\n\t\t\treturn 1;\n\t\t}\n\t\tinfo->dictq = temp_dictq;\n\n\t\tinfo->dictq[info->dictionary_count] = (string_t *)malloc(sizeof(string_t));\n\t\tif (!info->dictq[info->dictionary_count]) {\n\t\t\tprintf(\"Failed allocating memory while parsing dictionary file %s.\", filename);\n\t\t\tfree(file_contents);\n\t\t\tFindClose(h);\n\t\t\treturn 1;\n\t\t}\n\n\t\tinfo->dictq[info->dictionary_count]->len = length;\n\t\tinfo->dictq[info->dictionary_count]->s = (u8*)file_contents;\n\t\tinfo->dictionary_count++;\n\n\t} while (FindNextFile(h, &fdata));\n\n\tFindClose(h);\n\n#else\n\n\tDIR* d;\n\tstruct dirent* de;\n\tstruct stat st;\n\tint fd;\n\n\td = opendir(path);\n\tif (!d) {\n\t\tret = load_dictionary_file(info, path, &min_len, &max_len, dict_level);\n\t\tif (ret)\n\t\t\treturn ret;\n\t\tgoto check_dictionary;\n\t}\n\n\tif (x) {\n\t\tprintf(\"Dictionary levels not supported for directories.\");\n\t\treturn 1;\n\t}\n\n\twhile ((de = readdir(d))) {\n\n\t\tsnprintf(filename, sizeof(filename), \"%s/%s\", path, de->d_name);\n\t\tif (lstat(filename, &st) || access(filename, R_OK)) {\n\t\t\tprintf(\"Unable to access dictionary file '%s'\", filename);\n\t\t\treturn 1;\n\t\t}\n\n\t\t/* This also takes care of . and .. */\n\t\tif (!S_ISREG(st.st_mode) || !st.st_size)\n\t\t\tcontinue;\n\n\t\tif (st.st_size > MAX_DICT_FILE) {\n\t\t\tprintf(\"Dictionary item '%s' is too big (%s, limit is %s)\", filename, DMS(st.st_size), DMS(MAX_DICT_FILE));\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (min_len > st.st_size) min_len = st.st_size;\n\t\tif (max_len < st.st_size) max_len = st.st_size;\n\n\t\tinfo->dictq = (string_t **)realloc(info->dictq, (info->dictionary_count + 1) * sizeof(string_t *));\n\t\tinfo->dictq[info->dictionary_count] = (string_t *)malloc(sizeof(string_t));\n\n\t\tlength = read_file(filename, (char **)&info->dictq[info->dictionary_count]->s);\n\t\tif (length < 0) {\n\t\t\tprintf(\"Unable to open dictionary file '%s'\", filename);\n\t\t\treturn 1;\n\t\t}\n\t\tinfo->dictq[info->dictionary_count]->len = length;\n\t\tinfo->dictionary_count++;\n\t}\n\n\tclosedir(d);\n\n#endif\n\ncheck_dictionary:\n\tif (!info->dictionary_count) {\n\t\tprintf(\"No usable dictionary files in '%s'\", path);\n\t\treturn 1;\n\t}\n\n\tOKF(\"Loaded %llu dictionary tokens, size range %s to %s.\", info->dictionary_count, DMS(min_len), DMS(max_len));\n\tif (max_len > 32)\n\t\tWARNF(\"Some tokens are relatively large (%s) - consider trimming.\", DMS(max_len));\n\tif (info->dictionary_count > MAX_DET_EXTRAS)\n\t\tWARNF(\"More than %u tokens - will use them probabilistically.\", MAX_DET_EXTRAS);\n\n\treturn 0;\n}\n\nMUTATORS_API int single_walking_bit(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tif (info->stage_cur >= buf->length << 3)\n\t\treturn MUTATOR_DONE;\n\tFLIP_BIT(buf->buffer, info->stage_cur);\n\treturn (int)buf->length;\n}\n\nMUTATORS_API int two_walking_bit(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tif (info->stage_cur >= (buf->length << 3) - 1)\n\t\treturn MUTATOR_DONE;\n\tFLIP_BIT(buf->buffer, info->stage_cur);\n\tFLIP_BIT(buf->buffer, info->stage_cur + 1);\n\treturn (int)buf->length;\n}\n\nMUTATORS_API int four_walking_bit(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tif (info->stage_cur >= (buf->length << 3) - 3)\n\t\treturn MUTATOR_DONE;\n\tFLIP_BIT(buf->buffer, info->stage_cur);\n\tFLIP_BIT(buf->buffer, info->stage_cur + 1);\n\tFLIP_BIT(buf->buffer, info->stage_cur + 2);\n\tFLIP_BIT(buf->buffer, info->stage_cur + 3);\n\treturn (int)buf->length;\n}\n\nMUTATORS_API int walking_byte(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tif (info->stage_cur >= buf->length)\n\t\treturn MUTATOR_DONE;\n\tbuf->buffer[info->stage_cur] ^= 0xFF;\n\treturn (int)buf->length;\n}\n\nMUTATORS_API int two_walking_byte(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tif (info->stage_cur >= buf->length - 1 || buf->length < 2)\n\t\treturn MUTATOR_DONE;\n\t*(u16*)(buf->buffer + info->stage_cur) ^= 0xFFFF;\n\treturn (int)buf->length;\n}\n\nMUTATORS_API int four_walking_byte(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tif (info->stage_cur >= buf->length - 3 || buf->length < 4)\n\t\treturn MUTATOR_DONE;\n\t*(u32*)(buf->buffer + info->stage_cur) ^= 0xFFFFFFFF;\n\treturn (int)buf->length;\n}\n\nMUTATORS_API int one_byte_arithmetics(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tuint64_t index, round;\n\tu8 old_value, new_value, arith_value;\n\n\tif (info->stage_cur >= 2 * buf->length * ARITH_MAX)\n\t\treturn MUTATOR_DONE;\n\n\tindex = info->stage_cur / (2 * ARITH_MAX);\n\tround = (info->stage_cur / ARITH_MAX) % 2;\n\tarith_value = (u8)(info->stage_cur % (ARITH_MAX));\n\n\told_value = buf->buffer[index];\n\n\tif (round == 0) //one byte addition\n\t\tnew_value = old_value + (arith_value + 1);\n\telse //one byte subtraction\n\t\tnew_value = old_value - (arith_value + 1);\n\n\t// Do arithmetic operations only if the result couldn't be a product of a bitflip.\n\tif (info->should_skip_previous && could_be_bitflip(old_value ^ new_value))\n\t\treturn MUTATOR_TRY_AGAIN;\n\n\tbuf->buffer[index] = new_value;\n\treturn (int)buf->length;\n}\n\nMUTATORS_API int two_byte_arithmetics(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tuint64_t index, round;\n\tu16 old_value, new_value, arith_value;\n\n\tif (info->stage_cur >= 4 * (buf->length - 1) * ARITH_MAX || buf->length < 2)\n\t\treturn MUTATOR_DONE;\n\n\tindex = info->stage_cur / (4 * ARITH_MAX);\n\tround = (info->stage_cur / ARITH_MAX) % 4;\n\tarith_value = (info->stage_cur % (ARITH_MAX)) + 1;\n\told_value = *(u16*)(buf->buffer + index);\n\n\tif (round == 0) //little endian addition\n\t\tnew_value = old_value + arith_value;\n\telse if (round == 1) //little endian subtraction\n\t\tnew_value = old_value - arith_value;\n\telse if (round == 2) //big endian addition\n\t\tnew_value = SWAP16(SWAP16(old_value) + arith_value);\n\telse //big endian subtraction\n\t\tnew_value = SWAP16(SWAP16(old_value) - arith_value);\n\n\t// Try little endian addition and subtraction first, then big endian. Do it only\n\t// if the operation would affect more than one byte (hence the & 0xff overflow checks)\n\t// and if it couldn't be a product of a bitflip.\n\tif ((info->should_skip_previous && could_be_bitflip(old_value ^ new_value))\n\t\t|| (round == 0 && (old_value & 0xff) + arith_value <= 0xff)\n\t\t|| (round == 1 && (old_value & 0xff) > arith_value)\n\t\t|| (round == 2 && (old_value >> 8) + arith_value <= 0xff)\n\t\t|| (round == 3 && (old_value >> 8)  > arith_value))\n\t\treturn MUTATOR_TRY_AGAIN;\n\n\t*(u16*)(buf->buffer + index) = new_value;\n\treturn (int)buf->length;\n}\n\nMUTATORS_API int four_byte_arithmetics(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tuint64_t index, round;\n\tu32 old_value, new_value, arith_value;\n\n\tif (info->stage_cur >= 4 * (buf->length - 3) * ARITH_MAX || buf->length < 4)\n\t\treturn MUTATOR_DONE;\n\n\tindex = info->stage_cur / (4 * ARITH_MAX);\n\tround = (info->stage_cur / ARITH_MAX) % 4;\n\tarith_value = (info->stage_cur % (ARITH_MAX)) + 1;\n\told_value = *(u32*)(buf->buffer + index);\n\n\tif (round == 0) //little endian addition\n\t\tnew_value = old_value + arith_value;\n\telse if (round == 1) //little endian subtraction\n\t\tnew_value = old_value - arith_value;\n\telse if (round == 2) //big endian addition\n\t\tnew_value = SWAP32(SWAP32(old_value) + arith_value);\n\telse //big endian subtraction\n\t\tnew_value = SWAP32(SWAP32(old_value) - arith_value);\n\n\t// Little endian first. Same deal as with 16-bit: we only want to\n\t// try if the operation would have effect on more than two bytes.\n\tif ((info->should_skip_previous && could_be_bitflip(old_value ^ new_value))\n\t\t|| (round == 0 && (old_value & 0xffff) + arith_value <= 0xffff)\n\t\t|| (round == 1 && (old_value & 0xffff) > arith_value)\n\t\t|| (round == 2 && (SWAP32(old_value) & 0xffff) + arith_value <= 0xffff)\n\t\t|| (round == 3 && (SWAP32(old_value) & 0xffff) > arith_value))\n\t\treturn MUTATOR_TRY_AGAIN;\n\n\t*(u32*)(buf->buffer + index) = new_value;\n\treturn (int)buf->length;\n}\n\nMUTATORS_API int interesting_one_byte(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tuint64_t index;\n\tu8 old_value, new_value;\n\n\tif (info->stage_cur >= buf->length * ARRAY_SIZE(interesting_8))\n\t\treturn MUTATOR_DONE;\n\n\tindex = info->stage_cur / ARRAY_SIZE(interesting_8);\n\told_value = buf->buffer[index];\n\tnew_value = interesting_8[info->stage_cur % ARRAY_SIZE(interesting_8)];\n\n\t// Skip if the value could be a product of bitflips or arithmetics.\n\tif (info->should_skip_previous && (could_be_bitflip(old_value ^ new_value) || could_be_arith(old_value, new_value, 1)))\n\t\treturn MUTATOR_TRY_AGAIN;\n\n\tbuf->buffer[index] = new_value;\n\treturn (int)buf->length;\n}\n\nMUTATORS_API int interesting_two_byte(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tuint64_t index, round;\n\tu16 old_value, new_value;\n\n\tif (info->stage_cur >= 2 * (buf->length - 1) * ARRAY_SIZE(interesting_16) || buf->length < 2)\n\t\treturn MUTATOR_DONE;\n\n\tindex = info->stage_cur / (2 * ARRAY_SIZE(interesting_16));\n\tround = (info->stage_cur / ARRAY_SIZE(interesting_16)) % 2;\n\told_value = *(u16*)(buf->buffer + index);\n\tnew_value = interesting_16[info->stage_cur % ARRAY_SIZE(interesting_16)];\n\tif (round) //second round, use reverse endian\n\t\tnew_value = SWAP16(new_value);\n\n\t/* Skip if this could be a product of a bitflip, arithmetics,\n\tsingle-byte interesting value insertion, or if on the reverse endian\n\tround and the value is the same in both endians */\n\tif ((info->should_skip_previous &&\n\t\t(could_be_bitflip(old_value ^ new_value)\n\t\t|| could_be_arith(old_value, new_value, 2)\n\t\t|| could_be_interest(old_value, new_value, 2, round)))\n\t\t|| (round == 1 && new_value == SWAP16(new_value)))\n\t\treturn MUTATOR_TRY_AGAIN;\n\n\t*(u16*)(buf->buffer + index) = new_value;\n\treturn (int)buf->length;\n}\n\nMUTATORS_API int interesting_four_byte(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tuint64_t index, round;\n\tu32 old_value, new_value;\n\n\tif (info->stage_cur >= 2 * (buf->length - 3) * ARRAY_SIZE(interesting_32) || buf->length < 4)\n\t\treturn MUTATOR_DONE;\n\n\tindex = info->stage_cur / (2 * ARRAY_SIZE(interesting_32));\n\tround = (info->stage_cur / ARRAY_SIZE(interesting_32)) % 2;\n\told_value = *(u32*)(buf->buffer + index);\n\tnew_value = interesting_32[info->stage_cur % ARRAY_SIZE(interesting_32)];\n\tif (round) //second round, use reverse endian\n\t\tnew_value = SWAP32(new_value);\n\n\t/* Skip if this could be a product of a bitflip, arithmetics,\n\tsingle-byte interesting value insertion, or if on the reverse endian\n\tround and the value is the same in both endians */\n\tif ((info->should_skip_previous && \n\t\t(could_be_bitflip(old_value ^ new_value)\n\t\t|| could_be_arith(old_value, new_value, 4)\n\t\t|| could_be_interest(old_value, new_value, 4, round)))\n\t\t|| (round == 1 && new_value == SWAP32(new_value)))\n\t\treturn MUTATOR_TRY_AGAIN;\n\n\t*(u32*)(buf->buffer + index) = new_value;\n\treturn (int)buf->length;\n}\n\nMUTATORS_API int dictionary_overwrite(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tuint64_t index;\n\tstring_t * dictionary_item;\n\n\tif (!info->dictionary_count || !info->dictq || info->stage_cur > buf->length * info->dictionary_count)\n\t\treturn MUTATOR_DONE;\n\n\tindex = info->stage_cur / info->dictionary_count;\n\tdictionary_item = info->dictq[info->stage_cur % info->dictionary_count];\n\n\t// Skip extras probabilistically if extras_cnt > MAX_DET_EXTRAS. Also\n\t// skip if there's no room to insert the payload or if the token is redundant.\n\tif ((info->dictionary_count > MAX_DET_EXTRAS && UR(info, info->dictionary_count) >= MAX_DET_EXTRAS)\n\t\t|| dictionary_item->len > buf->max_length - index\n\t\t|| !memcmp(dictionary_item->s, buf->buffer + index, dictionary_item->len))\n\t\treturn MUTATOR_TRY_AGAIN;\n\n\tmemcpy(buf->buffer + index, dictionary_item->s, dictionary_item->len);\n\tbuf->length = MAX(buf->length, index + dictionary_item->len);\n\treturn (int)buf->length;\n}\n\nMUTATORS_API int dictionary_insert(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tuint64_t index;\n\tstring_t * dictionary_item;\n\n\tif (!info->dictionary_count || !info->dictq || info->stage_cur > buf->length * info->dictionary_count)\n\t\treturn MUTATOR_DONE;\n\n\tindex = info->stage_cur / info->dictionary_count;\n\tdictionary_item = info->dictq[info->stage_cur % info->dictionary_count];\n\n\t// Skip extras probabilistically if extras_cnt > MAX_DET_EXTRAS. Also\n\t// skip if there's no room to insert the payload or if the token is redundant.\n\tif ((info->dictionary_count > MAX_DET_EXTRAS && UR(info, info->dictionary_count) >= MAX_DET_EXTRAS)\n\t\t|| dictionary_item->len > buf->max_length - index\n\t\t|| buf->length + dictionary_item->len > buf->max_length\n\t\t|| !memcmp(dictionary_item->s, buf->buffer + index, dictionary_item->len))\n\t\treturn MUTATOR_TRY_AGAIN;\n\n\tmemmove(buf->buffer + index + dictionary_item->len, buf->buffer + index, buf->length - index);\n\tmemcpy(buf->buffer + index, dictionary_item->s, dictionary_item->len);\n\tbuf->length += dictionary_item->len;\n\treturn (int)buf->length;\n}\n\nMUTATORS_API int havoc(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tuint64_t use_stacking, i;\n\tu32 pos, num32, del_from, del_len, insert_at, use_extra;\n\tu32 copy_from, copy_to, copy_len;\n\tu32 clone_from, clone_to, clone_len;\n\tu16 num16;\n\tu8  actually_clone;\n\tstring_t * dictionary_item;\n\n\tuse_stacking = 1ULL << (1 + UR(info, HAVOC_STACK_POW2));\n\tfor (i = 0; i < use_stacking; i++)\n\t{\n\t\tswitch (UR(info, 15 + (info->dictionary_count ? 2 : 0)))\n\t\t{\n\t\tcase 0: // Flip a single bit somewhere. Spooky!\n\t\t\tFLIP_BIT(buf->buffer, UR(info, buf->length << 3));\n\t\t\tbreak;\n\n\t\tcase 1: // Set byte to interesting value.\n\t\t\tbuf->buffer[UR(info, buf->length)] = interesting_8[UR(info, sizeof(interesting_8))];\n\t\t\tbreak;\n\n\t\tcase 2: // Set word to interesting value, randomly choosing endian.\n\t\t\tif (buf->length < 2)\n\t\t\t\tbreak;\n\n\t\t\tif (UR(info, 2)) {\n\t\t\t\t*(u16*)(buf->buffer + UR(info, buf->length - 1)) =\n\t\t\t\t\tinteresting_16[UR(info, sizeof(interesting_16) >> 1)];\n\t\t\t}\n\t\t\telse {\n\t\t\t\t*(u16*)(buf->buffer + UR(info, buf->length - 1)) =\n\t\t\t\t\tSWAP16(interesting_16[UR(info, sizeof(interesting_16) >> 1)]);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 3: // Set dword to interesting value, randomly choosing endian.\n\t\t\tif (buf->length < 4)\n\t\t\t\tbreak;\n\n\t\t\tif (UR(info, 2)) {\n\t\t\t\t*(u32*)(buf->buffer + UR(info, buf->length - 3)) =\n\t\t\t\t\tinteresting_32[UR(info, sizeof(interesting_32) >> 2)];\n\t\t\t}\n\t\t\telse {\n\t\t\t\t*(u32*)(buf->buffer + UR(info, buf->length - 3)) =\n\t\t\t\t\tSWAP32(interesting_32[UR(info, sizeof(interesting_32) >> 2)]);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 4: // Randomly subtract from byte.\n\t\t\tbuf->buffer[UR(info, buf->length)] -= 1 + UR(info, ARITH_MAX);\n\t\t\tbreak;\n\n\t\tcase 5: // Randomly add to byte.\n\t\t\tbuf->buffer[UR(info, buf->length)] += 1 + UR(info, ARITH_MAX);\n\t\t\tbreak;\n\n\t\tcase 6: // Randomly subtract from word, random endian.\n\t\t\tif (buf->length < 2)\n\t\t\t\tbreak;\n\n\t\t\tpos = UR(info, buf->length - 1);\n\t\t\tnum16 = 1 + UR(info, ARITH_MAX);\n\t\t\tif (UR(info, 2))\n\t\t\t\t*(u16*)(buf->buffer + pos) -= num16;\n\t\t\telse\n\t\t\t\t*(u16*)(buf->buffer + pos) = SWAP16(SWAP16(*(u16*)(buf->buffer + pos)) - num16);\n\t\t\tbreak;\n\n\t\tcase 7: // Randomly add to word, random endian.\n\t\t\tif (buf->length < 2)\n\t\t\t\tbreak;\n\n\t\t\tpos = UR(info, buf->length - 1);\n\t\t\tnum16 = 1 + UR(info, ARITH_MAX);\n\t\t\tif (UR(info, 2))\n\t\t\t\t*(u16*)(buf->buffer + pos) += num16;\n\t\t\telse\n\t\t\t\t*(u16*)(buf->buffer + pos) = SWAP16(SWAP16(*(u16*)(buf->buffer + pos)) + num16);\n\t\t\tbreak;\n\n\t\tcase 8: // Randomly subtract from dword, random endian.\n\t\t\tif (buf->length < 4)\n\t\t\t\tbreak;\n\n\t\t\tpos = UR(info, buf->length - 3);\n\t\t\tnum32 = 1 + UR(info, ARITH_MAX);\n\t\t\tif (UR(info, 2))\n\t\t\t\t*(u32*)(buf->buffer + pos) -= num32;\n\t\t\telse\n\t\t\t\t*(u32*)(buf->buffer + pos) = SWAP32(SWAP32(*(u32*)(buf->buffer + pos)) - num32);\n\t\t\tbreak;\n\n\t\tcase 9: // Randomly add to dword, random endian.\n\t\t\tif (buf->length < 4)\n\t\t\t\tbreak;\n\n\t\t\tpos = UR(info, buf->length - 3);\n\t\t\tnum32 = 1 + UR(info, ARITH_MAX);\n\t\t\tif (UR(info, 2))\n\t\t\t\t*(u32*)(buf->buffer + pos) += num32;\n\t\t\telse\n\t\t\t\t*(u32*)(buf->buffer + pos) = SWAP32(SWAP32(*(u32*)(buf->buffer + pos)) + num32);\n\t\t\tbreak;\n\n\t\tcase 10:\n\t\t\t/* Just set a random byte to a random value. Because,\n\t\t\twhy not. We use XOR with 1-255 to eliminate the\n\t\t\tpossibility of a no-op. */\n\t\t\tbuf->buffer[UR(info, buf->length)] ^= 1 + UR(info, 255);\n\t\t\tbreak;\n\n\t\tcase 11:\n\t\tcase 12:\n\t\t\t/* Delete bytes. We're making this a bit more likely\n\t\t\tthan insertion (the next option) in hopes of keeping\n\t\t\tfiles reasonably small. */\n\t\t\tif (buf->length < 2)\n\t\t\t\tbreak;\n\n\t\t\tdel_len = choose_block_len(info, buf->length - 1);\n\t\t\tdel_from = UR(info, buf->length - del_len + 1);\n\t\t\tmemmove(buf->buffer + del_from, buf->buffer + del_from + del_len,\n\t\t\t\tbuf->length - del_from - del_len);\n\t\t\tbuf->length -= del_len;\n\t\t\tbreak;\n\n\t\tcase 13: //Clone bytes (75%) or insert a block of constant bytes (25%).\n\t\t\tif (buf->length + HAVOC_BLK_XL >= MAX_FILE)\n\t\t\t\tbreak;\n\n\t\t\tactually_clone = UR(info, 4);\n\t\t\tif (actually_clone) {\n\t\t\t\tclone_len = choose_block_len(info, buf->length);\n\t\t\t\tclone_len = MIN(clone_len, buf->max_length - buf->length);\n\t\t\t\tclone_from = UR(info, buf->length - clone_len + 1);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tclone_len = choose_block_len(info, HAVOC_BLK_XL);\n\t\t\t\tclone_len = MIN(clone_len, buf->max_length - buf->length);\n\t\t\t\tclone_from = 0;\n\t\t\t}\n\n\t\t\tclone_to = UR(info, buf->length);\n\t\t\tmemmove(buf->buffer + clone_to + clone_len, buf->buffer + clone_to, buf->length - clone_to);\n\t\t\tif (actually_clone)\n\t\t\t\tmemmove(buf->buffer + clone_to, buf->buffer + clone_from, clone_len);\n\t\t\telse\n\t\t\t\tmemset(buf->buffer + clone_to,\n\t\t\t\t\tUR(info, 2) ? UR(info, 256) : buf->buffer[UR(info, buf->length)], clone_len);\n\t\t\tbuf->length += clone_len;\n\t\t\tbreak;\n\n\t\tcase 14: // Overwrite bytes with a randomly selected chunk (75%) or fixed bytes (25%).\n\t\t\tif (buf->length < 2)\n\t\t\t\tbreak;\n\n\t\t\tcopy_len = choose_block_len(info, buf->length - 1);\n\t\t\tcopy_from = UR(info, buf->length - copy_len + 1);\n\t\t\tcopy_to = UR(info, buf->length - copy_len + 1);\n\n\t\t\tif (!UR(info, 4))\n\t\t\t\tmemset(buf->buffer + copy_to,\n\t\t\t\t\tUR(info, 2) ? UR(info, 256) : buf->buffer[UR(info, buf->length)], copy_len);\n\t\t\telse if (copy_from != copy_to)\n\t\t\t\tmemmove(buf->buffer + copy_to, buf->buffer + copy_from, copy_len);\n\t\t\tbreak;\n\n\t\tcase 15: // Overwrite bytes with a dictionary item\n\t\t\tuse_extra = UR(info, info->dictionary_count);\n\t\t\tdictionary_item = info->dictq[use_extra];\n\n\t\t\tif (dictionary_item->len > buf->length)\n\t\t\t\tbreak;\n\n\t\t\tinsert_at = UR(info, buf->length - dictionary_item->len + 1);\n\t\t\tmemcpy(buf->buffer + insert_at, dictionary_item->s, dictionary_item->len);\n\t\t\tbreak;\n\n\t\tcase 16: // Insert an extra. Do the same dice-rolling stuff as for the previous case.\n\t\t\tinsert_at = UR(info, buf->length + 1);\n\t\t\tuse_extra = UR(info, info->dictionary_count);\n\t\t\tdictionary_item = info->dictq[use_extra];\n\n\t\t\tif (buf->length + dictionary_item->len >= buf->max_length)\n\t\t\t\tbreak;\n\n\t\t\tmemmove(buf->buffer + insert_at + dictionary_item->len, buf->buffer + insert_at,\n\t\t\t\tbuf->length - insert_at);\n\t\t\tmemcpy(buf->buffer + insert_at, dictionary_item->s, dictionary_item->len);\n\t\t\tbuf->length += dictionary_item->len;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn (int)buf->length;\n}\n\nMUTATORS_API int splice_buffers(mutate_info_t * info, mutate_buffer_t * buf)\n{\n\tstring_t * target = NULL;\n\tu32 attempts = 0, split_at;\n\ts32 f_diff = -1, l_diff = -1;\n\n\t// Splicing takes the current input file, randomly selects another input, and\n\t// splices them together at some offset, then relies on the havoc code to mutate that blob.\n\tif (info->splice_files_count == 0)\n\t\treturn MUTATOR_DONE;\n\n\t//Pick a target to splice with\n\twhile (target == NULL || ((f_diff < 0 || l_diff < 2 || f_diff == l_diff) && (attempts < 2 * info->splice_files_count)))\n\t{\n\t\tattempts++;\n\t\ttarget = info->splice_files[UR(info, info->splice_files_count)];\n\t\tlocate_diffs(buf->buffer, target->s, MIN(buf->length, target->len), &f_diff, &l_diff);\n\t}\n\tif (f_diff < 0 || l_diff < 2 || f_diff == l_diff)\n\t\treturn MUTATOR_TRY_AGAIN;\n\n\t// Split somewhere between the first and last differing byte.\n\tsplit_at = f_diff + UR(info, l_diff - f_diff);\n\n\tbuf->length = target->len;\n\tmemcpy(buf->buffer + split_at, target->s + split_at, target->len - split_at);\n\treturn havoc(info, buf);\n}\n"
  },
  {
    "path": "mutators/mutators/afl_helpers.h",
    "content": "#pragma once\n\n#include \"mutators.h\"\n#include \"afl_types.h\"\n\n#include <utils.h>\n#include <jansson_helper.h>\n\ntypedef struct {\n\tu8* s;\n\tsize_t len;\n} string_t;\n\ntypedef struct {\n\tuint8_t * buffer;\n\tsize_t length;\n\tsize_t max_length;\n} mutate_buffer_t;\n\ntypedef struct {\n\tint should_skip_previous;\n\tint one_stage_only;\n\tint havoc_div;\n\tint perf_score;\n\n\tchar * dictionary_file;\n\tuint64_t dictionary_count;\n\tstring_t ** dictq;\n\n\tchar ** splice_filenames;\n\tsize_t splice_filenames_count;\n\tuint64_t splice_files_count;\n\tstring_t ** splice_files;\n\n\t//Used to protects the fields below, as well as any non-thread safe fields in\n\tmutex_t mutate_mutex; //the mutator-specific state (such as the iteration)\n\n\tuint64_t random_state[2]; //the state of the random number generator\n\tuint64_t stage_cur; //The current iteration number for the current mutation stage\n\tint stage; //The current mutation stage, an index into the mutation functions passed to mutate_one\n\tint queue_cycle;\n\n} mutate_info_t;\n\nMUTATORS_API u32 UR(mutate_info_t * info, u32 limit);\nMUTATORS_API int load_dictionary(mutate_info_t * info, char * path);\nMUTATORS_API int load_splice_files(mutate_info_t * info, char ** splice_filenames, size_t splice_filenames_count);\nMUTATORS_API int reset_mutate_info(mutate_info_t * info);\nMUTATORS_API void cleanup_mutate_info(mutate_info_t * info);\nMUTATORS_API int add_mutate_info_to_json(json_t * obj, mutate_info_t * info);\nMUTATORS_API int get_mutate_info_from_json(char * state, mutate_info_t * info);\nMUTATORS_API int mutate_one(mutate_info_t * info, mutate_buffer_t * buf, int(*const*mutate_funcs)(mutate_info_t *, mutate_buffer_t *), size_t num_funcs);\n\n//Individual mutation functions\nMUTATORS_API int single_walking_bit(mutate_info_t * info, mutate_buffer_t * buf);\nMUTATORS_API int two_walking_bit(mutate_info_t * info, mutate_buffer_t * buf);\nMUTATORS_API int four_walking_bit(mutate_info_t * info, mutate_buffer_t * buf);\nMUTATORS_API int walking_byte(mutate_info_t * info, mutate_buffer_t * buf);\nMUTATORS_API int two_walking_byte(mutate_info_t * info, mutate_buffer_t * buf);\nMUTATORS_API int four_walking_byte(mutate_info_t * info, mutate_buffer_t * buf);\nMUTATORS_API int one_byte_arithmetics(mutate_info_t * info, mutate_buffer_t * buf);\nMUTATORS_API int two_byte_arithmetics(mutate_info_t * info, mutate_buffer_t * buf);\nMUTATORS_API int four_byte_arithmetics(mutate_info_t * info, mutate_buffer_t * buf);\nMUTATORS_API int interesting_one_byte(mutate_info_t * info, mutate_buffer_t * buf);\nMUTATORS_API int interesting_two_byte(mutate_info_t * info, mutate_buffer_t * buf);\nMUTATORS_API int interesting_four_byte(mutate_info_t * info, mutate_buffer_t * buf);\nMUTATORS_API int dictionary_overwrite(mutate_info_t * info, mutate_buffer_t * buf);\nMUTATORS_API int dictionary_insert(mutate_info_t * info, mutate_buffer_t * buf);\nMUTATORS_API int havoc(mutate_info_t * info, mutate_buffer_t * buf);\nMUTATORS_API int splice_buffers(mutate_info_t * info, mutate_buffer_t * buf);\n\n//There are no more mutations possible for this mutation function\n#define MUTATOR_DONE 0\n//This specific mutation can't be done, try again (i.e. we are trying a mutation\n//that was already done in an earlier round)\n#define MUTATOR_TRY_AGAIN -1\n\n//A macro to parse the options used during afl fuzzing\n#define PARSE_MUTATE_INFO_OPTIONS(state, options, cleanup_func, dictionary_required, splice_required) \\\n\tPARSE_OPTION_UINT64T_TEMP(state, options, info.random_state[0], \"random_state0\", cleanup_func, random_state0);                     \\\n\tPARSE_OPTION_UINT64T_TEMP(state, options, info.random_state[1], \"random_state1\", cleanup_func, random_state1);                     \\\n\tPARSE_OPTION_INT_TEMP(state, options, info.stage, \"stage\", cleanup_func, stage);                                                   \\\n\tPARSE_OPTION_INT_TEMP(state, options, info.stage_cur, \"stage_cur\", cleanup_func, stage_cur);                                       \\\n\tPARSE_OPTION_INT_TEMP(state, options, info.should_skip_previous, \"skip_previous_stages\", cleanup_func, should_skip_previous);      \\\n\tPARSE_OPTION_INT_TEMP(state, options, info.queue_cycle, \"queue_cycle\", cleanup_func, queue_cycle);                                 \\\n\tPARSE_OPTION_INT_TEMP(state, options, info.havoc_div, \"havoc_div\", cleanup_func, havoc_div);                                       \\\n\tPARSE_OPTION_INT_TEMP(state, options, info.perf_score, \"perf_score\", cleanup_func, perf_score);                                    \\\n\tPARSE_OPTION_STRING_TEMP(state, options, info.dictionary_file, \"dictionary\", cleanup_func, dictionary);                            \\\n\tPARSE_OPTION_ARRAY_TEMP(state, options, info.splice_filenames, info.splice_filenames_count, \"splice_filenames\", cleanup_func, ss); \\\n\tif ((dictionary_required && !state->info.dictionary_file) ||                                                                       \\\n\t\t(state->info.dictionary_file && load_dictionary(&state->info, state->info.dictionary_file)))                                   \\\n\t{                                                                                                                                  \\\n\t\tcleanup_func(state);                                                                                                           \\\n\t\treturn NULL;                                                                                                                   \\\n\t}                                                                                                                                  \\\n\tif ((splice_required && !state->info.splice_filenames_count) ||                                                                    \\\n\t\t(state->info.splice_filenames_count &&                                                                                         \\\n\t\t\tload_splice_files(&state->info, state->info.splice_filenames, state->info.splice_filenames_count)))                        \\\n\t{                                                                                                                                  \\\n\t\tcleanup_func(state);                                                                                                           \\\n\t\treturn NULL;                                                                                                                   \\\n\t}                                                                                                                                  \\\n\n"
  },
  {
    "path": "mutators/mutators/afl_types.h",
    "content": "/*\n   american fuzzy lop - type definitions and minor macros\n   ------------------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This file has been modified from the original to suit the purposes of this\n   project.\n */\n\n#ifndef _HAVE_TYPES_H\n#define _HAVE_TYPES_H\n\n#include <stdint.h>\n#include <stdlib.h>\n\n#ifdef __APPLE__ //MacOS\n#include <sys/syslimits.h>\n#define MAX_PATH PATH_MAX //linux/apple have PATH_MAX, windows has MAX_PATH\n#elif !defined(_WIN32) //Not Windows\n#include <byteswap.h>\n#define MAX_PATH PATH_MAX //linux/apple have PATH_MAX, windows has MAX_PATH\n#endif\n\ntypedef uint8_t  u8;\ntypedef uint16_t u16;\ntypedef uint32_t u32;\n\n/*\n\n   Ugh. There is an unintended compiler / glibc #include glitch caused by\n   combining the u64 type an %llu in format strings, necessitating a workaround.\n\n   In essence, the compiler is always looking for 'unsigned long long' for %llu.\n   On 32-bit systems, the u64 type (aliased to uint64_t) is expanded to\n   'unsigned long long' in <bits/types.h>, so everything checks out.\n\n   But on 64-bit systems, it is #ifdef'ed in the same file as 'unsigned long'.\n   Now, it only happens in circumstances where the type happens to have the\n   expected bit width, *but* the compiler does not know that... and complains\n   about 'unsigned long' being unsafe to pass to %llu.\n\n */\n\n#ifdef __x86_64__\ntypedef unsigned long long u64;\n#else\ntypedef uint64_t u64;\n#endif /* ^__x86_64__ */\n\ntypedef int8_t   s8;\ntypedef int16_t  s16;\ntypedef int32_t  s32;\ntypedef int64_t  s64;\n\n#ifndef MIN\n#  define MIN(_a,_b) ((_a) > (_b) ? (_b) : (_a))\n#  define MAX(_a,_b) ((_a) > (_b) ? (_a) : (_b))\n#endif /* !MIN */\n\n#ifdef _WIN32\n#define SWAP16(_x) _byteswap_ushort(_x)\n#define SWAP32(_x) _byteswap_ulong(_x)\n#define SWAP64(_x) _byteswap_uint64(_x)\n#elif defined(__APPLE__)\n#define SWAP16(_x) __builtin_bswap16(_x)\n#define SWAP32(_x) __builtin_bswap32(_x)\n#define SWAP64(_x) __builtin_bswap64(_x)\n#else\n#define SWAP16(_x) bswap_16(_x)\n#define SWAP32(_x) bswap_32(_x)\n#define SWAP64(_x) bswap_64(_x)\n#endif\n\n\n#ifdef AFL_LLVM_PASS\n#  define AFL_R(x) (random() % (x))\n#else\n#  define R(x) (random() % (x))\n#endif /* ^AFL_LLVM_PASS */\n\n#define STRINGIFY_INTERNAL(x) #x\n#define STRINGIFY(x) STRINGIFY_INTERNAL(x)\n\n#define MEM_BARRIER() \\\n  asm volatile(\"\" ::: \"memory\")\n\n#define likely(_x)   __builtin_expect(!!(_x), 1)\n#define unlikely(_x)  __builtin_expect(!!(_x), 0)\n\n#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x))\n\n#endif /* ! _HAVE_TYPES_H */\n"
  },
  {
    "path": "mutators/mutators/mutators.c",
    "content": "#include \"mutators.h\"\n\n#include <stdint.h>\n#include <stdlib.h>\n\nMUTATORS_API void default_free_state(char * state)\n{\n\tfree(state);\n}\n\nMUTATORS_API int return_unknown_or_infinite_total_iterations(void * mutator_state)\n{\n\treturn -1; //infinite\n}\n"
  },
  {
    "path": "mutators/mutators/mutators.h",
    "content": "#pragma once\n\n#ifdef _WIN32\n#if defined(MUTATORS_EXPORTS)\n#define MUTATORS_API __declspec(dllexport)\n#elif defined(MUTATORS_NO_IMPORT)\n#define MUTATORS_API\n#elif defined(__cplusplus)\n#define MUTATORS_API extern \"C\" __declspec(dllimport)\n#else\n#define MUTATORS_API __declspec(dllimport)\n#endif\n#else\n#define MUTATORS_API\n#endif\n\n//If you're combining all of the mutators into one project, uncomment this to give them all\n//unique names\n//#define ALL_MUTATORS_IN_ONE\n#ifndef ALL_MUTATORS_IN_ONE\n#define FUNCNAME(name) name\n#else\n#define FUNCNAME(name) MUTATOR_NAME ## _ ## name\n#endif\n\nMUTATORS_API void default_free_state(char * state);\nMUTATORS_API int return_unknown_or_infinite_total_iterations(void * mutator_state);\n\n#define GENERIC_MUTATOR_CREATE(type_t, option_parser_func, cleanup_state_func) \\\n\ttype_t * new_state = option_parser_func(options);                            \\\n\tif (!new_state)                                                              \\\n\t\treturn NULL;                                                               \\\n\tnew_state->input = (char *)malloc(input_length);                             \\\n\tif (!new_state->input || !input_length)                                      \\\n\t{                                                                            \\\n\t\tcleanup_state_func(new_state);                                             \\\n\t\treturn NULL;                                                               \\\n\t}                                                                            \\\n\tmemcpy(new_state->input, input, input_length);                               \\\n\tnew_state->input_length = input_length;                                      \\\n\tif(state && FUNCNAME(set_state)(new_state, state)) {                         \\\n\t\tcleanup_state_func(new_state);                                       \\\n\t\treturn NULL;                                                         \\\n\t}                                                                            \\\n\treturn new_state;\n\n#define GENERIC_MUTATOR_CLEANUP(type_t)                                        \\\n\ttype_t * cleanup_state = (type_t *)mutator_state;                            \\\n\tfree(cleanup_state->input);                                                  \\\n\tfree(cleanup_state);\n\n#define GENERIC_MUTATOR_GET_ITERATION(type_t)                                  \\\n\ttype_t * iteration_state = (type_t *)mutator_state;                          \\\n\treturn iteration_state->iteration;\n\n#define GENERIC_MUTATOR_SET_INPUT(type_t)                                      \\\n\ttype_t * state = (type_t *)mutator_state;                                    \\\n\tif (state->input)                                                            \\\n\t\tfree(state->input);                                                        \\\n\tstate->input = (char *)malloc(input_length);                                 \\\n\tif (!state->input)                                                           \\\n\t\treturn -1;                                                                 \\\n\tstate->input_length = input_length;                                          \\\n\tmemcpy(state->input, new_input, input_length);                               \\\n\treturn 0;\n\n#define GENERIC_MUTATOR_HELP(msg)                                              \\\n\t*help_str = strdup(msg);                                                     \\\n\tif (*help_str == NULL)                                                       \\\n\t\treturn -1;                                                                 \\\n\treturn 0;                                                                    \\\n\n#define SINGLE_INPUT_GET_INFO(type_t)                                            \\\n\ttype_t * state = (type_t *)mutator_state;                                    \\\n\tif (num_inputs)                                                              \\\n\t\t*num_inputs = 1;                                                         \\\n\tif (input_sizes) {                                                           \\\n\t\t*input_sizes = malloc(sizeof(size_t));                                   \\\n\t\t*input_sizes[0] = state->input_length;                                   \\\n\t}\n\n#define SINGLE_INPUT_MUTATE_EXTENDED(type_t, mutex)                                   \\\n\ttype_t * state = (type_t *)mutator_state;                                           \\\n\tint ret;                                                                            \\\n\tif ((flags & MUTATE_MULTIPLE_INPUTS) && (flags & MUTATE_MULTIPLE_INPUTS_MASK) != 0) \\\n\t\treturn -1;                                                                        \\\n\tif ((flags & MUTATE_THREAD_SAFE) && take_mutex(mutex))                              \\\n\t\treturn -1;                                                                        \\\n\tret = FUNCNAME(mutate)(state, buffer, buffer_length);                               \\\n\tif ((flags & MUTATE_THREAD_SAFE) && release_mutex(mutex))                           \\\n\t\treturn -1;                                                                        \\\n\treturn ret;\n\n#define FLIP_BIT(_ar, _b) do { \\\n    u8* _arf = (u8*)(_ar); \\\n    u64 _bf = (_b); \\\n    _arf[(_bf) >> 3] ^= (128 >> ((_bf) & 7)); \\\n  } while (0)\n\n"
  },
  {
    "path": "mutators/ni_mutator/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (ni_mutator)\n\ninclude_directories (${PROJECT_SOURCE_DIR}/../mutators/)\n\nset(NI_SRC ${PROJECT_SOURCE_DIR}/ni_mutator.c)\nsource_group(\"Library Sources\" FILES ${NI_SRC})\n\nadd_library(ni_mutator SHARED ${NI_SRC}\n  $<TARGET_OBJECTS:mutators_object> $<TARGET_OBJECTS:jansson_object>)\ntarget_link_libraries(ni_mutator utils)\ntarget_compile_definitions(ni_mutator PUBLIC NI_MUTATOR_EXPORTS)\ntarget_compile_definitions(ni_mutator PUBLIC MUTATORS_NO_IMPORT)\ntarget_compile_definitions(ni_mutator PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(ni_mutator PUBLIC JANSSON_NO_IMPORT)\n\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(ni_mutator Shlwapi)\nendif (WIN32)\n"
  },
  {
    "path": "mutators/ni_mutator/ni_mutator.c",
    "content": "#include \"ni_mutator.h\"\n#include <mutators.h>\n\n#include <utils.h>\n#include <jansson_helper.h>\n#include <global_types.h>\n\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n//Uncomment this line to make the killerbeez ni mutator use the same random number generator\n//as ni and take the seed value from the $RANDSEED environment variable. This is useful when\n//comparing the output of this mutator against the ni executable to ensure their behavior\n//matches\n//#define NI_COMPARISON_TESTING\n\ntypedef struct sample {\n\tchar * content;\n\tint length;\n} sample_t;\n\nstruct ni_state\n{\n\tchar * input;\n\tsize_t input_length;\n\n\t//Protects the fields below, i.e. the iteration count, mutate buffer information, and random state\n\tmutex_t mutate_mutex;\n\n\tint iteration;\n\tuint8_t * mutated_buffer;\n\tuint64_t mutated_buffer_length;\n\tuint64_t max_mutated_buffer_length;\n\n\tuint64_t random_state[2];\n\tchar ** sample_filenames;\n\tsize_t num_samples;\n\tsample_t ** samples;\n};\ntypedef struct ni_state ni_state_t;\n\nmutator_t ni_mutator = {\n\tFUNCNAME(create),\n\tFUNCNAME(cleanup),\n\tFUNCNAME(mutate),\n\tFUNCNAME(mutate_extended),\n\tFUNCNAME(get_state),\n\tni_free_state,\n\tFUNCNAME(set_state),\n\tFUNCNAME(get_current_iteration),\n\tni_get_total_iteration_count,\n\tFUNCNAME(get_input_info),\n\tFUNCNAME(set_input),\n\tFUNCNAME(help)\n};\n\n////////////////////////////////////////////////////////////////////////////////////////////\n//// Ni mutator methods ////////////////////////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////////////////////////\n\n#define RAND(state,x)    ((x)?(rnd(state)%(x)):0)\n\n/*\n * xoroshiro128plus by David Blackman and Sebastiano Vigna\n */\nstatic inline uint64_t util_RotL(const uint64_t x, int k)\n{\n\treturn (x << k) | (x >> (64 - k));\n}\n\nstatic inline uint64_t rnd64(ni_state_t * state) {\n\tconst uint64_t s0 = state->random_state[0];\n\tuint64_t s1 = state->random_state[1];\n\tconst uint64_t result = s0 + s1;\n\ts1 ^= s0;\n\tstate->random_state[0] = util_RotL(s0, 55) ^ s1 ^ (s1 << 14);\n\tstate->random_state[1] = util_RotL(s1, 36);\n\treturn result;\n}\n\n/**\n * This function generates a positive random number\n * @param state - a mutator specific structure previously created by the create function.\n * @return the randomly generated number\n */\nstatic inline long long rnd(ni_state_t * state) {\n#ifdef NI_COMPARISON_TESTING\n\t//If testing to compare output against the ni binary, use random()\n\treturn random(); //instead of our own random number generator\n#else\n\tlong long r = rnd64(state);\n\tif (r < 0) r = -r;\n\treturn r;\n#endif\n}\n\n/**\n * This function returns a fresh copy of the input buffer or a sample provided by the\n * mutator options.\n * @param state - a mutator specific structure previously created by the create function.\n * @param index - The index of the sample file to retrieve. To retrieve the input buffer,\n * specify -1 for the index.\n * @param len - A pointer to a size_t used to return the length of the retrieved buffer\n * @return A pointer to the copy of the input buffer or sample\n */\nstatic char * get_sample(ni_state_t * state, int index, size_t *len)\n{\n\tchar * content, * copy;\n\tsize_t length;\n\n\tif(index < 0) {\n\t\tlength = state->input_length;\n\t\tcontent = state->input;\n\t} else {\n\t\tlength = state->samples[index]->length;\n\t\tcontent = state->samples[index]->content;\n\t}\n\tcopy = malloc(length);\n\tmemcpy(copy, content, length);\n\t*len = length;\n\treturn copy;\n}\n\n/**\n * This function picks a random sample provided by the mutator options or the input buffer\n * and returns a copy to it.\n * @param state - a mutator specific structure previously created by the create function.\n * @param len - A pointer to a size_t used to return the length of the retrieved buffer\n * @return A pointer to the copy of the input buffer or sample\n */\nstatic char * get_random_sample(ni_state_t * state, size_t *len)\n{\n\tint index = RAND(state, state->num_samples + 1);\n\tif(index == state->num_samples)\n\t\treturn get_sample(state, -1, len);\n\treturn get_sample(state, index, len);\n}\n\n/*\n * This code in this section below was taken from the ni mutator, available\n * at: https://github.com/aoh/ni . The ni project does not provide a\n * license for this code.\n *\n * It has been modified from the original to suit the purposes of this\n * project.\n */\n\n#define AIMROUNDS  256\n#define AIMAX      512\n#define AIMLEN     1024\n#define MIN(a, b)  (((a) < (b)) ? a : b)\n#define BUFSIZE    4096\n\nstatic char * random_block(ni_state_t * state, size_t orig_len, size_t * new_len) {\n\tsize_t sample_len, start, len;\n\tchar * sample, * block;\n\n\tsample = get_random_sample(state, &sample_len);\n\tif(sample_len < 3) {\n\t\tfree(sample);\n\t\treturn NULL;\n\t}\n\n\tstart = RAND(state,sample_len-2);\n\tlen = sample_len - start;\n\tif (len > 4 * orig_len)\n\t\tlen = 4 * orig_len;\n\tlen = RAND(state,len);\n\tlen = MIN(len, sample_len - start);\n\n\tblock = malloc(len);\n\tmemcpy(block, sample + start, len);\n\t*new_len = len;\n\tfree(sample);\n\treturn block;\n}\n\nstatic void write_all(ni_state_t * state, const char *data, size_t n) {\n\tsize_t num_bytes = MIN(n, state->max_mutated_buffer_length - state->mutated_buffer_length);\n\tif(num_bytes != 0) {\n\t\tmemcpy(state->mutated_buffer + state->mutated_buffer_length, data, num_bytes);\n\t\tstate->mutated_buffer_length += num_bytes;\n\t}\n}\n\nstatic void output_num(ni_state_t * state, char *buff, size_t buflen, long long n) {\n\tint negp = 0;\n\tif (n < 0) {\n\t\tn *= -1;\n\t\tnegp = 1;\n\t}\n\tif (n == 0) {\n\t\tbuff[0] = '0';\n\t\twrite_all(state, buff, 1);\n\t} else {\n\t\tsize_t p = buflen - 1;\n\t\twhile(n && p) {\n\t\t\tbuff[p--] = n % 10 + '0';\n\t\t\tn /= 10;\n\t\t}\n\t\tif (negp || !(rnd(state)&63))\n\t\t\tbuff[p--] = '-';\n\t\tp++;\n\t\twrite_all(state, buff + p, buflen - p);\n\t}\n}\n\nstatic int sufscore(const char *a, size_t al, const char *b, size_t bl) {\n\tint last = 256;\n\tint n = 0;\n\twhile(al-- && bl-- && *a == *b && n < AIMAX) {\n\t\tif (*a != last)\n\t\t\tn += 32;\n\t\tlast = *a++;\n\t\tb++;\n\t}\n\treturn n;\n}\n\n/* note, could have a separate aimer for runs */\nstatic void aim(ni_state_t * state, const char *from, size_t fend, const char *to, size_t tend, size_t *jump, size_t *land) {\n\tsize_t j, l;\n\tint best_score = 0, score, rounds = 0;\n\tif (!fend) {\n\t\t*jump = 0;\n\t\t*land = tend ? RAND(state,tend) : 0;\n\t\treturn;\n\t}\n\t*jump = RAND(state,fend);\n\tif (!tend) {\n\t\t*land = 0;\n\t\treturn;\n\t}\n\t*land = RAND(state,tend);\n\trounds = RAND(state,AIMROUNDS);\n\tscore = 0;\n\twhile(rounds--) {\n\t\tint maxs = AIMLEN;\n\t\tj = RAND(state,fend);\n\t\tl = RAND(state,tend);\n\t\twhile(maxs-- && l < tend && from[j] != to[l]) {\n\t\t\tl++;\n\t\t}\n\t\tscore = sufscore(from + j, fend - j, to + l, tend - l);\n\t\tif (score > best_score) {\n\t\t\tbest_score = score;\n\t\t\t*jump = j;\n\t\t\t*land = l;\n\t\t}\n\t}\n}\n\nstatic int delim_of(char c) {\n\tint d = 0;\n\tswitch(c) {\n\t\t//case '\"': d = '\"'; break;\n\t\tcase '<': d = '>'; break;\n\t\tcase '\\n': d = '\\n'; break;\n\t\tcase '(': d = ')'; break;\n\t\tcase '[': d = ']'; break;\n\t\tcase '{': d = '}'; break;\n\t\t//case '\\'': d = '\\''; break;\n\t\t//case ' ': d = ' '; break;\n\t\t//case ',': d = ','; break;\n\t}\n\treturn d;\n}\n\nstatic int drange_start(ni_state_t * state, const char *pos, size_t end, size_t *start, char *open, char *close) {\n\tint rounds = 32;\n\twhile (rounds--) {\n\t\tsize_t o = RAND(state, end);\n\t\tint n = AIMLEN;\n\t\to = RAND(state, o+1); /* prefer beginning */\n\t\twhile(o < end && n--) {\n\t\t\tchar c = pos[o], d;\n\t\t\tif (c & 128)\n\t\t\t\treturn 1;\n\t\t\td = delim_of(c);\n\t\t\tif (d) {\n\t\t\t\t*start = o; *open = c; *close = d;\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\to++;\n\t\t}\n\t}\n\treturn 1;\n}\n\nstatic int drange_start_of(ni_state_t * state, const char *pos, size_t end, char del, size_t *start) {\n\tint rounds = 32;\n\twhile (rounds--) {\n\t\tsize_t o = RAND(state, end);\n\t\tint n = AIMLEN;\n\t\twhile(o < end && n--) {\n\t\t\tchar c = pos[o];\n\t\t\tif (c & 128) {\n\t\t\t\treturn 1;\n\t\t\t} else if (c == del) {\n\t\t\t\t*start = o;\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\to++;\n\t\t\t}\n\t\t}\n\t}\n\treturn 1;\n}\n\n/* return 0 for failure, called after open  */\nstatic size_t drange_end(ni_state_t * state, const char *data, size_t end, size_t pos, char open, char close) {\n\tint depth = 1;\n\twhile(pos < end) {\n\t\tchar c = data[pos++];\n\t\tif (c == close) {\n\t\t\tdepth--;\n\t\t\tif (depth == 0) {\n\t\t\t\tsize_t next;\n\t\t\t\tif (rnd(state) & 3)\n\t\t\t\t\treturn pos;\n\t\t\t\tnext = drange_end(state, data, end, pos, open, close);\n\t\t\t\tif (next)\n\t\t\t\t\treturn next;\n\t\t\t\treturn pos;\n\t\t\t}\n\t\t} else if (c == open) {\n\t\t\tdepth++;\n\t\t} else if (c & 128) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\treturn 0;\n}\n\nstatic int drange(ni_state_t * state, const char *data, size_t end, size_t *rs, size_t *rl) {\n\tsize_t s, e;\n\tchar o, c;\n\tif (drange_start(state, data, end, &s, &o, &c))\n\t\treturn 1;\n\te = drange_end(state, data, end, s+1, o, c);\n\tif (e) {\n\t\t*rs = s;\n\t\t*rl = e - s;\n\t\treturn 0;\n\t}\n\treturn 1;\n}\n\nstatic int other_drange(ni_state_t * state, const char *data, size_t end, size_t fs, size_t *r2s, size_t *r2l) {\n\tchar open = data[fs];\n\tchar close = delim_of(open);\n\tint tries = 10;\n\tsize_t os = fs;\n\twhile(tries--) {\n\t\tif (drange_start_of(state, data, end, open, &os))\n\t\t\treturn 1;\n\t\tif (os != fs) {\n\t\t\tsize_t oe = drange_end(state, data, end, os+1, open, close);\n\t\t\tif (oe) {\n\t\t\t\t*r2s = os;\n\t\t\t\t*r2l = oe - os;\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t}\n\treturn 1;\n}\n\nstatic void seek_num(ni_state_t * state, const char *pos, size_t end, size_t *ns, size_t *ne) {\n\tsize_t o = RAND(state, end);\n\twhile(o < end && (pos[o] < '0' || pos[o] > '9')) {\n\t\tif (pos[o] & 128)\n\t\t\treturn;\n\t\to++;\n\t}\n\tif (o == end)\n\t\treturn;\n\t*ns = o++;\n\twhile(o < end && pos[o] >= '0' && pos[o] <= '9') {\n\t\to++;\n\t}\n\t*ne = o;\n}\n\nstatic int read_num(const char *pos, size_t end, long long *res) {\n\tlong long n = 0;\n\tsize_t p = 0;\n\twhile(p < end) {\n\t\tn = n * 10 + pos[p++] - '0';\n\t\tif (n < 0)\n\t\t\treturn 1;\n\t}\n\t*res = n;\n\treturn 0;\n}\n\nstatic long long twiddle(ni_state_t * state, long long val) {\n\tdo {\n\t\tswitch(RAND(state,3)) {\n\t\t\tcase 0:\n\t\t\t\tval = rnd(state);\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tval ^= (1 << RAND(state,sizeof(long long)*8 - 1));\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tval += RAND(state,5) - 2;\n\t\t\t\tbreak;\n\t\t}\n\t} while (rnd(state) & 1);\n\treturn(val);\n}\n\nstatic void mutate_area(ni_state_t * state, const char *data, size_t end) {\n\tchar buff[BUFSIZE];\n\tint choice;\nretry:\n\tchoice = rnd(state) % 35;\n\tswitch(choice) {\n\t\tcase 0: { /* insert a random byte */\n\t\t\tsize_t pos = (end ? rnd(state) % end : 0);\n\t\t\twrite_all(state, data, pos);\n\t\t\tbuff[0] = rnd(state) & 255;\n\t\t\twrite_all(state, buff, 1);\n\t\t\twrite_all(state, data + pos, end - pos);\n\t\t\tbreak;\n\t\t}\n\t\tcase 1: { /* drop a byte */\n\t\t\tsize_t pos = (end ? rnd(state) % end : 0);\n\t\t\tif (pos+1 >= end)\n\t\t\t\tgoto retry;\n\t\t\twrite_all(state, data, pos);\n\t\t\twrite_all(state, data+pos+1, end-(pos+1));\n\t\t\tbreak;\n\t\t}\n\t\tcase 2:\n\t\tcase 3: { /* jump in a sequence */\n\t\t\tsize_t s, e;\n\t\t\tif (!end)\n\t\t\t\tgoto retry;\n\t\t\ts = rnd(state) % end;\n\t\t\te = rnd(state) % end;\n\t\t\tif (s == e)\n\t\t\t\tgoto retry;\n\t\t\twrite_all(state, data, e);\n\t\t\twrite_all(state, data+s, end-s);\n\t\t\tbreak;\n\t\t}\n\t\tcase 4:\n\t\tcase 5: { /* repeat */\n\t\t\tsize_t a, b, s, e, l;\n\t\t\tint n = 8;\n\t\t\twhile (rnd(state) & 1 && n < 20000)\n\t\t\t\tn <<= 1;\n\t\t\tn = rnd(state) % n + 2;\n\t\t\tif (!end)\n\t\t\t\tgoto retry;\n\t\t\ta = (end ? rnd(state) % end : 0);\n\t\t\tb = (end ? rnd(state) % end : 0);\n\t\t\tif (a == b) {\n\t\t\t\tgoto retry;\n\t\t\t} else if (a > b) {\n\t\t\t\ts = b; e = a;\n\t\t\t} else {\n\t\t\t\ts = a; e = b;\n\t\t\t}\n\t\t\tl = e - s;\n\n\t\t\twrite_all(state, data, s);\n\t\t\tif (l * n > 134217728)\n\t\t\t\tl = rnd(state) % 1024 + 2;\n\t\t\twhile(n--)\n\t\t\t\twrite_all(state, data+s, l);\n\t\t\twrite_all(state, data+s, end-s);\n\t\t\tbreak;\n\t\t}\n\t\tcase 6: { /* insert random data */\n\t\t\tsize_t pos = (end ? rnd(state) % end : 0);\n\t\t\tint n = rnd(state) % 1022 + 2;\n\t\t\tint p = 0;\n\t\t\twhile (p < n)\n\t\t\t\tbuff[p++] = rnd(state) & 255;\n\t\t\twrite_all(state, data, pos);\n\t\t\twrite_all(state, buff, p);\n\t\t\twrite_all(state, data+pos, end-pos);\n\t\t\tbreak;\n\t\t}\n\t\tcase 7:\n\t\tcase 8:\n\t\tcase 9:\n\t\tcase 10:\n\t\tcase 11:\n\t\tcase 12: { /* aimed jump to self */\n\t\t\tsize_t j=0, l=0;\n\t\t\tif (end < 5)\n\t\t\t\tgoto retry;\n\t\t\twhile (j == l)\n\t\t\t\taim(state, data, end, data, end, &j, &l);\n\t\t\twrite_all(state, data, j);\n\t\t\twrite_all(state, data+l, end-l);\n\t\t\tbreak;\n\t\t}\n\t\tcase 13:\n\t\tcase 14:\n\t\tcase 15:\n\t\tcase 16:\n\t\tcase 17:\n\t\tcase 18:\n\t\tcase 19:\n\t\tcase 20:\n\t\tcase 21: { /* aimed random block fusion */\n\t\t\tsize_t j, l, dm, sm;\n\t\t\tchar *buff, *block;\n\t\t\tsize_t bend, block_len;\n\t\t\tif (end < 8) goto retry;\n\t\t\tblock = random_block(state, end, &block_len);\n\t\t\tif (block_len < 8)\n\t\t\t\tgoto retry;\n\t\t\tdm = end >> 1;\n\t\t\tsm = block_len >> 1;\n\t\t\taim(state, data, dm, block, sm, &j, &l);\n\t\t\twrite_all(state, data, j);\n\t\t\tdata += j;\n\t\t\tend -= j;\n\t\t\tbuff = block + l;\n\t\t\tbend = block_len - l;\n\t\t\taim(state, buff, bend , data, end, &j, &l);\n\t\t\twrite_all(state, buff, j);\n\t\t\twrite_all(state, data + l, end - l);\n\t\t\tfree(block);\n\t\t\tbreak;\n\t\t}\n\t\tcase 22:\n\t\tcase 23: { /* insert semirandom bytes */\n\t\t\tsize_t p = 0, n = RAND(state,BUFSIZE);\n\t\t\tsize_t pos = (end ? rnd(state) % end : 0);\n\t\t\tn = RAND(state,n+1);\n\t\t\tn = RAND(state,n+1);\n\t\t\tn = RAND(state,n+1);\n\t\t\tn = RAND(state,n+1);\n\t\t\tn = (n > 1) ? n : 2;\n\t\t\tif (!end)\n\t\t\t\tgoto retry;\n\t\t\twrite_all(state, data, pos);\n\t\t\twhile(n--)\n\t\t\t\tbuff[p++] = data[RAND(state,end)];\n\t\t\twrite_all(state, buff, p);\n\t\t\twrite_all(state, data + pos, end - pos);\n\t\t\tbreak;\n\t\t}\n\t\tcase 24: { /* overwrite semirandom bytes */\n\t\t\tsize_t a, b, p = 0;\n\t\t\tif (end < 2)\n\t\t\t\tgoto retry;\n\t\t\ta = RAND(state,end-2);\n\t\t\tb = a + 2 + ((rnd(state) & 1) ? RAND(state,MIN(BUFSIZE-2, end-a-2)) : RAND(state,32));\n\t\t\twrite_all(state, data, a);\n\t\t\twhile(a + p < b)\n\t\t\t\tbuff[p++] = data[RAND(state,end)];\n\t\t\twrite_all(state, buff, p);\n\t\t\tif (end > b)\n\t\t\t\twrite_all(state, data + b, end - b);\n\t\t\tbreak;\n\t\t}\n\t\tcase 25:\n\t\tcase 26:\n\t\tcase 27:\n\t\tcase 28: { /* textual number mutation */\n\t\t\tint n = RAND(state,AIMROUNDS);\n\t\t\tlong long val;\n\t\t\tsize_t ns, ne;\n\t\t\tns = ne = 0;\n\t\t\tif (!end)\n\t\t\t\tgoto retry;\n\t\t\twhile(n-- && !ne) {\n\t\t\t\tseek_num(state, data, end, &ns, &ne);\n\t\t\t}\n\t\t\tif (!ne)\n\t\t\t\tgoto retry;\n\t\t\twrite_all(state, data, ns);\n\t\t\tif (read_num(data + ns, ne - ns, &val) == 0)\n\t\t\t\toutput_num(state, buff, BUFSIZE, twiddle(state,val));\n\t\t\telse\n\t\t\t\toutput_num(state, buff, BUFSIZE, twiddle(state,0));\n\t\t\twrite_all(state, data + ne, end - ne);\n\t\t\tbreak;\n\t\t}\n\t\tcase 29:\n\t\tcase 30:\n\t\tcase 31:\n\t\tcase 32:\n\t\tcase 33:\n\t\tcase 34: { /* delimited swap */\n\t\t\tsize_t r1s, r1l, r2s, r2l;\n\t\t\tif (!end || drange(state, data, end, &r1s, &r1l) || other_drange(state, data, end, r1s, &r2s, &r2l))\n\t\t\t\tgoto retry;\n\t\t\twrite_all(state, data, r1s);\n\t\t\twrite_all(state, data + r2s, r2l);\n\t\t\tif (r2s > (r1s + r1l)) /* these can overlap */\n\t\t\t\twrite_all(state, data + r1s + r1l, r2s - (r1s + r1l));\n\t\t\twrite_all(state, data + r1s, r1l);\n\t\t\twrite_all(state, data + r2s + r2l, end - (r2s + r2l));\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tprintf(\"ni: bad mutation (choice=%d)\\n\", choice);\n\t\t\texit(1);\n\t\t}\n\t}\n}\n\nstatic void ni_area(ni_state_t * state, const char *data, size_t end, int n) {\n\tif (n == 0) {\n\t\twrite_all(state, data, end);\n\t\treturn;\n\t} else if (n == 1 || end < 256) {\n\t\tmutate_area(state, data, end);\n\t} else if (!end) {\n\t\treturn;\n\t} else {\n\t\tsize_t r = RAND(state,end);\n\t\tint m = RAND(state,n / 2);\n\t\tni_area(state, data, r, (n - m));\n\t\tni_area(state, data + r, end - r, m);\n\t}\n}\n\n/**\n * This function generates a new mutation from the input buffer and samples\n * @param state - a mutator specific structure previously created by the create function.\n */\nstatic void ni(ni_state_t* state) {\n\tchar *data;\n\tchar *datap;\n\tsize_t j, l, end, endp;\n\tint m, n = 0;\n\n\tdata = get_sample(state, -1, &end);\n\n\tm = ((rnd(state) & 3) == 1) ? 1 : 2 + RAND(state,((unsigned int) state->input_length >> 12) + 8);\n\tif (RAND(state,30)) {\n\t\tni_area(state, data, end, m);\n\t} else { /* small chance of global tail flip */\n\t\tm--;\n\t\tif (m) {\n\t\t\tn = RAND(state,m);\n\t\t\tm =- n;\n\t\t}\n\t\tdatap = get_random_sample(state, &endp);\n\t\taim(state, data, end, datap, endp, &j, &l);\n\t\tni_area(state, data, j, m);\n\t\tni_area(state, datap + l, endp - l, n);\n\t\tfree(datap);\n\t}\n\tfree(data);\n}\n\n////////////////////////////////////////////////////////////////////////////////////////////\n//// API methods ///////////////////////////////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////////////////////////\n\n#ifndef ALL_MUTATORS_IN_ONE\n\n/**\n * This function fills in the supplied mutator_t with all of the function\n * pointers for this mutator.\n * @param m - a pointer to a mutator_t structure\n */\nNI_MUTATOR_API void init(mutator_t * m)\n{\n\tmemcpy(m, &ni_mutator, sizeof(mutator_t));\n}\n\n#endif\n\n/**\n * This function creates and initializes a ni_state_t object based on the passed in JSON options.\n * @return the newly created ni_state_t object or NULL on failure\n */\nstatic ni_state_t * setup_options(char * options)\n{\n\tni_state_t * state;\n\tsize_t i;\n\tstate = (ni_state_t *)malloc(sizeof(ni_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(ni_state_t));\n\n\t//Setup defaults\n\tstate->random_state[0] = (((uint64_t)rand()) << 32) | rand();\n\tstate->random_state[1] = (((uint64_t)rand()) << 32) | rand();\n\tstate->mutate_mutex = create_mutex();\n\tif (!state->mutate_mutex) {\n\t\tfree(state);\n\t\treturn NULL;\n\t}\n\n\tif (!options || !strlen(options))\n\t\treturn state;\n\n\tPARSE_OPTION_UINT64T_TEMP(state, options, random_state[0], \"random_state0\", FUNCNAME(cleanup), temp1);\n\tPARSE_OPTION_UINT64T_TEMP(state, options, random_state[1], \"random_state1\", FUNCNAME(cleanup), temp2);\n\tPARSE_OPTION_ARRAY(state, options, sample_filenames, num_samples, \"samples\", FUNCNAME(cleanup));\n\n\tif(state->num_samples) {\n\t\tstate->samples = calloc(state->num_samples, sizeof(void *));\n\t\tif(!state->samples) {\n\t\t\tFUNCNAME(cleanup)(state);\n\t\t\treturn NULL;\n\t\t}\n\t\tfor(i = 0; i < state->num_samples; i++) {\n\n\t\t\tstate->samples[i] = malloc(sizeof(sample_t));\n\t\t\tif(!state->samples[i]) {\n\t\t\t\tFUNCNAME(cleanup)(state);\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\tstate->samples[i]->length = read_file(state->sample_filenames[i], &state->samples[i]->content);\n\t\t\tif(state->samples[i]->length < 0) {\n\t\t\t\tprintf(\"Could not read file %s\\n\", state->sample_filenames[i]);\n\t\t\t\tFUNCNAME(cleanup)(state);\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn state;\n}\n\n/**\n * This function will allocate and initialize the mutator state. The mutator state should be\n * freed by calling the cleanup function.\n * @param options - a json string that contains the ni specific options.\n * @param state - optionally, a previously dumped state (with the get_state() function) to load\n * @param input - The input that this mutator will later be mutating\n * @param input_length - the size of the input parameter\n * @return a mutator specific structure or NULL on failure. The returned value should\n * not be used for anything other than passing to the various Mutator API functions.\n */\nNI_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length)\n{\n\tni_state_t * ni_state = setup_options(options);\n\tif (!ni_state)\n\t\treturn NULL;\n\n\tni_state->input = (char *)malloc(input_length);\n\tif (!ni_state->input || !input_length)\n\t{\n\t\tFUNCNAME(cleanup)(ni_state);\n\t\treturn NULL;\n\t}\n\tmemcpy(ni_state->input, input, input_length);\n\tni_state->input_length = input_length;\n\tif (state && FUNCNAME(set_state)(ni_state, state)) {\n\t\tFUNCNAME(cleanup)(ni_state);\n\t\treturn NULL;\n\t}\n\treturn ni_state;\n}\n\n/**\n * This function will release any resources that the mutator has open\n * and free the mutator state structure.\n * @param mutator_state - a mutator specific structure previously created by\n * the create function. This structure will be freed and should not be referenced afterwards.\n */\nNI_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state)\n{\n\tsize_t i;\n\tni_state_t * ni_state = (ni_state_t *)mutator_state;\n\n\tdestroy_mutex(ni_state->mutate_mutex);\n\tfor(i = 0; i < ni_state->num_samples; i++) {\n\t\tif(ni_state->samples) {\n\t\t\tif(ni_state->samples[i])\n\t\t\t\tfree(ni_state->samples[i]->content);\n\t\t\tfree(ni_state->samples[i]);\n\t\t}\n\t\tfree(ni_state->sample_filenames[i]);\n\t}\n\tfree(ni_state->sample_filenames);\n\tfree(ni_state->samples);\n\tfree(ni_state->input);\n\tfree(ni_state);\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nNI_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length)\n{\n\tni_state_t * ni_state = (ni_state_t *)mutator_state;\n\t//Can't mutate an empty buffer\n\tif (buffer_length == 0)\n\t\treturn -1;\n\n#ifdef NI_COMPARISON_TESTING\n\t//If we're trying to compare against the actual ni binary, we should set the random number generator\n\t//to a known state that ni can match.\n\tsrandom(atoi(getenv(\"RANDSEED\")));\n#endif\n\n\t//Setup the mutated buffer\n\tni_state->mutated_buffer = (uint8_t *)buffer;\n\tni_state->mutated_buffer_length = 0;\n\tni_state->max_mutated_buffer_length = buffer_length;\n\n\t//Now mutate the buffer\n\tni_state->iteration++;\n\tni(ni_state);\n\treturn (int)ni_state->mutated_buffer_length;\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * This function also accepts a set of flags which instruct it how to mutate the input. See global_types.h\n * for the list of available flags.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.\n * @param flags - A set of mutate flags that modify how this mutator mutates the input.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nNI_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags)\n{\n  SINGLE_INPUT_MUTATE_EXTENDED(ni_state_t, state->mutate_mutex);\n}\n\n/**\n * This function will return the state of the mutator. The returned value can be used to restart the\n * mutator at a later time, by passing it to the create or set_state function. It is the caller's\n * responsibility to free the memory allocated here by calling the free_state function.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return - a buffer that defines the current state of the mutator. This will be a mutator specific JSON string.\n */\nNI_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state)\n{\n\tni_state_t * ni_state = (ni_state_t *)mutator_state;\n\tjson_t *obj, *temp;\n\tchar * ret;\n\n\tobj = json_object();\n\tADD_INT(temp, ni_state->iteration, obj, \"iteration\");\n\tADD_UINT64T(temp, ni_state->random_state[0], obj, \"random_state0\");\n\tADD_UINT64T(temp, ni_state->random_state[1], obj, \"random_state1\");\n\tret = json_dumps(obj, 0);\n\tjson_decref(obj);\n\treturn ret;\n}\n\n/**\n * This function will set the current state of the mutator.\n * This can be used to restart a mutator once from a previous run.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param state - a previously dumped state buffer obtained by the get_state function.\n * @return 0 on success or non-zero on failure\n */\nNI_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state)\n{\n\tni_state_t * ni_state = (ni_state_t *)mutator_state;\n\tint result, temp_int;\n\tuint64_t temp_uint64t;\n\n\tif (!state)\n\t\treturn 1;\n\n\tGET_INT(temp_int, state, ni_state->iteration, \"iteration\", result);\n\tGET_UINT64T(temp_uint64t, state, ni_state->random_state[0], \"random_state0\", result);\n\tGET_UINT64T(temp_uint64t, state, ni_state->random_state[1], \"random_state1\", result);\n\treturn 0;\n}\n\n/**\n * This function will return the current iteration count of the mutator, i.e.\n * how many mutations have been generated with it.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return value - the number of previously generated mutations\n */\nNI_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state)\n{\n\tGENERIC_MUTATOR_GET_ITERATION(ni_state_t);\n}\n\n/**\n * Obtains information about the inputs that were given to the mutator when it was created\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param num_inputs - a pointer to an integer used to return the number of inputs given to this mutator\n * when it was created. This parameter is optional and can be NULL, if this information is not needed\n * @param input_sizes - a pointer to a size_t array used to return the sizes of the inputs given to this\n * mutator when it was created. This parameter is optional and can be NULL, if this information is not needed.\n */\nNI_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes)\n{\n\tSINGLE_INPUT_GET_INFO(ni_state_t);\n}\n\n/**\n * This function will set the input(saved in the mutators state) to something new.\n * This can be used to reinitialize a mutator with new data, without reallocating the entire state struct.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param new_input - The new input used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size in bytes of the input buffer.\n * @return 0 on success and -1 on failure\n */\nNI_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length)\n{\n\tGENERIC_MUTATOR_SET_INPUT(ni_state_t);\n}\n\n/**\n * This function sets a help message for the mutator.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nNI_MUTATOR_API int FUNCNAME(help)(char ** help_str)\n{\n\tGENERIC_MUTATOR_HELP(\n\"ni - ni-based mutator\\n\"\n\"Options:\\n\"\n\"  random_state0         The first half of the seed to honggfuzz's random\\n\"\n\"                          number generator\\n\"\n\"  random_state1         The second half of the seed to honggfuzz's random\\n\"\n\"                          number generator\\n\"\n\"  samples               An array of files containing other samples to mutate\\n\"\n\"                          with the given input\\n\"\n\"\\n\"\n\t);\n}\n"
  },
  {
    "path": "mutators/ni_mutator/ni_mutator.h",
    "content": "#pragma once\n\n#include <global_types.h>\n#include <mutators.h>\n\n#ifdef _WIN32\n#ifdef NI_MUTATOR_EXPORTS\n#define NI_MUTATOR_API __declspec(dllexport)\n#else\n#define NI_MUTATOR_API __declspec(dllimport)\n#endif\n#else //_WIN32\n#define NI_MUTATOR_API\n#endif\n\n#define MUTATOR_NAME \"ni\"\n\nNI_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length);\nNI_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state);\nNI_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length);\nNI_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags);\nNI_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state);\n#define ni_free_state default_free_state\nNI_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state);\nNI_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state);\n#define ni_get_total_iteration_count return_unknown_or_infinite_total_iterations\nNI_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes);\nNI_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length);\nNI_MUTATOR_API int FUNCNAME(help)(char ** help_str);\n\n#ifndef ALL_MUTATORS_IN_ONE\nNI_MUTATOR_API void init(mutator_t * m);\n#endif\n"
  },
  {
    "path": "mutators/nop_mutator/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (nop_mutator)\n\ninclude_directories (${PROJECT_SOURCE_DIR}/../mutators/)\n\nset(NOP_SRC ${PROJECT_SOURCE_DIR}/nop_mutator.c)\nsource_group(\"Library Sources\" FILES ${NOP_SRC})\n\nadd_library(nop_mutator SHARED ${NOP_SRC}\n  $<TARGET_OBJECTS:mutators_object> $<TARGET_OBJECTS:jansson_object>)\ntarget_link_libraries(nop_mutator utils)\ntarget_compile_definitions(nop_mutator PUBLIC NOP_MUTATOR_EXPORTS)\ntarget_compile_definitions(nop_mutator PUBLIC MUTATORS_NO_IMPORT)\ntarget_compile_definitions(nop_mutator PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(nop_mutator PUBLIC JANSSON_NO_IMPORT)\n\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(nop_mutator Shlwapi)\nendif (WIN32)\n"
  },
  {
    "path": "mutators/nop_mutator/nop_mutator.c",
    "content": "#include \"nop_mutator.h\"\n#include <mutators.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#ifdef _WIN32\n#include <Windows.h>\n#endif\n\nstruct nop_state\n{\n\tchar * input;\n\tsize_t input_length;\n\tint iteration;\n};\ntypedef struct nop_state nop_state_t;\n\nmutator_t nop_mutator = {\n\tFUNCNAME(create),\n\tFUNCNAME(cleanup),\n\tFUNCNAME(mutate),\n\tFUNCNAME(mutate_extended),\n\tFUNCNAME(get_state),\n\tFUNCNAME(free_state),\n\tFUNCNAME(set_state),\n\tFUNCNAME(get_current_iteration),\n\tnop_get_total_iteration_count,\n\tFUNCNAME(get_input_info),\n\tFUNCNAME(set_input),\n\tFUNCNAME(help)\n};\n\n#ifndef ALL_MUTATORS_IN_ONE\nNOP_MUTATOR_API void init(mutator_t * m)\n{\n\tmemcpy(m, &nop_mutator, sizeof(mutator_t));\n}\n#endif\n\nNOP_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length)\n{\n\tnop_state_t * nop_state;\n\tnop_state = (nop_state_t *)malloc(sizeof(nop_state_t));\n\tif (!nop_state)\n\t\treturn NULL;\n\tmemset(nop_state, 0, sizeof(nop_state_t));\n\n\tnop_state->input = (char *)malloc(input_length);\n\tif (!nop_state->input || !input_length)\n\t{\n\t\tFUNCNAME(cleanup)(nop_state);\n\t\treturn NULL;\n\t}\n\tmemcpy(nop_state->input, input, input_length);\n\tnop_state->input_length = input_length;\n\treturn nop_state;\n}\n\nNOP_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state)\n{\n\tnop_state_t * nop_state = (nop_state_t *)mutator_state;\n\tfree(nop_state->input);\n\tfree(nop_state);\n}\n\nNOP_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length)\n{\n\tnop_state_t * nop_state = (nop_state_t *)mutator_state;\n#ifdef _WIN32\n\tInterlockedIncrement(&nop_state->iteration);\n#else\n\t__sync_fetch_and_add(&nop_state->iteration, 1);\n#endif\n\tmemcpy(buffer, nop_state->input, nop_state->input_length > buffer_length ? buffer_length : nop_state->input_length);\n\treturn nop_state->input_length;\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * This function also accepts a set of flags which instruct it how to mutate the input.  See global_types.h\n * for the list of available flags.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @param flags - A set of mutate flags that modify how this mutator mutates the input.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nNOP_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags)\n{\n\tif ((flags & MUTATE_MULTIPLE_INPUTS) && (flags & MUTATE_MULTIPLE_INPUTS_MASK) != 0)\n\t\treturn -1;\n\treturn FUNCNAME(mutate)(mutator_state, buffer, buffer_length);\n}\n\nNOP_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state)\n{\n\treturn \"{}\";\n}\n\nNOP_MUTATOR_API void FUNCNAME(free_state)(char * mutator_state)\n{\n}\n\nNOP_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state)\n{\n\treturn 0;\n}\n\nNOP_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state)\n{\n\tGENERIC_MUTATOR_GET_ITERATION(nop_state_t);\n}\n\n/**\n * Obtains information about the inputs that were given to the mutator when it was created\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param num_inputs - a pointer to an integer used to return the number of inputs given to this mutator\n * when it was created.  This parameter is optional and can be NULL, if this information is not needed\n * @param input_sizes - a pointer to a size_t array used to return the sizes of the inputs given to this\n * mutator when it was created. This parameter is optional and can be NULL, if this information is not needed.\n */\nNOP_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes)\n{\n\tSINGLE_INPUT_GET_INFO(nop_state_t);\n}\n\n/**\n* This function will set the input(saved in the mutators state) to something new.\n* This can be used to reinitialize a mutator with new data, without reallocating the entire state struct.\n* @param mutator_state - a mutator specific structure previously created by the create function.\n* @param new_input - The new input used to produce new mutated inputs later when the mutate function is called\n* @param input_length - the size in bytes of the input buffer.\n* @return 0 on success and -1 on failure\n*/\nNOP_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length)\n{\n\tGENERIC_MUTATOR_SET_INPUT(nop_state_t);\n}\n\n/**\n* This function sets a help message for the mutator. This is useful\n* if the mutator takes a JSON options string in the create() function.\n* @param help_str - A pointer that will be updated to point to the new help string.\n* @return 0 on success and -1 on failure\n*/\nNOP_MUTATOR_API int FUNCNAME(help)(char** help_str)\n{\n\tGENERIC_MUTATOR_HELP(\n\t\t\"nop - NOP mutator (doesn't mutate the input)\\n\"\n\t\t\"Options:\\n\"\n\t\t\"  None\\n\"\n\t\t\"\\n\"\n\t);\n}\n"
  },
  {
    "path": "mutators/nop_mutator/nop_mutator.h",
    "content": "#pragma once\n\n#include <global_types.h>\n#include <mutators.h>\n\n#ifdef _WIN32\n#ifdef NOP_MUTATOR_EXPORTS\n#define NOP_MUTATOR_API __declspec(dllexport)\n#else\n#define NOP_MUTATOR_API __declspec(dllimport)\n#endif\n#else //_WIN32\n#define NOP_MUTATOR_API\n#endif\n\n#define MUTATOR_NAME \"nop\"\n\nNOP_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length);\nNOP_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state);\nNOP_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length);\nNOP_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags);\nNOP_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state);\nNOP_MUTATOR_API void FUNCNAME(free_state)(char * mutator_state);\nNOP_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state);\nNOP_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state);\n#define nop_get_total_iteration_count return_unknown_or_infinite_total_iterations\nNOP_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes);\nNOP_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length);\nNOP_MUTATOR_API int FUNCNAME(help)(char ** help_str);\n\n#ifndef ALL_MUTATORS_IN_ONE\nNOP_MUTATOR_API void init(mutator_t * m);\n#endif\n"
  },
  {
    "path": "mutators/radamsa_mutator/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (radamsa_mutator)\n\ninclude_directories (${PROJECT_SOURCE_DIR}/../mutators/)\n\nset(RADAMSA_SRC ${PROJECT_SOURCE_DIR}/radamsa_mutator.c)\nsource_group(\"Library Sources\" FILES ${RADAMSA_SRC})\n\nadd_library(radamsa_mutator SHARED ${RADAMSA_SRC}\n  $<TARGET_OBJECTS:mutators_object> $<TARGET_OBJECTS:jansson_object>)\ntarget_link_libraries(radamsa_mutator utils)\ntarget_compile_definitions(radamsa_mutator PUBLIC RADAMSA_MUTATOR_EXPORTS)\ntarget_compile_definitions(radamsa_mutator PUBLIC MUTATORS_NO_IMPORT)\ntarget_compile_definitions(radamsa_mutator PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(radamsa_mutator PUBLIC JANSSON_NO_IMPORT)\n\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(radamsa_mutator Shlwapi)\n  target_link_libraries(radamsa_mutator ws2_32)\nendif (WIN32)\n"
  },
  {
    "path": "mutators/radamsa_mutator/radamsa_mutator.c",
    "content": "#include \"radamsa_mutator.h\"\n\n#include <jansson.h>\n#include <jansson_helper.h>\n#include <utils.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n\n#ifdef _WIN32\n#include <process.h>\n#include <strsafe.h>\n#include <tchar.h>\n#include <windows.h>\n#else\n#include <arpa/inet.h>\n#include <netinet/in.h>\n#include <signal.h>\n#include <sys/socket.h>\n#include <sys/types.h>\n#include <sys/wait.h>\n#include <unistd.h>\n#endif\n\ntypedef struct radamsa_state\n{\n\tchar * input;\n\n\tsize_t input_length;\n\n\t//The iteration number\n\tint iteration;\n\n\t//Whether we have been able to connect to radamsa yet or not\n\tint radamsa_up;\n\n\t//The seed for radamsa\n\tint seed;\n\n\t//The path to the radamsa binary\n\tchar * path;\n\n\t//The port to bind radamsa to\n\tint port;\n\n\t//The number of times we've connected to radamsa's port.  This is different from iteration\n\t//since sometimes radamsa doesn't return input, and we have to call radamsa again.  Thus,\n\t//we need to keep track of radamsa's iteration count, so that we can later fast forward\n\t//if asked to load a previous mutator state.\n\tint radamsa_iteration;\n\n\t//The handle/pid of the radamsa instance\n#ifdef _WIN32\n\tHANDLE process;\n#else\n\tint process;\n#endif\n\n\t//A mutex used when doing thread safe mutations\n\tmutex_t mutate_mutex;\n} radamsa_state_t;\n\nstatic void cleanup_process(radamsa_state_t * state);\nstatic int start_process(radamsa_state_t * state);\n\nmutator_t radamsa_mutator = {\n\tFUNCNAME(create),\n\tFUNCNAME(cleanup),\n\tFUNCNAME(mutate),\n\tFUNCNAME(mutate_extended),\n\tFUNCNAME(get_state),\n\tradamsa_free_state,\n\tFUNCNAME(set_state),\n\tFUNCNAME(get_current_iteration),\n\tradamsa_get_total_iteration_count,\n\tFUNCNAME(get_input_info),\n\tFUNCNAME(set_input),\n\tFUNCNAME(help)\n};\n\n#ifndef ALL_MUTATORS_IN_ONE\nRADAMSA_MUTATOR_API void init(mutator_t * m)\n{\n\tmemcpy(m, &radamsa_mutator, sizeof(mutator_t));\n}\n#endif\n\n#ifdef _WIN32\n#define PATH_SEP \"\\\\\"\n#define RADAMSA_BIN_NAME \"radamsa.exe\"\n#define DEVELOP_PREFIX \"..\\\\..\\\\..\\\\..\\\\\" //CMake puts things at root/build/(Win32/x64)/(Debug/Release)/killerbeez/\n#else\n#define PATH_SEP \"/\"\n#define RADAMSA_BIN_NAME \"radamsa\"\n#define DEVELOP_PREFIX \"../../\" //CMake puts things at root/build/killerbeez/\n#endif\n\nRADAMSA_MUTATOR_API radamsa_state_t * setup_options(char * options)\n{\n\tradamsa_state_t * state;\n\tstate = (radamsa_state_t *)malloc(sizeof(radamsa_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(radamsa_state_t));\n\n\tsrand(time(NULL));\n\t//Setup defaults\n\tstate->port = 10000 + (rand() % 50000);\n\tstate->seed = rand();\n\tstate->mutate_mutex = create_mutex();\n\tif (!state->mutate_mutex) {\n\t\tfree(state);\n\t\treturn NULL;\n\t}\n\n\tif (options && strlen(options)) {\n\t\tPARSE_OPTION_STRING(state, options, path, \"path\", FUNCNAME(cleanup));\n\t\tPARSE_OPTION_INT(state, options, seed, \"seed\", FUNCNAME(cleanup));\n\t\tPARSE_OPTION_INT(state, options, port, \"port\", FUNCNAME(cleanup));\n\t\tPARSE_OPTION_INT(state, options, radamsa_iteration, \"radamsa_iteration\", FUNCNAME(cleanup));\n\t}\n\n\tif (!state->path) {\n\t\t// Usual location for binary distribution\n\t\tchar *default_path = filename_relative_to_binary_dir(\"..\" PATH_SEP \"radamsa\" PATH_SEP \"bin\" PATH_SEP RADAMSA_BIN_NAME);\n\t\tif (!default_path)\n\t\t{  // Usual location for 32-bit developer environment\n\t\t\tdefault_path = filename_relative_to_binary_dir(DEVELOP_PREFIX \"radamsa\" PATH_SEP \"bin\" PATH_SEP RADAMSA_BIN_NAME);\n\t\t}\n\t\tif (!default_path)\n\t\t{\n\t\t\tFUNCNAME(cleanup)(state);\n\t\t\treturn NULL;\n\t\t}\n\t\tstate->path = default_path;\n\t}\n\n\treturn state;\n}\n\nRADAMSA_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length)\n{\n\tradamsa_state_t * new_state;\n\n#ifdef _WIN32\n\tWSADATA wsaData;\n\tif (WSAStartup(MAKEWORD(2, 2), &wsaData))\n\t\treturn NULL;\n#endif\n\n\tnew_state = setup_options(options);\n\tif (!new_state)\n\t\treturn NULL;\n\n\tnew_state->input = (char *)malloc(input_length);\n\tif (!new_state->input || !input_length)\n\t{\n\t\tFUNCNAME(cleanup)(new_state);\n\t\treturn NULL;\n\t}\n\tmemcpy(new_state->input, input, input_length);\n\tnew_state->input_length = input_length;\n\n\tif (FUNCNAME(set_state)(new_state, state))\n\t{\n\t\tFUNCNAME(cleanup)(new_state);\n\t\treturn NULL;\n\t}\n\treturn new_state;\n}\n\nRADAMSA_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state)\n{\n\tradamsa_state_t * state = (radamsa_state_t *)mutator_state;\n\tcleanup_process(state);\n\tdestroy_mutex(state->mutate_mutex);\n\tfree(state->input);\n\tfree(state->path);\n\tfree(state);\n}\n\nstatic int mutate_inner(radamsa_state_t * state, char * buffer, size_t buffer_length)\n{\n\tstruct sockaddr_in addr;\n\tint attempts, result, total_read = 0;\n#ifdef _WIN32\n\tSOCKET sock;\n#else\n\tint sock;\n#endif\n\n\t//Create a socket for us to connect to the radamsa daemon\n\tsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\n#ifdef _WIN32\n\tif (sock == INVALID_SOCKET)\n#else\n\tif (sock < 0)\n#endif\n\t\treturn -1;\n\n\t//connect to the radamsa daemon.  Sometimes it takes a bit to startup and bind to the port, so if we just\n\t//started radamsa, we'll try multiple times with a little sleep in between if it fails.\n\tfor(attempts = 0; attempts == 0 || (attempts < 5 && !state->radamsa_up); attempts++) {\n\t\taddr.sin_family = AF_INET;\n\t\taddr.sin_addr.s_addr = inet_addr(\"127.0.0.1\");\n\t\taddr.sin_port = htons(state->port);\n#ifdef _WIN32\n\t\tresult = connect(sock, (SOCKADDR *)&addr, sizeof(addr));\n\t\tif (result != SOCKET_ERROR)\n\t\t\tbreak;\n\t\tSleep(250);\n#else\n\t\tresult = connect(sock, (struct sockaddr *)&addr, sizeof(addr));\n\t\tif (result >= 0)\n\t\t\tbreak;\n\t\tsleep(1);\n#endif\n\t}\n\tif(attempts >= 5)\n\t\treturn -1;\n\tstate->radamsa_up = 1;\n\tstate->radamsa_iteration++;\n\n\t//Read radamsa's response\n\tresult = 1;\n\twhile (total_read < (int)buffer_length && result > 0)\n\t{\n\t\tresult = recv(sock, buffer + total_read, buffer_length - total_read, 0);\n\t\tif (result > 0)\n\t\t\ttotal_read += result;\n\t\telse if (result < 0) //Error, then break\n\t\t\ttotal_read = -1;\n\t}\n\n#ifdef _WIN32\n\tclosesocket(sock);\n#else\n\tclose(sock);\n#endif\n\n\tif (total_read == 0) //In some non-error cases, radamsa just returns 0 bytes\n\t{ //Since we don't want to do this, just call the mutator again\n\t\ttotal_read = mutate_inner(state, buffer, buffer_length);\n\t}\n\n\treturn total_read;\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nRADAMSA_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length)\n{\n\tradamsa_state_t * state = (radamsa_state_t *)mutator_state;\n\tstate->iteration++;\n\treturn mutate_inner(state, buffer, buffer_length);\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * This function also accepts a set of flags which instruct it how to mutate the input.  See global_types.h\n * for the list of available flags.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @param flags - A set of mutate flags that modify how this mutator mutates the input.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nRADAMSA_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags)\n{\n\tSINGLE_INPUT_MUTATE_EXTENDED(radamsa_state_t, state->mutate_mutex);\n}\n\nRADAMSA_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state)\n{\n\tradamsa_state_t * state = (radamsa_state_t *)mutator_state;\n\tjson_t *state_obj, *temp;\n\tchar * ret;\n\n\tstate_obj = json_object();\n\tif (!state_obj)\n\t\treturn NULL;\n\tADD_INT(temp, state->iteration, state_obj, \"iteration\");\n\tADD_INT(temp, state->radamsa_iteration, state_obj, \"radamsa_iteration\");\n\tADD_INT(temp, state->seed, state_obj, \"seed\");\n\tret = json_dumps(state_obj, 0);\n\tjson_decref(state_obj);\n\treturn ret;\n}\n\nRADAMSA_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state)\n{\n\tradamsa_state_t * current_state = (radamsa_state_t *)mutator_state;\n\tint result, temp;\n\n\tif (state) {\n\t\tGET_INT(temp, state, current_state->iteration, \"iteration\", result);\n\t\tGET_INT(temp, state, current_state->radamsa_iteration, \"radamsa_iteration\", result);\n\t\tGET_INT(temp, state, current_state->seed, \"seed\", result);\n\t}\n\tcleanup_process(current_state);\n\treturn start_process(current_state);\n}\n\nRADAMSA_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state)\n{\n\tGENERIC_MUTATOR_GET_ITERATION(radamsa_state_t);\n}\n\n/**\n * Obtains information about the inputs that were given to the mutator when it was created\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param num_inputs - a pointer to an integer used to return the number of inputs given to this mutator\n * when it was created.  This parameter is optional and can be NULL, if this information is not needed\n * @param input_sizes - a pointer to a size_t array used to return the sizes of the inputs given to this\n * mutator when it was created. This parameter is optional and can be NULL, if this information is not needed.\n */\nRADAMSA_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes)\n{\n\tSINGLE_INPUT_GET_INFO(radamsa_state_t);\n}\n\n/**\n* This function will set the input(saved in the mutators state) to something new.\n* This can be used to reinitialize a mutator with new data, without reallocating the entire state struct.\n* @param mutator_state - a mutator specific structure previously created by the create function.\n* @param new_input - The new input used to produce new mutated inputs later when the mutate function is called\n* @param input_length - the size in bytes of the input buffer.\n* @return 0 on success and -1 on failure\n*/\nRADAMSA_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length)\n{\n\tradamsa_state_t * state = (radamsa_state_t *)mutator_state;\n\tif (state->input) {\n\t\tfree(state->input);\n\t\tstate->input = NULL;\n\t}\n\tstate->input = (char *)malloc(input_length);\n\tif (!state->input) {\n\t\treturn -1;\n\t}\n\tstate->input_length = input_length;\n\tmemcpy(state->input, new_input, input_length);\n\tFUNCNAME(set_state)(mutator_state, NULL); //give the new input to radamsa.exe\n\treturn 0;\n}\n\n/**\n* This function sets a help message for the mutator. This is useful\n* if the mutator takes a JSON options string in the create() function.\n* @param help_str - A pointer that will be updated to point to the new help string.\n* @return 0 on success and -1 on failure\n*/\nRADAMSA_MUTATOR_API int FUNCNAME(help)(char** help_str)\n{\n\tGENERIC_MUTATOR_HELP(\n\"radamsa - Radamsa mutator (Starts and calls radamsa to mutate input)\\n\"\n\"Options:\\n\"\n\"  path                  The path to radamsa.exe\\n\"\n\"  port                  The port to tell radamsa to bind to when starting up\\n\"\n\"  radamsa_iteration     The number of iterations to seek forward in the\\n\"\n\"                          radamsa output\\n\"\n\"  seed                  The random seed to use when mutating\\n\"\n\"\\n\"\n\t);\n}\n\nstatic void cleanup_process(radamsa_state_t * state)\n{\n\tif (state->process)\n\t{\n#ifdef _WIN32\n\t\tTerminateProcess(state->process, 9);\n\t\tCloseHandle(state->process);\n\t\tstate->process = NULL;\n#else\n\t\tint status;\n\t\tkill(state->process, 9);\n\t\twait(&status);\n\t\tstate->process = 0;\n#endif\n\t}\n\tstate->radamsa_up = 0;\n}\n\nstatic int start_process(radamsa_state_t * state)\n{\n\tchar cmd_line[256];\n\tsnprintf(cmd_line, sizeof(cmd_line), \"%s -o :%d -n inf -s %d \", state->path, state->port, state->seed);\n\tif (state->radamsa_iteration != 0)\n\t\tsnprintf(cmd_line, sizeof(cmd_line), \"%s -S %d \", cmd_line, state->radamsa_iteration + 1); //radamsa counts from 1\n\treturn start_process_and_write_to_stdin(cmd_line, state->input, state->input_length, &state->process);\n}\n"
  },
  {
    "path": "mutators/radamsa_mutator/radamsa_mutator.h",
    "content": "#pragma once\n\n#include <global_types.h>\n#include <mutators.h>\n\n#ifdef _WIN32\n#ifdef RADAMSA_MUTATOR_EXPORTS\n#define RADAMSA_MUTATOR_API __declspec(dllexport)\n#else\n#define RADAMSA_MUTATOR_API __declspec(dllimport)\n#endif\n#else //_WIN32\n#define RADAMSA_MUTATOR_API\n#endif\n\n#define MUTATOR_NAME \"radamsa\"\n\nRADAMSA_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length);\nRADAMSA_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state);\nRADAMSA_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length);\nRADAMSA_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags);\nRADAMSA_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state);\n#define radamsa_free_state default_free_state\nRADAMSA_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state);\nRADAMSA_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state);\n#define radamsa_get_total_iteration_count return_unknown_or_infinite_total_iterations\nRADAMSA_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes);\nRADAMSA_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length);\nRADAMSA_MUTATOR_API int FUNCNAME(help)(char **);\n\n#ifndef ALL_MUTATORS_IN_ONE\nRADAMSA_MUTATOR_API void init(mutator_t * m);\n#endif\n"
  },
  {
    "path": "mutators/splice_mutator/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (splice_mutator)\n\ninclude_directories (${PROJECT_SOURCE_DIR}/../mutators/)\n\nset(SPLICE_SRC ${PROJECT_SOURCE_DIR}/splice_mutator.c)\nsource_group(\"Library Sources\" FILES ${SPLICE_SRC})\n\nadd_library(splice_mutator SHARED ${SPLICE_SRC}\n  $<TARGET_OBJECTS:mutators_object> $<TARGET_OBJECTS:jansson_object>)\ntarget_link_libraries(splice_mutator utils)\ntarget_compile_definitions(splice_mutator PUBLIC SPLICE_MUTATOR_EXPORTS)\ntarget_compile_definitions(splice_mutator PUBLIC MUTATORS_NO_IMPORT)\ntarget_compile_definitions(splice_mutator PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(splice_mutator PUBLIC JANSSON_NO_IMPORT)\n\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(splice_mutator Shlwapi)\nendif (WIN32)\n"
  },
  {
    "path": "mutators/splice_mutator/splice_mutator.c",
    "content": "#include \"splice_mutator.h\"\n#include <mutators.h>\n#include <afl_helpers.h>\n#include <afl_config.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <utils.h>\n#include <jansson.h>\n#include <jansson_helper.h>\n\nstruct splice_state\n{\n\tchar * input;\n\tsize_t input_length;\n\tint iteration;\n\n\tmutate_info_t info;\n};\ntypedef struct splice_state splice_state_t;\n\nstatic int(*const mutate_funcs[])(mutate_info_t *, mutate_buffer_t *) = {\n\tsplice_buffers,\n};\n\nmutator_t splice_mutator = {\n\tFUNCNAME(create),\n\tFUNCNAME(cleanup),\n\tFUNCNAME(mutate),\n\tFUNCNAME(mutate_extended),\n\tFUNCNAME(get_state),\n\tsplice_free_state,\n\tFUNCNAME(set_state),\n\tFUNCNAME(get_current_iteration),\n\tsplice_get_total_iteration_count,\n\tFUNCNAME(get_input_info),\n\tFUNCNAME(set_input),\n\tFUNCNAME(help)\n};\n\n/**\n * This function fills in m with all of the function pointers for this mutator.\n * @param m - a pointer to a mutator_t structure\n * @return none\n */\n#ifndef ALL_MUTATORS_IN_ONE\nSPLICE_MUTATOR_API void init(mutator_t * m)\n{\n\tmemcpy(m, &splice_mutator, sizeof(mutator_t));\n}\n#endif\n\nstatic splice_state_t * setup_options(char * options)\n{\n\tsplice_state_t * state = (splice_state_t *)malloc(sizeof(splice_state_t));\n\tif (!state)\n\t\treturn NULL;\n\tmemset(state, 0, sizeof(splice_state_t));\n\n\t//Setup defaults\n\tif (reset_mutate_info(&state->info)) {\n\t\tfree(state);\n\t\treturn NULL;\n\t}\n\tif (!options || !strlen(options))\n\t\treturn state;\n\n\tPARSE_MUTATE_INFO_OPTIONS(state, options, FUNCNAME(cleanup), 0, 1);\n\treturn state;\n}\n\n\n/**\n * This function will allocate and initialize the mutator state used in the other Mutator API\n * functions.  \n * @param options - a json string that contains the mutator specific string of options.\n * @param state - Optionally, used to load a previously dumped state (with the get_state()\n * function), that defines the current iteration of the mutator.\n * @param input - used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size of the input buffer\n * @return a mutator specific structure or NULL on failure.\n */\nSPLICE_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length)\n{\n\tGENERIC_MUTATOR_CREATE(splice_state_t, setup_options, FUNCNAME(cleanup));\n}\n\n/**\n * This function will release any resources that the mutator has open \n * and free the mutator state structure.\n * @param mutator_state - a mutator specific structure previously created by \n * the create function.  This structure will be freed and should not be referenced afterwards.\n */\nSPLICE_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state)\n{\n\tcleanup_mutate_info(&((splice_state_t *)mutator_state)->info);\n\tGENERIC_MUTATOR_CLEANUP(splice_state_t)\n}\n\nstatic int mutate_inner(void * mutator_state, char * buffer, size_t buffer_length, int is_thread_safe)\n{\n\tsplice_state_t * state = (splice_state_t *)mutator_state;\n\tmutate_buffer_t buf;\n\tint ret;\n\tif (buffer_length < state->input_length)\n\t\treturn -1;\n\n\tbuf.buffer = (uint8_t *)buffer;\n\tbuf.length = MIN(buffer_length, state->input_length);\n\tbuf.max_length = buffer_length;\n\tmemcpy(buf.buffer, state->input, buf.length);\n\n\tif(is_thread_safe && take_mutex(state->info.mutate_mutex))\n\t\treturn -1;\n\tif (state->info.stage_cur > MAX(HAVOC_MIN, SPLICE_HAVOC * (state->info.perf_score / state->info.havoc_div) / 100))\n\t{\n\t\tstate->info.stage = 0;\n\t\tstate->info.stage_cur = 0;\n\t\tstate->info.queue_cycle++;\n\t}\n\tstate->iteration++;\n\tret = mutate_one(&state->info, &buf, mutate_funcs, ARRAY_SIZE(mutate_funcs));\n\tif (is_thread_safe && release_mutex(state->info.mutate_mutex))\n\t\treturn -1;\n\treturn ret;\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nSPLICE_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length)\n{\n\treturn mutate_inner(mutator_state, buffer, buffer_length, 0);\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * This function also accepts a set of flags which instruct it how to mutate the input.  See global_types.h\n * for the list of available flags.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.  It must be at least as large as\n * the original input buffer.\n * @param flags - A set of mutate flags that modify how this mutator mutates the input.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nSPLICE_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags)\n{\n\tSINGLE_INPUT_MUTATE_EXTENDED(splice_state_t, state->info.mutate_mutex);\n}\n\n/**\n * This function will return the state of the mutator.  The returned value can be used to restart the\n * mutator at a later time, by passing it to the create or set_state function.  It is the caller's\n * responsibility to free the memory allocated here by calling the free_state function.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return - a buffer that defines the current state of the mutator.\n */\nSPLICE_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state)\n{\n\tsplice_state_t * state = (splice_state_t *)mutator_state;\n\tjson_t *state_obj, *temp;\n\tchar * ret;\n\n\tstate_obj = json_object();\n\tADD_INT(temp, state->iteration, state_obj, \"iteration\");\n\tif (!add_mutate_info_to_json(state_obj, &state->info))\n\t\treturn NULL;\n\tret = json_dumps(state_obj, 0);\n\tjson_decref(state_obj);\n\treturn ret;\n}\n\n/**\n * This function will set the current state of the mutator.\n * This can be used to restart a mutator once from a previous run.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param state - a previously dumped state buffer obtained by the get_state function.\n * @return 0 on success or non-zero on failure\n */\nSPLICE_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state)\n{\n\tsplice_state_t * current_state = (splice_state_t *)mutator_state;\n\tint result, temp_int;\n\tif (!state)\n\t\treturn 1;\n\tGET_INT(temp_int, state, current_state->iteration, \"iteration\", result);\n\tif (get_mutate_info_from_json(state, &current_state->info))\n\t\treturn 1;\n\treturn 0;\n}\n\n/**\n * This function will return the current iteration count of the mutator, i.e.\n * how many mutations have been generated with it.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return value - the number of previously generated mutations\n */\nSPLICE_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state)\n{\n\tGENERIC_MUTATOR_GET_ITERATION(splice_state_t);\n}\n\n/**\n * Obtains information about the inputs that were given to the mutator when it was created\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param num_inputs - a pointer to an integer used to return the number of inputs given to this mutator\n * when it was created.  This parameter is optional and can be NULL, if this information is not needed\n * @param input_sizes - a pointer to a size_t array used to return the sizes of the inputs given to this\n * mutator when it was created. This parameter is optional and can be NULL, if this information is not needed.\n */\nSPLICE_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes)\n{\n\tSINGLE_INPUT_GET_INFO(splice_state_t);\n}\n\n/**\n * This function will set the mutator's input to something new.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param new_input - The new input used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size in bytes of the input buffer.\n * @return 0 on success and -1 on failure\n */\nSPLICE_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length)\n{\n\tGENERIC_MUTATOR_SET_INPUT(splice_state_t);\n}\n\n/**\n * This function sets a help message for the mutator.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nSPLICE_MUTATOR_API int FUNCNAME(help)(char **help_str)\n{\n\tGENERIC_MUTATOR_HELP(\n\"splice - afl-based splice mutator\\n\"\n\"Options:\\n\"\n\"  dictionary            A file or directory containing dictionary to use while\\n\"\n\"                          mangling input\\n\"\n\"  havoc_div             A divisor for determining the number of rounds that\\n\"\n\"                          the havoc stage should run (typically 1, 2, 5, or 10)\\n\"\n\"  perf_score            A performance score used to determine how long a havoc\\n\"\n\"                          round lasts.  Typically 100, higher results in a\\n\"\n\"                          larger number of mutations in these stages before\\n\"\n\"                          moving on.\\n\"\n\"  queue_cycle           The queue round counter.  Used in determining how to\\n\"\n\"                          mutate input.  Generally this shouldn't need to be set\\n\"\n\"  random_state0         The first half of the seed to afl's random number\\n\"\n\"                          generator\\n\"\n\"  random_state1         The second half of the seed to afl's random number\\n\"\n\"                          generator\\n\"\n\"  splice_filenames      An array of files to use during afl's splice stage,\\n\"\n\"                          for mixing with the input\\n\"\n\"\\n\"\n\t);\n}\n"
  },
  {
    "path": "mutators/splice_mutator/splice_mutator.h",
    "content": "#pragma once\n\n#include <global_types.h>\n#include <mutators.h>\n\n#ifdef _WIN32\n#ifdef SPLICE_MUTATOR_EXPORTS\n#define SPLICE_MUTATOR_API __declspec(dllexport)\n#else\n#define SPLICE_MUTATOR_API __declspec(dllimport)\n#endif\n#else //_WIN32\n#define SPLICE_MUTATOR_API\n#endif\n\n#define MUTATOR_NAME \"splice\"\n\nSPLICE_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length);\nSPLICE_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state);\nSPLICE_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length);\nSPLICE_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags);\nSPLICE_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state);\n#define splice_free_state default_free_state\nSPLICE_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state);\nSPLICE_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state);\n#define splice_get_total_iteration_count return_unknown_or_infinite_total_iterations\nSPLICE_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes);\nSPLICE_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length);\nSPLICE_MUTATOR_API int FUNCNAME(help)(char **help_str);\n\n#ifndef ALL_MUTATORS_IN_ONE\nSPLICE_MUTATOR_API void init(mutator_t * m);\n#endif\n"
  },
  {
    "path": "mutators/zzuf_mutator/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (zzuf_mutator)\n\ninclude_directories (${PROJECT_SOURCE_DIR}/../mutators/)\n\nset(ZZUF_SRC ${PROJECT_SOURCE_DIR}/zzuf_mutator.c)\nsource_group(\"Library Sources\" FILES ${ZZUF_SRC})\n\nadd_library(zzuf_mutator SHARED ${ZZUF_SRC}\n  $<TARGET_OBJECTS:mutators_object> $<TARGET_OBJECTS:jansson_object>)\ntarget_link_libraries(zzuf_mutator utils)\ntarget_compile_definitions(zzuf_mutator PUBLIC ZZUF_MUTATOR_EXPORTS)\ntarget_compile_definitions(zzuf_mutator PUBLIC MUTATORS_NO_IMPORT)\ntarget_compile_definitions(zzuf_mutator PUBLIC UTILS_NO_IMPORT)\ntarget_compile_definitions(zzuf_mutator PUBLIC JANSSON_NO_IMPORT)\n\nif (WIN32) # utils.dll needs Shlwapi\n  target_link_libraries(zzuf_mutator Shlwapi)\nendif (WIN32)\n"
  },
  {
    "path": "mutators/zzuf_mutator/zzuf_mutator.c",
    "content": "#include \"zzuf_mutator.h\"\n#include <mutators.h>\n\n#include <utils.h>\n#include <jansson_helper.h>\n#include <global_types.h>\n\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n// Fuzzing mode\nenum fuzzing_mode {\n  FUZZING_XOR = 0, FUZZING_SET, FUZZING_UNSET, FUZZING_UNKNOWN\n};\n\n// We arbitrarily split files into 1024-byte chunks. Each chunk has an\n// associated seed that can be computed from the zzuf seed, the chunk\n// index and the fuzziness density. This allows us to predictably fuzz\n// any part of the file without reading the whole file.\n#define CHUNKBYTES 1024\n\n// The default fuzzing ratio is, arbitrarily, 0.4%.  The minimal fuzzing\n// ratio is 0.000000001% (less than one bit changed on a whole DVD).\n#define DEFAULT_RATIO 0.004\n#define MIN_RATIO 0.00000000001\n#define MAX_RATIO 5.0\n\nstruct zzuf_state\n{\n  char * input;\n  size_t input_length;\n\n  //Option strings\n  char * protect_string;\n  char * refuse_string;\n  char * range_string;\n  char * mode_string;\n\n  //Parsed Options\n  enum fuzzing_mode mode;     // Fuzzing mode (xor, set, unset)\n  int seed;          // Random number generator seed\n  double ratio;\n  unsigned char protect[256]; // Per-value byte protection\n  unsigned char refuse[256];  // Per-value byte exclusion\n  int64_t *ranges;            // Per-offset byte protection\n\n  //Protects the fields below, i.e. the iteration count, data array, and random state\n  mutex_t mutate_mutex;\n\n  int iteration;\n  unsigned long ctx;\n  int current_chunk;\n  uint8_t data[CHUNKBYTES];\n};\ntypedef struct zzuf_state zzuf_state_t;\n\nmutator_t zzuf_mutator = {\n  FUNCNAME(create),\n  FUNCNAME(cleanup),\n  FUNCNAME(mutate),\n  FUNCNAME(mutate_extended),\n  FUNCNAME(get_state),\n  zzuf_free_state,\n  FUNCNAME(set_state),\n  FUNCNAME(get_current_iteration),\n  zzuf_get_total_iteration_count,\n  FUNCNAME(get_input_info),\n  FUNCNAME(set_input),\n  FUNCNAME(help)\n};\n\n////////////////////////////////////////////////////////////////////////////////////////////\n//// zzuf mutator methods //////////////////////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////////////////////////\n\n/*\n * The code in this section was taken from the zzuf project (available at\n * https://github.com/samhocevar/zzuf) and is licensed under the below\n * terms.  It has been modified from the original version to suit the\n * purposes of this project.\n *\n * zzuf - general purpose fuzzer\n *\n * Copyright © 2002—2015 Sam Hocevar <sam@hocevar.net>\n *\n * This program is free software. It comes without any warranty, to\n * the extent permitted by applicable law. You can redistribute it\n * and/or modify it under the terms of the Do What the Fuck You Want\n * to Public License, Version 2, as published by the WTFPL Task Force.\n * See http://www.wtfpl.net/ for more details.\n */\n\n#define MAGIC1 0x33ea84f7\n#define MAGIC2 0x783bc31f\n#define MAGIC3 0x9b5da2fb\n\nvoid zzuf_srand(zzuf_state_t * state, uint32_t seed)\n{\n  state->ctx = (seed ^ 0x12345678);\n}\n\nuint32_t zzuf_rand(zzuf_state_t * state, uint32_t max)\n{\n  /* Could be better, but do we care? */\n  long hi = state->ctx / 12773L;\n  long lo = state->ctx % 12773L;\n  long x = 16807L * lo - 2836L * hi;\n  if (x <= 0)\n    x += 0x7fffffffL;\n  return (state->ctx = x) % (unsigned long)max;\n}\n\n/* This function converts a string containing a list of ranges in the format\n * understood by cut(1) such as \"1-5,8,10-\" into a C array for lookup. It is\n * the caller's duty to call free() on the returned value */\nint64_t *_zz_allocrange(char const *list)\n{\n  char const *parser;\n  int64_t *ranges;\n  unsigned int i, chunks;\n\n  /* Count commas */\n  for (parser = list, chunks = 1; *parser; ++parser)\n    if (*parser == ',')\n      chunks++;\n\n  ranges = malloc((chunks + 1) * 2 * sizeof(int64_t));\n\n  /* Fill ranges list */\n  for (parser = list, i = 0; i < chunks; ++i)\n  {\n    char const *comma = strchr(parser, ',');\n    char const *dash = strchr(parser, '-');\n\n    ranges[i * 2] = (dash == parser) ? 0 : atoi(parser);\n    if (dash && (dash + 1 == comma || dash[1] == '\\0'))\n      ranges[i * 2 + 1] = ranges[i * 2]; /* special case */\n    else if (dash && (!comma || dash < comma))\n      ranges[i * 2 + 1] = atoi(dash + 1) + 1;\n    else\n      ranges[i * 2 + 1] = ranges[i * 2] + 1;\n    parser = comma + 1;\n  }\n  ranges[i * 2] = ranges[i * 2 + 1] = 0;\n\n  return ranges;\n}\n\nint _zz_isinrange(int64_t value, int64_t const *ranges)\n{\n  int64_t const *r;\n\n  if (!ranges)\n    return 1;\n\n  for (r = ranges; r[1]; r += 2)\n    if (value >= r[0] && (r[0] == r[1] || value < r[1]))\n      return 1;\n\n  return 0;\n}\n\nstatic void add_char_range(unsigned char *table, char const *list)\n{\n  static char const hex[] = \"0123456789abcdef0123456789ABCDEF\";\n  char const *tmp;\n  int a, b;\n\n  memset(table, 0, 256 * sizeof(unsigned char));\n\n  for (tmp = list, a = b = -1; *tmp; ++tmp)\n  {\n    int ch;\n\n    if (*tmp == '\\\\' && tmp[1] == '\\0')\n      ch = '\\\\';\n    else if (*tmp == '\\\\')\n    {\n      tmp++;\n      if (*tmp == 'n')\n        ch = '\\n';\n      else if (*tmp == 'r')\n        ch = '\\r';\n      else if (*tmp == 't')\n        ch = '\\t';\n      else if (tmp[0] >= '0' && tmp[0] <= '7' && tmp[1] >= '0'\n          && tmp[1] <= '7' && tmp[2] >= '0' && tmp[2] <= '7')\n      {\n        ch = tmp[2] - '0';\n        ch |= (int)(tmp[1] - '0') << 3;\n        ch |= (int)(tmp[0] - '0') << 6;\n        tmp += 2;\n      }\n      else if ((*tmp == 'x' || *tmp == 'X')\n          && tmp[1] && strchr(hex, tmp[1])\n          && tmp[2] && strchr(hex, tmp[2]))\n      {\n        ch = ((int)(strchr(hex, tmp[1]) - hex) & 0xf) << 4;\n        ch |= (int)(strchr(hex, tmp[2]) - hex) & 0xf;\n        tmp += 2;\n      }\n      else\n        ch = (unsigned char)*tmp; /* XXX: OK for \\\\, but what else? */\n    }\n    else\n      ch = (unsigned char)*tmp;\n\n    if (a != -1 && b == '-' && a <= ch)\n    {\n      while (a <= ch)\n        table[a++] = 1;\n      a = b = -1;\n    }\n    else\n    {\n      if (a != -1)\n        table[a] = 1;\n      a = b;\n      b = ch;\n    }\n  }\n\n  if (a != -1)\n    table[a] = 1;\n  if (b != -1)\n    table[b] = 1;\n}\n\nstatic enum fuzzing_mode _zz_fuzzing(char const *mode)\n{\n  if (!strcmp(mode, \"xor\"))\n    return FUZZING_XOR;\n  else if (!strcmp(mode, \"set\"))\n    return FUZZING_SET;\n  else if (!strcmp(mode, \"unset\"))\n    return FUZZING_UNSET;\n  return FUZZING_UNKNOWN;\n}\n\nvoid _zz_fuzz(zzuf_state_t * state, char * buf, int64_t len)\n{\n  uint32_t chunkseed;\n  int64_t i, j, start, stop;\n  unsigned char byte, fuzzbyte;\n  int todo;\n  unsigned int idx;\n  uint8_t bit;\n\n  for (i = 0; i < (len + CHUNKBYTES - 1) / CHUNKBYTES; ++i)\n  {\n    /* Cache bitmask array */\n    if (state->current_chunk != (int)i)\n    {\n      chunkseed = (uint32_t)i;\n      chunkseed ^= MAGIC2;\n      chunkseed += (uint32_t)(state->ratio * MAGIC1);\n      chunkseed ^= (state->seed + state->iteration); //Increment the zzuf seed each mutation\n      chunkseed += (uint32_t)(i * MAGIC3);\n\n      zzuf_srand(state, chunkseed);\n\n      memset(state->data, 0, CHUNKBYTES);\n\n      /* Add some random dithering to handle ratio < 1.0/CHUNKBYTES */\n      todo = (int)((state->ratio * (8 * CHUNKBYTES) * 1000000.0 + zzuf_rand(state, 1000000)) / 1000000.0);\n      while (todo--)\n      {\n        idx = zzuf_rand(state, CHUNKBYTES);\n        bit = (1 << zzuf_rand(state, 8));\n        state->data[idx] ^= bit;\n      }\n\n      state->current_chunk = i;\n    }\n\n    // Apply our bitmask array to the buffer\n    start = (i * CHUNKBYTES > 0) ? i * CHUNKBYTES : 0;\n    stop = ((i + 1) * CHUNKBYTES < len) ? (i + 1) * CHUNKBYTES : len;\n\n    for (j = start; j < stop; ++j)\n    {\n      if (state->ranges && !_zz_isinrange(j, state->ranges))\n        continue; // Not in one of the ranges, skip byte\n\n      byte = (uint8_t)buf[j];\n\n      if(state->protect[byte])\n        continue;\n\n      fuzzbyte = state->data[j % CHUNKBYTES];\n      if(!fuzzbyte)\n        continue;\n\n      switch (state->mode)\n      {\n        case FUZZING_XOR:\n          byte ^= fuzzbyte;\n          break;\n        case FUZZING_SET:\n          byte |= fuzzbyte;\n          break;\n        case FUZZING_UNSET:\n          byte &= ~fuzzbyte;\n          break;\n      }\n\n      if(state->refuse[byte])\n        continue;\n\n      buf[j] = (uint8_t)byte;\n    }\n  }\n}\n\n////////////////////////////////////////////////////////////////////////////////////////////\n//// API methods ///////////////////////////////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////////////////////////\n\n#ifndef ALL_MUTATORS_IN_ONE\n\n/**\n * This function fills in the supplied mutator_t with all of the function\n * pointers for this mutator.\n * @param m - a pointer to a mutator_t structure\n */\nZZUF_MUTATOR_API void init(mutator_t * m)\n{\n  memcpy(m, &zzuf_mutator, sizeof(mutator_t));\n}\n\n#endif\n\n/**\n * This function sets up the refuse, protect, and range tables from the associated strings in a\n * state.  Additionally, the fuzzing mode is set from the mode string.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n */\nstatic void setup_state_from_strings(zzuf_state_t * state)\n{\n  if(state->refuse_string)\n    add_char_range(state->refuse, state->refuse_string);\n  if(state->protect_string)\n    add_char_range(state->protect, state->protect_string);\n  if(state->range_string)\n    state->ranges = _zz_allocrange(state->range_string);\n  if(state->mode_string)\n    state->mode = _zz_fuzzing(state->mode_string);\n}\n\n/**\n * This function frees the memory associated with the protect, refuse, mode, and range strings. Also\n * the range table is freed.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n */\nstatic void free_ranges(zzuf_state_t * state)\n{\n  free(state->protect_string);\n  state->protect_string = NULL;\n  free(state->refuse_string);\n  state->refuse_string = NULL;\n  free(state->range_string);\n  state->range_string = NULL;\n  free(state->mode_string);\n  state->mode_string = NULL;\n  free(state->ranges);\n  state->ranges = NULL;\n}\n\n/**\n * This function creates and initializes a zzuf_state_t object based on the passed in JSON options.\n * @return the newly created zzuf_state_t object or NULL on failure\n */\nstatic zzuf_state_t * setup_options(char * options)\n{\n  zzuf_state_t * state;\n  size_t i;\n  state = (zzuf_state_t *)malloc(sizeof(zzuf_state_t));\n  if (!state)\n    return NULL;\n  memset(state, 0, sizeof(zzuf_state_t));\n\n  state->current_chunk = -1;\n  state->mutate_mutex = create_mutex();\n  if (!state->mutate_mutex) {\n    free(state);\n    return NULL;\n  }\n\n  //Setup defaults\n  state->seed = rand();\n  state->mode = FUZZING_XOR;\n  state->ratio = DEFAULT_RATIO;\n\n  if (!options || !strlen(options))\n    return state;\n\n  PARSE_OPTION_STRING(state, options, mode_string, \"mode\", FUNCNAME(cleanup));\n  PARSE_OPTION_DOUBLE(state, options, ratio, \"ratio\", FUNCNAME(cleanup));\n  PARSE_OPTION_STRING(state, options, range_string, \"range\", FUNCNAME(cleanup));\n  PARSE_OPTION_STRING(state, options, refuse_string, \"refuse\", FUNCNAME(cleanup));\n  PARSE_OPTION_INT(state, options, seed, \"seed\", FUNCNAME(cleanup));\n  PARSE_OPTION_STRING(state, options, protect_string, \"protect\", FUNCNAME(cleanup));\n\n  state->ratio = state->ratio < MIN_RATIO ? MIN_RATIO : state->ratio > MAX_RATIO ? MAX_RATIO : state->ratio;\n  setup_state_from_strings(state);\n  if(state->mode == FUZZING_UNKNOWN) {\n    FUNCNAME(cleanup)(state);\n    return NULL;\n  }\n  return state;\n}\n\n/**\n * This function will allocate and initialize the mutator state. The mutator state should be\n * freed by calling the cleanup function.\n * @param options - a json string that contains the zzuf specific options.\n * @param state - optionally, a previously dumped state (with the get_state() function) to load\n * @param input - The input that this mutator will later be mutating\n * @param input_length - the size of the input parameter\n * @return a mutator specific structure or NULL on failure. The returned value should\n * not be used for anything other than passing to the various Mutator API functions.\n */\nZZUF_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length)\n{\n  zzuf_state_t * zzuf_state = setup_options(options);\n  if (!zzuf_state)\n    return NULL;\n\n  zzuf_state->input = (char *)malloc(input_length);\n  if (!zzuf_state->input || !input_length)\n  {\n    FUNCNAME(cleanup)(zzuf_state);\n    return NULL;\n  }\n  memcpy(zzuf_state->input, input, input_length);\n  zzuf_state->input_length = input_length;\n  if (state && FUNCNAME(set_state)(zzuf_state, state)) {\n    FUNCNAME(cleanup)(zzuf_state);\n    return NULL;\n  }\n  return zzuf_state;\n}\n\n/**\n * This function will release any resources that the mutator has open\n * and free the mutator state structure.\n * @param mutator_state - a mutator specific structure previously created by\n * the create function. This structure will be freed and should not be referenced afterwards.\n */\nZZUF_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state)\n{\n  size_t i;\n  zzuf_state_t * state = (zzuf_state_t *)mutator_state;\n\n  destroy_mutex(state->mutate_mutex);\n  free_ranges(state);\n  free(state->input);\n  free(state);\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nZZUF_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length)\n{\n  zzuf_state_t * state = (zzuf_state_t *)mutator_state;\n  size_t mutated_buffer_length;\n  //Can't mutate an empty buffer\n  if (buffer_length == 0)\n    return -1;\n\n  mutated_buffer_length = buffer_length > state->input_length ? state->input_length : buffer_length;\n  memcpy(buffer, state->input, mutated_buffer_length);\n  _zz_fuzz(state, buffer, mutated_buffer_length);\n  state->iteration++;\n  return (int)mutated_buffer_length;\n}\n\n/**\n * This function will mutate the input given in the create function and return it in the buffer argument.\n * This function also accepts a set of flags which instruct it how to mutate the input. See global_types.h\n * for the list of available flags.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param buffer - a buffer that the mutated input will be written to\n * @param buffer_length - the size of the passed in buffer argument.\n * @param flags - A set of mutate flags that modify how this mutator mutates the input.\n * @return - the length of the mutated data, 0 when the mutator is out of mutations, or -1 on error\n */\nZZUF_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags)\n{\n  SINGLE_INPUT_MUTATE_EXTENDED(zzuf_state_t, state->mutate_mutex);\n}\n\n/**\n * This function will return the state of the mutator. The returned value can be used to restart the\n * mutator at a later time, by passing it to the create or set_state function. It is the caller's\n * responsibility to free the memory allocated here by calling the free_state function.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return - a buffer that defines the current state of the mutator. This will be a mutator specific JSON string.\n */\nZZUF_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state)\n{\n  zzuf_state_t * state = (zzuf_state_t *)mutator_state;\n  json_t *obj, *temp;\n  char * ret;\n\n  obj = json_object();\n  ADD_INT(temp, state->iteration, obj, \"iteration\");\n  ADD_INT(temp, state->seed, obj, \"seed\");\n  ADD_INT(temp, state->mode, obj, \"mode\");\n  ADD_DOUBLE(temp, state->ratio, obj, \"ratio\");\n  ADD_STRING(temp, state->protect_string, obj, \"protect\");\n  ADD_STRING(temp, state->refuse_string, obj, \"refuse\");\n  ADD_STRING(temp, state->range_string, obj, \"range\");\n  ret = json_dumps(obj, 0);\n  json_decref(obj);\n  return ret;\n}\n\n/**\n * This function will set the current state of the mutator.\n * This can be used to restart a mutator once from a previous run.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param state - a previously dumped state buffer obtained by the get_state function.\n * @return 0 on success or non-zero on failure\n */\nZZUF_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state)\n{\n  zzuf_state_t * zzuf_state = (zzuf_state_t *)mutator_state;\n  int result, temp_int;\n  double temp_double;\n  char * temp_str;\n\n  if (!state)\n    return 1;\n\n  free_ranges(zzuf_state);\n  zzuf_state->current_chunk = -1;\n\n  GET_INT(temp_int, state, zzuf_state->iteration, \"iteration\", result);\n  GET_INT(temp_int, state, zzuf_state->seed, \"seed\", result);\n  GET_INT(temp_int, state, zzuf_state->mode, \"mode\", result);\n  GET_DOUBLE(temp_double, state, zzuf_state->ratio, \"ratio\", result);\n  GET_STRING(temp_str, state, zzuf_state->protect_string, \"protect\", result);\n  GET_STRING(temp_str, state, zzuf_state->refuse_string, \"refuse\", result);\n  GET_STRING(temp_str, state, zzuf_state->range_string, \"range\", result);\n  setup_state_from_strings(zzuf_state);\n\n  return 0;\n}\n\n/**\n * This function will return the current iteration count of the mutator, i.e.\n * how many mutations have been generated with it.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @return value - the number of previously generated mutations\n */\nZZUF_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state)\n{\n  GENERIC_MUTATOR_GET_ITERATION(zzuf_state_t);\n}\n\n/**\n * Obtains information about the inputs that were given to the mutator when it was created\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param num_inputs - a pointer to an integer used to return the number of inputs given to this mutator\n * when it was created. This parameter is optional and can be NULL, if this information is not needed\n * @param input_sizes - a pointer to a size_t array used to return the sizes of the inputs given to this\n * mutator when it was created. This parameter is optional and can be NULL, if this information is not needed.\n */\nZZUF_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes)\n{\n  SINGLE_INPUT_GET_INFO(zzuf_state_t);\n}\n\n/**\n * This function will set the input(saved in the mutators state) to something new.\n * This can be used to reinitialize a mutator with new data, without reallocating the entire state struct.\n * @param mutator_state - a mutator specific structure previously created by the create function.\n * @param new_input - The new input used to produce new mutated inputs later when the mutate function is called\n * @param input_length - the size in bytes of the input buffer.\n * @return 0 on success and -1 on failure\n */\nZZUF_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length)\n{\n  GENERIC_MUTATOR_SET_INPUT(zzuf_state_t);\n}\n\n/**\n * This function sets a help message for the mutator.\n * @param help_str - A pointer that will be updated to point to the new help string.\n * @return 0 on success and -1 on failure\n */\nZZUF_MUTATOR_API int FUNCNAME(help)(char ** help_str)\n{\n  GENERIC_MUTATOR_HELP(\n      \"zzuf - zzuf-based mutator\\n\"\n      \"Options:\\n\"\n      \"\\tmode                  fuzzing mode to use: xor, set, or unset\\n\"\n      \"\\tprotect               protect bytes and characters in <list>\\n\"\n      \"\\trange                 only fuzz bytes at offsets within <ranges>\\n\"\n      \"\\tratio                 bit fuzzing ratio\\n\"\n      \"\\trefuse                refuse bytes and characters in <list>\\n\"\n      \"\\tseed                  random seed\\n\"\n      \"\\n\"\n      );\n}\n"
  },
  {
    "path": "mutators/zzuf_mutator/zzuf_mutator.h",
    "content": "#pragma once\n\n#include <global_types.h>\n#include <mutators.h>\n\n#ifdef _WIN32\n#ifdef ZZUF_MUTATOR_EXPORTS\n#define ZZUF_MUTATOR_API __declspec(dllexport)\n#else\n#define ZZUF_MUTATOR_API __declspec(dllimport)\n#endif\n#else //_WIN32\n#define ZZUF_MUTATOR_API\n#endif\n\n#define MUTATOR_NAME \"zzuf\"\n\nZZUF_MUTATOR_API void * FUNCNAME(create)(char * options, char * state, char * input, size_t input_length);\nZZUF_MUTATOR_API void FUNCNAME(cleanup)(void * mutator_state);\nZZUF_MUTATOR_API int FUNCNAME(mutate)(void * mutator_state, char * buffer, size_t buffer_length);\nZZUF_MUTATOR_API int FUNCNAME(mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags);\nZZUF_MUTATOR_API char * FUNCNAME(get_state)(void * mutator_state);\n#define zzuf_free_state default_free_state\nZZUF_MUTATOR_API int FUNCNAME(set_state)(void * mutator_state, char * state);\nZZUF_MUTATOR_API int FUNCNAME(get_current_iteration)(void * mutator_state);\n#define zzuf_get_total_iteration_count return_unknown_or_infinite_total_iterations\nZZUF_MUTATOR_API void FUNCNAME(get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes);\nZZUF_MUTATOR_API int FUNCNAME(set_input)(void * mutator_state, char * new_input, size_t input_length);\nZZUF_MUTATOR_API int FUNCNAME(help)(char ** help_str);\n\n#ifndef ALL_MUTATORS_IN_ONE\nZZUF_MUTATOR_API void init(mutator_t * m);\n#endif\n"
  },
  {
    "path": "picker/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (picker)\n\ninclude_directories (${CMAKE_SOURCE_DIR}/driver/)\ninclude_directories (${CMAKE_SOURCE_DIR}/instrumentation/)\n\nset(PICKER_SRC ${PROJECT_SOURCE_DIR}/main.c)\nsource_group(\"Executable Sources\" FILES ${PICKER_SRC})\nadd_executable(picker ${PICKER_SRC} $<TARGET_OBJECTS:driver>\n\t$<TARGET_OBJECTS:instrumentation>)\ntarget_compile_definitions(picker PUBLIC INSTRUMENTATION_NO_IMPORT)\ntarget_compile_definitions(picker PUBLIC DRIVER_NO_IMPORT)\n\ntarget_link_libraries(picker utils)\ntarget_link_libraries(picker jansson)\nif (WIN32)\n  target_link_libraries(picker Shlwapi)  # utils needs Shlwapi\n  target_link_libraries(picker ws2_32)   # driver needs ws2_32\n  target_link_libraries(picker iphlpapi) # network driver needs iphlpapi\nendif (WIN32)"
  },
  {
    "path": "picker/main.c",
    "content": "//This program helps the user decide which libraries should be instrumented\n//while fuzzing.  This is accomplished by running the target program and\n//recording coverage information on each of the loaded libraries. It then\n//analyzes the coverage information for each library to determine which\n//libraries the coverage information varies based on the input file.  These\n//libraries are most likely the ones that process the input file, and thus the\n//most likely targets for fuzzing.\n\n#include <driver.h>\n#include <driver_factory.h>\n#include <instrumentation.h>\n#include <instrumentation_factory.h>\n#include <utils.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n\n\n/**\n* This function prints out the usage information for the fuzzer and each of the individual components.\n* @param program_name - the name of the program currently being run (for use in the outputted message)\n*/\nvoid usage(char * program_name)\n{\n\tchar * help_text;\n\tprintf(\n\t\t\"Usage: %s driver_name instrumentation_name seed_directory [options]\\n\"\n\t\t\"\\n\"\n\t\t\"Options:\\n\"\n\t\t\"\\t -d driver_options             Set the options for the driver\\n\"\n\t\t\"\\t -i instrumentation_options    Set the options for the instrumentation\\n\"\n\t\t\"\\t -ib ignore_bytes_dir          The directory to write the list of bytes in the instrumentation to ignore\\n\"\n\t\t\"\\t -l logging_options            Set the options for logging\\n\"\n\t\t\"\\t -n num_iterations             The number of iterations to run per file [default 10 per file]\\n\"\n\t\t\"\\n\",\n\t\tprogram_name\n\t);\n\n#define PRINT_HELP(x, y) \\\n\tx = y;               \\\n\tif(x) {              \\\n\t\tputs(x);         \\\n\t\tfree(x);         \\\n\t}\n\n\tPRINT_HELP(help_text, driver_help());\n\tPRINT_HELP(help_text, instrumentation_help());\n\texit(1);\n}\n\n\nint main(int argc, char ** argv)\n{\n\tdriver_t * driver;\n\tinstrumentation_t * instrumentation;\n\tchar *driver_name, *driver_options = NULL,\n\t\t*seed_directory = NULL, *seed_buffer = NULL, * module_name = NULL, *logging_options = NULL,\n\t\t*instrumentation_name = NULL, *instrumentation_options = NULL, *ignore_bytes_dir = NULL;\n\tvoid * instrumentation_state = NULL;\n\tint seed_length = 0, file_count, module_index, new_path, cur_index;\n\tint iteration = 0;\n\tWIN32_FIND_DATA fdFile;\n\tHANDLE file_handle;\n\tchar filename[4096];\n\tchar ** module_names = NULL, ** filenames = NULL;\n\tchar * module_infos = NULL;\n\tint * module_results = NULL;\n\tchar * info, * ignore_bytes;\n\tint num_modules = 0, num_files = 0, info_size, module_info_size = -1, i;\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Parse Arguments ///////////////////////////////////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\t//Default options\n\tint num_iterations = 10;\n\n\tif (argc < 4)\n\t{\n\t\tusage(argv[0]);\n\t}\n\n\tdriver_name = argv[1];\n\tinstrumentation_name = argv[2];\n\tseed_directory = argv[3];\n\tfor (int i = 4; i < argc; i++)\n\t{\n\t\tIF_ARG_OPTION(\"-d\", driver_options)\n\t\tELSE_IF_ARG_OPTION(\"-i\", instrumentation_options)\n\t\tELSE_IF_ARG_OPTION(\"-ib\", ignore_bytes_dir)\n\t\tELSE_IF_ARG_OPTION(\"-l\", logging_options)\n\t\tELSE_IF_ARGINT_OPTION(\"-n\", num_iterations)\n\t\telse\n\t\t{\n\t\t\tif (strcmp(\"-h\", argv[i]))\n\t\t\t\tprintf(\"Unknown argument: %s\\n\", argv[i]);\n\t\t\tusage(argv[0]);\n\t\t}\n\t}\n\n\tif (setup_logging(logging_options))\n\t{\n\t\tprintf(\"Failed setting up logging, exitting\\n\");\n\t\treturn 1;\n\t}\n\n\tif (num_iterations < 2)\n\t\tFATAL_MSG(\"Bad iteration number (%d).  Must have a iteration count greater than 1.\", num_iterations);\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Ojbect Setup //////////////////////////////////////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\tinstrumentation = instrumentation_factory(instrumentation_name);\n\tif (!instrumentation)\n\t\tFATAL_MSG(\"Unknown instrumentation '%s'\", instrumentation_name);\n\tinstrumentation_state = instrumentation->create(instrumentation_options, NULL);\n\tif (!instrumentation_state)\n\t\tFATAL_MSG(\"Bad options/state for instrumentation %s\", instrumentation_name);\n\tif (!instrumentation->get_module_info)\n\t\tFATAL_MSG(\"Instrumentation '%s' does not support per module coverage\", instrumentation_name);\n\n\t//Create the driver\n\tdriver = driver_instrumentation_factory(driver_name, driver_options, instrumentation, instrumentation_state);\n\tif (!driver)\n\t\tFATAL_MSG(\"Unknown driver '%s' or bad options: %s\", driver_name, driver_options);\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Get the list of files to test /////////////////////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t\n\tmemset(filename, 0, sizeof(filename));\n\tsnprintf(filename, sizeof(filename) - 1, \"%s\\\\*\", seed_directory);\n\tfile_count = 0;\n\n\tint success = 1;\n\tfor (file_handle = FindFirstFile(filename, &fdFile);\n\t\tfile_handle != INVALID_HANDLE_VALUE && success;\n\t\tsuccess = FindNextFile(file_handle, &fdFile))\n\t{\n\t\t//Skip directories\n\t\tif (fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)\n\t\t\tcontinue;\n\n\t\t//Read the seed file\n\t\tmemset(filename, 0, sizeof(filename));\n\t\tsnprintf(filename, sizeof(filename) - 1, \"%s\\\\%s\", seed_directory, fdFile.cFileName);\n\t\tseed_length = read_file(filename, &seed_buffer);\n\t\tif (seed_length <= 0) //Couldn't read file, or empty file\n\t\t\tcontinue;\n\t\tfree(seed_buffer);\n\n\t\tnum_files++;\n\t\tfilenames = (char **)realloc(filenames, num_files * sizeof(char *));\n\t\tfilenames[num_files - 1] = strdup(filename);\n\t}\n\tFindClose(file_handle);\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Main Test Loop ////////////////////////////////////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\n#define INITIAL_STATE 0\n#define PATH_SET 1\n#define NEW_PATH_ON_SAME_FILE 2\n#define NEW_PATH_ON_DIFF_FILE 3\n\tchar * module_results_descriptions[] = {\n\t\t\"no paths set\", //INITIAL_STATE\n\t\t\"a single path for all files\", //PATH_SET\n\t\t\"multiple paths for the same file\", //NEW_PATH_ON_SAME_FILE\n\t\t\"one path for each file\" //NEW_PATH_ON_DIFF_FILE\n\t};\n\n\tfor(file_count = 0; file_count < num_files; file_count++)\n\t{\n\t\t//Read the seed file\n\t\tseed_length = read_file(filenames[file_count], &seed_buffer);\n\t\tif (seed_length <= 0) //Couldn't read file, or empty file\n\t\t\tcontinue;\n\n\t\tINFO_MSG(\"Testing file '%s'\", filenames[file_count]);\n\t\tfor (iteration = 0; iteration < num_iterations; iteration++)\n\t\t{\n\t\t\tdriver->test_input(driver->state, seed_buffer, seed_length);\n\n\t\t\tmodule_index = 0;\n\t\t\twhile (!instrumentation->get_module_info(instrumentation_state, module_index, &new_path, &module_name, &info, &info_size))\n\t\t\t{\n\t\t\t\tcur_index = module_index;\n\t\t\t\tmodule_index++;\n\n\t\t\t\tif (module_info_size == -1)\n\t\t\t\t\tmodule_info_size = info_size;\n\t\t\t\tif (info_size != module_info_size)\n\t\t\t\t\tFATAL_MSG(\"Module instrumentation data varies per size, not supported (yet)\");\n\t\t\t\tif (!info)\n\t\t\t\t\tFATAL_MSG(\"Instrumentation data unavailable from the %s instrumentation.\\n\", instrumentation_name);\n\n\t\t\t\tif (num_modules < module_index)\n\t\t\t\t{\n\t\t\t\t\t//module_infos is a dynamically allocated array that holds all of the instrumentation data for each of the\n\t\t\t\t\t//instrumented modules.  While it is declared/used as a char *, it can be thought of as a 4-dimension array:\n\t\t\t\t\t//char module_infos[NUM_MODULES_TRACED][NUM_FILES_TRACED][NUM_ITERATIONS_PER_FILE][MODULE_INFO_SIZE];\n\n\t\t\t\t\tmodule_names = (char **)realloc(module_names, module_index * sizeof(char *));\n\t\t\t\t\tmodule_names[cur_index] = module_name;\n\t\t\t\t\tmodule_results = (int *)realloc(module_results, module_index * sizeof(int *));\n\t\t\t\t\tmodule_results[cur_index] = INITIAL_STATE;\n\t\t\t\t\tmodule_infos = (char *)realloc(module_infos, module_index * num_files * num_iterations * module_info_size);\n\t\t\t\t\tnum_modules = module_index;\n\t\t\t\t}\n\n\t\t\t\tint pos = ((cur_index * num_files * num_iterations) + (file_count * num_iterations) + iteration) * module_info_size;\n\t\t\t\tmemcpy(module_infos + pos, info, module_info_size);\n\n\t\t\t\t//Logic:\n\t\t\t\t//If it's the first time we've run this module, mark that we've set the path\n\t\t\t\t//If it's the first iteration that we've tried a new file and we found a new path, it has\n\t\t\t\t//  at least one new path per file. So until we determine that it can take multiple\n\t\t\t\t//  paths for the same file, mark it as having one path per file.\n\t\t\t\t//Otherwise, we've found a new path, then it must be a new path for the same file.  Mark it as\n\t\t\t\t//\tsuch.  After we've decided that, there is no coming back from that state.\n\t\t\t\tif (module_results[cur_index] == INITIAL_STATE)\n\t\t\t\t\tmodule_results[cur_index] = PATH_SET;\n\t\t\t\telse if (new_path && iteration == 0 && module_results[cur_index] != NEW_PATH_ON_SAME_FILE)\n\t\t\t\t\tmodule_results[cur_index] = NEW_PATH_ON_DIFF_FILE;\n\t\t\t\telse if (new_path)\n\t\t\t\t\tmodule_results[cur_index] = NEW_PATH_ON_SAME_FILE;\n\t\t\t}\n\t\t}\n\t\tfree(seed_buffer);\n\t}\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Compare the runs and calculate ignore bytes ///////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\t//In the next portion, we have the variables:\n\t//module_index     = the module index (since you can use the picker on many different modules at once).\n\t//num_files        = the number of files being tested\n\t//num_iterations   = the number of times each file was traced\n\t//file_count       = the iterator over the files for a specific module\n\t//iteration        = the iterator over the individual traces for a specific file\n\t//module_info_size = the size of the instrumentation data from the traced module (a constant value, that doesn't change per file/module/iteration)\n\t//cur_pos          = an index into module_infos to the instrumentation data for the $iteration trace of the $file_count file\n\t//prev_pos         = an index into module_infos to the instrumentation data for the ($iteration-1) trace of the $file_count file\n\n\n\n\tignore_bytes = (char *)malloc(module_info_size);\n\tfor (module_index = 0; module_index < num_modules; module_index++)\n\t{\n\t\tif (module_results[module_index] != NEW_PATH_ON_SAME_FILE)\n\t\t\tcontinue;\n\n\t\tmemset(ignore_bytes, 0xff, module_info_size);\n\t\tint total_ignore_count = 0;\n\t\tfor (file_count = 0; file_count < num_files; file_count++)\n\t\t{\n\t\t\tfor (iteration = 1; iteration < num_iterations; iteration++)\n\t\t\t{\n\t\t\t\tint ignore_count = 0;\n\n\t\t\t\t//The calculations for cur_pos and prev_pos are done as such:\n\t\t\t\t//index * num_files * num_iterations = skip over the modules we've already checked\n\t\t\t\t//file_count * num_iterations = skip over the files we've already checked for this module\n\t\t\t\t//iteration = skip to the iteration that we're currently checking (prev_pos uses iteration - 1, since it's jumping to the previous iteration's instrumentation data)\n\t\t\t\t//and then it's all multiplied by the module_info_size since each one of the instrumentation data records that we're skipping is that many bytes large\n\t\t\t\tint prev_pos = ((module_index * num_files * num_iterations) + (file_count * num_iterations) + iteration - 1) * module_info_size;\n\t\t\t\tint cur_pos = ((module_index * num_files * num_iterations) + (file_count * num_iterations) + iteration) * module_info_size;\n\n\t\t\t\tfor (i = 0; i < module_info_size; i++)\n\t\t\t\t{\n\t\t\t\t\tif (module_infos[prev_pos + i] != module_infos[cur_pos + i])\n\t\t\t\t\t{\n\t\t\t\t\t\tif (ignore_bytes[i])\n\t\t\t\t\t\t\ttotal_ignore_count++;\n\t\t\t\t\t\tignore_bytes[i] = 0x00;\n\t\t\t\t\t\tignore_count++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tDEBUG_MSG(\"Module %s File %s iteration (%d/%d) ignore count %d total ignore count %d\", module_names[module_index], filenames[file_count], iteration - 1, iteration, ignore_count, total_ignore_count);\n\t\t\t}\n\t\t}\n\n\t\tif (ignore_bytes_dir)\n\t\t{\n\t\t\tmemset(filename, 0, sizeof(filename));\n\t\t\tsnprintf(filename, sizeof(filename) - 1, \"%s\\\\%s.dat\", ignore_bytes_dir, module_names[module_index]);\n\n/*\n\t\t\t//Swap the byte ordering here, so we don't have to in the hashing function later\n#if defined(_M_X64) || defined(__x86_64__)\n\t\t\tfor (i = 0; i < sizeof(ignore_bytes); i += sizeof(u64))\n\t\t\t\t*((u64 *)&ignore_bytes[i]) = _byteswap_uint64(*((u64 *)&ignore_bytes[i]));\n#else\n\t\t\tfor (i = 0; i < sizeof(ignore_bytes); i += sizeof(u32))\n\t\t\t\t*((u32 *)&ignore_bytes[i]) = SWAP32(*((u32 *)&ignore_bytes[i]));\n#endif\n*/\n\n\t\t\twrite_buffer_to_file(filename, ignore_bytes, module_info_size);\n\t\t}\n\t}\n\tfree(ignore_bytes);\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Print the results /////////////////////////////////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\tCRITICAL_MSG(\"Results:\");\n\tfor (module_index = 0; module_index < num_modules; module_index++)\n\t\tCRITICAL_MSG(\"Module %s had %s\", module_names[module_index], module_results_descriptions[module_results[module_index]]);\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Cleanup ///////////////////////////////////////////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t\n\t//free the generated info\n\tfree(module_results);\n\tfree(module_names);\n\tfree(module_infos);\n\tfor (file_count = 0; file_count < num_files; file_count++)\n\t\tfree(filenames[file_count]);\n\tfree(filenames);\n\n\t//Cleanup the objects and exit\n\tdriver->cleanup(driver->state);\n\tinstrumentation->cleanup(instrumentation_state);\n\tfree(driver);\n\tfree(instrumentation);\n\treturn 0;\n}\n"
  },
  {
    "path": "python/manager/app/__init__.py",
    "content": "import time, traceback, os, uuid\n\nfrom flask import Flask, jsonify, request, json\nfrom flask_sqlalchemy import SQLAlchemy\nfrom flask_restful import Api\n\nimport app.config as config_file\nfrom app.encoder import JSONEncoder\n\napp = Flask(__name__, static_folder='static', static_url_path='')\n\n\n\"\"\"\n    Setup DB Models\n\"\"\"\napp.config['SQLALCHEMY_DATABASE_URI'] = config_file.DATABASE_URI\napp.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False\napp.config['RESTFUL_JSON'] = {'cls': JSONEncoder}\napp.config['ERROR_404_HELP'] = False\napp.config['db'] = db = SQLAlchemy(app)\n\n# TODO verification of version via metadata table.\n\n\n\"\"\"\n    Setup Routes\n\"\"\"\nfrom controller.Hello import HelloCtrl\nfrom controller.Minimize import MinimizeCtrl\n# TODO The controllers below here still need to be finished\nfrom controller.File import FileCtrl\nfrom controller.Job import JobCtrl\nfrom controller.Target import TargetCtrl\nfrom controller.Config import ConfigCtrl\nfrom controller.Results import ResultsCtrl\n\napi = Api(app)\napi.add_resource(HelloCtrl, '/')\napi.add_resource(MinimizeCtrl, '/api/minimize')\napi.add_resource(FileCtrl, '/api/file', methods=['GET', 'POST'])\n\napi.add_resource(JobCtrl, '/api/job', methods=['GET', 'POST'])\napi.add_resource(JobCtrl, '/api/job/<int:id>', methods=['GET', 'PUT'], endpoint='jobctrl_id')\napi.add_resource(JobCtrl, '/api/boinc_job/<int:boinc_id>', methods=['GET', 'PUT'], endpoint='jobctrl_boincid')\napi.add_resource(ResultsCtrl, '/api/results', methods=['GET'])\napi.add_resource(ResultsCtrl, '/api/job/<int:job_id>/results', endpoint='resultsctrl_job')\napi.add_resource(ResultsCtrl, '/api/boinc_job/<int:boinc_id>/results', endpoint='resultsctrl_boincjob')\n\napi.add_resource(TargetCtrl, '/api/target', methods=['GET', 'POST'])\napi.add_resource(TargetCtrl, '/api/target/<int:id>', methods=['GET', 'PUT', 'DELETE'], endpoint='targetctrl_id')\n# api.add_resource(CrashBucketCtrl, '/api/bucket', '/api/bucket/<string:id>')\n\napi.add_resource(ConfigCtrl, '/api/config')\n#api.add_resource(UpdateCtrl, '/api/update/<string:hash>')\n\n"
  },
  {
    "path": "python/manager/app/config.py",
    "content": "import os\n# For feature testing, it's ok to use sqlite. SQLAlchemy will magic away the difference under the hood\nDATABASE_URI = \"sqlite:///../../../../moflow.db\"\n#DATABASE_URI = \"postgresql://localhost/killerbeez?user=killerbeez&password=killerbeez\"\nMANAGER_VERSION = 0.1\nCLIENT_FOLDER = \"client\"\nUPLOAD_FOLDER = 'static' + os.sep + 'upload'\n"
  },
  {
    "path": "python/manager/app/encoder.py",
    "content": "import json\n\nclass JSONEncoder(json.JSONEncoder):\n    def default(self, o):\n        try:\n            ts = o.timestamp()\n            return ts\n        except AttributeError:\n            pass\n\n        return super(JSONEncoder, self).default(o)\n"
  },
  {
    "path": "python/manager/controller/Config.py",
    "content": "from flask_restful import Resource, reqparse, fields, marshal_with, abort\nimport sys\n\nfrom model.FuzzingJob import fuzz_jobs\nfrom model.Config import FuzzingConfig\n\nfrom app import app\n\ndb = app.config['db']\n\nconfig_fields = {\n    'name': fields.String,\n    'target_id': fields.Integer,\n    'job_id': fields.Integer,\n    'value': fields.String,\n}\n\nclass ConfigCtrl(Resource):\n    def create(self, target_id, job_id, name, value):\n        config = FuzzingConfig(name, value, target=target_id, job=job_id)\n        db.session.add(config)\n        db.session.commit()\n        return config\n\n    def read(self, id):\n        # TODO allow for querying of configs\n        pass\n\n    @marshal_with(config_fields)\n    def post(self):\n        err = list()\n        target_id = None\n        job_id = None\n        parser = reqparse.RequestParser()\n        parser.add_argument('job_id', type=int)\n        parser.add_argument('target_id', type=int)\n        parser.add_argument('name', type=str)\n        parser.add_argument('value', type=str)\n        args = parser.parse_args()\n        if args.name is None or args.name == \"\":\n            err.append(\"no configuration name supplied; it is required\")\n        if args.value is None or args.value == \"\":\n            err.append(\"no configuration value supplied; it is required\")\n        # Determine if this is for a target or a job\n        if args.target_id is not None and args.target_id != 0:\n            target_id = args.target_id\n        if args.job_id is not None and args.job_id != 0:\n            job_id = args.job_id\n        if target_id is not None and job_id is not None:\n            err.append(\"target_id and job_id are mutually exclusive\")\n        if target_id is None and job_id is None:\n            err.append('must supply either a target_id or a job_id')\n        if len(err) != 0:\n            abort(400, err=', '.join(err))\n        # Ok, make one.\n        if target_id is None:\n            target_id = 0\n        if job_id is None:\n            job_id = 0\n        return self.create(target_id, job_id, args.name, args.value)\n\n    @marshal_with(config_fields)\n    def get(self):\n        target_id = None\n        job_id = None\n        parser = reqparse.RequestParser()\n        parser.add_argument('job_id', type=int)\n        parser.add_argument('target_id', type=int)\n        parser.add_argument('name', type=str)\n        args = parser.parse_args()\n        # Determine if this is for a target or a job\n        if args.target_id is not None and args.target_id != 0:\n            target_id = args.target_id\n        if args.job_id is not None and args.job_id != 0:\n            job_id = args.job_id\n        if target_id is not None and job_id is not None:\n            abort(400, err='target_id and job_id are mutually exclusive')\n\n        query = db.session.query(FuzzingConfig)\n        if args.name is not None:\n            query = query.filter_by(name=args.name)\n        if job_id is not None:\n            query = query.filter_by(job_id=job_id)\n        if target_id is not None:\n            query = query.filter_by(target_id=target_id)\n        configs = query.all()\n        #configs = [config.as_dict() for config in configs]\n        return configs\n"
  },
  {
    "path": "python/manager/controller/File.py",
    "content": "import base64\nimport logging\nimport os.path\nimport sys\nimport urllib.parse\n\nfrom flask import request, make_response, json\nfrom flask_restful import Resource, reqparse, fields, marshal_with, abort\n\nfrom app import app\nfrom lib import boinc\nfrom lib import errors\nfrom model.FuzzingJob import fuzz_jobs\n\ndb = app.config['db']\nlogger = logging.getLogger(__name__)\n\nfile_fields = {\n    'filename': fields.String(),\n    # TODO: this should be the whole URL\n    'path': fields.String(),\n    'hash': fields.String(),\n}\n\nclass FileCtrl(Resource):\n    def create(self, contents):\n        try:\n            filename = boinc.filename_to_download_path(\n                boinc.stage_file('input', contents))\n        except errors.Error:\n            logger.exception('unable to stage file')\n            abort(400, err='unable to stage file')\n\n        return {'filename': os.path.basename(filename), 'path': filename,\n                'hash': filename.split('_')[-1]}, 200\n\n    def _get_hash(self, content):\n        return hashlib.md5(content).hexdigest()\n\n    @marshal_with(file_fields)\n    def search(self, hash=None, content=None):\n        if hash is not None:\n            filename = boinc.get_filename('input', hash)\n        elif content is not None:\n            hash = self._get_hash(content)\n            filename = boinc.get_filename('input', hash)\n        else:\n            abort(400, err='no filtering criteria provided')\n\n        if os.path.exists(filename):\n            with open(filename, 'rb') as input_file:\n                if content is not None and input_file.read() != content:\n                    abort(400, err='file does not match specified contents')\n            return [{'filename': os.path.basename(filename),\n                     'path': boinc.filename_to_download_path(filename),\n                     'hash': hash}]\n        else:\n            # Nothing valid found\n            abort(404, err='not found')\n\n    def _content_decode(self, args):\n        if args.encoding == 'url':\n            content = urllib.parse.unquote_to_bytes(args.content)\n        elif args.encoding == 'base64':\n            try:\n                content = base64.b64decode(args.content)\n            except binascii.Error:\n                abort(400, err='Invalid base64 encoding')\n        else:\n            abort(400, err='Invalid encoding (accepted values are \"url\" and \"base64\")')\n\n        if args.hash:\n            hash = self._get_hash(content)\n            if hash != args.hash:\n                abort(400, err='Content does not match provided hash')\n\n        return content\n\n    @marshal_with(file_fields)\n    def post(self):\n        parser = reqparse.RequestParser()\n        parser.add_argument('encoding', type=str, default='url')\n        parser.add_argument('content', type=str, required=True)\n        parser.add_argument('hash', type=str)\n        args = parser.parse_args()\n\n        content = self._content_decode(args)\n        return self.create(content)\n\n    def get(self):\n        \"\"\"\n        Query the file DB for a matching file\n        :return: Dict containing the info on the file and 200, if present, else error message and 400 or 404\n        \"\"\"\n        parser = reqparse.RequestParser()\n        parser.add_argument('encoding', type=str, default='url')\n        parser.add_argument('content', type=str)\n        parser.add_argument('hash', type=str)\n        args = parser.parse_args()\n\n        content = self._content_decode(args) if args.content else None\n        return self.search(args.hash, content)\n"
  },
  {
    "path": "python/manager/controller/Hello.py",
    "content": "from flask_restful import Resource\n\n\nclass HelloCtrl(Resource):\n    def get(self):\n        return {'hello': 'world'}\n\n"
  },
  {
    "path": "python/manager/controller/Job.py",
    "content": "import datetime\n\nfrom flask_restful import Resource, reqparse, fields, marshal_with, abort\n\nfrom lib import boinc\nfrom lib import fuzzer\nfrom model.FuzzingJob import fuzz_jobs\nfrom model.FuzzingTarget import targets\nfrom model.job_inputs import job_inputs\n\nfrom app import app\nimport logging\n\ndb = app.config['db']\nlogger = logging.getLogger(__name__)\n\n\njob_fields = {\n    'job_id': fields.Integer(),\n    'boinc_id': fields.Integer(),\n    'job_type': fields.String(),\n    'status': fields.String(),\n    'mutator_state': fields.String(),\n    'mutator': fields.String(),\n    'instrumentation_type': fields.String(),\n    'driver': fields.String(),\n    'assign_time': fields.DateTime(dt_format='iso8601'),\n    'end_time': fields.DateTime(dt_format='iso8601'),\n    'input_ids': fields.List(fields.Integer(attribute='input_id'), attribute='inputs'),\n    'seed_file': fields.String(),\n}\n\nclass JobCtrl(Resource):\n    def read(self, id=None, boinc_id=None):\n        \"\"\"\n        Fetch the db entry for a given job id or boinc job id, or error if not found\n        :param id: job_id of the job to be fetched\n        :param boinc_id: boinc_id of the job to be fetched\n        :return: list containing the dictionary representing the job object, or a dictionary indicating error.\n        \"\"\"\n        query = fuzz_jobs.query\n        if id is not None:\n            query = query.filter_by(job_id=id)\n        if boinc_id is not None:\n            query = query.filter_by(boinc_id=boinc_id)\n        job = query.first()\n        if job is None:\n            abort(404, err=\"not found\")\n        return job, 200\n\n    def readAll(self, target_id):\n        \"\"\"\n        Get all jobs associated with the specified target_id, or error if not found\n        :param target_id: target_id for which all jobs should be returned\n        :return: list containing all jobs for the given target, or a dictionary indicating error.\n        \"\"\"\n        target = targets.query.filter_by(target_id=target_id).first()\n        if target is None:\n            abort(404, err=\"not found\")\n        jobs = fuzz_jobs.query.filter_by(target_id=target_id).all()\n        #jobs = [{'job': job} for job in jobs]\n        return jobs, 200\n\n    def create(self, data):\n        \"\"\"\n        Create a new job.\n        :param data: dictionary of attributes for the new job object\n        :return: newly created job object on 200, error dictionary on 400\n        \"\"\"\n        type = data.job_type\n        if type is None:\n            # Default to \"fuzz\" type\n            type = \"fuzz\"\n        if data.target_id is None or data.target_id == 0:\n            abort(400, err=\"target_id must be supplied and non-zero\")\n        else:\n            # verify the target exists\n            target = targets.query.filter_by(target_id=data.target_id).first()\n            if target is None:\n                abort(400, err=\"supplied target_id not found\")\n        if data.input_files:\n            for input_file in data.input_files:\n                if not os.path.exists(boinc.path_for_file(input_file)):\n                    abort(400, err=\"supplied input_file not found\")\n        try:\n            job = fuzz_jobs(type, data.target_id,\n                            mutator=data.mutator,\n                            mutator_state=data.mutator_state,\n                            instrumentation_type=data.instrumentation_type,\n                            driver=data.driver, seed_file=data.seed_file,\n                            iterations=data.iterations\n                            )\n            if data.input_files:\n                job.inputs = [job_inputs(input_file=input_file) for input_file in data.input_files]\n            db.session.add(job)\n            db.session.commit()\n        except Exception as e:\n            logger.exception('failed to add job')\n            abort(400, err=\"invalid request\")\n\n        mutator_options = job.lookup_config('mutator', data.mutator)\n        instrumentation_options = job.lookup_config('instrumentation', data.instrumentation_type)\n        driver_options = job.lookup_config('driver', data.driver)\n        shell_format = job.lookup_config('platform', 'shell_format')\n\n        command_line = fuzzer.format_cmdline(\n            job.driver, job.instrumentation_type, job.mutator, job.iterations,\n            shell_format,\n            driver_options=driver_options,\n            instrumentation_options=instrumentation_options,\n            mutator_options=mutator_options)\n        logger.debug('Submitting job with command line: %s', command_line)\n        job_id = boinc.submit_job(str(target), command_line, seed_file=job.seed_file)\n        job.boinc_id = job_id\n        db.session.commit()\n\n        return job, 200\n\n\n    def update(self, data, id=None, boinc_id=None):\n        query = fuzz_jobs.query\n        if id is not None:\n            query = query.filter_by(job_id=id)\n        if boinc_id is not None:\n            query = query.filter_by(boinc_id=boinc_id)\n        job = query.first()\n        if job is None:\n            abort(404, err='Unknown job ID')\n\n        if data.seed_file is not None:\n            job.seed_file = data.seed_file\n        if data.status is not None:\n            job.status = data.status\n        db.session.commit()\n        return job, 200\n\n    @marshal_with(job_fields)\n    def get(self, id=None, boinc_id=None):\n        \"\"\"\n        Request either a single job (by id/boinc_id) or all jobs for a target\n        (by target_id)\n        :return: List of jobs that match the query on 200; error dict on 400\n        \"\"\"\n        parser = reqparse.RequestParser()\n        parser.add_argument(\"target_id\", type=int)\n\n        args = parser.parse_args()\n        # The two options are mutually exclusive\n        if (id is not None or boinc_id is not None) and args.target_id is not None:\n            abort(400, err='id/boinc_id and target_id are mutually exclusive')\n        # But at least one must be supplied\n        if id is None and boinc_id is None and args.target_id is None:\n            abort(400, err='either id, boinc_id, or target_id must be supplied')\n        if id is not None or boinc_id is not None:\n            return self.read(id, boinc_id)\n        else:\n            return self.readAll(args.target_id)\n\n    @marshal_with(job_fields)\n    def post(self):\n        \"\"\"\n        Create a new job.\n        :return: The job created on 200, error on 400\n        \"\"\"\n        parser = reqparse.RequestParser()\n        parser.add_argument(\"job_type\", type=str)\n        parser.add_argument(\"target_id\", type=int, required=True)\n        parser.add_argument(\"mutator\", type=str, required=True)\n        parser.add_argument(\"mutator_state\", type=str)\n        parser.add_argument(\"instrumentation_type\", type=str, required=True)\n        parser.add_argument(\"driver\", type=str, required=True)\n        parser.add_argument(\"input_files\", type=str, action='append', location='json')\n        parser.add_argument(\"seed_file\", type=str, required=True)\n        parser.add_argument(\"iterations\", type=int, required=True)\n        args = parser.parse_args()\n        return self.create(args)\n\n    @marshal_with(job_fields)\n    def put(self, id=None, boinc_id=None):\n        \"\"\"\n        Update a job.\n        \"\"\"\n        if id is None and boinc_id is None:\n            abort(400, err='one of id and boinc_id must be provided')\n\n        parser = reqparse.RequestParser()\n        parser.add_argument(\"seed_file\", type=str)\n        parser.add_argument(\"status\", type=str)\n        args = parser.parse_args()\n        return self.update(args, id, boinc_id)\n"
  },
  {
    "path": "python/manager/controller/Log.py",
    "content": "from flask_restful import Resource, reqparse\nfrom app import app\nfrom app import logFile\n\ndb = app.config['db']\n\n\nclass LogCtrl(Resource):\n    def post(self):\n        parser = reqparse.RequestParser()\n        parser.add_argument('message', required=True, location='json')\n        args = parser.parse_args()\n        with open(logFile, 'a') as f:\n            f.write(args['message'])\n\n        return { \"msg\" : \"log created successfully\" }, 201\n\n    def get(self):\n        try:\n            log = open(logFile, 'r').read()\n        except:\n            return {\"err\": \"not found\"}, 404\n\n        return { \"log\" : log }, 200"
  },
  {
    "path": "python/manager/controller/Minimize.py",
    "content": "import collections, operator\nfrom app import app\nfrom flask_restful import Resource, reqparse\nfrom flask import request\nfrom model.tracer_info import tracer_info\nfrom sqlalchemy.sql.expression import func\n\ndb = app.config['db']\n\ndef minimize(target_id, num_files_per_edge = None):\n    if num_files_per_edge == None:\n        num_files_per_edge = 1\n\n    # get the data\n    query = db.session.query(tracer_info.target_id, tracer_info.from_edge, tracer_info.to_edge, tracer_id.input_file) \\\n                .filter_by(target_id=target_id)\n    data = query.all()\n\n    # Group the data by edge\n    edges = collections.defaultdict(list)\n    edges_per_input = collections.defaultdict(list)\n    for target_id, from_edge, to_edge, input_file in data:\n        edges[(int(from_edge), int(to_edge))].append(input_file)\n        edges_per_input[input_file].append((from_edge, to_edge))\n\n    edges_by_popularity = sorted(edges, key=lambda k: len(edges[k]), reverse=True)\n\n    already_have = collections.defaultdict(int)\n    working_set = []\n    for edge in edges_by_popularity:\n        if already_have[edge] > num_files_per_edge:\n            continue\n\n        files = edges[edge][:(num_files_per_edge - already_have[edge])]\n        working_set.extend(files)\n        for file in files:\n            for edge in edges_per_input[file]:\n                already_have[edge] += 1\n\n    return set(working_set)\n\nclass MinimizeCtrl(Resource):\n    def get(self):\n        parser = reqparse.RequestParser()\n        parser.add_argument('target_id', type=int, required=True)\n        parser.add_argument('num_files_per_edge', type=int)\n        args = parser.parse_args()\n        return list(minimize(args.target_id, args.num_files_per_edge)) # The return value must be JSON serializable, so turn it back to a list\n\nif __name__ == \"__main__\":\n    import argparse\n\n    parser = argparse.ArgumentParser(description=\"Calculate the working set for a given target\")\n    parser.add_argument(\"target_id\", type=int, help=\"The target id to get the working set of\")\n    args = parser.parse_args()\n\n    files = minimize(args.target_id, args.s)\n    print(\"Working set: {}\".format(\", \".join(files)))\n"
  },
  {
    "path": "python/manager/controller/Results.py",
    "content": "from flask_restful import Resource, reqparse, fields, marshal_with, abort\nfrom model.FuzzingJob import fuzz_jobs\nfrom model.FuzzingResults import results\nfrom app import app\n\n\ndb = app.config['db']\n\nresult_fields = {\n    'result_id': fields.Integer(),\n    'job_id': fields.Integer(),\n    'repro_file': fields.String(),\n    'result_type': fields.String(),\n}\n\nclass ResultsCtrl(Resource):\n    def create(self, data, job_id=None, boinc_id=None):\n        if job_id is not None:\n            job = fuzz_jobs.query.get(job_id)\n            if job is None:\n                abort(404, err=\"job not found\")\n        elif boinc_id is not None:\n            job = fuzz_jobs.query.filter_by(boinc_id=boinc_id).first()\n            if job is None:\n                abort(404, err=\"boinc_job not found\")\n            job_id = job.job_id\n\n        try:\n            result = results(job_id, data['repro_file'], type=data['result_type'])\n            db.session.add(result)\n            db.session.commit()\n        except Exception as e:\n            abort(400, err=\"invalid request\")\n\n        return result, 201\n\n    # TODO if needed\n    def read(self, job_id=None):\n        query = results.query\n        if job_id:\n            query = query.filter_by(job_id=job_id)\n        job_results = query.all()\n        # TODO: maybe don't error depending on job status\n        if not job_results:\n            abort(404, err=\"not found\")\n        return job_results, 200\n\n    # TODO if needed\n    def update(self, id, data):\n        crash = FuzzingCrash.query.filter_by(id=id).first()\n        if crash is None:\n            abort(404, err=\"not found\")\n\n\n        job = FuzzingJob.query.filter_by(id=data['job_id']).first()\n        if job is not None:\n            crash.job = job\n\n        if data['repro_file'] is not None:\n            crash.repro_file= data['dump_file']\n\n        if data['dump_file'] is not None:\n            crash.dump_file = data['dump_file']\n\n        if data['dbg_file'] is not None:\n            crash.dbg_file = data['dbg_file']\n        try:\n            db.session.commit()\n        except Exception as e:\n            abort(400, err=\"invalid request\")\n\n        return crash.as_dict(), 201\n\n\n    # TODO if needed\n    def delete(self, id):\n        crash = FuzzingCrash.query.filter_by(id=id).first()\n        if crash is None:\n            abort(404, err=\"not found\")\n        try:\n            db.session.delete(crash)\n            db.session.commit()\n        except Exception as e:\n            abort(400, err=\"invalid request\")\n\n        return {\"msg\" : \"record removed successfully\"}, 201\n\n    def list(self, offset=None, limit=None, job_id=None, boinc_id=None, repro_file=None):\n        query = results.query\n        # results filters\n        if job_id:\n            query = query.filter_by(job_id=job_id)\n        if repro_file:\n            query = query.filter_by(repro_file=repro_file)\n\n        # filters requiring join with fuzz_jobs\n        if boinc_id:\n            query = query.join(fuzz_jobs).filter(fuzz_jobs.boinc_id == boinc_id)\n\n        if offset is None:\n            offset = 0\n        if limit is None:\n            limit = 20\n        crashes = query.offset(offset).limit(limit).all()\n        return crashes, 200\n\n    @marshal_with(result_fields)\n    def get(self, job_id=None, boinc_id=None):\n        parser = reqparse.RequestParser()\n        parser.add_argument('offset', type=int)\n        parser.add_argument('limit', type=int)\n        parser.add_argument('repro_file', type=str)\n        args = parser.parse_args()\n        return self.list(args['offset'], args['limit'], job_id, boinc_id, args['repro_file'])\n\n    @marshal_with(result_fields)\n    def post(self, job_id=None, boinc_id=None):\n        parser = reqparse.RequestParser()\n        parser.add_argument('repro_file', required=True, location='json')\n        parser.add_argument('result_type', required=True, location='json')\n        parser.add_argument('parent_file', location='json')\n        return self.create(parser.parse_args(), job_id, boinc_id)\n"
  },
  {
    "path": "python/manager/controller/Status.py",
    "content": "from flask_restful import Resource\nfrom datetime import datetime\n#from model.FuzzingJobState import FuzzingJobState\nfrom model.FuzzingJob import fuzz_jobs\n#from model.FuzzingHost import FuzzingHost\nfrom model.FuzzingCrash import results\n\nclass StatusCtrl(Resource):\n    def get(self):\n        status_active = FuzzingJobState.query.filter_by(name='Active').first()\n        status_completed = FuzzingJobState.query.filter_by(name='Completed').first()\n        status_queued = FuzzingJobState.query.filter_by(name='Queued').first()\n\n        total_job_count = FuzzingJob.query.count()\n        active_job_count = FuzzingJob.query.filter_by(state_id=status_active.id).count()\n        completed_job_count = FuzzingJob.query.filter_by(state_id=status_completed.id).count()\n        queued_job_count = FuzzingJob.query.filter_by(state_id=status_queued.id).count()\n        crash_count = FuzzingCrash.query.count()\n        node_count = FuzzingHost.query.count()\n        return {\n            'total_job_count': total_job_count,\n            'active_job_count': active_job_count,\n            'completed_job_count': completed_job_count,\n            'queued_job_count': queued_job_count,\n            'crash_count': crash_count,\n            'node_count': node_count,\n            'serverTime' : str(datetime.now())\n        }, 200\n"
  },
  {
    "path": "python/manager/controller/Target.py",
    "content": "import logging\n\nfrom flask_restful import Resource, reqparse, fields, marshal_with, abort\nfrom model.FuzzingTarget import targets\n#from model.FuzzingArch import FuzzingArch\n#from model.FuzzingPlatform import FuzzingPlatform\n#from model.FuzzingConfig import FuzzingConfig\nfrom app import app\n\n\nlogger = logging.getLogger(__name__)\ndb = app.config['db']\n\ntarget_fields = {\n    'id': fields.Integer(attribute='target_id'),\n    'platform': fields.String,\n    'target_executable': fields.String,\n}\n\n\nclass TargetCtrl(Resource):\n    def create(self, data):\n        try:\n            target = targets(data['platform'], data['target_executable'])\n            db.session.add(target)\n            db.session.commit()\n        except Exception:\n            logger.exception('Error creating target')\n            abort(400, err=\"invalid request\")\n\n        return target, 201\n\n    def read(self, id):\n        target = targets.query.get(id)\n        if target is None:\n            abort(404, err=\"not found\")\n        return target\n\n    def update(self, id, data):\n        target = targets.query.get(id)\n        if target is None:\n            abort(404, err=\"not found\")\n\n        target.platform = data['platform']\n        target.target_executable = data['target_executable']\n        try:\n            db.session.commit()\n        except Exception as e:\n            abort(400, err=\"invalid request\")\n\n        return target, 200\n\n    def list(self, offset=0, limit=10000):\n        targets_found = targets.query.offset(offset).limit(limit).all()\n        return targets_found\n\n    @marshal_with(target_fields)\n    def get(self, id=None):\n        parser = reqparse.RequestParser()\n        parser.add_argument('offset', type=int)\n        parser.add_argument('limit', type=int)\n        args = parser.parse_args()\n        if id is None:\n            if args['offset'] is not None and args['limit'] is not None:\n                return self.list(args['offset'], args['limit'])\n            else:\n                return self.list()\n        else:\n            return self.read(id)\n\n    @marshal_with(target_fields)\n    def post(self):\n        parser = reqparse.RequestParser()\n        parser.add_argument('target_executable', required=True, location='json')\n        parser.add_argument('platform', required=True, location='json')\n        return self.create(parser.parse_args())\n\n    @marshal_with(target_fields)\n    def put(self, id):\n        parser = reqparse.RequestParser()\n        parser.add_argument('target_executable', required=True, location='json')\n        parser.add_argument('platform', required=True, location='json')\n        return self.update(id, parser.parse_args())\n\n    def delete(self, id):\n        target = targets.query.get(id)\n        if target is None:\n            return {\"err\": \"not found\"}, 404\n        try:\n            db.session.delete(target)\n            db.session.commit()\n        except Exception as e:\n            return {\"err\": \"invalid request\"}, 400\n\n        return {\"msg\" : \"record removed successfully\"}, 200\n"
  },
  {
    "path": "python/manager/controller/Update.py",
    "content": "from flask_restful import Resource\nfrom flask import request\nfrom app.config import CLIENT_FOLDER\nimport os, zipfile, hashlib\n\nclass UpdateCtrl(Resource):\n    def get(self, hash):\n        path = 'static' + os.sep + 'client.zip'\n        try:\n            os.remove(path)\n        except:\n            None\n        zip = zipfile.ZipFile(path, 'w', zipfile.ZIP_DEFLATED)\n        for root, dirs, files in os.walk(CLIENT_FOLDER):\n            for f in files:\n                zip.write(os.path.join(root, f))\n        zip.close()\n\n        client = open(path).read()\n\n        if hash == hashlib.md5(client).hexdigest():\n            return {\"err\": \"invalid request\"}, 400\n        else:\n            return {\"url\": request.url_root + path}, 200\n\n"
  },
  {
    "path": "python/manager/controller/__init__.py",
    "content": ""
  },
  {
    "path": "python/manager/lib/__init__.py",
    "content": ""
  },
  {
    "path": "python/manager/lib/boinc.py",
    "content": "import hashlib\nimport os.path\nimport re\nimport subprocess\nimport xml.etree.ElementTree as ET\n\nfrom app import app\nfrom lib import errors\n\ndef clean_download_path(path):\n    \"\"\"Turns an absolute path in the BOINC download dir into a relative path.\n\n    This allows paths to be used as URL components, and doesn't expose\n    unnecessary server configuration data.\n    \"\"\"\n    _, _, relpath = path.rpartition('/download/')\n    return relpath\n\n\ndef dir_hier_path(filename):\n    \"\"\"Convert a filename to an absolute path in the BOINC download tree.\n\n    In the download tree, files are stored in a subdirectory based on the hash\n    of the filename. This function calls out to BOINC to find the correct path\n    for a given filename.\n    \"\"\"\n    abspath = subprocess.check_output(\n        ['bin/dir_hier_path', filename], cwd=app.config['BOINC_PROJECT_DIR'])\n    return abspath.strip().decode('utf8')\n\n\ndef filename_to_download_path(filename):\n    \"\"\"Convert a filename to a path relative to the download directory.\n\n    Given a filename, returns a path that can be appended to the URL of the\n    download directory to download that file.\n    \"\"\"\n    abspath = dir_hier_path(filename)\n    return clean_download_path(abspath)\n\n\ndef stage_file(prefix, contents):\n    filename = _filename_for_contents(prefix, contents)\n    abspath = dir_hier_path(filename)\n    if os.path.exists(abspath):\n        with open(abspath, 'rb') as existing:\n            if existing.read() != contents:\n                raise errors.InternalError(\n                    'Attempted to stage {} with differing contents'.format(filename))\n    else:\n        with open(abspath, 'wb') as new_file:\n            new_file.write(contents)\n        os.chmod(abspath, 0o755)\n    return abspath\n\ndef get_filename(prefix, hash):\n    return dir_hier_path('{}_{}'.format(prefix, hash))\n\ndef _filename_for_contents(prefix, contents):\n    file_hash = hashlib.md5(contents).hexdigest()\n    return '{}_{}'.format(prefix, file_hash)\n\n\ndef submit_job(appname, cmdline, seed_file=None, seed_contents=None):\n    if seed_file and seed_contents:\n        raise errors.InternalError(\n            'Only one of seed_file and seed_contents can be specified')\n\n    if seed_contents:\n        seed_file = stage_file('input', seed_contents)\n    elif not seed_file:\n        raise errors.InternalError('No seed specified')\n\n    # TODO: should the cmdline files have guaranteed unique filenames?\n    cmd_contents = cmdline.encode('utf8')\n    cmd_file = os.path.basename(stage_file('cmdline', cmd_contents))\n\n    create_work_args = ['bin/create_work', '--appname', appname, '--verbose',\n                        seed_file, cmd_file]\n    try:\n        result = subprocess.check_output(\n            create_work_args, cwd=app.config['BOINC_PROJECT_DIR'],\n            stderr=subprocess.STDOUT)\n    except subprocess.CalledProcessError as e:\n        raise errors.BoincError('create_work returned error: {}'.format(e.output))\n\n    for line in result.splitlines():\n        match = re.match(rb'created workunit; .*, ID ([0-9]+)', line)\n        if match:\n            return int(match.group(1))\n\n    raise errors.BoincError('Could not find ID in create_work output: {}'.format(result))\n"
  },
  {
    "path": "python/manager/lib/errors.py",
    "content": "class Error(Exception):\n    \"\"\"Base class for all Killerbeez exceptions\"\"\"\n\nclass InternalError(Error):\n    \"\"\"Internal code used incorrectly\"\"\"\n\nclass BoincError(Error):\n    \"\"\"Error interacting with BOINC\"\"\"\n\nclass InputError(Error):\n    \"\"\"Error from invalid input\"\"\"\n"
  },
  {
    "path": "python/manager/lib/fuzzer.py",
    "content": "import shlex\n\nfrom lib import errors\n\n\ndef _create_state_file(state):\n    # TODO: possibly obsolete\n    tmpdir = os.path.join(self.outdir, 'tmp')\n    os.makedirs(tmpdir, exist_ok=True)\n    with tempfile.NamedTemporaryFile(prefix=tmpdir, delete=False) as f:\n        f.write(contents.encode('utf-8'))\n        return f.name\n\n\ndef bat_escape(args):\n    \"\"\"Quote a set of arguments for a windows command line.\n\n    Double-quote each argument, and backslash-escape any backslashes before\n    double quotes and the double quotes themselves. Finally, put a ^ before\n    each shell metacharacter so it will survive cmd.exe. Based on the algorithm in\n    https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/\n    \"\"\"\n    escaped_args = []\n    for arg in args:\n        escaped_parts = ['\"']\n        num_backslashes = 0\n        for c in arg:\n            if c == '\\\\':\n                num_backslashes += 1\n            elif c == '\"':\n                escaped_parts.append('\\\\'*(2*num_backslashes+1) + c)\n                num_backslashes = 0\n            else:\n                escaped_parts.append('\\\\'*num_backslashes + c)\n                num_backslashes = 0\n        escaped_parts.append('\\\\'*(2*num_backslashes) + '\"')\n        escaped_args.append(''.join(escaped_parts))\n    final_cmdline = ' '.join(escaped_args)\n\n    # That is what we want to be passed to CreateProcess; however, cmd is going\n    # to mangle it first so we must escape all chars it considers special.\n    metachars = ['(', ')', '%', '!', '^', '\"', '<', '>', '&', '|']\n    for char in metachars:\n        final_cmdline = final_cmdline.replace(char, '^'+char)\n    return '%1 {}'.format(final_cmdline)\n\n\ndef sh_escape(args):\n    escaped_args = [shlex.quote(arg) for arg in args]\n    # The >&2 redirects stdout to stderr, which will make it show up in the\n    # BOINC UI\n    return '$1 >&2 {}'.format(' '.join(escaped_args))\n\n\ndef format_cmdline(\n        driver, instrumentation, mutator, iterations, shell_format,\n        driver_options=None, instrumentation_options=None,\n        mutator_options=None, instrumentation_state=None, mutator_state=None):\n    # BOINC takes care of renaming the seed file for us\n    args = [driver, instrumentation, mutator, '-sf', 'seed', '-n', str(iterations)]\n    if instrumentation_options:\n        args.extend([\"-i\", instrumentation_options])\n    if mutator_options:\n        args.extend([\"-m\", mutator_options])\n    if driver_options:\n        args.extend([\"-d\", driver_options])\n    # TODO - we can't create files client-side so we have to have a way to\n    # bundle these\n    # if instrumentation_state:\n    #     filename = self.create_state_file(instrumentation_state)\n    #     args.extend([\"-isf\", filename])\n    # if mutator_state):\n    #     filename = self.create_state_file(mutator_state)\n    #     args.extend([\"-msf\", filename])\n\n    # In order to make this command line work on the target platform, it needs\n    # to be escaped. The shell_format value comes from a config option\n    # platform_opts_shell_format, however it could also be a column of the\n    # target, or we could just choose a format based on the target's platform.\n    # When we are working on automated target adding, we should revisit this to\n    # see what works best.\n    if shell_format == 'sh':\n        return sh_escape(args)\n    elif shell_format == 'bat':\n        return bat_escape(args)\n    else:\n        if shell_format:\n            raise errors.InputError('Unknown shell_format \"{}\"'.format(shell_format))\n        else:\n            raise errors.InputError(\n                'This target has no shell_format configured. Set the '\n                'platform_opts_shell_format config option.')\n"
  },
  {
    "path": "python/manager/model/Config.py",
    "content": "from app import app\nfrom model.FuzzingTarget import targets\nfrom model.FuzzingJob import fuzz_jobs\ndb = app.config['db']\n\nclass FuzzingConfig(db.Model):\n    config_id = db.Column(db.Integer, primary_key=True, nullable=False)\n    target_id = db.Column(db.Integer, db.ForeignKey('targets.target_id'))\n    job_id = db.Column(db.Integer, db.ForeignKey('fuzz_jobs.job_id'))\n    name = db.Column(db.String(), nullable=False,)\n    value = db.Column(db.String(), nullable=False)\n\n    target = db.relationship('targets', back_populates='configs')\n    job = db.relationship('fuzz_jobs', back_populates='configs')\n\n    def __init__(self, config_name, config_value, config_id=None, target=0, job=0):\n        # TODO: sanity check that target and job aren't both 0?\n        # TODO: The check is already done in the post, but should san check it here anyway.\n        self.config_id = config_id\n        self.target_id = target\n        self.job_id = job\n        self.name = config_name\n        self.value = config_value\n\n    def as_dict(self):\n        out = {c.name: str(getattr(self, c.name)) for c in self.__table__.columns}\n        return out\n"
  },
  {
    "path": "python/manager/model/FuzzingJob.py",
    "content": "from app import app\nfrom datetime import *\n\nfrom sqlalchemy.orm.collections import attribute_mapped_collection\n\ndb = app.config['db']\n\n\nclass fuzz_jobs(db.Model):\n    job_id = db.Column(db.Integer(), primary_key=True, nullable=False)\n    boinc_id = db.Column(db.Integer())\n    job_type = db.Column(db.String())\n    status = db.Column(db.String()) # unassigned, assigned, complete\n    mutator_state = db.Column(db.String()) # json of the current state\n    mutator = db.Column(db.String())\n    instrumentation_type = db.Column(db.String())\n    assign_time = db.Column(db.DateTime())\n    end_time = db.Column(db.DateTime())\n    driver = db.Column(db.String())\n    target_id = db.Column(db.Integer(), db.ForeignKey('targets.target_id'))\n    seed_file = db.Column(db.String())\n    iterations = db.Column(db.Integer())\n\n    target = db.relationship('targets')\n    inputs = db.relationship('job_inputs', back_populates='job')\n    configs = db.relationship('FuzzingConfig', back_populates='job',\n                              collection_class=attribute_mapped_collection('name'))\n\n    def __init__(self,\n                 type,\n                 target_id,\n                 mutator=None, mutator_state=None,\n                 instrumentation_type=None,\n                 status='unassigned',\n                 job_id=None,\n                 assign_time=None, driver=None, seed_file=None,\n                 iterations=None):\n        self.job_id = job_id\n        self.job_type = type\n        self.target_id = target_id\n        self.mutator = mutator\n        self.mutator_state = mutator_state\n        self.status = status\n        self.instrumentation_type = instrumentation_type\n        self.assign_time = assign_time\n        self.end_time = None\n        self.driver = driver\n        self.seed_file = seed_file\n        self.iterations = iterations\n\n    def lookup_config(self, config_type, config_name):\n        \"\"\"\n        Gets options configured for a specific instrumentation, mutator, or\n        driver. Looks for job-specific configs first, then falls back to target\n        configs.\n        :param job: fuzz_jobs, the job the configs should apply to.\n        :param config_type: str, the type of object to get configs for, such as\n        'instrumentation', 'mutator', or 'driver'.\n        :param config_name: str, the name of the mutator, instrumentation, or\n        driver to get configs for.\n        :return: str if any configuration is stored for the given\n        instrumentation/mutator/driver type, otherwise None.\n        \"\"\"\n        config_fullname = \"{}_opts_{}\".format(config_type, config_name)\n        # First, check job-specific config\n        config = self.configs.get(config_fullname)\n        if config is None:\n            # If nothing, fall back to target-specific config\n            config = self.target.configs.get(config_fullname)\n        if config is None:\n            return None\n        # if we got a result from either of the queries, get the string value\n        return config.value\n\n    def as_dict(self):\n        return {c.name: getattr(self, c.name) for c in self.__table__.columns}\n"
  },
  {
    "path": "python/manager/model/FuzzingResults.py",
    "content": "from app import app\nfrom datetime import *\n\ndb = app.config['db']\n\n'''\nFor simplicity I am just using one simple model for each crash and not using the previous db schema. We may want to move\nthe crash system to a bugzilla friendly format. Based on the decision on the design of crash analysis (clientside or serverside)\n, improvement could be made.\n'''\n\n\nclass results(db.Model):\n    result_id = db.Column(db.Integer, primary_key=True)\n    job_id = db.Column(db.Integer, db.ForeignKey('fuzz_jobs.job_id'), nullable=False)\n    repro_file = db.Column(db.String, nullable=False)\n    result_type = db.Column(db.String) # 'hang' or 'crash'\n\n    def __init__(self, job_id, repro, type='crash'):\n        self.job_id = job_id\n        self.repro_file = repro\n        self.result_type = type\n\n    def as_dict(self):\n        return {c.name: str(getattr(self, c.name)) for c in self.__table__.columns}\n"
  },
  {
    "path": "python/manager/model/FuzzingTarget.py",
    "content": "from app import app\n\nfrom sqlalchemy.orm.collections import attribute_mapped_collection\n\ndb = app.config['db']\n\nclass targets(db.Model):\n    target_id = db.Column(db.Integer, primary_key=True, nullable=False)\n    platform = db.Column(db.String(), nullable=False)\n    target_executable = db.Column(db.String(), nullable=False)\n\n    configs = db.relationship('FuzzingConfig', back_populates='target',\n                              collection_class=attribute_mapped_collection('name'))\n\n    def __init__(self, platform, exe):\n        self.platform = platform\n        self.target_executable = exe\n\n    def __str__(self):\n        return '{}_{}'.format(self.target_executable, self.platform)\n\n    def as_dict(self):\n        return {c.name: str(getattr(self, c.name)) for c in self.__table__.columns}\n"
  },
  {
    "path": "python/manager/model/__init__.py",
    "content": ""
  },
  {
    "path": "python/manager/model/instrumentation_state.py",
    "content": "from app import app\n\ndb = app.config['db']\n\nclass instrumentation_state(db.Model):\n    instrumentation_type = db.Column(db.String(), primary_key=True, nullable=False)\n    state = db.Column(db.String())\n    target_id = db.Column(db.Integer, db.ForeignKey('targets.target_id'), nullable=False, primary_key=True)\n    target = db.relationship('targets')\n\n    def __init__(self, instrumentation_type, state, target_id):\n        self.target_id = target_id\n        self.state = state\n        self.instrumentation_type = instrumentation_type\n\n    def as_dict(self):\n        return {c.name: str(getattr(self, c.name)) for c in self.__table__.columns}\n"
  },
  {
    "path": "python/manager/model/job_inputs.py",
    "content": "from app import app\n\ndb = app.config['db']\n\nclass job_inputs(db.Model):\n    job_id = db.Column(db.Integer, db.ForeignKey('fuzz_jobs.job_id'), nullable=False, primary_key=True)\n    job = db.relationship('fuzz_jobs', back_populates='inputs')\n    input_file = db.Column(db.String, nullable=False, primary_key=True)\n\n    def as_dict(self):\n        return {c.name: str(getattr(self, c.name)) for c in self.__table__.columns}\n"
  },
  {
    "path": "python/manager/model/tracer_info.py",
    "content": "from app import app\n\ndb = app.config['db']\n\nclass tracer_info(db.Model):\n    target_id = db.Column(db.Integer, db.ForeignKey('targets.target_id'), nullable=False, primary_key=True)\n    target = db.relationship('targets')\n    input_file = db.Column(db.String, nullable=False, primary_key=True)\n    from_edge = db.Column(db.Numeric(asdecimal=True), nullable=False, primary_key=True)\n    to_edge = db.Column(db.Numeric(asdecimal=True), nullable=False, primary_key=True)\n\n    def __init__(self, target_id, input_file, from_edge, to_edge):\n        self.target_id = target_id\n        self.input_file = input_file\n        self.from_edge = from_edge\n        self.to_edge = to_edge\n\n    def as_dict(self):\n        return {c.name: str(getattr(self, c.name)) for c in self.__table__.columns}\n"
  },
  {
    "path": "python/manager/requirements.txt",
    "content": "flask\nflask-restful\nflask-sqlalchemy\nrequests\n"
  },
  {
    "path": "python/manager/server.py",
    "content": "from app import app\nimport argparse\nimport logging\nimport os.path\n\nimport sys\n  \nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\n        '-project_dir', help=\"BOINC project directory (default: /home/boincadm/projects/killerbeez)\",\n        default='/home/boincadm/projects/killerbeez')\n    parser.add_argument('-seed', help=\"For debugging. Which test to load seed data for. -listseeds for list.\")\n    parser.add_argument('-clear', action=\"store_true\", help=\"For debugging. Clear all data from the database\")\n    parser.add_argument('-create', action=\"store_true\", help=\"For debugging. Force creation of databases\")\n    parser.add_argument('-listseeds', action=\"store_true\", help=\"List debug seeds that you can choose the exit\")\n    args = parser.parse_args()\n\n    if os.path.isdir(args.project_dir):\n        app.config['BOINC_PROJECT_DIR'] = os.path.abspath(args.project_dir)\n    else:\n        print(\"project_dir does not exist or is not a directory\")\n        sys.exit(1)\n\n    db = app.config['db']\n\n    logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s %(name)s %(message)s')\n    logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)\n\n    if args.listseeds:\n        import tests.seeds as seeds\n        seeds.listseeds()\n        sys.exit(0)\n    if args.clear:\n        db.drop_all()\n    #  TODO: Determine if DB already exists and check its schema version\n    if args.create:\n        db.create_all()\n        db.session.commit()\n    if args.seed is not None:\n        import tests.seeds as seeds\n        # Seed data into the database for testing.\n        if not seeds.seed(db, args.seed):\n            print(\"DEBUG ERROR: Attempting to seed db for invalid test: {}\".format(args.seed))\n\n    app.run(host='0.0.0.0')\n"
  },
  {
    "path": "python/manager/tests/job_query_test.py",
    "content": "from flask_sqlalchemy import sqlalchemy\nimport os, sys, random\n\n# Find the directory with our source in it and add it to the lookup path\nif \"app\" in os.listdir():\n    sys.path.insert(0, os.path.abspath('.'))\nelse:\n    sys.path.insert(0, os.path.abspath('..'))\n\nfrom app import app\nfrom model.FuzzingTarget import targets\nfrom model.FuzzingJob import fuzz_jobs\nfrom model.job_inputs import job_inputs\nfrom model.FuzzingInputs import inputs\n#from model.tracer_info import tracer_info\n#from controller.Minimize import minimize\n\ndb = app.config['db']\n\nif __name__ == '__main__':\n    import argparse\n\n    parser = argparse.ArgumentParser(description=\"Test things\")\n    parser.add_argument(\"-setup\", action=\"store_true\", help=\"Setup the database\")\n    parser.add_argument(\"-clear\", action=\"store_true\", help=\"Clear the database\")\n    parser.add_argument(\"-target_id\", type=int, default=1, help=\"target id to use\")\n    args = parser.parse_args()\n\n    if args.clear:\n        db.drop_all()\n        db.create_all()\n        db.session.commit()\n\n    #if args.setup:\n    if True:\n        # Add some fake data to test against\n        #base = (args.target_id << 8)\n\n        # Add a few targets\n        db.session.add(targets(None, \"x86\", \"Windows 10\", \"test2.exe\"))\n        db.session.add(targets(None, \"x86\", \"Windows 8\", \"test1.exe\"))\n        db.session.add(targets(None, \"x86_64\", \"Windows 10\", \"test2.exe\"))\n        db.session.add(fuzz_jobs(\"fuzz\", 1, status='assigned'))\n        db.session.add(fuzz_jobs(\"fuzz\", 2))\n        db.session.add(fuzz_jobs(\"fuzz\", 2))\n        db.session.add(fuzz_jobs(\"fuzz\", 1))\n        db.session.add(fuzz_jobs(\"fuzz\", 1))\n        db.session.add(fuzz_jobs(\"fuzz\", 3))\n        db.session.add(inputs(\"AAAAAAAA\"))\n        db.session.add(inputs(\"BBBBBBBB\"))\n        db.session.add(job_inputs(4, 1))\n        db.session.add(job_inputs(4, 2))\n        #db.session.add(job_inputs(5, 1))\n        db.session.add(job_inputs(5, 2))\n        db.session.add(job_inputs(1, 1))\n        #db.session.add(job_inputs(1, 2))\n        db.session.commit()\n        # Can we get a result back out?\n        tars = db.session.query(targets).all()\n        print(\"all targets:{}\".format(len(tars)))\n        tars = db.session.query(targets).filter_by(architecture=\"x86\").all()\n        print(\"x86 targets:{}\".format(len(tars)))\n        tars = db.session.query(targets).filter_by(target_executable=\"test2.exe\").all()\n        print(\"test2 tars :{}\".format(len(tars)))\n        # Get all jobs associated with x86 architecture and windows 10 that are unassigned\n        query = db.session.query(fuzz_jobs) \\\n                .filter_by(status='unassigned') \\\n                .join(targets, targets.target_id == fuzz_jobs.target_id) \\\n                .filter_by(architecture=\"x86\", os=\"Windows 10\")\n        jobs = query.all()\n        print(len(jobs))\n        job = random.choice(jobs)\n        print(job.job_id)\n        #inputs = db.session.query(job_inputs.input_id).filter_by(job_id=job.job_id).all()\n        #inputs = db.session.query(job_inputs.input_id, inputs) \\\\\n        inputs = db.session.query(job_inputs.input_id, inputs) \\\n                 .filter_by(job_id=job.job_id) \\\n                 .join(inputs, job_inputs.input_id == inputs.input_id).all()\n        if len(inputs):\n            inputs = [input[1].as_dict() for input in inputs]\n        else:\n            print(\"No inputs, we can't do anything\")\n        print(inputs)\n    sys.exit()"
  },
  {
    "path": "python/manager/tests/minimizer_test.py",
    "content": "from flask_sqlalchemy import sqlalchemy\nimport os, sys\n\n# Find the directory with our source in it and add it to the lookup path\nif \"app\" in os.listdir():\n    sys.path.insert(0, os.path.abspath('.'))\nelse:\n    sys.path.insert(0, os.path.abspath('..'))\n\nfrom app import app \nfrom model.FuzzingTarget import targets\nfrom model.FuzzingJob import fuzz_jobs\nfrom model.FuzzingInputs import inputs, inputs_hash\nfrom model.tracer_info import tracer_info\nfrom controller.Minimize import minimize\n\ndb = app.config['db']\n\nif __name__ == '__main__':\n    import argparse\n\n    parser = argparse.ArgumentParser(description=\"Test things\")\n    parser.add_argument(\"-setup\", action=\"store_true\", help=\"Setup the database\")\n    parser.add_argument(\"-clear\", action=\"store_true\", help=\"Clear the database\")\n    parser.add_argument(\"-target_id\", type=int, default=1, help=\"target id to use\")\n    parser.add_argument(\"-num_files_per_edge\", type=int, default=1, help=\"The number of files per edge to include in the working set\")\n    args = parser.parse_args()\n\n    if args.clear:\n        db.drop_all()\n        db.create_all()\n        db.session.commit()\n\n    if args.setup:\n        # Add some fake data to test against\n        base = (args.target_id << 8)\n        tests_info = [\n            {\"job_id\": base + 1, \"input_id\" : base + 1, \"data\": \"AAAA\",  \"edges\" : [(1, 2), (3, 4)]},\n            {\"job_id\": base + 2, \"input_id\" : base + 2, \"data\": \"ABCD\",  \"edges\" : [(1, 2), (5, 6)]},\n            {\"job_id\": base + 3, \"input_id\" : base + 3, \"data\": \"XXXXXXX\", \"edges\" : [(1, 2), (3, 4), (5,6)]},\n            {\"job_id\": base + 4, \"input_id\" : base + 4, \"data\": \"XXXXXX\", \"edges\" : [(1, 2), (3, 4), (5,6)]},\n            {\"job_id\": base + 5, \"input_id\" : base + 5, \"data\": \"XXXXX\", \"edges\" : [(1, 2), (3, 4), (5,6)]},\n            {\"job_id\": base + 6, \"input_id\" : base + 6, \"data\": \"ZZZZZZZZZ\", \"edges\" : [(7,8)]},\n        ]\n\n        db.session.add(targets(args.target_id, \"x86\", \"Windows10\", \"test2.exe\"))\n        for test_info in tests_info:\n            db.session.add(fuzz_jobs(\"user\", args.target_id, None, None, None, None, \"finished\", test_info[\"job_id\"]))\n            \n            hash = inputs_hash(test_info[\"data\"])\n            input = inputs.query.filter_by(hash = hash).all() \n            if len(input) == 0:\n                db.session.add(inputs(test_info[\"data\"], test_info[\"job_id\"], input_id = test_info[\"input_id\"]))\n            else:\n                test_info[\"input_id\"] = input[0].input_id\n\n            for edge in test_info[\"edges\"]:\n                db.session.add(tracer_info(args.target_id, test_info[\"input_id\"], edge[0], edge[1]))\n        db.session.commit()\n\n    files = minimize(args.target_id, args.num_files_per_edge)\n    print(files)"
  },
  {
    "path": "python/manager/tests/seeds.py",
    "content": "import base64\nimport json\n\nfrom model.FuzzingTarget import targets\nfrom model.FuzzingJob import fuzz_jobs\nfrom model.FuzzingInputs import inputs\nfrom model.job_inputs import job_inputs\nfrom model.Config import FuzzingConfig\nfrom model.instrumentation_state import instrumentation_state\n\ndef listseeds():\n    \"\"\"\n    Prints the list of seed funcctions that we accept. Make sure to keep this up to date.\n    Having this kept up to date is cleaner than trying to parse the AST or getattr and isfunction.\n    :return: Nothing; just prints\n    \"\"\"\n    print(\"The following seed options exist:\")\n    print(\"\\tclient_request: For testing that a client can request a job successfully. Creates x86 and x86_64\")\n    print(\"\\t\\t jobs that the client get endpoint should be able to find.\")\n\ndef seed(db, forwhich):\n    if forwhich == \"client_request\":\n        client_request(db)\n        return True\n    return False\n\ndef client_request(db):\n    #db.session.add(targets(None, \"x86\", \"Windows 10\", \"test2.exe\"))\n    #db.session.add(targets(None, \"x86\", \"Windows 8\", \"test1.exe\"))\n    #db.session.add(targets(None, \"x86_64\", \"Windows 10\", \"test2.exe\"))\n    db.session.add(targets(\"x86\", \"CYGWIN_NT-10.0 2.10.0(0.325/5/3)\", \"test2.exe\"))\n    db.session.add(targets(\"x86\", \"CYGWIN_NT-10.0 2.10.0(0.325/5/3)\", \"test1.exe\"))\n    db.session.add(targets(\"x86_64\", \"Windows 10\", \"test2.exe\"))\n    db.session.add(fuzz_jobs(\"fuzz\", 1, status='assigned'))\n    db.session.add(fuzz_jobs(\"fuzz\", 3, mutator='nop', instrumentation_type='dynamorio', driver='wmp'))\n    db.session.add(fuzz_jobs(\"fuzz\", 3, mutator='radamsa', instrumentation_type='dynamorio', driver='wmp'))\n    db.session.add(fuzz_jobs(\"fuzz\", 2))\n    db.session.add(fuzz_jobs(\"fuzz\", 1))\n    db.session.add(fuzz_jobs(\"fuzz\", 3, instrumentation_type=\"testinstrumentor\"))\n    db.session.add(inputs(\"AAAAAAAA\"))\n    db.session.add(inputs(\"BBBBBBBB\"))\n    db.session.add(job_inputs(4, 1))\n    db.session.add(job_inputs(4, 2))\n    # db.session.add(job_inputs(5, 1))\n    db.session.add(job_inputs(5, 2))\n    db.session.add(job_inputs(2, 2))\n    db.session.add(job_inputs(3, 2))\n    db.session.add(job_inputs(1, 1))\n    db.session.add(job_inputs(6, 1))\n    # db.session.add(job_inputs(1, 2))\n    db.session.add(FuzzingConfig(\"instrumentation_opts_testinstrumentor\", \"testfallbacktarget\", target=3))\n    db.session.add(FuzzingConfig(\"driver_opts_stdin\", \"stdinopts\", target=3))\n    db.session.add(FuzzingConfig(\"mutator_opts_radamsa\", json.dumps({'seed': 5}), target=3))\n    db.session.add(FuzzingConfig(\"mutator_opts_radamsa\", \"{radamsoo}\", target=2))\n    #db.session.add(FuzzingConfig(\"instrumentation_opts_testinstrumentor\", \"testfallbackjob\", job=6))\n    db.session.add(FuzzingConfig('instrumentation_opts_dynamorio', json.dumps({\n        \"per_module_coverage\": 1,\n        \"timeout\": 10000,\n        \"coverage_modules\": [\"wmp.DLL\"],\n        \"client_params\": \"-target_module wmplayer.exe -target_offset 0x1F20 -nargs 3\",\n        \"fuzz_iterations\":1,\n        \"target_path\": \"C:\\\\Program Files (x86)\\\\Windows Media Player\\\\wmplayer.exe\"\n    }), target=3))\n    db.session.commit()\n"
  },
  {
    "path": "server/add_target.py",
    "content": "#!/usr/bin/env python2\n#\n# This script will add a target to the BOINC system, which would normally\n# require a bunch of manual work in terms of editing files, and creating\n# a whole directory structure.  The gist of it is this:\n# - Edit project.xml if the platform is new\n# - Edit config.xml to add daemons such as validators and assimilators\n# - Create the following directory structure:\n#     apps/$TARGET_NAME/$VERSION/$PLATFORM\n#   (where $VERSION is currently hard-coded to \"1\")\n# - The contents of skel/$PLATFORM are then copied to the new app directory\n#   with the filenames getting the $TARGET_NAME injected into them and\n#   version.xml has all instances of {app} replaced with $TARGET_NAME\n# - Creates templates/$TARGET_NAME_$PLATFORM_{in,out} based on files in\n#   skel/templates. See: https://boinc.berkeley.edu/trac/wiki/JobTemplates\n# - Calls xadd, stop, and start to ensure BOINC knows about all these changes\n#\n\nimport argparse\nimport fcntl\nimport os\nimport os.path\nimport shutil\nimport socket\nimport subprocess\nimport sys\n\nimport boinc_path_config\nfrom Boinc import configxml, projectxml\n\ndef parse_args():\n    parser = argparse.ArgumentParser()\n    parser.add_argument('app')\n    parser.add_argument('platforms', nargs=argparse.REMAINDER)\n    return parser.parse_args()\n\ndef add_app(project_file, name, platform):\n    app_name = '{}_{}'.format(name, platform)\n    for node in project_file.elements:\n        if node._name == 'app' and node.name == app_name:\n            print('App {} already in project.xml, not adding app'.format(app_name))\n            return\n\n    a = project_file.elements.make_node_and_append('app')\n    a.name = app_name\n    a.user_friendly_name = '{} running on {}'.format(name, platform)\n\ndef create_app_dir(name, platform):\n    app_name = '{}_{}'.format(name, platform)\n    app_dir = os.path.join('apps', app_name)\n    if os.path.exists(app_dir):\n        print('App directory {} already exists, not adding app versions'.format(app_dir))\n        return\n\n    app_version_dir = os.path.join(app_dir, '1', platform)\n    os.makedirs(app_version_dir)\n\n    skel_dir = os.path.join('skel', platform)\n    for filename in os.listdir(skel_dir):\n        if filename != 'version.xml':\n            name, dot, ext = filename.partition('.')\n            new_filename = ''.join((name, '.', app_name, dot, ext))\n            shutil.copy(os.path.join(skel_dir, filename),\n                        os.path.join(app_version_dir, new_filename))\n        else:\n            with open(os.path.join(skel_dir, filename)) as template:\n                version_xml = template.read().format(app=app_name)\n            with open(os.path.join(app_version_dir, filename), 'w') as version_file:\n                version_file.write(version_xml)\n\ndef create_app_templates(name, platform):\n    in_template_path = os.path.join('templates', '{}_{}_in'.format(name, platform))\n    if os.path.exists(in_template_path):\n        print('Input template {} already exists, not adding templates'.format(in_template_path))\n        return\n    out_template_path = os.path.join('templates', '{}_{}_out'.format(name, platform))\n    if os.path.exists(out_template_path):\n        print('Output template {} already exists, not adding templates'.format(out_template_path))\n        return\n\n    shutil.copyfile(os.path.join('skel', 'templates', '{}_in'.format(platform)), in_template_path)\n    shutil.copyfile(os.path.join('skel', 'templates', '{}_out'.format(platform)), out_template_path)\n\n\ndef add_daemons(config_file, name, platform):\n    app_name = '{}_{}'.format(name, platform)\n    cmd = 'killerbeez_assimilator.py -app {}'.format(app_name)\n\n    for node in config_file.daemons:\n        if node.cmd == cmd:\n            print('Assimilator daemon for app {} already exists, not adding it'.format(app_name))\n            return\n\n    daemon = config_file.daemons.make_node_and_append('daemon')\n    daemon.cmd = cmd\n    daemon.pid_file = 'killerbeez_assimilator_{}.pid'.format(app_name)\n    daemon.lock_file = 'killerbeez_assimilator_{}.lock'.format(app_name)\n    daemon.output = 'killerbeez_assimilator_{}.log'.format(app_name)\n\n    daemon = config_file.daemons.make_node_and_append('daemon')\n    daemon.cmd = 'sample_trivial_validator --app {}'.format(app_name)\n    daemon.pid_file = 'sample_trivial_validator_{}.pid'.format(app_name)\n    daemon.lock_file = 'sample_trivial_validator_{}.lock'.format(app_name)\n    daemon.output = 'sample_trivial_validator_{}.log'.format(app_name)\n\ndef lock_file(filename):\n    os.umask(02)\n    file = open(filename,'w')\n    fcntl.lockf(file.fileno(), fcntl.LOCK_EX|fcntl.LOCK_NB)\n\n\ndef main():\n    args = parse_args()\n    if not os.path.isfile('project.xml'):\n        print('Must be run from the project directory')\n        sys.exit(1)\n\n    hostname = socket.gethostname().split('.')[0]\n    lockfile_name = os.path.join('pid_{}'.format(hostname), 'add_target.lock')\n    try:\n        lock_file(lockfile_name)\n    except IOError:\n        print('Another {} process is running, please try again'.format(sys.argv[0]))\n\n    project_file = projectxml.ProjectFile('project.xml').read()\n    config_file = configxml.ConfigFile('config.xml').read()\n\n    name = args.app\n    platforms = args.platforms\n\n    for platform in platforms:\n        # Add name_platform to apps in project.xml\n        add_app(project_file, name, platform)\n        # Create app directory with wrapper, version.xml\n        create_app_dir(name, platform)\n        create_app_templates(name, platform)\n        add_daemons(config_file, name, platform)\n\n    project_file.write()\n    config_file.write()\n    os.unlink(lockfile_name)\n\n    # Update db from project file\n    subprocess.check_call(['bin/xadd'])\n    # Restart project\n    subprocess.check_call(['bin/stop'])\n    subprocess.check_call(['bin/start'])\n\n    print('New app versions installed into apps/{}_*. Make any changes you '\n          'need, then run bin/update_versions to install them.'.format(name))\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "server/boinc_submit.py",
    "content": "#!/usr/bin/env python\n\nimport base64\nimport collections\n\nimport requests\n\n# Set the following to configure your job\nPROJECT = 'http://localhost:5000/api'\nSEED = b\"1234seed\"\n\ndef main():\n    # Make sure we have a DB entry for the target\n    target_resp = requests.post(\n        '%s/target' % PROJECT,\n        json={\"platform\": \"windows_x86_64\", \"target_executable\": \"wmp\"})\n    target_resp.raise_for_status()\n    target_id = target_resp.json()['id']\n    # Set up shell format for this target - change value to \"sh\" for linux\n    requests.post(\n        '%s/config' % PROJECT,\n        json={\"target_id\": target_id,\n              \"name\": \"platform_opts_shell_format\",\n              \"value\": \"bat\"}).raise_for_status()\n\n    # Create the driver and instrumentation configs\n    requests.post(\n        '%s/config' % PROJECT,\n        json={\"target_id\": target_id,\n              \"name\": \"driver_opts_wmp\",\n              \"value\": r'{\"path\": \"C:\\\\Program Files\\\\Windows Media Player\\\\wmplayer.exe\"}'}).raise_for_status()\n    requests.post(\n        '%s/config' % PROJECT,\n        json={\"target_id\": target_id,\n              \"name\": \"instrumentation_opts_dynamorio\",\n              \"value\": r'{\"per_module_coverage\": 1, \"timeout\": 10000, \"coverage_modules\": [\"wmp.DLL\"], \"client_params\": \"-target_module wmplayer.exe -target_offset 0x1F20 -nargs 3\", \"fuzz_iterations\": 1, \"target_path\": \"C:\\\\Program Files\\\\Windows Media Player\\\\wmplayer.exe\"}'}).raise_for_status()\n\n    # Create the seed file\n    seed_resp = requests.post(\n        '%s/file' % PROJECT,\n        json={\"content\": base64.b64encode(SEED).decode(), \"encoding\": \"base64\"})\n    seed_resp.raise_for_status()\n    seed_file = seed_resp.json()['filename']\n\n    # Create the job!\n    job_resp = requests.post(\n        '%s/job' % PROJECT,\n        json={\"job_type\": \"fuzz\",\n              \"target_id\": target_id,\n              \"mutator\": \"radamsa\",\n              \"instrumentation_type\": \"dynamorio\",\n              \"driver\": \"wmp\",\n              \"seed_file\": seed_file,\n              \"iterations\": 2})\n    job_resp.raise_for_status()\n    job_json = job_resp.json()\n\n    print('Created job %s with BOINC id %s' % (job_json['job_id'], job_json['boinc_id']))\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "server/killerbeez_assimilator.py",
    "content": "#!/usr/bin/env python\n\nimport logging\nimport os.path\nimport re\nimport shutil\nimport subprocess\nimport tempfile\nimport zipfile\n\nimport requests\n\nimport assimilator\nimport xml.etree.ElementTree as ET\n\nlogger = logging.getLogger(__name__)\n\nAPI_SERVER = 'http://localhost:5000/api'\n\n\ndef clean_download_path(path):\n    \"\"\"Turns an absolute path in the BOINC download dir into a relative path.\n\n    This allows paths to be used as URL components, and doesn't expose\n    unnecessary server configuration data.\n    \"\"\"\n    _, _, relpath = path.rpartition('/download/')\n    return relpath\n\n\ndef filename_to_download_path(path):\n    abspath = subprocess.check_output(\n        ['bin/dir_hier_path', path], cwd='..').strip()\n    return clean_download_path(abspath)\n\n\ndef dirname_to_result_type(dirname):\n    result_types = {'crashes': 'crash', 'hangs': 'hang', 'new_paths': 'new_path'}\n    return result_types[dirname]\n\n\nclass KillerbeezAssimilator(assimilator.Assimilator):\n    def __init__(self):\n        assimilator.Assimilator.__init__(self)\n\n    def _stage_file(self, filename):\n        logger.debug('Staging %s', filename)\n        process = subprocess.Popen(\n            ['bin/stage_file', '--verbose', filename],\n            cwd='..', stdout=subprocess.PIPE)\n        stdout, stderr = process.communicate()\n        if process.returncode:\n            self.logError('Error staging file: {} | {}\\n'.format(stdout, stderr))\n            return None\n\n        # Try to parse stdout to find out where the file was staged to\n        new_path = None\n        for line in stdout.splitlines():\n            if line.startswith(b'staging '):\n                _, _, path = line.partition(b' to ')\n                new_path = path.decode('utf8')\n            elif b'already exists as' in line:\n                _, _, path = line.partition(b' as ')\n                new_path = path.decode('utf8')\n\n        return clean_download_path(new_path)\n\n    def _record_job(self, wu):\n        job_id = wu.id\n        # ET doesn't like multiple root elements, so we need to wrap the whole\n        # document in one element\n        xml_doc = ET.fromstring('<xml_doc>{}</xml_doc>'.format(wu.xml_doc))\n        file_name_element = xml_doc.find(\"workunit/file_ref[open_name='seed']/file_name\")\n        if file_name_element is None:\n            return # TODO: error handling\n        seed_file = filename_to_download_path(file_name_element.text)\n        requests.put('{}/boinc_job/{}'.format(API_SERVER, job_id),\n                    json={'seed_file': seed_file, 'status': 'completed'})\n\n    def _record_result(self, file_path, result_type, job_id):\n        # TODO: use client helper module, maybe\n        requests.post('{}/boinc_job/{}/results'.format(API_SERVER, job_id),\n                    json={'repro_file': file_path, 'result_type': result_type})\n\n    def _process_zipfile(self, job_id, output_file):\n        tempdir = tempfile.mkdtemp()\n        try:\n            with zipfile.ZipFile(output_file, 'r') as results_file:\n                for result_name in results_file.namelist():\n                    match = re.match(r'killerbeez_result_([a-z]+)_([A-Za-z0-9]+)', result_name)\n                    if not match:\n                        continue\n                    result_type = match.group(1)\n                    md5 = match.group(2)\n\n                    filename = os.path.join(tempdir, 'input_{}'.format(md5.lower()))\n                    with open(filename, 'wb') as dest, results_file.open(result_name) as src:\n                        dest.write(src.read())\n\n                    staged_path = self._stage_file(filename)\n                    self._record_result(staged_path, dirname_to_result_type(result_type), job_id)\n        finally:\n            shutil.rmtree(tempdir)\n\n    def assimilate_handler(self, wu, results, canonical_result):\n        \"\"\"\n        This method is called for each workunit (wu) that needs to be\n        processed. A canonical result is not guarenteed and several error\n        conditions may be present on the wu. Call report_errors(wu) when\n        overriding this method.\n        \n        Note that the -noinsert flag (self.noinsert) must be accounted for when\n        overriding this method.\n        \"\"\"\n        if self.report_errors(wu) or canonical_result is None:\n            return\n\n        # TODO: handle error status, maybe\n        self._record_job(wu)\n        zipfile_name = self.get_file_path(canonical_result)\n        self._process_zipfile(wu.id, zipfile_name)\n\n\nif __name__ == '__main__':\n    asm = KillerbeezAssimilator()\n    asm.run()\n"
  },
  {
    "path": "server/skel/templates/windows_x86_64_in",
    "content": "<input_template>\n    <file_info>\n        <number>0</number>\n        <no_delete/>\n    </file_info>\n    <file_info>\n        <number>1</number>\n        <no_delete/>\n    </file_info>\n    <workunit>\n        <file_ref>\n            <file_number>0</file_number>\n            <open_name>seed</open_name>\n            <copy_file/>\n        </file_ref>\n        <file_ref>\n            <file_number>1</file_number>\n            <open_name>cmdline.bat</open_name>\n            <copy_file/>\n        </file_ref>\n        <target_nresults>1</target_nresults>\n        <min_quorum>1</min_quorum>\n    </workunit>\n</input_template>\n"
  },
  {
    "path": "server/skel/templates/windows_x86_64_out",
    "content": "<output_template>\n    <file_info>\n        <name><OUTFILE_0/></name>\n        <generated_locally/>\n        <upload_when_present/>\n        <max_nbytes>5000000</max_nbytes>\n        <url><UPLOAD_URL/></url>\n    </file_info>\n    <result>\n        <file_ref>\n            <file_name><OUTFILE_0/></file_name>\n            <open_name>results.zip</open_name>\n        </file_ref>\n    </result>\n</output_template>\n"
  },
  {
    "path": "server/skel/templates/x86_64-pc-linux-gnu_in",
    "content": "<input_template>\n    <file_info>\n        <number>0</number>\n        <no_delete/>\n    </file_info>\n    <file_info>\n        <number>1</number>\n        <no_delete/>\n    </file_info>\n    <workunit>\n        <file_ref>\n            <file_number>0</file_number>\n            <open_name>seed</open_name>\n            <copy_file/>\n        </file_ref>\n        <file_ref>\n            <file_number>1</file_number>\n            <open_name>cmdline.sh</open_name>\n            <copy_file/>\n        </file_ref>\n        <target_nresults>1</target_nresults>\n        <min_quorum>1</min_quorum>\n    </workunit>\n</input_template>\n"
  },
  {
    "path": "server/skel/templates/x86_64-pc-linux-gnu_out",
    "content": "<output_template>\n    <file_info>\n        <name><OUTFILE_0/></name>\n        <generated_locally/>\n        <upload_when_present/>\n        <max_nbytes>5000000</max_nbytes>\n        <url><UPLOAD_URL/></url>\n    </file_info>\n    <result>\n        <file_ref>\n            <file_name><OUTFILE_0/></file_name>\n            <open_name>results.zip</open_name>\n        </file_ref>\n    </result>\n</output_template>\n"
  },
  {
    "path": "server/skel/windows_x86_64/flatten_results.ps1",
    "content": "echo \"Results from a killerbeez run. This file ensures an empty zip file is not generated.\" > README.txt\nForeach($type in \"crashes\", \"hangs\", \"new_paths\") {\n  Get-ChildItem output\\$type |\n  Foreach-Object {\n    cp $_.FullName $('killerbeez_result_{0}_{1}' -f $type, $_.Name)\n  }\n}\n"
  },
  {
    "path": "server/skel/windows_x86_64/job.xml",
    "content": "<job_desc>\n    <task>\n      <application>C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe</application>\n      <command_line>boinc_resolve(unpack_killerbeez.ps1) -from boinc_resolve(killerbeez-x64.zip) -into $PROJECT_DIR</command_line>\n    </task>\n    <task>\n      <application>cmdline.bat</application>\n      <command_line>$PROJECT_DIR\\killerbeez-x64\\killerbeez\\fuzzer.exe</command_line>\n    </task>\n    <task>\n      <application>C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe</application>\n      <command_line>boinc_resolve(flatten_results.ps1)</command_line>\n    </task>\n    <zip_output>\n      <zipfilename>results.zip</zipfilename>\n      <filename>killerbeez_result_.*</filename>\n      <filename>README.txt</filename>\n    </zip_output>\n</job_desc>\n"
  },
  {
    "path": "server/skel/windows_x86_64/unpack_killerbeez.ps1",
    "content": "param (\n  $from = \"killerbeez-x64.zip\",\n  $into = $(pwd),\n  $lockfile = \"$into\\unpack_killerbeez-x64.lock\",\n  $hashfile = \"$into\\killerbeez-x64.sha256\",\n  $extracted_name = \"$into\\killerbeez-x64\"\n)\n\n# Try to prevent multiple copies from running at once. Yes, this has a TOCTOU\n# race condition, but fixing it makes the script a lot more complicated, and it\n# should just cause failed jobs that will be retried anyway.\nwhile (Test-Path $lockfile) {\n  sleep 10\n}\necho $pid > $lockfile\n\n# Check the hash of our killerbeez zip against the last one that was extracted\n# to see if we have a new zip\n$hash = (Get-FileHash $from -Algorithm SHA256).Hash\nif (Test-Path $hashfile) {\n  $old_hash = $(cat $hashfile).Trim()\n  if ($old_hash -eq $hash) {\n    echo \"Killerbeez already unpacked, skipping archive extraction\"\n    rm $lockfile\n    exit 0\n  }\n}\n# Hash wasn't saved or didn't match, extract the zip\nrmdir -r $extracted_name -ErrorAction 'silentlycontinue'\nExpand-Archive $from -DestinationPath $into\necho $hash > $hashfile\nrm $lockfile\n"
  },
  {
    "path": "server/skel/windows_x86_64/version.xml",
    "content": "<version>\n    <file>\n        <physical_name>wrapper_26014_windows_x86_64.{app}.exe</physical_name>\n        <main_program/>\n        <is_wrapper/>\n    </file>\n    <file>\n        <physical_name>killerbeez-x64.{app}.zip</physical_name>\n        <logical_name>killerbeez-x64.zip</logical_name>\n    </file>\n    <file>\n        <physical_name>job.{app}.xml</physical_name>\n        <logical_name>job.xml</logical_name>\n    </file>\n    <file>\n        <physical_name>unpack_killerbeez.{app}.ps1</physical_name>\n        <logical_name>unpack_killerbeez.ps1</logical_name>\n    </file>\n    <file>\n        <physical_name>flatten_results.{app}.ps1</physical_name>\n        <logical_name>flatten_results.ps1</logical_name>\n    </file>\n</version>\n"
  },
  {
    "path": "server/skel/x86_64-pc-linux-gnu/flatten_results.sh",
    "content": "#!/bin/bash\nexec >&2 # Redirect stdout to stderr so that it's captured for BOINC\n\necho \"Results from a killerbeez run. This file ensures an empty zip file is not generated.\" > README.txt\nfor result_type in crashes hangs new_paths; do\n  for file in $(ls output/$result_type); do\n    cp output/$result_type/$file killerbeez_result_${result_type}_${file}\n  done\ndone\n"
  },
  {
    "path": "server/skel/x86_64-pc-linux-gnu/job.xml",
    "content": "<job_desc>\n    <task>\n      <application>unpack_killerbeez.sh</application>\n      <command_line>boinc_resolve(killerbeez.zip) $PROJECT_DIR</command_line>\n    </task>\n    <task>\n      <application>/bin/bash</application>\n      <command_line>boinc_resolve(cmdline.sh) $PROJECT_DIR/killerbeez-Linux/killerbeez/fuzzer</command_line>\n    </task>\n    <task>\n      <application>flatten_results.sh</application>\n    </task>\n    <zip_output>\n      <zipfilename>results.zip</zipfilename>\n      <filename>killerbeez_result_.*</filename>\n      <filename>README.txt</filename>\n    </zip_output>\n</job_desc>\n"
  },
  {
    "path": "server/skel/x86_64-pc-linux-gnu/unpack_killerbeez.sh",
    "content": "#!/bin/bash\nexec >&2 # Redirect stdout to stderr so that it's captured for BOINC\n\n# Ensure absolute paths\nFROM=$(readlink -f $1)\nINTO=$(readlink -f $2)\n\nHASHFILE=$INTO/$(basename $FROM).sha256\nEXTRACTED_NAME=$INTO/killerbeez-Linux\n\n# Ensure only one copy of this script runs at a time\n[ \"${FLOCKER}\" != \"$0\" ] && exec env FLOCKER=\"$0\" flock -en \"$0\" \"$0\" \"$@\" || :\n\nif [[ -e \"$HASHFILE\" ]]; then\n  sha256sum -c \"$HASHFILE\"\n  if [[ $? -eq 0 ]]; then\n    echo >&2 \"Already have a build of this version of Killerbeez, skipping\"\n    exit 0\n  fi\nfi\n\nset -e\n\nrm -rf $EXTRACTED_NAME\ncd $INTO\nunzip $FROM\n\nsha256sum $FROM > $HASHFILE\n"
  },
  {
    "path": "server/skel/x86_64-pc-linux-gnu/version.xml",
    "content": "<version>\n    <file>\n        <physical_name>wrapper.{app}</physical_name>\n        <main_program/>\n        <is_wrapper/>\n    </file>\n    <file>\n        <physical_name>killerbeez-Linux.{app}.zip</physical_name>\n        <logical_name>killerbeez.zip</logical_name>\n    </file>\n    <file>\n        <physical_name>job.{app}.xml</physical_name>\n        <logical_name>job.xml</logical_name>\n    </file>\n    <file>\n        <physical_name>unpack_killerbeez.{app}.sh</physical_name>\n        <logical_name>unpack_killerbeez.sh</logical_name>\n    </file>\n    <file>\n        <physical_name>flatten_results.{app}.sh</physical_name>\n        <logical_name>flatten_results.sh</logical_name>\n    </file>\n</version>\n"
  },
  {
    "path": "tests/build.bat",
    "content": "rem Dependencies:\nrem git https://git-scm.com/download/win\nrem wget http://gnuwin32.sourceforge.net/packages/wget.htm\nrem cmake https://cmake.org/download/\nrem unzip ?\n\nmkdir C:\\killerbeez\ncd \\killerbeez\n\ngit clone https://github.com/grimm-co/killerbeez.git\ngit clone https://github.com/grimm-co/killerbeez-mutators.git\ngit clone https://github.com/grimm-co/killerbeez-utils.git\nwget https://github.com/DynamoRIO/dynamorio/releases/download/release_6_2_0/DynamoRIO-Windows-6.2.0-2.zip\nunzip DynamoRIO-Windows-6.2.0-2.zip\nmv DynamoRIO-Windows-6.2.0-2 dynamorio\ncd killerbeez\nmkdir build\ncd build\ncmake -DCMAKE_GENERATOR_PLATFORM=x64 -DCMAKE_BUILD_TYPE=Release ..\ncmake --build .\n\n"
  },
  {
    "path": "tests/smoke_test.sh",
    "content": "#!/bin/bash\n#\n# Run this from the directory above the killerbeez checkout\n#\n# Dependencies:\n# sudo apt install build-essential cmake clang libtool-bin automake bison flex libglib2.0-dev libc6-dev-i386\n\nif [[ \"$1\" == \"kill\" ]]; then\n\t# Clean out the old\n\trm -fR killerbeez\nfi\n\n# Check out the new (if needed)\nif [[ ! -d killerbeez ]]; then\n\tgit clone --recursive https://github.com/grimm-co/killerbeez\nfi\n\nfunction generic_error {\n\t# $1 = return code\n\t# $2 = command output\n\t# $3 = error string\n\tif [[ $1 -ne 0 ]]; then\n\t\techo \"$3\"\n\t\techo \"Output: $2\"\n\t\texit 1\n\tfi\n}\nfunction test_linux_error {\n\t# $1 = return code\n\t# $2 = command output\n\t# $3 = mutator\n\t# $4 = crashing or non-crashing?\n\terr=\"Error running fuzzer with $3 on test-linux ($4)\"\n\tgeneric_error \"$1\" \"$2\" \"$err\"\n}\n\ncd killerbeez\n# Compile things\nmkdir -p build; cd build\ncmake .. && make || exit 1\n\n# Try running the fuzzer and make sure we have some basic functionality\ncd killerbeez\n\n# Run the test-linux program with input which should not cause a crash\necho \"AAAA\" > test0\necho \"Running expected non-crashing test\"\necho '{\"path\":\"corpus/test-linux\",\"arguments\":\"@@\"}' > driver.json\noutput=`./fuzzer -n 300 -s test0 -d driver.json file return_code honggfuzz`\ntest_linux_error $? \"$output\" \"honggfuzz\" \"non-crashing\"\n\n# There should not have been anything critical in this run (rc should == 1)\necho \"$output\" | grep CRITICAL &> /dev/null\nx=$?\n# test_linux_error expects rc = 0\ntest_linux_error $((x-1)) \"$output\" \"honggfuzz\" \"non-crashing\"\n\n# There should be a number of iterations done\necho \"$output\" | grep -i ran.*iterations &> /dev/null\ntest_linux_error $? \"$output\" \"honggfuzz\" \"non-crashing\"\n\n\n# Ensure that it can also find crashes, given a reasonable seed\necho \"ABC@\" > test1\necho \"Running expected crashing test\"\noutput=`./fuzzer -n 300 -s test1 -d driver.json file return_code honggfuzz`\ntest_linux_error $? \"$output\" \"honggfuzz\" \"crashing\"\necho \"$output\" | grep CRITICAL &> /dev/null\ntest_linux_error $? \"$output\" \"honggfuzz\" \"non-crashing\"\necho \"$output\" | grep -i ran.*iterations &> /dev/null\ntest_linux_error $? \"$output\" \"honggfuzz\" \"non-crashing\"\n\n\nfunction string_not_present {\n\tneedle=\"$1\"\n\thaystack=\"$2\"\n\t# rc = 0 means string was not present\n\techo \"$haystack\" | grep \"$needle\" &> /dev/null\n\tx=$?  # we expect this to be 1 if not found, we want to return 0\n\treturn $((x-1))  # if the needle is not found, so we subtract 1\n}\nfunction string_count {\n\tneedle=\"$1\"\n\thaystack=\"$2\"\n\t# prints the number of times the needle was found in the haystack\n\techo \"$haystack\" | grep \"$needle\" | wc -l\n}\nfunction no_warnings_no_errors {\n\toutput=\"$1\"\n\tmutator=\"$2\"\n\t#echo \"output=$output\"\n\tstring_not_present \"WARNING\" \"$output\"\n\ttest_linux_error $? \"$output\" \"$mutator\" \"WARNING\"\n\tstring_not_present \"FATAL\" \"$output\"\n\ttest_linux_error $? \"$output\" \"$mutator\" \"FATAL\"\n\tstring_not_present \"CRITICAL\" \"$output\"\n\ttest_linux_error $? \"$output\" \"$mutator\" \"CRITICAL\"\n\tstring_not_present \"Ran 0 iterations\" \"$output\"\n\ttest_linux_error $? \"$output\" \"$mutator\" \"Ran 0 iterations\"\n}\n\nfunction find_llvm_config {\n\tfor name in llvm-config llvm-config-3.8 llvm-config-3.7 llvm-config-3.6 llvm-config-3.5; do\n\t\twhich $name > /dev/null\n\t\tif [ \"$?\" = \"0\" ]; then\n\t\t\techo $name\n\t\t\treturn 0\n\t\tfi\n\tdone\n\tgeneric_error 1 \"Could not find llvm-config\" \"Failed to build afl-clang-fast\"\n}\n\n#####################################################################################\n## AFL Instrumentation Tests ########################################################\n#####################################################################################\n\necho \"Running tests - instrumentation - afl - building\"\n\n# Build afl-gcc\nmake -C ../../afl_progs/\ngeneric_error $? \"make failed\" \"Failed to build afl-gcc\"\n\n# Build afl-clang-fast\nLLVM_CONFIG=$(find_llvm_config)\nmake -C ../../afl_progs/llvm_mode/ LLVM_CONFIG=$LLVM_CONFIG\ngeneric_error $? \"make failed\" \"Failed to build afl-clang-fast\"\n\n# Build afl-qemu-trace\npushd ../../afl_progs/qemu_mode/\n./build_qemu_support.sh\ngeneric_error $? \"make failed\" \"Failed to build afl-qemu-trace\"\npopd\n\n# Build afl test programs\nafl_testdir=\"../../corpus/afl_test\"\nmake -C $afl_testdir AFL_PATH=../../afl_progs/\ngeneric_error $? \"make failed\" \"Failed to build afl test programs\"\n\n# Run the test programs with various different AFL based instrumentations\necho \"Running tests - instrumentation - afl - testing\"\nfor test_file in test test32 test-qemu test-fast test-fast-deferred test-fast-persist test-fast-persist-deferred; do\n\t# Note: in Debian 9 (stretch), there appears to be a bug in the code coverage\n\t# of afl-gcc which only detects 2 paths instead of 3 (paths: AA, BA, AB).  Running\n\t# the program manually confirms that there are 3 code paths which are hit, it's\n\t# just that the instrumentation only picks up 2 of them. The version info on gcc\n\t# on that Debian system is: gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516\n\t# The same target and compiler code, running on Fedora 29 and gcc 8.3.1 work fine.\n\texpected=3\n\t# Unfortunately the persistence mode tests overly report new paths, so we need to adjust the count for them\n\tif [ \"$test_file\" = \"test-fast-persist\" -o \"$test_file\" = \"test-fast-persist-deferred\" ]; then\n\t\texpected=4\n\tfi\n\n\t# Build the instrumentation options\n\tinst_options=\"{\"\n\tif [ \"$test_file\" = \"test-fast-deferred\" -o \"$test_file\" = \"test-fast-persist-deferred\" ]; then\n\t\tinst_options=\"$inst_options\\\"deferred_startup\\\":1\"\n\tfi\n\tif [ \"$test_file\" = \"test-fast-persist\" -o \"$test_file\" = \"test-fast-persist-deferred\" ]; then\n\t\tif [ \"$test_file\" = \"test-fast-persist-deferred\" ]; then\n\t\t\tinst_options=\"$inst_options,\"\n\t\tfi\n\t\tinst_options=\"$inst_options\\\"persistence_max_cnt\\\":5\"\n\tfi\n\tif [ \"$test_file\" = \"test-qemu\" ]; then\n\t\tinst_options=\"$inst_options\\\"qemu_mode\\\":1,\\\"qemu_path\\\":\\\"../../afl_progs/afl-qemu-trace\\\"\"\n\tfi\n\tinst_options=\"$inst_options}\"\n\n\t# Set up our JSON files\n        echo \"{\\\"path\\\":\\\"$afl_testdir/$test_file\\\"}\" > driver.json\n\techo $inst_options > instrumentation.json\n\n\t# Run the test and check the number of new paths found\n\techo \"Running bit_flip with seed file test0 on $afl_testdir/$test_file\"\n\toutput=$(./fuzzer -n 127 -s test0 -d driver.json -i instrumentation.json stdin afl bit_flip)\n\ttest_linux_error $? \"$output\" bit_flip \"AFL instrumentation with $test_file new path test\"\n\tno_warnings_no_errors \"$output\" bit_flip\n\tnew_path_count=$(string_count \"Found new_paths\" \"$output\")\n\ttest $new_path_count -eq $expected\n# TODO/FIXME: This check is broken due to a bug in AFL's instrumentation\n#             It should able to be re-enabled when we pull in the new code\n#             from AFL++, which will take care of tickets #154 and #155\n#\tgeneric_error $? \"AFL new paths test failed\" \\\n#\t\t\"AFL instrumentation with $test_file failed to detect new paths (found: $new_path_count expected: $expected)\"\n\n\t# Run the test again and make sure it finds a crashing input\n\toutput=$(./fuzzer -n 100 -s test1 -d driver.json -i instrumentation.json stdin afl bit_flip)\n\ttest_linux_error $? \"$output\" bit_flip \"AFL instrumentation with $test_file crash test\"\n\techo \"$output\" | grep \"Found crashes\" > /dev/null\n\tgeneric_error $? \"AFL crash test failed\" \"AFL instrumentation with $test_file failed to detect a crash\"\ndone\n\n#####################################################################################\n## Return Code Instrumentation Tests ################################################\n#####################################################################################\n\n# Test the return_code instrumentation with and without the fork server\necho \"Running tests - instrumentation - return_code\"\n\necho '{\"path\":\"corpus/test-linux\",\"arguments\":\"@@\"}' > driver.json\noutput=$(./fuzzer -n 100 -s test0 -d driver.json file return_code nop)\ntest_linux_error $? \"$output\" nop \"return_code forkserver test\"\nno_warnings_no_errors \"$output\" nop\n\necho '{\"path\":\"corpus/test-linux\"}' > driver.json\noutput=$(./fuzzer -n 100 -s test1 -d driver.json stdin return_code bit_flip)\ntest_linux_error $? \"$output\" bit_flip \"return_code forkserver crash test\"\necho \"$output\" | grep \"Found crashes\" > /dev/null\ngeneric_error $? \"return_code forkserver crash test failed\" \"return_code instrumentation failed to detect a crash\"\n\necho '{\"path\":\"corpus/test-linux\",\"arguments\":\"@@\"}' > driver.json\necho '{\"use_fork_server\":0}' > instrumentation.json\noutput=$(./fuzzer -n 100 -s test0 -d driver.json -i instrumentation.json file return_code nop)\ntest_linux_error $? \"$output\" nop \"return_code no forkserver test\"\nno_warnings_no_errors \"$output\" nop\n\necho '{\"path\":\"corpus/test-linux\"}' > driver.json\necho '{\"use_fork_server\":0}' > instrumentation.json\noutput=$(./fuzzer -n 100 -s test1 -d driver.json -i instrumentation.json stdin return_code bit_flip)\ntest_linux_error $? \"$output\" bit_flip \"return_code no forkserver crash test\"\necho \"$output\" | grep \"Found crashes\" > /dev/null\ngeneric_error $? \"return_code no forkserver crash test failed\" \"return_code instrumentation without the forkserver failed to detect a crash\"\n\n#####################################################################################\n## Mutator Tests ####################################################################\n#####################################################################################\n\n# Now we do more basic tests using other mutators\nfor mutator in ni bit_flip nop interesting_value havoc arithmetic afl zzuf; do\n\techo \"Running tests - mutator - $mutator\"\n\n\techo '{\"path\":\"corpus/test-linux\",\"arguments\":\"@@\"}' > driver.json\n\toutput=$(./fuzzer -n 30 -s test0 -d driver.json file return_code $mutator)\n\ttest_linux_error $? \"$output\" $mutator \"$mutator file basic test\"\n\tno_warnings_no_errors \"$output\" $mutator\n\n\techo '{\"path\":\"corpus/test-linux\"}' > driver.json\n\toutput=$(./fuzzer -n 30 -s test0 -d driver.json stdin return_code $mutator)\n\ttest_linux_error $? \"$output\" $mutator \"$mutator stdin basic test\"\n\tno_warnings_no_errors \"$output\" $mutator\ndone\n\n# TODO: add tests for multipart, radamsa, dictionary, and splice\n#echo '{\"path\":\"corpus/test-linux\",\"arguments\":\"@@\"}' > driver.json\n#output=`./fuzzer -n 30 -s test0 -d driver.json file return_code splice`\n#test_linux_error $? \"$output\" splice \"basic test\"\n#no_warnings_no_errors \"$output\" splice\n\n# Want to test the no_warnings_no_errors function?  Uncomment\n# the blog below to try a made-up mutator\n#output=`./fuzzer -n 30 -s test0 -d driver.json file return_code doesnotexist`\n#test_linux_error $? \"$output\" thisdoesnotexist \"basic test\"\n#no_warnings_no_errors \"$output\" thisdoesnotexist\n\nexit 0  # If we got here, we're good\n\n"
  },
  {
    "path": "tests/test-fuzzer.sh",
    "content": "#!/bin/sh\n# For Windows, this assumes you're using Cygwin, and everything is at C:\\killerbeez\n# For Linux, this assumes LINUX_BASE_PATH ($HOME/killerbeez/ by default) contains:\n#\tkillerbeez, killerbeez-mutators, killerbeez-utils\n\nif [ -z \"$KILLERBEEZ_TEST\" ]\nthen\n\techo \"Please set KILLERBEEZ_TEST in your environment. Recommended: export KILLERBEEZ_TEST='simple'\"\n\texit 1\nfi\n\nWINDOWS_BASE_PATH='C:\\killerbeez\\killerbeez\\'\nWINDOWS_JSON_ESCAPED_BASE_PATH='C:\\\\killerbeez\\\\Killerbeez\\\\' # JSON uses '\\' as an escape.\nWINDOWS_CYGWIN_BASE_PATH=\"/cygdrive/c/killerbeez/\"\nWINDOWS_BUILD_PATH=$WINDOWS_CYGWIN_BASE_PATH\"build/X64/Debug/killerbeez\"\n\nLINUX_BASE_PATH=\"$HOME/killerbeez/\"\nLINUX_BUILD_PATH=\"$LINUX_BASE_PATH/build/killerbeez/\"\n\nFUZZER=\"./fuzzer\"\nFUZZER_WITH_GDB=\"gdb -q -ex run -ex quit --args ./fuzzer\" # Remove -ex quit to stay in gdb after completion.\nFUZZER_WITH_LLDB='lldb -o run -- ./fuzzer'\n\n# https://stackoverflow.com/a/3466183\nunameOut=\"$(uname -s)\"\ncase \"${unameOut}\" in\n    Linux*)     machine=Linux;;\n    Darwin*)    machine=Mac;;\n    CYGWIN*)    machine=Cygwin;;\n    MINGW*)     machine=MinGw;;\n    *)          machine=\"UNKNOWN:${unameOut}\"\nesac\n\n# test is a 32-bit binary that crashes on ABCD via stdin or in a file passed as argv[1].\n# hang is a 32-bit binary that hangs.\n\nif [ $machine = \"Cygwin\" ]\nthen\n\t# cygwin permissions are strange, so make sure the executables are executable.\n\tchmod +x $WINDOWS_CYGWIN_BASE_PATH/killerbeez/corpus/test/test.exe\n\tchmod +x $WINDOWS_CYGWIN_BASE_PATH/killerbeez/corpus/hang/hang.exe\n\n\tif [ $KILLERBEEZ_TEST = \"debug\" ]\n\tthen\n\t\tcd $WINDOWS_BUILD_PATH\n\n\t\t./fuzzer.exe \\\n\t\tfile debug bit_flip \\\n\t\t-n 9 \\\n\t\t-l '{\"level\":0}' \\\n\t\t-sf $WINDOWS_BASE_PATH'corpus\\test\\inputs\\close.txt' \\\n\t\t-d '{\"timeout\":20,\n\t\t\t \"path\":\"'$WINDOWS_JSON_ESCAPED_BASE_PATH'corpus\\\\test\\\\test.exe\",\n\t\t\t \"arguments\":\"@@\"}'\n\tfi\n\n\tif [ $KILLERBEEZ_TEST = \"simple\" ]\n\tthen\n\t\tcd $WINDOWS_BUILD_PATH\n\n\t\t./fuzzer.exe \\\n\t\tfile dynamorio radamsa \\\n\t\t-n 3 \\\n\t\t-sf $WINDOWS_BASE_PATH'\\corpus\\test\\inputs\\input.txt' \\\n\t\t\\\n\t\t-d '{\"timeout\":20,\n\t\t\t \"path\":\"'$WINDOWS_JSON_ESCAPED_BASE_PATH'corpus\\\\test\\\\test.exe\",\n\t\t\t \"arguments\":\"@@\"}' \\\n\t\t\\\n\t\t-i '{\"per_module_coverage\": 1,\n\t\t\t\"coverage_modules\":[\"test.exe\"],\n\t\t\t\"timeout\": 2000,\n\t\t\t\"client_params\":\n\t\t\t\t\"-target_module test.exe -target_offset 0x1000 -nargs 3\",\n\t\t\t\"fuzz_iterations\":1,\n\t\t\t\"target_path\":\"'$WINDOWS_JSON_ESCAPED_BASE_PATH'corpus\\\\test\\\\test.exe\"}' \\\n\t\t-l '{\"level\":0}'\n\tfi\n\n\tif [ $KILLERBEEZ_TEST = \"hang\" ]\n\tthen\n\t\tcd $WINDOWS_BUILD_PATH\n\n\t\t./fuzzer \\\n\t\tfile debug bit_flip \\\n\t\t-n 1 \\\n\t\t-l '{\"level\":0}' \\\n\t\t-sf $WINDOWS_BASE_PATH'corpus\\test\\inputs\\input.txt' \\\n\t\t-d '{\"timeout\":3,\n\t\t\t \"path\":\"'$WINDOWS_JSON_ESCAPED_BASE_PATH'corpus\\\\hang\\\\hang.exe\",\n\t\t\t \"arguments\":\"@@\"}'\n\tfi\n\n\t# Tests a single packet via the server driver. If you're sending multiple\n\t# packets, consider the manager mutator instead.\n\tif [ $KILLERBEEZ_TEST = \"network_server\" ]\n\tthen\n\t\tcd $WINDOWS_BUILD_PATH\n\n\t\t./fuzzer \\\n\t\tnetwork_server debug bit_flip \\\n\t\t-n 10 \\\n\t\t-l '{\"level\":0}' \\\n\t\t-sf $WINDOWS_BASE_PATH'\\corpus\\network\\close.txt' \\\n\t\t-d '{\"timeout\":20,\n\t\t\t\"path\":\"'$WINDOWS_JSON_ESCAPED_BASE_PATH'corpus\\\\network\\\\server\\\\server.exe\",\n\t\t\t\"ip\":\"127.0.0.1\",\n\t\t\t\"port\":4444}'\n\tfi\n\n    if [ $KILLERBEEZ_TEST = \"network_client\" ]\n    then\n        cd $WINDOWS_BUILD_PATH\n\n        ./fuzzer \\\n        network_client debug bit_flip \\\n        -n 10 \\\n        -l '{\"level\":0}' \\\n        -sf $WINDOWS_BASE_PATH'\\corpus\\network\\close.txt' \\\n        -d '{\"timeout\":20,\n            \"path\":\"'$WINDOWS_JSON_ESCAPED_BASE_PATH'corpus\\\\network\\\\client\\\\client.exe\",\n            \"ip\":\"127.0.0.1\",\n            \"port\":4444}'\n\n    fi\nfi\n\n\nif [ $machine = \"Linux\" ] || [ $machine = \"Mac\" ]\nthen\n\n\tif [ $machine = \"Linux\" ]\n\tthen\n\t\tFUZZER=$FUZZER_WITH_GDB\n\tfi\n\n\t# LLDB interprets commas as some kind of syntax, so they need to be\n\t# escaped. You'll need to do so manually (in the -d option's json string,\n\t# usually) if you'd like to use this script w/ LLDB.\n\n\t# FUZZER=$FUZZER_WITH_LLDB # uncomment me to use\n\n\tif [ $KILLERBEEZ_TEST = \"simple\" ]\n\tthen\n\t\tcd $LINUX_BUILD_PATH\n\n\t\t$FUZZER \\\n\t\tfile return_code bit_flip \\\n\t\t-n 9 \\\n\t\t-sf $HOME'/killerbeez/killerbeez/corpus/test/inputs/close.txt' \\\n\t\t-d '{\"timeout\":20, \"path\":\"'$LINUX_BUILD_PATH'/corpus/test-linux\", \"arguments\":\"@@\"}' \\\n\t\t-l '{\"level\":0}' \\\n\t\t-m '{\"num_bits\":1}'\n\tfi\n\n\tif [ $KILLERBEEZ_TEST = \"hang\" ]\n\tthen\n\t\tcd $LINUX_BUILD_PATH\n\n\t\t$FUZZER \\\n\t\tfile return_code bit_flip \\\n\t\t-n 3 \\\n\t\t-l '{\"level\":0}' \\\n\t\t-sf $HOME'/killerbeez/killerbeez/corpus/test/inputs/input.txt' \\\n\t\t-d '{\"timeout\":2, \"path\":\"'$LINUX_BUILD_PATH'corpus/hang-linux\", \"arguments\":\"@@\"}'\n\tfi\n\n\tif [ $KILLERBEEZ_TEST = \"radamsa\" ]\n\tthen\n\t\tcd $LINUX_BUILD_PATH\n\n\t\t$FUZZER \\\n\t\tfile return_code radamsa \\\n\t\t-n 3 \\\n\t\t-l '{\"level\":0}' \\\n\t\t-sf $HOME'/killerbeez/killerbeez/corpus/test/inputs/input.txt' \\\n\t\t-d '{\"timeout\":20, \"path\":\"'$LINUX_BUILD_PATH'corpus/test-linux\", \"arguments\":\"@@\"}'\n\tfi\n\n\tif [ $KILLERBEEZ_TEST = \"stdin\" ]\n\tthen\n\t\tcd $LINUX_BUILD_PATH\n\n\t\t$FUZZER \\\n\t\tstdin return_code bit_flip \\\n\t\t-n 9 \\\n\t\t-l '{\"level\":0}' \\\n\t\t-sf $LINUX_BASE_PATH'/killerbeez/corpus/test/inputs/close.txt' \\\n\t\t-d '{\"timeout\":20, \"path\":\"'$LINUX_BUILD_PATH'corpus/test-linux\"}'\n\tfi\n\n\t# Tests a single packet via the server driver. If you're sending\n\t# multiple packets, consider the manager mutator instead.\n\tif [ $KILLERBEEZ_TEST = \"network_server\" ]\n\tthen\n\t\tcd $LINUX_BUILD_PATH\n\n\t\t$FUZZER \\\n\t\tnetwork_server return_code bit_flip \\\n\t\t-n 10 \\\n\t\t-l '{\"level\":0}' \\\n\t\t-sf $LINUX_BASE_PATH'/killerbeez/corpus/network/close.txt' \\\n\t\t-d '{\"timeout\":20,\"path\":\"'$LINUX_BUILD_PATH'/corpus/server-linux\",\"ip\":\"127.0.0.1\",\"port\":4444}'\n\tfi\n\n    if [ $KILLERBEEZ_TEST = \"network_client\" ]\n    then\n        cd $LINUX_BUILD_PATH\n\n        $FUZZER \\\n        network_client return_code bit_flip \\\n        -n 10 \\\n        -l '{\"level\":0}' \\\n        -sf $LINUX_BASE_PATH'/killerbeez/corpus/network/close.txt' \\\n        -d '{\"timeout\":20,\"path\":\"'$LINUX_BUILD_PATH'corpus/client-linux\",\"ip\":\"127.0.0.1\",\"port\":4444}'\n\n    fi\n\n\tif [ $KILLERBEEZ_TEST = \"multipart\" ]\n\tthen\n\t\tcd $LINUX_BUILD_PATH\n\n\t\t$FUZZER_WITH_GDB \\\n\t\tnetwork_server return_code manager \\\n\t\t-n 10 \\\n\t\t-l '{\"level\":0}' \\\n\t\t-m '{\"mutators\":[\"bit_flip\",\"bit_flip\"]}' \\\n\t\t-sf $LINUX_BASE_PATH'/killerbeez/corpus/network/multipart.txt' \\\n\t\t-d '{\"timeout\":20,\"path\":\"'$LINUX_BUILD_PATH'/corpus/server-linux\",\"ip\":\"127.0.0.1\",\"port\":4444}'\n\tfi\nfi\n\n# successful output should look like:\n\n# Mon Jun 11 19:59:28 2018 - INFO     - Logging Started\n# Mon Jun 11 19:59:28 2018 - DEBUG    - Fuzzing the 0 iteration\n# Mon Jun 11 19:59:28 2018 - DEBUG    - Setting up shm region: afl_shm_ce57db765140e79b_0\n# Mon Jun 11 19:59:29 2018 - DEBUG    - Dynamorio Instrumentation got hash 4aad8251 temp 4aad8251 (last hash 00000000)\n# Mon Jun 11 19:59:29 2018 - DEBUG    - has_new_bits = 2\n# Mon Jun 11 19:59:29 2018 - DEBUG    - Module test.exe has new bits (hash 4aad8251, last hash 00000000)\n# Mon Jun 11 19:59:29 2018 - CRITICAL - Found new_paths\n# Mon Jun 11 19:59:29 2018 - DEBUG    - Fuzzing the 1 iteration\n# Mon Jun 11 19:59:30 2018 - DEBUG    - Dynamorio Instrumentation got hash 5052d8f9 temp 5052d8f9 (last hash 4aad8251)\n# Mon Jun 11 19:59:30 2018 - DEBUG    - has_new_bits = 2\n# Mon Jun 11 19:59:30 2018 - DEBUG    - Module test.exe has new bits (hash 5052d8f9, last hash 4aad8251)\n# Mon Jun 11 19:59:30 2018 - CRITICAL - Found new_paths\n# Mon Jun 11 19:59:30 2018 - DEBUG    - Fuzzing the 2 iteration\n# Mon Jun 11 19:59:30 2018 - DEBUG    - Dynamorio Instrumentation got hash 4aad8251 temp 4aad8251 (last hash 5052d8f9)\n# Mon Jun 11 19:59:30 2018 - DEBUG    - has_new_bits = 0\n# Mon Jun 11 19:59:30 2018 - INFO     - Ran 3 iterations in 2 seconds\n\n"
  },
  {
    "path": "tools/README.md",
    "content": "# Build/CI Tools\n\n## Windows\n* **setup_build_env.ps1** - script that installs build dependencies on a Windows machine (to set it up as a CI runner)\n* **release_vs2017.bat** - script run by CI to build a binary release of Killerbeez for windows on Visual Studio 2017\n* **release_vs2019.bat** - script run by CI to build a binary release of Killerbeez for windows on Visual Studio 2019\n* **release_excludes.txt** - file used by `release_*.bat` during packaging step\n"
  },
  {
    "path": "tools/release_excludes.txt",
    "content": ".exp\\\n.iobj\\\n.ipdb\\\n.lib\\\n.pdb\\\n.manifest\\\n"
  },
  {
    "path": "tools/release_vs2017.bat",
    "content": "REM Meant to be run by CI from the root directory of one of the repos\nREM Usage: cd killerbeez; tools\\release\n\nif \"%RADAMSA_URL%\" == \"\" (\n  set RADAMSA_URL=https://gitlab.com/akihe/radamsa.git\n)\nif \"%DYNAMORIO_URL%\" == \"\" (\n  set DYNAMORIO_URL=https://storage.googleapis.com/chromium-dynamorio/builds/DynamoRIO-Windows-6.2.17295-0xa77808f.zip\n)\nif \"%CI_PROJECT_DIR%\" == \"\" (\n  set CI_PROJECT_DIR=%cd%\n)\n\nrmdir /s /q build\n\nif not exist radamsa (\n  git clone %RADAMSA_URL% || exit /b 1\n) else (\n  cd radamsa\n  git checkout master || exit /b 1\n  git pull || exit /b 1\n  cd ..\n)\n\nif not exist dynamorio (\n  powershell.exe -nologo -noprofile -command \"& { Add-Type -A 'System.IO.Compression.FileSystem'; $wc = New-Object System.Net.WebClient; $wc.DownloadFile('%DYNAMORIO_URL%', '.\\dynamorio.zip'); [IO.Compression.Zipfile]::ExtractToDirectory('.\\dynamorio.zip', '.\\dynamorio-unzip'); }\"\n  move dynamorio-unzip\\DynamoRIO* dynamorio\n  rmdir dynamorio-unzip\n  del dynamorio.zip\n)\n\nREM On some systems, vcvarsall.bat will change your working directory\nREM To work around this infuriating bug, pushd and popd are used\npushd .\ncall \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat\" x86\npopd\ncall :compile || exit /b 1\n\ncall :buildradamsa C:\\cygwin\\bin\n\ncall :package X86\n\npushd .\ncall \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat\" x64\npopd\ncall :compile || exit /b 1\n\ncall :buildradamsa C:\\cygwin64\\bin\n\ncall :package x64\n\npopd\nexit /b 0\n\n:compile\nrmdir /s /q cmaketmp\nmkdir cmaketmp\ncd cmaketmp\nREM Make Ninja build files\n\"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\Common7\\IDE\\CommonExtensions\\Microsoft\\CMake\\CMake\\bin\\cmake.exe\" -G \"Ninja\" -DCMAKE_CXX_COMPILER=\"cl.exe\"  -DCMAKE_C_COMPILER=\"cl.exe\"  -DCMAKE_BUILD_TYPE=\"Release\" -DCMAKE_MAKE_PROGRAM=\"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\Common7\\IDE\\CommonExtensions\\Microsoft\\CMake\\Ninja\\ninja.exe\" \"..\" || exit /b 1\nREM Run Ninja to build\n\"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\Common7\\IDE\\CommonExtensions\\Microsoft\\CMake\\Ninja\\ninja.exe\" || exit /b 1\ncd ..\nrmdir /s /q cmaketmp\nexit /b 0\n\n:package\nset platform=%1\nset relname=killerbeez-%platform%\nset distdir=dist\\%relname%\nrmdir /s /q %distdir%\nmkdir %distdir%\n\nxcopy /s /exclude:%~dp0\\release_excludes.txt build\\%platform%\\Release\\* %distdir%\nif \"%platform%\" == \"x64\" (\n  xcopy /s /exclude:%~dp0\\release_excludes.txt build\\X86\\Release\\killerbeez\\bin32\\* %distdir%\\killerbeez\\bin32\\\n)\nxcopy /s /i docs %distdir%\\docs\n\nmkdir %distdir%\\radamsa\nxcopy /s /i radamsa\\bin %distdir%\\radamsa\\bin\nxcopy radamsa\\LICENCE %distdir%\\radamsa\nif \"%platform%\" == \"x64\" (\n  if exist C:\\cygwin64\\bin\\cygwin1.dll (\n    xcopy C:\\cygwin64\\bin\\cygwin1.dll %distdir%\\radamsa\\bin\n  )\n) else (\n  if exist C:\\cygwin\\bin\\cygwin1.dll (\n    xcopy C:\\cygwin\\bin\\cygwin1.dll %distdir%\\radamsa\\bin\n  )\n  if exist C:\\cygwin\\bin\\cyggcc_s-1.dll (\n    xcopy C:\\cygwin\\bin\\cyggcc_s-1.dll %distdir%\\radamsa\\bin\n  )\n)\n\nmkdir %distdir%\\dynamorio\nxcopy /s /i dynamorio\\bin32 %distdir%\\dynamorio\\bin32\nxcopy /s /i dynamorio\\bin64 %distdir%\\dynamorio\\bin64\nxcopy /s /i dynamorio\\lib32 %distdir%\\dynamorio\\lib32\nxcopy /s /i dynamorio\\lib64 %distdir%\\dynamorio\\lib64\nxcopy /s /i dynamorio\\ext %distdir%\\dynamorio\\ext\nxcopy dynamorio\\License.txt %distdir%\\dynamorio\nxcopy dynamorio\\ACKNOWLEDGEMENTS %distdir%\\dynamorio\n\nif \"%platform%\" == \"x64\" (\n  mkdir %distdir%\\server\\skel\\windows_x86_64\n  REM Include wrapper binary, stored in C:\\killerbeez on the runner\n  xcopy C:\\killerbeez\\wrapper_26014_windows_x86_64.exe %distdir%\\server\\skel\\windows_x86_64\n  REM Include license files from the BOINC repo\n  xcopy server\\boinc\\COPYING %distdir%\\server\\skel\\windows_x86_64\n  xcopy server\\boinc\\COPYING.LESSER %distdir%\\server\\skel\\windows_x86_64\n  xcopy server\\boinc\\README.md %distdir%\\server\\skel\\windows_x86_64\n)\n\nset releasezip=%CI_PROJECT_DIR%\\release\\%relname%.zip\necho Creating %releasezip%\nmkdir \"%CI_PROJECT_DIR%\\release\"\ndel \"%releasezip%\"\npowershell.exe -nologo -noprofile -command \"& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.Zipfile]::CreateFromDirectory('%distdir%', '%releasezip%', [IO.Compression.CompressionLevel]::Optimal, 1); }\"\n\nexit /b 0\n\n:buildradamsa\nrem The argument is the path to the cygwin binary\nrem If the path doesn't exist, we just bail without\nrem building radamsa.\nrem\nrem Fun fact: If the set command is used inside the if statement\nrem it will not set oldpath, despite all logic.\nrem To hack around this, the if statement was inverted and the\nrem set commands were unconditional, where they work just fine.\nrem To test this yourself, try this:\nrem\nrem if exist C:\\windows (\nrem    echo \"oldpath=%oldpath\"\nrem    set \"oldpath=%path%\"\nrem    echo \"oldpath=%oldpath%\"\nrem )\nrem\nrem Want to see something even more amazing?  Paste in that exact\nrem same text again and watch it work just fine!  Isn't Windows cool?\nrem\necho \"Checking for %1\"\nif not exist %1 (\n  echo \"Cygwin not found, skipping radamsa build: %1\"\n  exit /b 0\n)\necho \"Building radamsa with %1\"\n\nset \"oldpath=%path%\"\nset \"path=%1;%oldpath%\"\nmake -C radamsa clean || exit /b 1\nmake -C radamsa || exit /b 1\nset \"path=%oldpath%\"\n\nexit /b 0\n"
  },
  {
    "path": "tools/release_vs2019.bat",
    "content": "REM Meant to be run by CI from the root directory of one of the repos\nREM Usage: cd killerbeez; tools\\release\nSETLOCAL EnableDelayedExpansion\n\nif \"%RADAMSA_URL%\" == \"\" (\n  set RADAMSA_URL=https://gitlab.com/akihe/radamsa.git\n)\nif \"%DYNAMORIO_URL%\" == \"\" (\n  set DYNAMORIO_URL=https://storage.googleapis.com/chromium-dynamorio/builds/DynamoRIO-Windows-6.2.17295-0xa77808f.zip\n)\nif \"%CI_PROJECT_DIR%\" == \"\" (\n  set CI_PROJECT_DIR=%cd%\n)\n\nrmdir /s /q build\n\nif not exist radamsa (\n  git clone %RADAMSA_URL% || exit /b 1\n) else (\n  cd radamsa\n  git checkout master || exit /b 1\n  git pull || exit /b 1\n  cd ..\n)\n\nif not exist dynamorio (\n  powershell.exe -nologo -noprofile -command \"& { Add-Type -A 'System.IO.Compression.FileSystem'; $wc = New-Object System.Net.WebClient; $wc.DownloadFile('%DYNAMORIO_URL%', '.\\dynamorio.zip'); [IO.Compression.Zipfile]::ExtractToDirectory('.\\dynamorio.zip', '.\\dynamorio-unzip'); }\"\n  move dynamorio-unzip\\DynamoRIO* dynamorio\n  rmdir dynamorio-unzip\n  del dynamorio.zip\n)\n\ncall \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat\" x86\ncall :compile || exit /b 1\n\nif exist C:\\cygwin\\bin (\n  set \"oldpath=%path%\"\n  set \"path=C:\\cygwin\\bin\\;!oldpath!\"\n  make -C radamsa clean || exit /b 1\n  make -C radamsa || exit /b 1\n  set \"path=!oldpath!\"\n)\n\ncall :package X86\n\ncall \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat\" x64\ncall :compile || exit /b 1\n\nif exist C:\\cygwin64\\bin (\n  set \"oldpath=%path%\"\n  set \"path=C:\\cygwin64\\bin\\;!oldpath!\"\n  make -C radamsa clean || exit /b 1\n  make -C radamsa || exit /b 1\n  set \"path=!oldpath!\"\n)\n\ncall :package x64\n\nexit /b 0\n\n:compile\nrmdir /s /q cmaketmp\nmkdir cmaketmp\ncd cmaketmp\nREM Make Ninja build files\n\"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\Common7\\IDE\\CommonExtensions\\Microsoft\\CMake\\CMake\\bin\\cmake.exe\" -G \"Ninja\" -DCMAKE_CXX_COMPILER=\"cl.exe\"  -DCMAKE_C_COMPILER=\"cl.exe\"  -DCMAKE_BUILD_TYPE=\"Release\" -DCMAKE_MAKE_PROGRAM=\"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\Common7\\IDE\\CommonExtensions\\Microsoft\\CMake\\Ninja\\ninja.exe\" \"..\" || exit /b 1\nREM Run Ninja to build\n\"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\Common7\\IDE\\CommonExtensions\\Microsoft\\CMake\\Ninja\\ninja.exe\" || exit /b 1\ncd ..\nrmdir /s /q cmaketmp\nexit /b 0\n\n:package\nset platform=%1\nset relname=killerbeez-%platform%\nset distdir=dist\\%relname%\nrmdir /s /q %distdir%\nmkdir %distdir%\n\nxcopy /s /exclude:%~dp0\\release_excludes.txt build\\%platform%\\Release\\* %distdir%\nif \"%platform%\" == \"x64\" (\n  xcopy /s /exclude:%~dp0\\release_excludes.txt build\\X86\\Release\\killerbeez\\bin32\\* %distdir%\\killerbeez\\bin32\\\n)\nxcopy /s /i docs %distdir%\\docs\n\nmkdir %distdir%\\radamsa\nxcopy /s /i radamsa\\bin %distdir%\\radamsa\\bin\nxcopy radamsa\\LICENCE %distdir%\\radamsa\nif \"%platform%\" == \"x64\" (\n  if exist C:\\cygwin64\\bin\\cygwin1.dll (\n    xcopy C:\\cygwin64\\bin\\cygwin1.dll %distdir%\\radamsa\\bin\n  )\n) else (\n  if exist C:\\cygwin\\bin\\cygwin1.dll (\n    xcopy C:\\cygwin\\bin\\cygwin1.dll %distdir%\\radamsa\\bin\n  )\n  if exist C:\\cygwin\\bin\\cyggcc_s-1.dll (\n    xcopy C:\\cygwin\\bin\\cyggcc_s-1.dll %distdir%\\radamsa\\bin\n  )\n)\n\nmkdir %distdir%\\dynamorio\nxcopy /s /i dynamorio\\bin32 %distdir%\\dynamorio\\bin32\nxcopy /s /i dynamorio\\bin64 %distdir%\\dynamorio\\bin64\nxcopy /s /i dynamorio\\lib32 %distdir%\\dynamorio\\lib32\nxcopy /s /i dynamorio\\lib64 %distdir%\\dynamorio\\lib64\nxcopy /s /i dynamorio\\ext %distdir%\\dynamorio\\ext\nxcopy dynamorio\\License.txt %distdir%\\dynamorio\nxcopy dynamorio\\ACKNOWLEDGEMENTS %distdir%\\dynamorio\n\nif \"%platform%\" == \"x64\" (\n  mkdir %distdir%\\server\\skel\\windows_x86_64\n  REM Include wrapper binary, stored in C:\\killerbeez on the runner\n  xcopy C:\\killerbeez\\wrapper_26014_windows_x86_64.exe %distdir%\\server\\skel\\windows_x86_64\n  REM Include license files from the BOINC repo\n  xcopy server\\boinc\\COPYING %distdir%\\server\\skel\\windows_x86_64\n  xcopy server\\boinc\\COPYING.LESSER %distdir%\\server\\skel\\windows_x86_64\n  xcopy server\\boinc\\README.md %distdir%\\server\\skel\\windows_x86_64\n)\n\nset releasezip=%CI_PROJECT_DIR%\\release\\%relname%.zip\necho Creating %releasezip%\nmkdir \"%CI_PROJECT_DIR%\\release\"\ndel \"%releasezip%\"\npowershell.exe -nologo -noprofile -command \"& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.Zipfile]::CreateFromDirectory('%distdir%', '%releasezip%', [IO.Compression.CompressionLevel]::Optimal, 1); }\"\n\nexit /b 0\n"
  },
  {
    "path": "tools/setup_build_env.ps1",
    "content": "param($build_env = $PSScriptRoot, $cygwin_mirror = \"http://mirrors.kernel.org/sourceware/cygwin/\", $vs_version = \"2019\")\nSet-PSDebug -Trace 1\npushd $build_env\n\n$ErrorActionPreference = \"Stop\"\nAdd-Type -A 'System.IO.Compression.FileSystem'\n\nif ($env:DNS_SERVER) {\n  netsh interface ip set dns Ethernet static $env:DNS_SERVER\n}\n\n[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12\n$wc = New-Object System.Net.WebClient\n\nif (!(Test-Path \"C:\\Gitlab-Runner\\gitlab-runner-windows-amd64.exe\")) {\n  mkdir -Force C:\\Gitlab-Runner\n  $url = \"https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-windows-amd64.exe\"\n  $wc.DownloadFile($url, \"C:\\Gitlab-Runner\\gitlab-runner-windows-amd64.exe\")\n}\n\n# Install cygwin 32 and 64 bit\nmkdir -Force installers\n$url = \"https://cygwin.com/setup-x86_64.exe\"\n$wc.DownloadFile($url, \"$build_env\\installers\\cygwin-x86_64.exe\")\n$ret = Start-Process \"installers\\cygwin-x86_64.exe\" -ArgumentList \"--arch\",\"x86_64\",\"--packages\",\"gcc-core,make,wget\",\"--upgrade-also\",\"--root\",\"C:\\cygwin64\",\"--site\",\"$cygwin_mirror\",\"--quiet-mode\" -Wait -PassThru -RedirectStandardOutput \"$build_env\\cygwin-x86_64-stdout\" -RedirectStandardError \"$build_env\\cygwin-x86_64-stderr\"\nif ($ret.ExitCode) {\n  throw \"Cygwin 64-bit install failed\"\n}\n$ret = Start-Process \"installers\\cygwin-x86_64.exe\" -ArgumentList \"--arch\",\"x86\",\"--packages\",\"gcc-core,make,wget\",\"--upgrade-also\",\"--root\",\"C:\\cygwin\",\"--site\",\"$cygwin_mirror\",\"--quiet-mode\" -Wait -PassThru -RedirectStandardOutput \"$build_env\\cygwin-x86-stdout\" -RedirectStandardError \"$build_env\\cygwin-x86-stderr\"\nif ($ret.ExitCode) {\n  throw \"Cygwin 32-bit install failed\"\n}\n\n# Install Visual Studio\necho \"Beginning Visual Studio install\"\nif ($vs_version -eq \"2017\") {\n    $url = \"https://aka.ms/vs/15/release/vs_community.exe\"\n    $vs_exe = \"$build_env\\installers\\vs_community.exe\"\n    $example_file = \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat\"\n    $extra_args = @()\n} else {\n    $url = \"https://aka.ms/vs/16/release/vs_community.exe\"\n    $vs_exe = \"$build_env\\installers\\vs_community.exe\"\n    $example_file = \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat\"\n    $extra_args = \"--add\",\"Microsoft.VisualStudio.Component.Windows10SDK.18362\"\n}\n$wc.DownloadFile($url, $vs_exe)\nif (Test-Path $example_file) {\n  $ret = Start-Process $vs_exe -ArgumentList \"update\",\"--passive\" -Wait -PassThru\n} else {\n  $ret = Start-Process $vs_exe -ArgumentList (\"--add\",\"Microsoft.VisualStudio.Component.VC.Tools.x86.x64\",\"--add\",\"Microsoft.VisualStudio.Component.VC.CMake.Project\",\"--add\",\"Microsoft.VisualStudio.Component.Git\",\"--passive\",\"--norestart\" + $extra_args) -Wait -PassThru\n}\n\nif ($ret.ExitCode) {\n  throw \"Visual Studio install failed\"\n}\necho \"Visual Studio install complete\"\n\n$env:Path = [System.Environment]::GetEnvironmentVariable(\"Path\",\"Machine\") + \";\" + [System.Environment]::GetEnvironmentVariable(\"Path\",\"User\")\n\npopd\n"
  },
  {
    "path": "tracer/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (tracer)\n\ninclude_directories (${CMAKE_SOURCE_DIR}/driver/)\ninclude_directories (${CMAKE_SOURCE_DIR}/instrumentation/)\n\nset(TRACER_SRC ${PROJECT_SOURCE_DIR}/main.c)\nsource_group(\"Executable Sources\" FILES ${TRACER_SRC})\nadd_executable(tracer ${TRACER_SRC} $<TARGET_OBJECTS:driver>\n\t$<TARGET_OBJECTS:instrumentation>)\ntarget_compile_definitions(tracer PUBLIC INSTRUMENTATION_NO_IMPORT)\ntarget_compile_definitions(tracer PUBLIC DRIVER_NO_IMPORT)\n\ntarget_link_libraries(tracer utils)\ntarget_link_libraries(tracer jansson)\nif (WIN32)\n  target_link_libraries(tracer Shlwapi)  # utils needs Shlwapi\n  target_link_libraries(tracer ws2_32)   # driver needs ws2_32\n  target_link_libraries(tracer iphlpapi) # network driver needs iphlpapi\nendif (WIN32)\n"
  },
  {
    "path": "tracer/main.c",
    "content": "#include <driver.h>\n#include <driver_factory.h>\n#include <instrumentation.h>\n#include <instrumentation_factory.h>\n#include <jansson_helper.h>\n#include <utils.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\nvoid usage(char * program_name)\n{\n\tchar * help_text;\n\tprintf(\n\t\t\"Usage: %s driver_name instrumentation_name input_file output_file [options]\\n\"\n\t\t\"\\n\"\n\t\t\"Required:\\n\"\n\t\t\"\\t driver_name                   The driver framework used to run the target program\\n\"\n\t\t\"\\t instrumentation_name          The instrumenation framework to use to determine the path a program took\\n\"\n\t\t\"\\t input_file                    The input to the target program\\n\"\n\t\t\"\\t output_file                   Write the edges to the given file.  The given path will be used as a prefix when recording multiple modules\\n\"\n\t\t\"Options:\\n\"\n\t\t\"\\t -b                            When writing the edges to a file, write them in binary (rather than human readable text)\\n\"\n\t\t\"\\t -d driver_options             Set the options for the driver\\n\"\n\t\t\"\\t -i instrumentation_options    Set the options for the instrumentation\\n\"\n\t\t\"\\t -l logging_options            Set the options for logging\\n\"\n\t\t\"\\t -n num_iterations             The number of iterations to run [5 per file].  Edges which are only in one run will be excluded\\n\"\n\t\t\"\\t -p                            Record the edges for each module independently\\n\"\n\t\t\"\\n\",\n\t\tprogram_name\n\t);\n\n#define PRINT_HELP(x, y) \\\n\tx = y;               \\\n\tif(x) {              \\\n\t\tputs(x);         \\\n\t\tfree(x);         \\\n\t}\n\n\tPRINT_HELP(help_text, logging_help());\n\tPRINT_HELP(help_text, driver_help());\n\tPRINT_HELP(help_text, instrumentation_help());\n\texit(1);\n}\n\nstruct edge_counts\n{\n\tinstrumentation_edge_t edge;\n\tint count;\n};\n\nvoid record_edges(instrumentation_edges_t * edges, struct edge_counts ** all_runs, int * all_runs_num_edges)\n{\n\tint this_run_num_edges;\n\tinstrumentation_edge_t *this_run;\n\tint i, j, found;\n\n\tthis_run = NULL;\n\tthis_run_num_edges = 0;\n\n\tfor (i = 0; i < edges->num_edges; i++)\n\t{\n\t\t//First check for the edge in this run\n\t\tfound = 0;\n\t\tfor (j = 0; j < this_run_num_edges; j++)\n\t\t{\n\t\t\tif (this_run[j].to == edges->edges[i].to && this_run[j].from == edges->edges[i].from)\n\t\t\t{\n\t\t\t\tfound = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (found) //If we've already recorded this one, just skip it\n\t\t\tcontinue;\n\n\t\t//If we haven't recorded this edge for this run before, add it to the this_run list\n\t\tthis_run_num_edges++;\n\t\tthis_run = (instrumentation_edge_t *)realloc(this_run, this_run_num_edges * sizeof(instrumentation_edge_t));\n\t\tthis_run[this_run_num_edges - 1].to = edges->edges[i].to;\n\t\tthis_run[this_run_num_edges - 1].from = edges->edges[i].from;\n\n\t\t//Now check to see if it's been recorded already in other runs\n\t\tfor (j = 0; j < *all_runs_num_edges; j++)\n\t\t{\n\t\t\tif ((*all_runs)[j].edge.to == edges->edges[i].to && (*all_runs)[j].edge.from == edges->edges[i].from)\n\t\t\t{\n\t\t\t\t(*all_runs)[j].count++;\n\t\t\t\tfound = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t//If we haven't found this edge before, add it to the all_runs list\n\t\tif (!found)\n\t\t{\n\t\t\t*all_runs_num_edges = *all_runs_num_edges + 1;\n\t\t\t*all_runs = (struct edge_counts *)realloc(*all_runs, *all_runs_num_edges * sizeof(struct edge_counts));\n\t\t\t(*all_runs)[*all_runs_num_edges - 1].edge.to = edges->edges[i].to;\n\t\t\t(*all_runs)[*all_runs_num_edges - 1].edge.from = edges->edges[i].from;\n\t\t\t(*all_runs)[*all_runs_num_edges - 1].count = 1;\n\t\t}\n\t}\n\tfree(this_run);\n}\n\n#define MAX_MODULES 512\n\nint main(int argc, char ** argv)\n{\n\tdriver_t * driver;\n\tinstrumentation_t * instrumentation;\n\tchar *driver_name, *driver_options = NULL,\n\t\t*input_filename = NULL, *seed_buffer = NULL, *output_file = NULL,\n\t\t*instrumentation_name = NULL, *instrumentation_options = NULL,\n\t\t*logging_options = NULL;\n\tvoid * instrumentation_state = NULL;\n\tint seed_length, iteration;\n\tinstrumentation_edges_t * edges;\n\tinstrumentation_edge_t *deterministic_edges;\n\tstruct edge_counts * all_runs[MAX_MODULES];\n\tint all_runs_num_edges[MAX_MODULES];\n\tint i, j, deterministic_edges_num_edges, num_modules = 0;\n\tchar * module_name = NULL;\n\tchar * module_names[MAX_MODULES];\n\tchar filename_buffer[MAX_PATH];\n\tFILE * fp;\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Parse Arguments ///////////////////////////////////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\t//Default options\n\tint num_iterations = 5;\n\tint binary_mode = 0;\n\tint per_module_edges = 0;\n\n\tif (argc < 5)\n\t{\n\t\tusage(argv[0]);\n\t}\n\n\tdriver_name = argv[1];\n\tinstrumentation_name = argv[2];\n\tinput_filename = argv[3];\n\toutput_file = argv[4];\n\tfor (int i = 5; i < argc; i++)\n\t{\n\t\tIF_ARG_SET_TRUE(\"-b\", binary_mode)\n\t\tELSE_IF_ARG_OPTION(\"-d\", driver_options)\n\t\tELSE_IF_ARG_OPTION(\"-i\", instrumentation_options)\n\t\tELSE_IF_ARG_OPTION(\"-l\", logging_options)\n\t\tELSE_IF_ARGINT_OPTION(\"-n\", num_iterations)\n\t\tELSE_IF_ARG_SET_TRUE(\"-p\", per_module_edges)\n\t\telse\n\t\t{\n\t\t\tif (strcmp(\"-h\", argv[i]))\n\t\t\t\tprintf(\"Unknown argument: %s\\n\", argv[i]);\n\t\t\tusage(argv[0]);\n\t\t}\n\t}\n\n\tif (setup_logging(logging_options))\n\t{\n\t\tprintf(\"Failed setting up logging, exiting\\n\");\n\t\treturn 1;\n\t}\n\n\tif (num_iterations < 1)\n\t\tFATAL_MSG(\"Bad iteration number (%d).  Must have a iteration count 1 or greater.\", num_iterations);\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Ojbect Setup //////////////////////////////////////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\tinstrumentation = instrumentation_factory(instrumentation_name);\n\tif (!instrumentation)\n\t\tFATAL_MSG(\"Unknown instrumentation '%s'\", instrumentation_name);\n\tif (!instrumentation->get_edges)\n\t\tFATAL_MSG(\"Instrumentation '%s' does not support the ability to get a list of edges\", instrumentation_name);\n\n\tif (instrumentation_options)\n\t\tinstrumentation_options = add_int_option_to_json(instrumentation_options, \"edges\", 1);\n\telse\n\t\tinstrumentation_options = \"{\\\"edges\\\": 1}\";\n\n\tinstrumentation_state = instrumentation->create(instrumentation_options, NULL);\n\tif (!instrumentation_state)\n\t\tFATAL_MSG(\"Bad options/state for instrumentation %s\", instrumentation_name);\n\n\tdriver = driver_instrumentation_factory(driver_name, driver_options, instrumentation, instrumentation_state);\n\tif (!driver)\n\t\tFATAL_MSG(\"Unknown driver '%s' or bad options: %s\", driver_name, driver_options ? driver_options : \"none\");\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Main Test Loop ////////////////////////////////////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\t//Read the seed file\n\tseed_length = read_file(input_filename, &seed_buffer);\n\tif (seed_length <= 0) //Couldn't read file, or empty file\n\t\tFATAL_MSG(\"Unable to open the input file \\\"%s\\\"\", input_filename);\n\n\tmemset(&all_runs, 0, sizeof(all_runs));\n\tmemset(&all_runs_num_edges, 0, sizeof(all_runs_num_edges));\n\tmemset(&module_names, 0, sizeof(module_names));\n\tif (!per_module_edges)\n\t{\n\t\tnum_modules = 1;\n\t}\n\telse\n\t{\n\t\twhile (!instrumentation->get_module_info(instrumentation_state, num_modules, NULL, &module_name, NULL, NULL))\n\t\t{\n\t\t\tif (num_modules >= MAX_MODULES)\n\t\t\t\tFATAL_MSG(\"Too many modules specified, %d specified, %d maximum\", num_modules, MAX_MODULES);\n\t\t\tmodule_names[num_modules] = module_name;\n\t\t\tnum_modules++;\n\t\t}\n\t}\n\n\tfor (iteration = 0; iteration < num_iterations; iteration++)\n\t{\n\t\tdriver->test_input(driver->state, seed_buffer, seed_length);\n\t\tfor (i = 0; i < num_modules; i++)\n\t\t{\n\t\t\tedges = instrumentation->get_edges(instrumentation_state, i);\n\t\t\tif (!edges)\n\t\t\t\tFATAL_MSG(\"Instrumentation failed to get the program edges from the tested process.\");\n\t\t\trecord_edges(edges, &all_runs[i], &all_runs_num_edges[i]);\n\t\t}\n\t}\n\tfree(seed_buffer);\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Reduce the list of edges to just the ones in every run, and store it //////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\tfor (i = 0; i < num_modules; i++)\n\t{\n\t\tdeterministic_edges = NULL;\n\t\tdeterministic_edges_num_edges = 0;\n\t\tfor (j = 0; j < all_runs_num_edges[i]; j++)\n\t\t{\n\t\t\tif (all_runs[i][j].count == num_iterations) //if the edge was found in all the iterations\n\t\t\t{\n\t\t\t\tdeterministic_edges_num_edges++;\n\t\t\t\tdeterministic_edges = (instrumentation_edge_t *)realloc(deterministic_edges, deterministic_edges_num_edges * sizeof(instrumentation_edge_t));\n\t\t\t\tdeterministic_edges[deterministic_edges_num_edges - 1].to = all_runs[i][j].edge.to;\n\t\t\t\tdeterministic_edges[deterministic_edges_num_edges - 1].from = all_runs[i][j].edge.from;\n\t\t\t}\n\t\t}\n\n\t\tif (!module_names[i])\n\t\t\tsnprintf(filename_buffer, sizeof(filename_buffer) - 1, \"%s\", output_file);\n\t\telse\n\t\t\tsnprintf(filename_buffer, sizeof(filename_buffer) - 1, \"%s_%s.%s\", output_file, module_names[i], binary_mode ? \"dat\" : \"txt\");\n\n\t\tfp = fopen(filename_buffer, \"wb+\");\n\t\tif (fp == NULL)\n\t\t\tFATAL_MSG(\"Couldn't open the file %s to write the edges to for %s\", filename_buffer, module_names[i] ? module_names[i] : \"the program\");\n\n\t\tfor (j = 0; j < deterministic_edges_num_edges; j++)\n\t\t{\n\t\t\tif (binary_mode)\n\t\t\t\tfwrite(&deterministic_edges[j], sizeof(instrumentation_edge_t), 1, fp);\n\t\t\telse\n\t\t\t\tfprintf(fp, \"%016x:%016x\\n\", deterministic_edges[j].from, deterministic_edges[j].to);\n\t\t}\n\t\tfclose(fp);\n\n\t\tfree(deterministic_edges);\n\t}\n\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\t// Cleanup ///////////////////////////////////////////////////////////////////////////////////////////\n\t//////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\t//Cleanup the objects and exit\n\tdriver->cleanup(driver->state);\n\tinstrumentation->cleanup(instrumentation_state);\n\tfree(driver);\n\tfree(instrumentation);\n\treturn 0;\n}\n"
  },
  {
    "path": "utils/XGetopt.c",
    "content": "// XGetopt.cpp  Version 1.2\n//\n// Author:  Hans Dietrich\n//          hdietrich2@hotmail.com\n//\n// Description:\n//     XGetopt.cpp implements getopt(), a function to parse command lines.\n//\n// History\n//     Version 1.2 - 2003 May 17\n//     - Added Unicode support\n//\n//     Version 1.1 - 2002 March 10\n//     - Added example to XGetopt.cpp module header\n//\n// This software is released into the public domain.\n// You are free to use it in any way you like.\n//\n// This software is provided \"as is\" with no expressed\n// or implied warranty.  I accept no liability for any\n// damage or loss of business that this software may cause.\n//\n///////////////////////////////////////////////////////////////////////////////\n\n\n///////////////////////////////////////////////////////////////////////////////\n// if you are using precompiled headers then include this line:\n//#include \"stdafx.h\"\n///////////////////////////////////////////////////////////////////////////////\n\n\n///////////////////////////////////////////////////////////////////////////////\n// if you are not using precompiled headers then include these lines:\n#include <windows.h>\n#include <stdio.h>\n#include <tchar.h>\n///////////////////////////////////////////////////////////////////////////////\n\n\n#include \"XGetopt.h\"\n\n\n///////////////////////////////////////////////////////////////////////////////\n//\n//  X G e t o p t . c p p\n//\n//\n//  NAME\n//       getopt -- parse command line options\n//\n//  SYNOPSIS\n//       int getopt(int argc, char *argv[], char *optstring)\n//\n//       extern char *optarg;\n//       extern int optind;\n//\n//  DESCRIPTION\n//       The getopt() function parses the command line arguments. Its\n//       arguments argc and argv are the argument count and array as\n//       passed into the application on program invocation.  In the case\n//       of Visual C++ programs, argc and argv are available via the\n//       variables __argc and __argv (double underscores), respectively.\n//       getopt returns the next option letter in argv that matches a\n//       letter in optstring.  (Note:  Unicode programs should use\n//       __targv instead of __argv.  Also, all character and string\n//       literals should be enclosed in _T( ) ).\n//\n//       optstring is a string of recognized option letters;  if a letter\n//       is followed by a colon, the option is expected to have an argument\n//       that may or may not be separated from it by white space.  optarg\n//       is set to point to the start of the option argument on return from\n//       getopt.\n//\n//       Option letters may be combined, e.g., \"-ab\" is equivalent to\n//       \"-a -b\".  Option letters are case sensitive.\n//\n//       getopt places in the external variable optind the argv index\n//       of the next argument to be processed.  optind is initialized\n//       to 0 before the first call to getopt.\n//\n//       When all options have been processed (i.e., up to the first\n//       non-option argument), getopt returns EOF, optarg will point\n//       to the argument, and optind will be set to the argv index of\n//       the argument.  If there are no non-option arguments, optarg\n//       will be set to NULL.\n//\n//       The special option \"--\" may be used to delimit the end of the\n//       options;  EOF will be returned, and \"--\" (and everything after it)\n//       will be skipped.\n//\n//  RETURN VALUE\n//       For option letters contained in the string optstring, getopt\n//       will return the option letter.  getopt returns a question mark (?)\n//       when it encounters an option letter not included in optstring.\n//       EOF is returned when processing is finished.\n//\n//  BUGS\n//       1)  Long options are not supported.\n//       2)  The GNU double-colon extension is not supported.\n//       3)  The environment variable POSIXLY_CORRECT is not supported.\n//       4)  The + syntax is not supported.\n//       5)  The automatic permutation of arguments is not supported.\n//       6)  This implementation of getopt() returns EOF if an error is\n//           encountered, instead of -1 as the latest standard requires.\n//\n//  EXAMPLE\n//       BOOL CMyApp::ProcessCommandLine(int argc, char *argv[])\n//       {\n//           int c;\n//\n//           while ((c = getopt(argc, argv, _T(\"aBn:\"))) != EOF)\n//           {\n//               switch (c)\n//               {\n//                   case _T('a'):\n//                       TRACE(_T(\"option a\\n\"));\n//                       //\n//                       // set some flag here\n//                       //\n//                       break;\n//\n//                   case _T('B'):\n//                       TRACE( _T(\"option B\\n\"));\n//                       //\n//                       // set some other flag here\n//                       //\n//                       break;\n//\n//                   case _T('n'):\n//                       TRACE(_T(\"option n: value=%d\\n\"), atoi(optarg));\n//                       //\n//                       // do something with value here\n//                       //\n//                       break;\n//\n//                   case _T('?'):\n//                       TRACE(_T(\"ERROR: illegal option %s\\n\"), argv[optind-1]);\n//                       return FALSE;\n//                       break;\n//\n//                   default:\n//                       TRACE(_T(\"WARNING: no handler for option %c\\n\"), c);\n//                       return FALSE;\n//                       break;\n//               }\n//           }\n//           //\n//           // check for non-option args here\n//           //\n//           return TRUE;\n//       }\n//\n///////////////////////////////////////////////////////////////////////////////\n\nchar\t*optarg;\t\t// global argument pointer\nint\t\toptind = 0; \t// global argv index\n\nint getopt(int argc, char *argv[], char *optstring)\n{\n\tstatic char *next = NULL;\n\tif (optind == 0)\n\t\tnext = NULL;\n\n\toptarg = NULL;\n\n\tif (next == NULL || *next == _T('\\0'))\n\t{\n\t\tif (optind == 0)\n\t\t\toptind++;\n\n\t\tif (optind >= argc || argv[optind][0] != _T('-') || argv[optind][1] == _T('\\0'))\n\t\t{\n\t\t\toptarg = NULL;\n\t\t\tif (optind < argc)\n\t\t\t\toptarg = argv[optind];\n\t\t\treturn EOF;\n\t\t}\n\n\t\tif (_tcscmp(argv[optind], _T(\"--\")) == 0)\n\t\t{\n\t\t\toptind++;\n\t\t\toptarg = NULL;\n\t\t\tif (optind < argc)\n\t\t\t\toptarg = argv[optind];\n\t\t\treturn EOF;\n\t\t}\n\n\t\tnext = argv[optind];\n\t\tnext++;\t\t// skip past -\n\t\toptind++;\n\t}\n\n\tchar c = *next++;\n\tchar *cp = _tcschr(optstring, c);\n\n\tif (cp == NULL || c == _T(':'))\n\t\treturn _T('?');\n\n\tcp++;\n\tif (*cp == _T(':'))\n\t{\n\t\tif (*next != _T('\\0'))\n\t\t{\n\t\t\toptarg = next;\n\t\t\tnext = NULL;\n\t\t}\n\t\telse if (optind < argc)\n\t\t{\n\t\t\toptarg = argv[optind];\n\t\t\toptind++;\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn _T('?');\n\t\t}\n\t}\n\n\treturn c;\n}\n"
  },
  {
    "path": "utils/XGetopt.h",
    "content": "// XGetopt.h  Version 1.2\n//\n// Author:  Hans Dietrich\n//          hdietrich2@hotmail.com\n//\n// This software is released into the public domain.\n// You are free to use it in any way you like.\n//\n// This software is provided \"as is\" with no expressed\n// or implied warranty.  I accept no liability for any\n// damage or loss of business that this software may cause.\n//\n///////////////////////////////////////////////////////////////////////////////\n\n#ifndef XGETOPT_H\n#define XGETOPT_H\n\nextern int optind, opterr;\nextern char *optarg;\n\nint getopt(int argc, char *argv[], char *optstring);\n\n#endif //XGETOPT_H\n"
  },
  {
    "path": "utils/global_types.h",
    "content": "#pragma once\n\n#include <stdlib.h>\n#include <stdint.h>\n\n/**\n * This macro can be used to mask off the rest of the flags in mutate_extended's\n * flag parameter to get just the input part's index that should be mutated when\n * the MUTATE_MULTIPLE_INPUTS bit is set.\n */\n#define MUTATE_MULTIPLE_INPUTS_MASK ((1 << 16) - 1)\n/**\n * This flag signifies that the mutator should mutate a specific input part,\n * defined by the index set in the bits covered by MUTATE_MULTIPLE_INPUTS_MASK\n */\n#define MUTATE_MULTIPLE_INPUTS (1 << 16)\n/**\n * This flag signifies that the mutations should be done in a thread safe way.\n */\n#define MUTATE_THREAD_SAFE (1 << 17)\n\ntypedef struct mutator\n{\n\tvoid * (*create)(char * options, char * state, char * input, size_t input_length);\n\tvoid(*cleanup)(void * mutator_state);\n\n\tint(*mutate)(void * mutator_state, char * buffer, size_t buffer_length);\n\tint(*mutate_extended)(void * mutator_state, char * buffer, size_t buffer_length, uint64_t flags);\n\n\tchar * (*get_state)(void * mutator_state);\n\tvoid(*free_state)(char * state);\n\tint(*set_state)(void * mutator_state, char * state);\n\n\tint(*get_current_iteration)(void * mutator_state);\n\tint(*get_total_iteration_count)(void * mutator_state);\n\tvoid(*get_input_info)(void * mutator_state, int * num_inputs, size_t **input_sizes);\n\n\tint(*set_input)(void * mutator_state, char * new_input, size_t input_length);\n\tint(*help)(char **help_str);\n} mutator_t;\n"
  },
  {
    "path": "utils/mutator_factory.c",
    "content": "#include \"mutator_factory.h\"\n#include \"utils.h\"\n\n#include <string.h>\n#include <stdlib.h>\n#include <stdio.h>\n\n#ifdef _WIN32\n#include <Windows.h>\n#else\n#include <dirent.h>\n#include <dlfcn.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#endif\n\n/**\n * Looks in a directory and retrieves a list of filenames of library files in that directory\n * @param directory - the directory to look for the library files in\n * @param num_libraries - a pointer to an int in which to return the number of library files found\n * @return - a pointer to a list of library files on success, or NULL if no library files were found\n */\nstatic char ** get_mutator_library_filenames(char * directory, int * num_libraries)\n{\n\tint num_files = 0;\n\tchar ** mutator_dlls = NULL;\n\tchar filename[MAX_PATH] ;\n\n#ifdef _WIN32\n\tHANDLE file_handle;\n\tWIN32_FIND_DATA fdFile;\n\tBOOL success;\n\n\tmemset(filename, 0, sizeof(filename));\n\tsnprintf(filename, sizeof(filename) - 1, \"%s\\\\*.dll\", directory);\n\n\tsuccess = 1;\n\tfor (file_handle = FindFirstFile(filename, &fdFile);\n\t\tfile_handle != INVALID_HANDLE_VALUE && success;\n\t\tsuccess = FindNextFile(file_handle, &fdFile))\n\t{\n\t\t//Skip directories\n\t\tif (fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)\n\t\t\tcontinue;\n\n\t\t//Read the seed file\n\t\tmemset(filename, 0, sizeof(filename));\n\t\tsnprintf(filename, sizeof(filename) - 1, \"%s\\\\%s\", directory, fdFile.cFileName);\n\n\t\tnum_files++;\n\t\tmutator_dlls = (char **)realloc(mutator_dlls, num_files * sizeof(char *));\n\t\tmutator_dlls[num_files - 1] = strdup(filename);\n\t}\n\tFindClose(file_handle);\n#else\n\n#ifdef __APPLE__\n\tchar * extension = \"dylib\";\n#else\n\tchar * extension = \"so\";\n#endif\n\tstruct dirent *dp;\n\tDIR *dfd;\n\tstruct stat stbuf;\n\n\tif ((dfd = opendir(directory)) != NULL)\n\t{\n\t\twhile ((dp = readdir(dfd)) != NULL)\n\t\t{\n\t\t\tsnprintf(filename, sizeof(filename), \"%s/%s\", directory, dp->d_name);\n\t\t\tif(stat(filename, &stbuf ) == -1)\n\t\t\t\tcontinue;\n\n\t\t\tif ((stbuf.st_mode & S_IFMT) == S_IFDIR)\n\t\t\t\tcontinue; // Skip directories\n\n\t\t\tif (!strncmp(&filename[strlen(filename)-strlen(extension)], extension, strlen(extension))) {\n\t\t\t\tnum_files++;\n\t\t\t\tmutator_dlls = (char **)realloc(mutator_dlls, num_files * sizeof(char *));\n\t\t\t\tmutator_dlls[num_files - 1] = strdup(filename);\n\t\t\t}\n\t\t}\n\t}\n\tclosedir(dfd);\n\n#endif\n\n\t*num_libraries = num_files;\n\treturn mutator_dlls;\n}\n\nUTILS_API mutator_t * mutator_factory(char * mutator_filename)\n{\n\tvoid(*init_ptr)(mutator_t *);\n\tmutator_t * ret;\n\n#ifdef _WIN32\n\tHINSTANCE handle = LoadLibrary(mutator_filename);\n#else\n\tvoid * \thandle = dlopen(mutator_filename, RTLD_LAZY);\n#endif\n\tif (!handle) //Couldn't load the requested mutator library\n\t\treturn NULL;\n\n#ifdef _WIN32\n\tinit_ptr = (void(*)(mutator_t *))GetProcAddress(handle, \"init\");\n#else\n\tinit_ptr = (void(*)(mutator_t *))dlsym(handle, \"init\");\n#endif\n\tif (!init_ptr) { //The library didn't have our init function\n#ifdef _WIN32\n\t\tFreeLibrary(handle);\n#else\n\t\tdlclose(handle);\n#endif\n\t\treturn NULL;\n\t}\n\n\t//Call the mutator's init function to initailize the mutators struct\n\tret = (mutator_t *)malloc(sizeof(mutator_t));\n\tinit_ptr(ret);\n\treturn ret;\n}\n\nstatic void generate_mutator_filename(char * mutator_directory, char * mutator_type, int include_mutator, char * output_filename, size_t output_filename_length)\n{\n#ifdef _WIN32\n\tchar * extension = \"dll\", *prefix = \"\";\n#elif defined(__APPLE__)\n\tchar * extension = \"dylib\", *prefix = \"lib\";\n#else\n\tchar * extension = \"so\", *prefix = \"lib\";\n#endif\n\n\tmemset(output_filename, 0, output_filename_length);\n\tif(mutator_directory) {\n\t\tif (include_mutator)\n\t\t\tsnprintf(output_filename, output_filename_length, \"%s/%s%s_mutator.%s\", mutator_directory, prefix, mutator_type, extension);\n\t\telse\n\t\t\tsnprintf(output_filename, output_filename_length, \"%s/%s%s.%s\", mutator_directory, prefix, mutator_type, extension);\n\t} else {\n\t\tif (include_mutator)\n\t\t\tsnprintf(output_filename, output_filename_length, \"%s%s_mutator.%s\", prefix, mutator_type, extension);\n\t\telse\n\t\t\tsnprintf(output_filename, output_filename_length, \"%s%s.%s\", prefix, mutator_type, extension);\n\t}\n}\n\n/**\n * This function obtains a mutator_t object by calling the mutator specified by mutator's init method.\n * @param mutator_directory - the directory to load the mutator library file from.\n * @param mutator_type - the name of the mutator that should be created.\n * @return - a instrumentation_t object of the specified type on success or NULL on failure\n */\nUTILS_API mutator_t * mutator_factory_directory(char * mutator_directory, char * mutator_type)\n{\n\tchar filename[MAX_PATH];\n\tmutator_t * ret;\n\n\tgenerate_mutator_filename(mutator_directory, mutator_type, 0, filename, sizeof(filename));\n\tret = mutator_factory(filename);\n\tif (!ret) {\n\t\tgenerate_mutator_filename(mutator_directory, mutator_type, 1, filename, sizeof(filename));\n\t\tret = mutator_factory(filename);\n\t}\n\treturn ret;\n}\n\n/**\n * This function returns help text for all the mutators found in the specified mutator directory.  This help text will\n * describe the mutators and any options that can be passed to their create functions.\n * @param mutator_directory - The directory to look for mutator libraries in\n * @return - a newly allocated string containing the help text.\n */\nUTILS_API char * mutator_help(char * mutator_directory)\n{\n#ifdef _WIN32\n\tHINSTANCE handle;\n#else\n\tvoid * handle;\n#endif\n\tint num_libraries = 0, i;\n\tchar ** mutator_libraries;\n\tint(*help_ptr)(char **);\n\tchar * text = NULL, * new_text = NULL;\n\n\tmutator_libraries = get_mutator_library_filenames(mutator_directory, &num_libraries);\n\tif (!num_libraries)\n\t{\n\t\tprintf(\"ERROR: Could not find any mutators.  Please ensure that the directory %s contains the mutator library files\", mutator_directory);\n\t\treturn NULL;\n\t}\n\n\ttext = strdup(\"\\nMutator Options:\\n\\n\");\n\tfor (i = 0; i < num_libraries; i++)\n\t{\n#ifdef _WIN32\n\t\thandle = LoadLibrary(mutator_libraries[i]);\n#else\n\t\thandle = dlopen(mutator_libraries[i], RTLD_LAZY);\n#endif\n\t\tif (!handle) //if we couldn't load the library, just continue\n\t\t\tcontinue;\n#ifdef _WIN32\n\t\thelp_ptr = (int(*)(char **))GetProcAddress(handle, \"help\");\n#else\n\t\thelp_ptr = (int(*)(char **))dlsym(handle, \"help\");\n#endif\n\t\tif (help_ptr) {//The library has a help function\n\t\t\tif (!help_ptr(&new_text)) //Call help() and check for failure\n\t\t\t{\n\t\t\t\ttext = (char *)realloc(text, strlen(text) + strlen(new_text) + 1);\n\t\t\t\tstrcat(text, new_text);\n\t\t\t\tfree(new_text);\n\t\t\t}\n\t\t}\n#ifdef _WIN32\n\t\tFreeLibrary(handle);\n#else\n\t\tdlclose(handle);\n#endif\n\t\thandle = NULL;\n\t}\n\ttext = (char *)realloc(text, strlen(text) + 2);\n\tstrcat(text, \"\\n\");\n\tfree(mutator_libraries);\n\treturn text;\n}\n"
  },
  {
    "path": "utils/mutator_factory.h",
    "content": "#pragma once\n#include <global_types.h>\n#include <utils.h>\n\nUTILS_API mutator_t * mutator_factory(char * mutator_filename);\nUTILS_API mutator_t * mutator_factory_directory(char * mutator_directory, char * mutator_type);\nUTILS_API char * mutator_help(char * mutator_directory);\n"
  },
  {
    "path": "utils/utils.c",
    "content": "#include \"utils.h\"\n\n#include <jansson_helper.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n#include <time.h>\n#include <errno.h>\n\n#ifdef _WIN32\n#include <io.h>\n#include <process.h>\n#include <tchar.h>\n#include <strsafe.h>\n#include <Shlwapi.h>\n#include <windows.h>\n\n#define F_OK 0\n#else\n\n#ifdef __APPLE__\n#include <mach-o/dyld.h> // _NSGetExecutablePath\n#endif\n\n#include <errno.h>\n#include <libgen.h>\n#include <signal.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <sys/wait.h>\n#include <unistd.h>\n#include <wordexp.h>\n#endif\n\n#ifdef _WIN32\nstatic int CreateChildProcess(char * cmd_line, HANDLE read_pipe, HANDLE * process_out, DWORD creation_flags);\n\n/**\n* This function converts a char * to a wchar *\n* @param - The char * string that should be converted to a wchar * string\n* @param - A wchar * buffer that the converted string should be placed into.  If NULL,\n* this function will allocate a wchar * buffer to place the converted string into.\n* @return - A pointer to the converted string\n*/\nUTILS_API wchar_t * convert_char_array_to_wchar(char * string, wchar_t * out_buffer)\n{\n\tsize_t size = (strlen(string) + 1) * sizeof(wchar_t);\n\tsize_t converted_length = 0;\n\n\tif (!out_buffer)\n\t{\n\t\tout_buffer = (wchar_t *)malloc(size);\n\t\tif (!out_buffer)\n\t\t\treturn NULL;\n\t}\n\n\tmbstowcs_s(&converted_length, out_buffer, strlen(string) + 1, string, size);\n\treturn out_buffer;\n}\n\n/**\n* This function converts a wchar * to a char *\n* @param - The wchar * string that should be converted to a char * string\n* @param - A char * buffer that the converted string should be placed into.  If NULL,\n* this function will allocate a char * buffer to place the converted string into.\n* @return - A pointer to the converted string\n*/\nUTILS_API char * convert_wchar_array_to_char(wchar_t * string, char * out_buffer)\n{\n\tsize_t size = (wcslen(string) + 1) * 2;\n\tsize_t converted_length = 0;\n\n\tif (!out_buffer)\n\t{\n\t\tout_buffer = (char *)malloc(size);\n\t\tif (!out_buffer)\n\t\t\treturn NULL;\n\t}\n\n\twcstombs_s(&converted_length, out_buffer, size, string, size-1);\n\treturn out_buffer;\n}\n\n\n#define CLOSE_PIPES() \\\n\tif(pipe_rd) CloseHandle(pipe_rd); \\\n\tif(pipe_wr) CloseHandle(pipe_wr);\n\n#define MAX_CMD_LEN 10*4096\n#define MAX_STANDARD_IN_PIPE_SIZE 8*1024 *1024 //8MB\n\nstatic int start_process_and_write_to_stdin_inner(char * cmd_line, char * input, size_t input_length, HANDLE * process_out, HANDLE * pipe_rd_ptr, HANDLE * pipe_wr_ptr, DWORD timeout_ms, DWORD creation_flags)\n{\n\tSECURITY_ATTRIBUTES saAttr;\n\tint ret;\n\tHANDLE pipe_rd, pipe_wr;\n\n\t//Mark the process as not started in case we error out\n\t*process_out = NULL;\n\tif (strlen(cmd_line) > MAX_CMD_LEN)\n\t\treturn 1;\n\n\t// Set the bInheritHandle flag so pipe handles are inherited.\n\tsaAttr.nLength = sizeof(SECURITY_ATTRIBUTES);\n\tsaAttr.bInheritHandle = TRUE;\n\tsaAttr.lpSecurityDescriptor = NULL;\n\n\t// Create a pipe for the child process's STDIN.\n\tif (!CreatePipe(&pipe_rd, &pipe_wr, &saAttr, min(input_length, MAX_STANDARD_IN_PIPE_SIZE)))\n\t\treturn 1;\n\n\t// Ensure the write handle to the pipe for STDIN is not inherited.\n\tif (!SetHandleInformation(pipe_wr, HANDLE_FLAG_INHERIT, 0))\n\t{\n\t\tCLOSE_PIPES();\n\t\treturn 1;\n\t}\n\n\t// Create the child process.\n\tif (CreateChildProcess(cmd_line, pipe_rd, process_out, creation_flags))\n\t{\n\t\tCLOSE_PIPES();\n\t\treturn 1;\n\t}\n\n\t//Write the input buffer\n\tret = 0;\n\tif (input && input_length > 0)\n\t{\n\t\tif (WriteToPipe(*process_out, pipe_wr, pipe_rd, input, input_length, timeout_ms))\n\t\t\tret = 1;\n\t}\n\n\t//Either save the pipes, or close them so we don't leak resources\n\tif (pipe_rd_ptr)\n\t\t*pipe_rd_ptr = pipe_rd;\n\telse\n\t\tCloseHandle(pipe_rd);\n\tif (pipe_wr_ptr)\n\t\t*pipe_wr_ptr = pipe_wr;\n\telse\n\t\tCloseHandle(pipe_wr);\n\treturn ret;\n}\n\n/**\n  * This function starts a process and writes to the stdin of the process.\n  * @param cmd_line - The command line of the new process to start\n  * @param input - a buffer that should be pasesd to the newly created process's stdin\n  * @param input_length - The length of the input parameter\n  * @param process_out - a pointer to a HANDLE that will be filled in with a handle to the newly created process\n  * @param pipe_rd_ptr - a pointer to a HANDLE that will be filled in with the read end of the stdin pipe for the new process.\n  * If pipe_rd_ptr is NULL, the read end of the stdin pipe will be closed instead.\n  * @param pipe_wr_ptr - a pointer to a HANDLE that will be filled in with the write end of the stdin pipe for the new process.\n  * If pipe_wr_ptr is NULL, the write end of the stdin pipe will be closed instead.\n  * @param timeout_ms - The maximum number of milliseconds to wait when writing to the newly created process's stdin pipe.\n  * @return - zero on success, non-zero on failure\n  */\nUTILS_API int start_process_and_write_to_stdin_and_save_pipes_timeout(char * cmd_line, char * input, size_t input_length, HANDLE * process_out, HANDLE * pipe_rd_ptr, HANDLE * pipe_wr_ptr, DWORD timeout_ms)\n{\n\treturn start_process_and_write_to_stdin_inner(cmd_line, input, input_length, process_out, pipe_rd_ptr, pipe_wr_ptr, timeout_ms, 0);\n}\n\n/**\n  * This function starts a process and writes to the stdin of the process.\n  * @param cmd_line - The command line of the new process to start\n  * @param input - a buffer that should be pasesd to the newly created process's stdin\n  * @param input_length - The length of the input parameter\n  * @param process_out - a pointer to a HANDLE that will be filled in with a handle to the newly created process\n  * @return - zero on success, non-zero on failure\n  */\nUTILS_API int start_process_and_write_to_stdin(char * cmd_line, char * input, size_t input_length, HANDLE * process_out)\n{\n\treturn start_process_and_write_to_stdin_inner(cmd_line, input, input_length, process_out, NULL, NULL, 0, 0);\n}\n\n/**\n  * This function starts a process and writes to the stdin of the process.\n  * @param cmd_line - The command line of the new process to start\n  * @param input - a buffer that should be pasesd to the newly created process's stdin\n  * @param input_length - The length of the input parameter\n  * @param process_out - a pointer to a HANDLE that will be filled in with a handle to the newly created process\n  * @param creation_flags - The creation flags that should be passed to the CreateProcess Windows API\n  * @return - zero on success, non-zero on failure\n  */\nUTILS_API int start_process_and_write_to_stdin_flags(char * cmd_line, char * input, size_t input_length, HANDLE * process_out, DWORD creation_flags)\n{\n\treturn start_process_and_write_to_stdin_inner(cmd_line, input, input_length, process_out, NULL, NULL, 0, creation_flags);\n}\n\n\n/**\n  * This function starts a new process\n  * @param cmd_line - The command line for the process to create\n  * @param read_pipe - A handle to the read end of a pipe that should be assigned to the newly created process's stdin\n  * @param process_out - A pointer toa HANDLE that will be filled in with a handle to the newly created process\n  * @param creation_flags - The creation flags that should be passed to the CreateProcess Windows API\n  * @return - zero on success, non-zero on failure\n  */\nstatic int CreateChildProcess(char * cmd_line, HANDLE read_pipe, HANDLE * process_out, DWORD creation_flags)\n{\n\tPROCESS_INFORMATION piProcInfo;\n\tSTARTUPINFO siStartInfo;\n\tBOOL bSuccess = FALSE;\n\n\t// Set up members of the PROCESS_INFORMATION structure.\n\n\tZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));\n\n\n\t// Set up members of the STARTUPINFO structure.\n\t// This structure specifies the STDIN and STDOUT handles for redirection.\n\n\tZeroMemory(&siStartInfo, sizeof(STARTUPINFO));\n\tsiStartInfo.cb = sizeof(STARTUPINFO);\n\tsiStartInfo.hStdInput = read_pipe;\n\tsiStartInfo.hStdError = NULL;\n\tsiStartInfo.hStdOutput = NULL;\n\tsiStartInfo.dwFlags |= STARTF_USESTDHANDLES;\n\tsiStartInfo.wShowWindow = 1;\n\n\t// Create the child process.\n\tbSuccess = CreateProcess(NULL,\n\t\tcmd_line,      // command line\n\t\tNULL,          // process security attributes\n\t\tNULL,          // primary thread security attributes\n\t\tTRUE,          // handles are inherited\n\t\tcreation_flags,// creation flags\n\t\tNULL,          // use parent's environment\n\t\tNULL,          // use parent's current directory\n\t\t&siStartInfo,  // STARTUPINFO pointer\n\t\t&piProcInfo);  // receives PROCESS_INFORMATION\n\n\t// If an error occurs, exit the application.\n\tif (!bSuccess)\n\t\treturn 1;\n\n\tCloseHandle(piProcInfo.hThread); //We don't need the thread handle\n\t*process_out = piProcInfo.hProcess;\n\treturn 0;\n}\n\n#define MAX_WRITE_SIZE 8*1024*1024 //8MB\n\n#define GET_FILETIME_DIFF_IN_MILLISECONDS(x,y,z) \\\n\tULARGE_INTEGER temp1##x##y, temp2##x##y; \\\n\ttemp1##x##y.LowPart = x.dwLowDateTime; temp1##x##y.HighPart = x.dwHighDateTime; \\\n\ttemp2##x##y.LowPart = y.dwLowDateTime; temp2##x##y.HighPart = y.dwHighDateTime; \\\n\tz = (temp1##x##y.QuadPart - temp2##x##y.QuadPart) / 10000;\n\n/**\n * Writes the given input buffer the a pipe, checking to make sure the other process hasn't died\n * and that there is room on the pipe to write.\n * @param process - The process that holds the read end of the pipe.\n * @param pipe_wr - The write end of the pipe that will be written to.\n * @param pipe_rd - The read end of the pipe being written to\n * @param input - a buffer to write to the the pipe_wr parameter\n * @param input_length - The length of the input parameter\n * @param timeout_ms - The maximum number of milliseconds to wait when writing to the pipe\n * @return - 0 on success (all bytes written to the pipe), 1 on failure\n */\nUTILS_API int WriteToPipe(HANDLE process, HANDLE pipe_wr, HANDLE pipe_rd, char * input, size_t input_length, DWORD timeout_ms)\n{\n\tDWORD dwWritten, out_size, total_in_pipe, timediff;\n\tsize_t total_written = 0, write_size;\n\tBOOL bSuccess = FALSE;\n\tFILETIME start_time, time;\n\n\tGetSystemTimeAsFileTime(&start_time);\n\twhile (total_written < input_length && get_process_status(process))\n\t{\n\t\tif (!GetNamedPipeInfo(pipe_wr, NULL, &out_size, NULL, NULL))\n\t\t\tbreak;\n\t\tif (!PeekNamedPipe(pipe_rd, NULL, 0, NULL, &total_in_pipe, NULL))\n\t\t\tbreak;\n\t\twrite_size = min(min(input_length - total_written, MAX_WRITE_SIZE), out_size - total_in_pipe);\n\t\tif (write_size == 0) //There's no room to write to the pipe\n\t\t{\n\t\t\tGetSystemTimeAsFileTime(&time);\n\t\t\tGET_FILETIME_DIFF_IN_MILLISECONDS(time, start_time, timediff);\n\t\t\tif (timeout_ms && timediff > timeout_ms)\n\t\t\t\treturn 1;\n\t\t\tdwWritten = WaitForSingleObject(pipe_wr, timeout_ms);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbSuccess = WriteFile(pipe_wr, input + total_written, write_size, &dwWritten, NULL);\n\t\t\tif (!bSuccess) break;\n\t\t\ttotal_written += dwWritten;\n\t\t}\n\t}\n\treturn total_written != input_length;\n}\n\n/**\n * Flushes any input waiting on the given pipe\n * @param pipe_rd - a handle to the pipe that should be flushed\n * @return - 0 on success, non-zero on failure\n */\nUTILS_API int FlushPipe(HANDLE pipe_rd)\n{\n\tDWORD total_in_pipe, num_read;\n\tint failed;\n\tchar * temp;\n\n\tif (!PeekNamedPipe(pipe_rd, NULL, 0, NULL, &total_in_pipe, NULL))\n\t\treturn 1;\n\tif (!total_in_pipe)\n\t\treturn 0;\n\n\ttemp = (char *)malloc(total_in_pipe);\n\tfailed = ReadFile(pipe_rd, temp, total_in_pipe, &num_read, NULL) != TRUE;\n\tfree(temp);\n\tif (num_read != total_in_pipe)\n\t\tfailed = 1;\n\treturn failed;\n}\n\n#endif //_WIN32\n\n/**\n * This function checks if a process is still alive\n * @param - a HANDLE to the process to check\n * @return - FUZZ_RUNNING (1) if the process is alive, FUZZ_NONE (0) if it is not, FUZZ_ERROR (-1) on failure\n */\n#ifdef _WIN32\nUTILS_API int get_process_status(HANDLE process)\n{\n\tDWORD exitCode;\n\tif (GetExitCodeProcess(process, &exitCode) == 0)\n\t\treturn FUZZ_ERROR;\n\treturn exitCode == STILL_ACTIVE;\n}\n#else\n/**\n * This function checks if a CHILD process is still alive\n * @return - FUZZ_CRASH (2) if the process exited by crash, FUZZ_RUNNING (1) if\n * the process is alive, FUZZ_NONE (0) if it exited cleanly, FUZZ_ERROR (-1) on\n * failure\n *\n * NOTE: This should only be called once after a process has terminated.\n *\n */\nUTILS_API int get_process_status(pid_t pid)\n{\n\n\t// We can't use kill here, because it'll return \"alive\" if the process is\n\t// in a zombie state (ie, unreaped).  So, we have to reap here.\n\n\tint status;\n\tpid_t result;\n\n\t// WNOHANG result: 0 means it exists and is alive, pid means it has exited,\n\t// -1 means error\n\tresult = waitpid(pid, &status, WNOHANG);\n\n\tif(result == 0) {\n\t\treturn FUZZ_RUNNING;\n\t} else if (result > 0) {\n\t\tif(WIFEXITED(status))\n\t\t\treturn FUZZ_NONE; // it exited normally\n\t\tif(WIFSIGNALED(status))\n\t\t\treturn FUZZ_CRASH; // it crashed\n\t}\n\t// either waitpid failed, or the process is not running, did not exit\n\t// normally, and was not signaled, in either case we don't know what\n\t// went wrong\n\treturn FUZZ_ERROR;\n}\n#endif\n\n/**\n * Generates a temporary filename\n * @param suffix - Optionally, a suffix to append to the generated temporary filename.  If NULL,\n * no file extension will be added.\n * @return - NULL on failure, or a newly allocated character buffer holding the temporary filename.\n * The caller should free the returned buffer\n */\nUTILS_API char * get_temp_filename(char * suffix)\n{\n#ifdef _WIN32\n\tchar temp_dir[MAX_PATH];\n\tchar temp_filename[MAX_PATH];\n\tchar * ret;\n\tsize_t suffix_length = 0;\n\n\t//Get the temp filename\n\t// eg C:\\Users\\<name>\\AppData\\Local\\Temp\\ \n\tif (GetTempPath(MAX_PATH, temp_dir) == 0)\n\t\treturn NULL;\n\t// eg C:\\Users\\<name>\\AppData\\Local\\Temp\\fuzD828.tmp\n\tGetTempFileName(temp_dir, \"fuzzfile\", 0, temp_filename);\n\n\t//Add the suffix and convert it to a useable format\n\tif (suffix)\n\t\tsuffix_length = strlen(suffix);\n\n\tret = (char *)malloc(MAX_PATH + suffix_length);\n\tif (!ret)\n\t\treturn NULL;\n\n\tmemset(ret, 0, MAX_PATH + suffix_length);\n\tstrncpy(ret, temp_filename, MAX_PATH);\n\tunlink(ret); //Cleanup the file without the extension that GetTempFileName generated\n\tif(suffix)\n\t\tstrncat(ret, suffix, MAX_PATH + suffix_length);\n\t// eg C:\\Users\\<name>\\AppData\\Local\\Temp\\fuzFEAD.tmp.txt\n\n#else\n\t// on macOS we can use $TMPDIR. ubuntu doesn't seem to have one, stackoverflow recommends\n\t// /tmp. /dev/shm might be a better option, because it's a tmpfs (doesn't write to disk)\n\t// but i suspect it's less portable to other *nixes.\n\tchar temp_filename[] = \"/tmp/fuzzfileXXXXXX\"; // X's required for mktemp\n\tchar * ret;\n\tsize_t suffix_length = 0;\n\n\t// mktemp is unsafe, but i'm not sure what the threat model is.\n\t// for ours, it might be sufficient.\n\t// alternatively, we can mkstemp, but that will also create a file\n\t// (as is happening in the windows version of the code) and requires deletion.\n\t// that's probably as simple as an unlink(), but it's almost certainly slower.\n\tmktemp(temp_filename);\n\n\tif (suffix)\n\t\tsuffix_length = strlen(suffix);\n\n\tret = (char *)malloc(MAX_PATH + suffix_length);\n\tif (!ret)\n\t\treturn NULL;\n\n\tmemset(ret, 0, MAX_PATH + suffix_length);\n\tstrncpy(ret, temp_filename, MAX_PATH);\n\tif(suffix)\n\t\tstrncat(ret, suffix, MAX_PATH + suffix_length);\n\n#endif\n\n\treturn ret;\n}\n\n/**\n * Determines whether a file exists or not\n * @param path - The path of the file to check for existence\n * @return - 1 if the file exists, 0 otherwise\n */\nUTILS_API int file_exists(char * path)\n{\n\treturn !access(path,F_OK);\n}\n\n/**\n * This function writes a buffer to the specified file.\n * @param filename - The filename to write the buffer to\n * @param buffer - The buffer to write\n * @param length - THe length of the buffer parameter\n * @param return - 0 on success, non-zero otherwise\n */\nUTILS_API int write_buffer_to_file(char * filename, char * buffer, size_t length)\n{\n\tint num_written;\n\tsize_t total = 0;\n\tFILE * fp = NULL;\n\tint error = EACCES;\n\n#ifdef _WIN32\n\t//On Windows, we need to do this in a loop, since we may\n\t//need to wait for a process to stop holding this file\n\twhile (!fp && error == EACCES)\n\t{\n\t\tfp = fopen(filename, \"wb+\");\n\t\terror = errno;\n\t}\n#else\n\tfp = fopen(filename, \"wb+\");\n#endif\n\tif (!fp)\n\t\treturn -1;\n\n\twhile (total < length)\n\t{\n\t\tnum_written = fwrite(buffer + total, 1, length - total, fp);\n\t\tif (num_written < 0 && errno != EAGAIN && errno != EINTR)\n\t\t\tbreak;\n\t\telse if (num_written > 0)\n\t\t\ttotal += num_written;\n\t}\n\tfclose(fp);\n\treturn total != length;\n}\n\n/**\n* This function takes a relative path representing a location relative to the\n* running binary (note: NOT the working directory) and returns the\n* corresponding absolute path, if that path exists in the filesystem.\n*\n* @param relative_path - a char * pointing to the path relative to the executable\n* @return - NULL on error or nonexistent path, or a char * pointing to a\n* newly-allocated buffer containing the absolute path. The caller should free the\n* returned buffer\n*/\nUTILS_API char * filename_relative_to_binary_dir(char * relative_path) {\n\tchar exedir[2*MAX_PATH], temppath[MAX_PATH];\n\tint len;\n\n// write full path into exedir\n#ifdef _WIN32\n\tif (!GetModuleFileName(NULL, exedir, 2*MAX_PATH)) {\n\t\treturn NULL;\n\t}\n\tPathRemoveFileSpec(exedir);  // Cut off file name\n\tlen = snprintf(temppath, MAX_PATH, \"%s\\\\%s\", exedir, relative_path);\n#elif __APPLE__\n\tunsigned int bufsize = sizeof(exedir) + 1;\n\tif (_NSGetExecutablePath(exedir, &bufsize) != 0)\n\t\treturn NULL;\n\trealpath(exedir, temppath);\n\tdirname_r(temppath, temppath); // Cut off file name\n\tlen = snprintf(temppath, MAX_PATH, \"%s/%s\", temppath, relative_path);\n#else\n\tif ((len = readlink(\"/proc/self/exe\", exedir, MAX_PATH)) < 0)\n\t\treturn NULL;\n\n\texedir[len] = 0; //readlink doesn't null terminate\n\tdirname(exedir); // Cut off file name\n\tlen = snprintf(temppath, MAX_PATH, \"%s/%s\", exedir, relative_path);\n#endif\n\n\tif (len == MAX_PATH) {\n\t\treturn NULL;\n\t}\n\n\tif (!file_exists(temppath)) {\n\t\treturn NULL;\n\t}\n\treturn strdup(temppath);\n}\n\n/**\n * Calculates the MD5 hash of a buffer and return the value as a hexstring.\n * Taken from https://gist.github.com/creationix/4710780\n * @param buffer - The buffer to calculate the md5 hash on\n * @param buffer_length - the length of the buffer parameter\n * @param output - a buffer to record the md5 hash to.\n * @param output_size - the length of the output parameter\n */\nvoid md5(uint8_t *buffer, size_t buffer_length, char * output, size_t output_size) {\n\n\t// leftrotate function definition\n\t#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))\n\n\n\t// These vars will contain the hash\n\tuint32_t h0, h1, h2, h3;\n\n\t// Message (to prepare)\n\tuint8_t *msg = NULL;\n\n\t// Note: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating\n\n\t// r specifies the per-round shift amounts\n\n\tuint32_t r[] = { 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,\n\t\t5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20,\n\t\t4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,\n\t\t6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 };\n\n\t// Use binary integer part of the sines of integers (in radians) as constants// Initialize variables:\n\tuint32_t k[] = {\n\t\t0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,\n\t\t0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,\n\t\t0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,\n\t\t0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,\n\t\t0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,\n\t\t0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,\n\t\t0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,\n\t\t0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,\n\t\t0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,\n\t\t0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,\n\t\t0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,\n\t\t0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,\n\t\t0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,\n\t\t0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,\n\t\t0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,\n\t\t0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };\n\n\th0 = 0x67452301;\n\th1 = 0xefcdab89;\n\th2 = 0x98badcfe;\n\th3 = 0x10325476;\n\n\t// Pre-processing: adding a single 1 bit\n\t//append \"1\" bit to message\n\t/* Notice: the input bytes are considered as bits strings,\n\twhere the first bit is the most significant bit of the byte.[37] */\n\n\t// Pre-processing: padding with zeros\n\t//append \"0\" bit until message length in bit = 448 (mod 512)\n\t//append length mod (2 pow 64) to message\n\n\tint new_len;\n\tfor (new_len = buffer_length * 8 + 1; new_len % 512 != 448; new_len++);\n\tnew_len /= 8;\n\n\tmsg = (uint8_t *)calloc(new_len + 64, 1); // also appends \"0\" bits\n                                              // (we alloc also 64 extra bytes...)\n\tmemcpy(msg, buffer, buffer_length);\n\tmsg[buffer_length] = 128; // write the \"1\" bit\n\n\tuint32_t bits_len = 8 * buffer_length; // note, we append the len\n\tmemcpy(msg + new_len, &bits_len, 4); // in bits at the end of the buffer\n\n\t// Process the message in successive 512-bit chunks:\n\tint offset;\n\tfor (offset = 0; offset<new_len; offset += (512 / 8)) {\n\n\t\t// break chunk into sixteen 32-bit words w[j], 0 = j = 15\n\t\tuint32_t *w = (uint32_t *)(msg + offset);\n\n\t\t// Initialize hash value for this chunk:\n\t\tuint32_t a = h0;\n\t\tuint32_t b = h1;\n\t\tuint32_t c = h2;\n\t\tuint32_t d = h3;\n\n\t\tuint32_t i;\n\t\tfor (i = 0; i<64; i++) {\n\n\t\t\tuint32_t f, g;\n\n\t\t\tif (i < 16) {\n\t\t\t\tf = (b & c) | ((~b) & d);\n\t\t\t\tg = i;\n\t\t\t}\n\t\t\telse if (i < 32) {\n\t\t\t\tf = (d & b) | ((~d) & c);\n\t\t\t\tg = (5 * i + 1) % 16;\n\t\t\t}\n\t\t\telse if (i < 48) {\n\t\t\t\tf = b ^ c ^ d;\n\t\t\t\tg = (3 * i + 5) % 16;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tf = c ^ (b | (~d));\n\t\t\t\tg = (7 * i) % 16;\n\t\t\t}\n\n\t\t\tuint32_t temp = d;\n\t\t\td = c;\n\t\t\tc = b;\n\t\t\tb = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]);\n\t\t\ta = temp;\n\t\t}\n\n\t\t// Add this chunk's hash to result so far:\n\t\th0 += a;\n\t\th1 += b;\n\t\th2 += c;\n\t\th3 += d;\n\n\t}\n\tfree(msg);\n\n\t//Copy the hash to the output buffer\n\tuint8_t *p0 = (uint8_t *)&h0, *p1 = (uint8_t *)&h1, *p2 = (uint8_t *)&h2, *p3 = (uint8_t *)&h3;\n\tsnprintf(output, output_size, \"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\",\n\t\tp0[0], p0[1], p0[2], p0[3], p1[0], p1[1], p1[2], p1[3],\n\t\tp2[0], p2[1], p2[2], p2[3], p3[0], p3[1], p3[2], p3[3]\n\t);\n}\n\nstatic struct logging_info {\n\tint initialized;\n\tint level;\n\tFILE * log_file;\n\n\tint stdout_on:1;\n\tint file_on:1;\n} logging = { .initialized = 0, .level = INFO, .log_file = NULL, .stdout_on = 1, .file_on = 1, };\n\nconst char * log_level_names[] = {\n\t\"DEBUG\",\n\t\"INFO\",\n\t\"WARNING\",\n\t\"ERROR\",\n\t\"CRITICAL\",\n\t\"FATAL\"\n};\n\n/**\n * Returns a string describing the options for the logging subsystem\n */\nUTILS_API char * logging_help(void)\n{\n\treturn strdup(\n\"Logging Options:\\n\"\n\"  file                  Enable/disable file logging (default enabled)\\n\"\n\"  filename              Set the filename of the logging file\\n\"\n\"                          (default killerbeez.log)\\n\"\n\"  level                 Set the log level (0-4), higher is less verbose, lower\\n\"\n\"                          is more verbose (default 1)\\n\"\n\"  stdout                Enable/disable logging to stdout (default enabled)\\n\"\n\t);\n}\n\n#define GET_OPTIONAL_ARG(temp, options, dest, name, ret, func) \\\n\ttemp = func(options, name, &ret);                          \\\n\tif (ret < 0)                                               \\\n\t\treturn 1;                                              \\\n\tif (ret > 0)                                               \\\n\t\tdest = temp;\n\n/**\n  * This function takes a JSON string of logging options and sets up the desired\n  * logging state.\n  *\n  * @param log_options - a JSON string of logging options.  For the default options,\n  * NULL can be provided\n  * @return - zero on success, non-zero on error\n  */\nUTILS_API int setup_logging(const char * log_options)\n{\n\tint temp_int, result;\n\tchar * temp_str, * filename = NULL;\n\n\tif (logging.initialized)\n\t\treturn 0;\n\t\n\tif (log_options) {\n\t\tGET_OPTIONAL_ARG(temp_int, log_options, logging.level, \"level\", result, get_int_options);\n\t\tGET_OPTIONAL_ARG(temp_int, log_options, logging.stdout_on, \"stdout\", result, get_int_options);\n\t\tGET_OPTIONAL_ARG(temp_int, log_options, logging.file_on, \"file\", result, get_int_options);\n\t\tGET_OPTIONAL_ARG(temp_str, log_options, filename, \"filename\", result, get_string_options);\n\t}\n\n\tif (logging.file_on) {\n\t\tif (!filename)\n\t\t\tfilename = strdup(\"killerbeez.log\");\n\n\t\tlogging.log_file = fopen(filename, \"a+\");\n\t\tif (!logging.log_file) {\n#ifdef _WIN32\n\t\t\tprintf(\"[LOGGING] ERROR: Failed to open file %s. GetLastError %d\", filename, GetLastError());\n#else\n\t\t\tprintf(\"[LOGGING] ERROR: Failed to open file %s. errno %d\", filename, errno);\n#endif\n\t\t\treturn 1;\n\t\t}\n\t\tfree(filename);\n\t}\n\n\tlogging.initialized = 1;\n\tINFO_MSG(\"Logging Started\");\n\treturn 0;\n}\n\n/**\n  * This function takes a log level, a printf style format string, and printf style\n  * arguments and outputs the message to any of the configured loggers.  Prior to\n  * calling this function, logging must be initialized via the setup_logging\n  * function prior to any calls to log_msg.  If the specified level is FATAL or\n  * above, log_msg will exit(1) immediately after logging the specified message.\n  *\n  * @param level - the log level of the message to log\n  * @param msg - a printf style format string to log\n  * @param ... - printf style arguments to log\n  * @return - zero on success, non-zero on error\n  */\nUTILS_API int log_msg(enum LOG_LEVEL level, const char * msg, ...)\n{\n\tva_list args, temp_args;\n\tstruct tm new_time;\n\ttime_t aclock;\n\tchar time_buf[64];\n\n\tif (!logging.initialized)\n\t\treturn 1;\n\tif (level < logging.level)\n\t\treturn 0;\n\n\ttime(&aclock);\n#ifdef _WIN32\n\tlocaltime_s(&new_time, &aclock);\n\tif (asctime_s(time_buf, sizeof(time_buf), &new_time))\n#else\n\tlocaltime_r(&aclock, &new_time);\n\tif (!asctime_r(&new_time, time_buf))\n#endif\n\t{ //If we couldn't get the time, NULL out time_buf, so we don't print garbage\n\t\tstrncpy(time_buf, \"TIME FAILURE\", sizeof(time_buf));\n\t}\n\telse //asctime appends a newline to the end of the buffer,\n\t\ttime_buf[strlen(time_buf) - 1] = 0; //remove it\n\n\tva_start(args, msg);\n\tif (logging.stdout_on) {\n\t\tva_copy(temp_args, args);\n\t\tfprintf(stdout, \"%s - %-8s - \", time_buf, log_level_names[level]);\n\t\tvprintf(msg, temp_args);\n\t\tfwrite(\"\\n\", 1, 1, stdout);\n\t\tfflush(stdout);\n\t\tva_end(temp_args);\n\t}\n\tif (logging.file_on) {\n\t\tva_copy(temp_args, args);\n\t\tfprintf(logging.log_file, \"%s - %-8s - \", time_buf, log_level_names[level]);\n\t\tvfprintf(logging.log_file, msg, temp_args);\n\t\tfwrite(\"\\n\", 1, 1, logging.log_file);\n\t\tfflush(logging.log_file);\n\t\tva_end(temp_args);\n\t}\n\tva_end(args);\n\n\t//If the message is FATAL, we should die after logging\n\tif (level >= FATAL)\n\t\texit(1);\n\n\treturn 0;\n}\n\n/**\n * Reads a file from disk\n * @param filename - The filename of the file to read\n * @param buffer - A pointer to a character buffer that will be assigned a newly allocated\n * buffer to hold the file contents.  The caller should free this buffer.\n * @return - -1 on failure, otherwise the number of bytes read from the file\n */\nUTILS_API int read_file(char * filename, char **buffer)\n{\n\tFILE *fp;\n\tlong fsize, total = 0, num_read;\n\n\t*buffer = NULL;\n\n\tfp = fopen(filename, \"rb\");\n\tif (!fp)\n\t\treturn -1;\n\n\t//Get the size\n\tfseek(fp, 0, SEEK_END);\n\tfsize = ftell(fp);\n\tfseek(fp, 0, SEEK_SET);\n\n\t*buffer = (char *)malloc(fsize + 1);\n\tif (!*buffer)\n\t{\n\t\tfclose(fp);\n\t\treturn -1;\n\t}\n\n\t(*buffer)[fsize] = 0; //NULL terminate in case the caller wants to use it as a string\n\twhile (total < fsize)\n\t{\n\t\tnum_read = fread(*buffer + total, 1, fsize, fp);\n\t\ttotal += num_read;\n\t}\n\n\tfclose(fp);\n\n\treturn fsize;\n}\n\n/**\n * This function prints a data buffer in hex\n * @param data - a char * data buffer\n * @param size - the size of the data buffer\n * @return none\n */\nUTILS_API void print_hex(char * data, size_t size) {\n\tunsigned char *p = (unsigned char *)data;\n\tfor (size_t i = 0; i<size; i++) {\n\t\tif ((i % 16 == 0) && i)\n\t\t\tprintf(\"\\n\");\n\t\tprintf(\"%02x\", p[i]);\n\t}\n}\n\n/**\n * Allocates a new region of memory and copies the specified buffer onto it\n * @param src - a pointer to the region of memory to copy\n * @param length - the length of the region of memory to copy\n * @return a newly created region of memory with the specified contents on success, or NULL on failure\n */\nUTILS_API void * memdup(void * src, size_t length)\n{\n\tvoid * dest = malloc(length);\n\tif (dest)\n\t\tmemcpy(dest, src, length);\n\treturn dest;\n}\n\n/**\n * Creates a mutex\n * @return - the created mutex on success, NULL on failure\n */\nUTILS_API mutex_t create_mutex(void)\n{\n#ifdef _WIN32\n\treturn CreateMutex(NULL, FALSE, NULL);\n#else\n\tpthread_mutex_t * mutex = malloc(sizeof(pthread_mutex_t));\n\tif (mutex)\n\t\tpthread_mutex_init(mutex, NULL);\n\treturn mutex;\n#endif\n}\n\n/**\n * Takes a mutex\n * @param mutex - the mutex to take\n * @return - zero on success, nonzero on failure\n */\nUTILS_API int take_mutex(mutex_t mutex)\n{\n#ifdef _WIN32\n\treturn WaitForSingleObject(mutex, INFINITE) == WAIT_FAILED;\n#else\n\treturn pthread_mutex_lock(mutex);\n#endif\n}\n\n/**\n * Releases a mutex\n * @param mutex - the mutex to release\n * @return - zero on success, nonzero on failure\n */\nUTILS_API int release_mutex(mutex_t mutex)\n{\n#ifdef _WIN32\n\treturn ReleaseMutex(mutex) == 0;\n#else\n\treturn pthread_mutex_unlock(mutex);\n#endif\n}\n\n/**\n * Cleans up the resources asscoiated with a mutex\n * @param mutex - the mutex to clean up\n */\nUTILS_API void destroy_mutex(mutex_t mutex)\n{\n\tif (mutex) {\n#ifdef _WIN32\n\t\tCloseHandle(mutex);\n#else\n\t\tpthread_mutex_destroy(mutex);\n\t\tfree(mutex);\n#endif\n\t}\n}\n\n/**\n * Creates a semaphore with the specified initial value and max value (max value\n * only used on Windows)\n * @param initial - the initial value of the semaphore\n * @param max - the max value of the semaphore (only used on Windows)\n * @return - the created semaphore on success, NULL on failure\n */\nUTILS_API semaphore_t create_semaphore(int initial, int max)\n{\n#ifdef _WIN32\n\treturn CreateSemaphore(NULL, initial, max, NULL);\n#else\n\tsem_t * semaphore = malloc(sizeof(sem_t));\n\tif (semaphore && sem_init(semaphore, 0, initial)) {\n\t\tfree(semaphore);\n\t\tsemaphore = NULL;\n\t}\n\treturn semaphore;\n#endif\n}\n\n/**\n * Takes a semaphore\n * @param semaphore - the semaphore to take\n * @return - zero on success, nonzero on failure\n */\nUTILS_API int take_semaphore(semaphore_t semaphore)\n{\n#ifdef _WIN32\n\treturn WaitForSingleObject(semaphore, INFINITE) == WAIT_FAILED;\n#else\n\t//Loop and wait to actually take it, in case we get stopped by a signal\n\tint taken = 0;\n\twhile (!taken) {\n\t\tif (!sem_wait(semaphore))\n\t\t\ttaken = 1;\n\t\telse if (errno != EINTR) //got a signal rather than took the semaphore\n\t\t\tbreak;\n\t}\n\treturn taken == 0;\n#endif\n}\n\n/**\n * Releases a semaphore\n * @param semaphore - the semaphore to release\n * @return - zero on success, nonzero on failure\n */\nUTILS_API int release_semaphore(semaphore_t semaphore)\n{\n#ifdef _WIN32\n\treturn ReleaseSemaphore(semaphore, 1, NULL) == 0;\n#else\n\treturn sem_post(semaphore);\n#endif\n}\n\n/**\n * Cleans up the resources asscoiated with a semaphore\n * @param semaphore - the semaphore to clean up\n */\nUTILS_API void destroy_semaphore(semaphore_t semaphore)\n{\n\tif (semaphore) {\n#ifdef _WIN32\n\t\tCloseHandle(semaphore);\n#else\n\t\tsem_destroy(semaphore);\n\t\tfree(semaphore);\n#endif\n\t}\n}\n\n#ifndef _WIN32\n\n/**\n * This function takes a command line and splits it into the executable filename and\n * the argv-array style arguments.\n * @param cmd_line - the command line to split\n * @param executable - A pointer that will be assigned the filename of the executable\n * in the command line.  The assigned pointer should be freed by the caller.\n * @param argv - A pointer that will be assigned the address of an argv style arguments\n * array.  This array and each item in it should be freed by the caller.\n * @return - 0 on success, non-zero on failure\n */\nUTILS_API int split_command_line(char * cmd_line, char ** executable, char ***argv)\n{\n\twordexp_t wordexp_result;\n\tsize_t i, j;\n\tchar * target_executable, **target_argv;\n\n\t// Expand the command line into the program and arguments\n\tif(wordexp(cmd_line, &wordexp_result, 0)) {\n\t\twordfree(&wordexp_result);\n\t\treturn -1;\n\t}\n\n\ttarget_executable = strdup(wordexp_result.we_wordv[0]);\n\ttarget_argv = malloc(sizeof(char *) * (wordexp_result.we_wordc+1));\n\tif(!target_executable || !target_argv) {\n\t\tfree(target_executable);\n\t\tfree(target_argv);\n\t\twordfree (&wordexp_result);\n\t\treturn -1;\n\t}\n\n\tfor(i = 0; i < wordexp_result.we_wordc; i++) {\n\t\ttarget_argv[i] = strdup(wordexp_result.we_wordv[i]);\n\t\tif(!target_argv[i]) {\n\t\t\tfree(target_executable);\n\t\t\tfor(j = 0; j < i; j++)\n\t\t\t\tfree(target_argv[j]);\n\t\t\tfree(target_argv);\n\t\t\twordfree (&wordexp_result);\n\t\t\treturn -1;\n\t\t}\n\t}\n\ttarget_argv[wordexp_result.we_wordc] = NULL;\n\n\twordfree (&wordexp_result);\n\t*executable = target_executable;\n\t*argv = target_argv;\n\treturn 0;\n}\n\n/**\n * This function starts a process and writes to the stdin of the process.\n * @param cmd_line - The command line of the new process to start.  The command line must start with the\n * path of the executable to start.\n * @param input - a buffer that should be pasesd to the newly created process's stdin\n * @param input_length - The length of the input parameter\n * @param process_out - a pointer to a pid_t that will be filled in with a handle to the newly created process\n * @return - zero on success, non-zero on failure\n */\nUTILS_API int start_process_and_write_to_stdin(char * cmd_line, char * input, size_t input_length, pid_t * process_out)\n{\n\tint pipes[2];\n\tint status, i;\n\tpid_t child_pid;\n\tssize_t result;\n\tsize_t total_written = 0;\n\tchar * executable, **argv;\n\n\tif(split_command_line(cmd_line, &executable, &argv))\n\t\treturn 1;\n\n\tif(pipe(pipes))\n\t\treturn 1;\n\n\tchild_pid = fork();\n\tif(child_pid < 0)\n\t\treturn 1;\n\telse if(child_pid == 0) { //Child\n\n\t\t// Open a file descriptor to /dev/null. I don't believe this needs to be closed.\n\t\tint dev_null = open(\"/dev/null\", O_WRONLY);\n\t\tif (dev_null == -1 )\n\t\t\tFATAL_MSG(\"Couldn't open /dev/null for child process.\");\n\n\t\tclose(pipes[1]); // close the in side of the pipe for the child\n\t\t// connect read side of pipe to child's stdin, closing the in side of the pipe for the child\n\t\tdup2(pipes[0], STDIN_FILENO);\n\t\tclose(pipes[0]); // close fd attached to out side of pipe\n\n\t\t// redirect child's stdout/stderr to devnull\n\t\tdup2(dev_null, STDOUT_FILENO);\n\t\tdup2(dev_null, STDERR_FILENO);\n\n\t\t// fd 1/2 now point to /dev/null, so it stays open.\n\t\tclose(dev_null);\n\n\t\texecv(executable, argv);\n\t\texit(EXIT_FAILURE);\n\t} // back to parent code\n\n\tclose(pipes[0]);\n\n\t// Write the fuzz input to the child, from the parent.\n\twhile (total_written < input_length)\n\t{\n\t\tresult = write(pipes[1], input + total_written, input_length - total_written);\n\t\tif (result > 0)\n\t\t\ttotal_written += result;\n\t\telse if (result < 0 && errno != EAGAIN) //Error, then break\n\t\t\tbreak;\n\t}\n\n\tclose(pipes[1]);\n\n\t// If the child stopped accepting input (write failed)\n\tif(total_written != input_length)\n\t{\n\t\tkill(child_pid, 9);\n\t\twait(&status);\n\t\treturn 1;\n\t}\n\n\tfree(executable);\n\tfor(i = 0; argv[i]; i++)\n\t\tfree(argv[i]);\n\tfree(argv);\n\n\t*process_out = child_pid;\n\treturn 0;\n}\n\n#endif //!_WIN32\n"
  },
  {
    "path": "utils/utils.h",
    "content": "#pragma once\n\n#ifdef _WIN32\n#include <Windows.h>\n#else\n#include <pthread.h>\n#include <semaphore.h>\n#include <dlfcn.h>\n#ifdef __APPLE__\n#include <sys/syslimits.h>\n#else\n#include <linux/limits.h>\n#endif\n#endif\n\n#include <stdint.h>\n#include <stdlib.h>\n\n#ifdef _WIN32\n#if defined(UTILS_EXPORTS)\n#define UTILS_API __declspec(dllexport)\n#elif defined(UTILS_NO_IMPORT)\n#define UTILS_API\n#elif defined(__cplusplus)\n#define UTILS_API extern \"C\" __declspec(dllimport)\n#else\n#define UTILS_API\n#endif\n#else //_WIN32\n#define UTILS_API\n#endif\n\n#ifndef MAX_PATH\n#define MAX_PATH PATH_MAX\n#endif\n\n#define FUZZ_ERROR -1\n#define FUZZ_NONE  0\n#define FUZZ_RUNNING 1\n#define FUZZ_CRASH 2\n#define FUZZ_HANG  3\n\n#ifdef _WIN32\ntypedef HANDLE mutex_t;\ntypedef HANDLE semaphore_t;\n#else\ntypedef pthread_mutex_t * mutex_t;\ntypedef sem_t * semaphore_t;\n#endif\n\n#ifdef _WIN32\nUTILS_API int start_process_and_write_to_stdin(char * cmd_line, char * input, size_t input_length, HANDLE * process_out);\nUTILS_API int start_process_and_write_to_stdin_flags(char * cmd_line, char * input, size_t input_length, HANDLE * process_out, DWORD creation_flags);\nUTILS_API int start_process_and_write_to_stdin_and_save_pipes_timeout(char * cmd_line, char * input, size_t input_length, HANDLE * process_out, HANDLE * pipe_rd_ptr, HANDLE * pipe_wr_ptr, DWORD timeout_ms);\nUTILS_API int WriteToPipe(HANDLE process, HANDLE pipe_wr, HANDLE pipe_rd, char * input, size_t input_length, DWORD timeout_ms);\nUTILS_API int FlushPipe(HANDLE pipe_rd);\nUTILS_API wchar_t * convert_char_array_to_wchar(char * string, wchar_t * out_buffer);\nUTILS_API char * convert_wchar_array_to_char(wchar_t * string, char * out_buffer);\nUTILS_API int get_process_status(HANDLE process);\n#else\nUTILS_API int get_process_status(pid_t process);\n#endif\n\nUTILS_API char * get_temp_filename(char * suffix);\nUTILS_API int file_exists(char * path);\nUTILS_API int write_buffer_to_file(char * filename, char * buffer, size_t length);\nUTILS_API char * filename_relative_to_binary_dir(char * relative_path);\nUTILS_API int read_file(char * filename, char **buffer);\nUTILS_API void print_hex(char * data, size_t size);\nUTILS_API void md5(uint8_t *initial_msg, size_t initial_len, char * output, size_t output_size);\nUTILS_API void * memdup(void * src, size_t length);\n\nUTILS_API mutex_t create_mutex(void);\nUTILS_API int take_mutex(mutex_t mutex);\nUTILS_API int release_mutex(mutex_t mutex);\nUTILS_API void destroy_mutex(mutex_t mutex);\nUTILS_API semaphore_t create_semaphore(int initial, int max);\nUTILS_API int take_semaphore(semaphore_t semaphore);\nUTILS_API int release_semaphore(semaphore_t semaphore);\nUTILS_API void destroy_semaphore(semaphore_t semaphore);\n\n#ifndef _WIN32\nUTILS_API int split_command_line(char * cmd_line, char ** executable, char ***argv);\nUTILS_API int start_process_and_write_to_stdin(char * cmd_line, char * input, size_t input_length, pid_t * process_out);\n#endif\n\n//Logging\nenum LOG_LEVEL {\n\tDEBUG,\n\tINFO,\n\tWARNING,\n\tERROR_LEVEL, //ERROR is already taken\n\tCRITICAL,\n\tFATAL,\n\tMAX_LOG_LEVEL,\n};\n\n#if defined(_DEBUG)\n#define DEBUG_MSG(msg, ...) log_msg(DEBUG, msg, ##__VA_ARGS__)\n#else\n#define DEBUG_MSG(msg, ...)\n#endif\n\n#define INFO_MSG(msg, ...) log_msg(INFO, msg, ##__VA_ARGS__)\n#define WARNING_MSG(msg, ...) log_msg(WARNING, msg, ##__VA_ARGS__)\n#define ERROR_MSG(msg, ...) log_msg(ERROR_LEVEL, msg, ##__VA_ARGS__)\n#define CRITICAL_MSG(msg, ...) log_msg(CRITICAL, msg, ##__VA_ARGS__)\n#define FATAL_MSG(msg, ...) log_msg(FATAL, msg, ##__VA_ARGS__)\n\nUTILS_API char * logging_help(void);\nUTILS_API int setup_logging(const char * log_options);\nUTILS_API int log_msg(enum LOG_LEVEL level, const char * msg, ...);\n\n//Argument parser helpers\n\n#define IF_ARG_OPTION(x, y)           \\\nif(!strcmp(argv[i], x) && i+1 < argc) \\\n{                                     \\\n\ty = argv[i + 1];                  \\\n\ti++;                              \\\n}\n#define IF_ARGINT_OPTION(x, y)        \\\nif(!strcmp(argv[i], x) && i+1 < argc) \\\n{                                     \\\n\ty = atoi(argv[i + 1]);            \\\n\ti++;                              \\\n}\n#define IF_ARGDOUBLE_OPTION(x, y)     \\\nif(!strcmp(argv[i], x) && i+1 < argc) \\\n{                                     \\\n\ty = atof(argv[i + 1]);            \\\n\ti++;                              \\\n}\n#define IF_ARG_SET_TRUE(x, y)         \\\nif(!strcmp(argv[i], x))               \\\n{                                     \\\n\ty = 1;                            \\\n}\n\n#define ELSE_IF_ARG_OPTION(x, y)       else IF_ARG_OPTION(x,y)\n#define ELSE_IF_ARGINT_OPTION(x, y)    else IF_ARGINT_OPTION(x,y)\n#define ELSE_IF_ARGDOUBLE_OPTION(x, y) else IF_ARGDOUBLE_OPTION(x,y)\n#define ELSE_IF_ARG_SET_TRUE(x, y)     else IF_ARG_SET_TRUE(x,y)\n\n/**\n * Get the number of items in an array\n */\n#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x))\n"
  },
  {
    "path": "vagrant/README.md",
    "content": "These are configuration files and scripts for [Vagrant](https://www.vagrantup.com/).\nThe scripts will install all necessary dependencies, checkout and build\nKillerbeez, and then run some basic tests to make sure it's working as\nexpected.\n\nThey are organized by Linux distribution and version.  To use them, copy the\nshell scripts into the distribution you want to run, `cd` into that directory\nand run `vagrant up` (assuming Vagrant is installed and configured, obviously).\nThese should work with any hypervisor, but they have been tested using\nVirtualBox as a back end.\n\nFor example, to get Killerbeez running on Ubuntu 16.04 (xenial):\n```\ncp *.sh ubuntu/xenial\ncd ubuntu/xenial\nvagrant up\n```\n\nIf you don't want to use Vagrant, the scripts in this directory should still\nhelp get you up and running on your own VM or on a bare-metal installation.\nThe dependencies.sh script should be run as root, as it'll install the\ndependencies.  The setup.sh script should be run as a normal user.\n\n"
  },
  {
    "path": "vagrant/ci_runner/Dockerfile",
    "content": "ARG SOURCE_IMG\nFROM ${SOURCE_IMG}\n\nCOPY dependencies.sh /usr/bin/dependencies.sh\nRUN /usr/bin/dependencies.sh\n"
  },
  {
    "path": "vagrant/ci_runner/Vagrantfile",
    "content": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\n# The following platforms are listed as having supported packages in the\n# gitlab-runner documentation\n# (https://docs.gitlab.com/runner/install/linux-repository.html). Thus we can\n# build runners for these platforms just by starting from the appropriate box\n# and installing the package.\nLINUX_BOXES = [\n    [\"ubuntu\", \"16.04\", \"ubuntu/xenial64\"],\n    [\"ubuntu\", \"18.04\", \"ubuntu/bionic64\"],\n\n    [\"fedora\", \"29\", \"generic/fedora29\"],\n\n    [\"debian\", \"8\", \"debian/jessie64\"],\n    [\"debian\", \"9\", \"debian/stretch64\"],\n]\n\n# The following platforms do not have supported gitlab-runner packages\n# according to the webpage, so we build on them using the docker executor\n# instead.\nDOCKER_IMAGES = [\n    [\"ubuntu\", \"14.04\", \"ubuntu:14.04\"],\n    [\"ubuntu\", \"19.04\", \"ubuntu:19.04\"],\n    [\"fedora\", \"30\", \"fedora:30\"],\n    [\"debian\", \"10\", \"debian:10\"],\n]\n\nWINDOWS_BOXES = [\n  [\"10\", \"x64\", \"2017\", \"Windows10x64en-noup\"],\n  [\"10\", \"x64\", \"2019\", \"Windows10x64en-noup\"],\n]\n\nVagrant.configure(\"2\") do |config|\n    LINUX_BOXES.each do |(distro, version, boxname)|\n        hostname = \"kb-#{distro}-#{version}\"\n        config.vm.define hostname do |config|\n            config.vm.box = boxname\n            config.vm.hostname = hostname.gsub(\".\", \"-\")\n\n            # Settings for Virtualbox\n            config.vm.provider \"virtualbox\" do |vb|\n                vb.linked_clone = true\n            end\n\n            config.vm.provision \"shell\", inline: \"mkdir -p /killerbeez; chown vagrant:vagrant /killerbeez\"\n            config.vm.provision \"file\", source: \".\", destination: \"/killerbeez\"\n            config.vm.provision \"shell\", path: \"../dependencies.sh\", name: \"dependencies\"\n            config.vm.provision \"shell\", path: \"runner.sh\", privileged: false\n        end\n    end\n\n    # Creates a VM for each of the docker platforms, containing a runner that\n    # defaults to the configured docker image. Thus we can tag these runners\n    # with the ${distro}-${version} like the above ones, and they will\n    # work the same way from the perspective of the .gitlab-ci.yml file. Under\n    # the hood they will run the configured script in a docker container of the\n    # configured OS rather than on the host filesystem, though.\n    DOCKER_IMAGES.each do |(distro, version, docker_image)|\n        hostname = \"kb-docker-#{distro}-#{version}\"\n        config.vm.define hostname do |config|\n            config.vm.box = \"ubuntu/bionic64\"\n            config.vm.hostname = hostname.gsub(\".\", \"-\")\n\n             # Settings for Virtualbox\n            config.vm.provider \"virtualbox\" do |vb|\n                vb.linked_clone = true\n            end\n\n            config.vm.provision \"shell\", inline: \"mkdir -p /killerbeez; chown vagrant:vagrant /killerbeez\"\n            config.vm.provision \"file\", source: \".\", destination: \"/killerbeez\"\n            config.vm.provision \"file\", source: \"../dependencies.sh\", destination: \"/killerbeez/dependencies.sh\"\n            config.vm.provision \"docker\" do |d|\n                d.build_image \"/killerbeez\",\n                    args: \"-t kb-#{distro}-#{version} --build-arg SOURCE_IMG=#{docker_image}\"\n                d.run \"gitlab-runner\", image: \"gitlab/gitlab-runner\",\n                    args: \"-v /srv/gitlab-runner/config:/etc/gitlab-runner \\\n                        -v /var/run/docker.sock:/var/run/docker.sock \\\n                        -v /killerbeez:/killerbeez\"\n            end\n            config.vm.provision \"shell\", path: \"register_docker_runner.sh\", privileged: false, args: [distro, version]\n        end\n    end\n\n    WINDOWS_BOXES.each do |(version, bitness, vs_version, boxname)|\n        hostname = \"kb-windows-#{version}-#{bitness}-vs#{vs_version}\"\n        config.vm.define hostname do | config|\n            config.vm.box = boxname\n            config.vm.hostname = hostname.gsub(\".\", \"-\")\n\n             # Settings for Virtualbox\n            config.vm.provider \"virtualbox\" do |vb|\n                vb.linked_clone = true\n            end\n\n            config.vm.communicator = \"winrm\"\n            config.vm.guest = :windows\n            config.windows.halt_timeout = 15\n\n            # RDP port for debugging\n            config.vm.network :forwarded_port, guest: 3389, host: 3389, auto_correct: true\n\n            config.vm.provision \"file\", source: \".\", destination: \"C:\\\\killerbeez\"\n            config.vm.provision \"shell\", path: \"../../tools/setup_build_env.ps1\",\n                args: [\"-build_env\", \"C:\\\\killerbeez\", \"-vs_version\", vs_version]\n            config.vm.provision \"shell\", path: \"runner.ps1\",\n\t\targs: [\"-version\", version, \"-bitness\", bitness, \"-vs_version\", vs_version]\n        end\n    end\nend\n"
  },
  {
    "path": "vagrant/ci_runner/register_docker_runner.sh",
    "content": "# TODO: exit early if already registered\nDISTRO=$1\nVERSION=$2\n\n# Register the runner\nRUNNER_NAME=kb-docker-${DISTRO}-${VERSION}\nRUNNER_TAG_LIST=${DISTRO},${DISTRO}-${VERSION}\nDOCKER_IMAGE=kb-${DISTRO}-${VERSION}\n\n# Check if already registered\nsudo docker run \\\n    --rm \\\n    -v /srv/gitlab-runner/config:/etc/gitlab-runner \\\n    -v /var/run/docker.sock:/var/run/docker.sock \\\n    -v /killerbeez:/killerbeez \\\n    gitlab/gitlab-runner list |& grep -qF \"$RUNNER_NAME\"\n\nif [[ $? -eq 0 ]]; then\n    echo \"$RUNNER_NAME already registered, skipping registration\"\n    exit 0\nfi\n\nsudo docker run \\\n    --rm \\\n    -e RUNNER_NAME=$RUNNER_NAME \\\n    -e RUNNER_TAG_LIST=$RUNNER_TAG_LIST \\\n    -e RUNNER_EXECUTOR=docker \\\n    -e DOCKER_IMAGE=$DOCKER_IMAGE \\\n    -e DOCKER_PULL_POLICY=never \\\n    --env-file /killerbeez/runner_vars \\\n    -v /srv/gitlab-runner/config:/etc/gitlab-runner \\\n    -v /var/run/docker.sock:/var/run/docker.sock \\\n    -v /killerbeez:/killerbeez \\\n    gitlab/gitlab-runner register\n"
  },
  {
    "path": "vagrant/ci_runner/runner.ps1",
    "content": "param($version, $bitness, $vs_version)\nSet-PSDebug -Trace 1\n\n$name = \"kb-windows-$version-$bitness-vs$vs_version\"\npushd C:\\Gitlab-Runner\n\n# Quit if already registered\nif (& C:\\Gitlab-Runner\\gitlab-runner-windows-amd64.exe list | Select-String -Quiet $name) {\n    exit 0\n}\n\nforeach($line in (Get-Content /killerbeez/runner_vars)) {\n  $key, $val = $line.Split(\"=\")\n  New-Item -Name $key -Value $val -ItemType Variable -Path Env: -Force\n}\n\n$env:RUNNER_EXECUTOR = \"shell\"\n$env:RUNNER_SHELL = \"cmd\"  # Workaround for https://gitlab.com/gitlab-org/gitlab-runner/issues/4814\n$env:RUNNER_NAME = $name\n$env:RUNNER_TAG_LIST = \"windows,windows-$version,$bitness,vs$vs_version\"\n\n& C:\\Gitlab-Runner\\gitlab-runner-windows-amd64.exe register\n& C:\\Gitlab-Runner\\gitlab-runner-windows-amd64.exe install\n& C:\\Gitlab-Runner\\gitlab-runner-windows-amd64.exe start\n\npopd\n"
  },
  {
    "path": "vagrant/ci_runner/runner.sh",
    "content": "distro=`grep '^ID=' /etc/os-release | sed -e 's/.*=//g'`\nversion=`grep 'VERSION_ID=' /etc/os-release | sed -e 's/\"$//g' -e 's/.*\"//g' -e 's/^VERSION_ID=//g'`\n\n# Set up repository\nif [[ \"$distro\" == \"debian\" || \"$distro\" == \"ubuntu\" ]]; then\n\t# For Debian/Ubuntu/Mint\n\tcurl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash\nelif [[ \"$distro\" == \"fedora\" ]]; then\n\t# For RHEL/CentOS/Fedora\n\tcurl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash\nfi\n\n# Create apt pin for debian\nif [[ \"$distro\" == \"debian\" ]]; then\ncat <<EOF | sudo tee /etc/apt/preferences.d/pin-gitlab-runner.pref\nExplanation: Prefer GitLab provided packages over the Debian native ones\nPackage: gitlab-runner\nPin: origin packages.gitlab.com\nPin-Priority: 1001\nEOF\nfi\n\n# Install runner package\nif [[ \"$distro\" == \"debian\" || \"$distro\" == \"ubuntu\" ]]; then\n\t# For Debian/Ubuntu/Mint\n\tsudo apt-get update\n\tsudo apt-get install -y gitlab-runner\nelif [[ \"$distro\" == \"fedora\" ]]; then\n\t# For RHEL/CentOS/Fedora\n\tsudo yum install -y gitlab-runner\n\n        # Disable SELinux\n        sudo sed -i /etc/selinux/config -e 's/^SELINUX=enforcing/SELINUX=permissive/g'\n        sudo setenforce 0\nfi\n\n# Check if already registered\nRUNNER_NAME=kb-${distro}-${version}\nRUNNER_TAG_LIST=${distro},${distro}-${version}\n\nsudo gitlab-runner list |& grep -qF \"$RUNNER_NAME\"\n\nif [[ $? -eq 0 ]]; then\n    echo \"$RUNNER_NAME already registered, skipping registration\"\n    exit 0\nfi\n\n# Register the runner\nsudo env $(cat /killerbeez/runner_vars | xargs) \\\n    RUNNER_NAME=$RUNNER_NAME RUNNER_TAG_LIST=$RUNNER_TAG_LIST RUNNER_EXECUTOR=shell \\\n    gitlab-runner register\n"
  },
  {
    "path": "vagrant/ci_runner/runner_vars.example",
    "content": "CI_SERVER_URL=\nREGISTRATION_TOKEN=\nREGISTER_NON_INTERACTIVE=true\nCI_SERVER_TLS_CA_FILE=\n"
  },
  {
    "path": "vagrant/debian/buster/Vagrantfile",
    "content": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\nVagrant.configure(\"2\") do |config|\n  config.vm.box = \"debian/buster64\"  # 10\n  hostname = \"kb-debian-buster64\"\n  config.vm.hostname = hostname\n\n  # Settings for Virtualbox\n  config.vm.provider \"virtualbox\" do |vb|\n     vb.linked_clone = true\n     vb.name = hostname\n  end\n\n  config.vm.provision \"shell\", path: \"dependencies.sh\", name: \"dependencies\"\n  config.vm.provision \"shell\", path: \"setup.sh\", privileged: false\nend\n"
  },
  {
    "path": "vagrant/debian/jessie/Vagrantfile",
    "content": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\nVagrant.configure(\"2\") do |config|\n  config.vm.box = \"debian/jessie64\"  # 8\n  hostname = \"kb-debian-jessie64\"\n  config.vm.hostname = hostname\n\n  # Settings for Virtualbox\n  config.vm.provider \"virtualbox\" do |vb|\n     vb.linked_clone = true\n     vb.name = hostname\n  end\n\n  config.vm.provision \"shell\", path: \"dependencies.sh\", name: \"dependencies\"\n  config.vm.provision \"shell\", path: \"setup.sh\", privileged: false\nend\n"
  },
  {
    "path": "vagrant/debian/stretch/Vagrantfile",
    "content": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\nVagrant.configure(\"2\") do |config|\n  config.vm.box = \"debian/stretch64\"  # 9\n  hostname = \"kb-debian-stretch64\"\n  config.vm.hostname = hostname\n\n  # Settings for Virtualbox\n  config.vm.provider \"virtualbox\" do |vb|\n     vb.linked_clone = true\n     vb.name = hostname\n  end\n\n  config.vm.provision \"shell\", path: \"dependencies.sh\", name: \"dependencies\"\n  config.vm.provision \"shell\", path: \"setup.sh\", privileged: false\nend\n"
  },
  {
    "path": "vagrant/dependencies.sh",
    "content": "#!/bin/bash\n# Installs dependencies for Debian, Ubuntu, or Fedora\n\ndistro=`grep '^ID=' /etc/os-release | sed -e 's/.*=//g'`\nversion=`grep 'VERSION_ID=' /etc/os-release | sed -e 's/\"$//g' -e 's/.*\"//g' -e 's/^VERSION_ID=//g'`\n\nif [[ \"$distro\" == \"debian\" ]]; then\n\tapt-get update\n\t# Install Debian dependencies\n\tapt-get -y install llvm clang libtool-bin build-essential cmake automake bison \\\n\t\tflex libglib2.0-dev libc6-dev-i386 libpixman-1-dev git curl wget\nelif [[ \"$distro\" == \"fedora\" ]]; then\n\t# Install Fedora dependencies\n\tdnf -y install llvm clang llvm-devel libtool libstdc++-static cmake bison \\\n\t\tflex glib2-devel glibc-devel.i686 zlib-devel git make wget which python xz patch\nelif [[ \"$distro\" == \"ubuntu\" ]]; then\n\tapt-get update\n\t# Install Ubuntu dependencies\n\tif [[ \"$version\" == \"14.04\" ]]; then\n\t\tapt-get -y install llvm clang libtool build-essential cmake automake bison \\\n\t\t\tflex libglib2.0-dev libc6-dev-i386 git wget\n\telif [[ \"$version\" == \"16.04\" || \"$version\" == \"18.04\" || \"$version\" == \"19.04\" ]]; then\n\t\tapt-get -y install llvm clang libtool-bin build-essential cmake automake bison \\\n\t\t\tflex libglib2.0-dev libc6-dev-i386 libpixman-1-dev git wget\n\telse\n\t\techo \"Unsupported version of Ubuntu: $version\"\n\tfi\nfi\n"
  },
  {
    "path": "vagrant/fedora/29/Vagrantfile",
    "content": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\nVagrant.configure(\"2\") do |config|\n  config.vm.box = \"generic/fedora29\"\n  hostname = \"kb-fedora-29\"\n\n  # Settings for Virtualbox\n  config.vm.provider \"virtualbox\" do |vb|\n     vb.linked_clone = true\n     vb.name = hostname\n  end\n\n  config.vm.provision \"shell\", path: \"dependencies.sh\", name: \"dependencies\"\n  config.vm.provision \"shell\", path: \"setup.sh\", privileged: false\nend\n"
  },
  {
    "path": "vagrant/fedora/30/Vagrantfile",
    "content": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\nVagrant.configure(\"2\") do |config|\n  config.vm.box = \"generic/fedora30\"\n  hostname = \"kb-fedora-30\"\n\n  # Settings for Virtualbox\n  config.vm.provider \"virtualbox\" do |vb|\n     vb.linked_clone = true\n     vb.name = hostname\n  end\n\n  config.vm.provision \"shell\", path: \"dependencies.sh\", name: \"dependencies\"\n  config.vm.provision \"shell\", path: \"setup.sh\", privileged: false\nend\n"
  },
  {
    "path": "vagrant/setup.sh",
    "content": "#!/bin/bash\nBRANCH=\"$1\"\n\n# Check out the code\ngit clone --recursive https://github.com/grimm-co/killerbeez\n\n# Test a specific branch if necessary\nif [[ \"$BRANCH\" != \"\" ]]; then\n\tcd killerbeez\n\tgit checkout \"$BRANCH\"\n\tcd ..\nfi\n\n# build it & run some basic tests\n./killerbeez/tests/smoke_test.sh\n"
  },
  {
    "path": "vagrant/ubuntu/bionic/Vagrantfile",
    "content": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\nVagrant.configure(\"2\") do |config|\n  config.vm.box = \"ubuntu/bionic64\"  # 18.04\n  hostname = \"kb-ubuntu-bionic64\"\n  config.vm.hostname = hostname\n\n  # Settings for Virtualbox\n  config.vm.provider \"virtualbox\" do |vb|\n     vb.linked_clone = true\n     vb.name = hostname\n  end\n\n  config.vm.provision \"shell\", path: \"dependencies.sh\", name: \"dependencies\"\n  config.vm.provision \"shell\", path: \"setup.sh\", privileged: false\nend\n"
  },
  {
    "path": "vagrant/ubuntu/disco/Vagrantfile",
    "content": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\nVagrant.configure(\"2\") do |config|\n  config.vm.box = \"ubuntu/disco64\"  # 19.04\n  hostname = \"kb-ubuntu-disco64\"\n  config.vm.hostname = hostname\n\n  # Settings for Virtualbox\n  config.vm.provider \"virtualbox\" do |vb|\n     vb.linked_clone = true\n     vb.name = hostname\n  end\n\n  config.vm.provision \"shell\", path: \"dependencies.sh\", name: \"dependencies\"\n  config.vm.provision \"shell\", path: \"setup.sh\", privileged: false\nend\n"
  },
  {
    "path": "vagrant/ubuntu/trusty/Vagrantfile",
    "content": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\nVagrant.configure(\"2\") do |config|\n  config.vm.box = \"ubuntu/trusty64\"  # 14.04\n  hostname = \"kb-ubuntu-trusty64\"\n  config.vm.hostname = hostname\n\n  # Settings for Virtualbox\n  config.vm.provider \"virtualbox\" do |vb|\n     vb.memory = \"4096\"  # 1GB RAM\n     vb.linked_clone = true\n     vb.name = hostname\n  end\n\n  config.vm.provision \"shell\", path: \"dependencies.sh\", name: \"dependencies\"\n  config.vm.provision \"shell\", path: \"setup.sh\", privileged: false\nend\n"
  },
  {
    "path": "vagrant/ubuntu/xenial/Vagrantfile",
    "content": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\nVagrant.configure(\"2\") do |config|\n  config.vm.box = \"ubuntu/xenial64\"  # 16.04\n  hostname = \"kb-ubuntu-xenial64\"\n  config.vm.hostname = hostname\n\n  # Settings for Virtualbox\n  config.vm.provider \"virtualbox\" do |vb|\n     vb.linked_clone = true\n     vb.name = hostname\n  end\n\n  config.vm.provision \"shell\", path: \"dependencies.sh\", name: \"dependencies\"\n  config.vm.provision \"shell\", path: \"setup.sh\", privileged: false\nend\n"
  },
  {
    "path": "winafl/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.8.8)\nproject (winafl)\n\n# Generate the strings for the correct version of DynamoRIO\nif( CMAKE_SIZEOF_VOID_P EQUAL 8 ) # 64-bit\n\tset(DYNAMORIO_LIB_FOLDER_NAME \"lib64\")\nelse( CMAKE_SIZEOF_VOID_P EQUAL 8 ) # 32-bit\n\tset(DYNAMORIO_LIB_FOLDER_NAME \"lib32\")\nendif (CMAKE_SIZEOF_VOID_P EQUAL 8)\n\n# Set debug/release version of DynamoRIO.  Pick release if not specified\nif( \"${CMAKE_CONFIGURATION_TYPES}\" STREQUAL \"\" )\nset(DYNAMORIO_FOLDER_NAME \"release\")\nelse( \"${CMAKE_CONFIGURATION_TYPES}\" STREQUAL \"\" )\nstring(TOLOWER \"${CMAKE_CONFIGURATION_TYPES}\" DYNAMORIO_FOLDER_NAME) # debug/release\nendif( \"${CMAKE_CONFIGURATION_TYPES}\" STREQUAL \"\" )\n\n# Find DynamoRIO\nfind_library(DYNAMORIO_LIBRARY dynamorio HINTS ${CMAKE_SOURCE_DIR}/dynamorio/${DYNAMORIO_LIB_FOLDER_NAME}/${DYNAMORIO_FOLDER_NAME})\nif(NOT DYNAMORIO_LIBRARY)\n  message(FATAL_ERROR \"Could not find DynamoRIO\")\nendif()\nget_filename_component(DYNAMORIO_LIB_PATH ${DYNAMORIO_LIBRARY} DIRECTORY)\n\n# Add DynamoRIO directories to the include and library paths\ninclude_directories (\n\t${DYNAMORIO_LIB_PATH}/../../include/\n\t${DYNAMORIO_LIB_PATH}/../../ext/include/\n)\nlink_directories(\n\t${DYNAMORIO_LIB_PATH}/\n\t${DYNAMORIO_LIB_PATH}/../\n\t${DYNAMORIO_LIB_PATH}/../../ext/${DYNAMORIO_LIB_FOLDER_NAME}/${DYNAMORIO_FOLDER_NAME}\n)\n\n# Make sure the winafl.dll gets put in the bin32/bin64 directory\nif (CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit\nSET( WINAFL_DIR \"bin64\" )\nelse (CMAKE_SIZEOF_VOID_P EQUAL 8) # 32-bit\nSET( WINAFL_DIR \"bin32\" )\nendif (CMAKE_SIZEOF_VOID_P EQUAL 8)\nSET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${WINAFL_DIR}/ )\nSET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${WINAFL_DIR}/ )\nSET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${WINAFL_DIR}/ )\n\n# Include the instrumentation headers\ninclude_directories (\n\t${PROJECT_SOURCE_DIR}/../instrumentation/\n)\n\n# Create the winafl project\nSET(WINAFL_SRC\n\t${PROJECT_SOURCE_DIR}/modules.c\n\t${PROJECT_SOURCE_DIR}/winafl.c\n)\nsource_group(\"Library Sources\" FILES ${WINAFL_SRC})\n\nadd_library(winafl SHARED ${WINAFL_SRC})\n\nif (WIN32)\n\ttarget_compile_definitions(winafl PUBLIC WINDOWS)\n\tset(LINK_FLAGS ${LINK_FLAGS} \"/NODEFAULTLIB:library\")\nelseif (APPLE)\n\ttarget_compile_definitions(winafl PUBLIC MACOS)\nelse (WIN32)\n\ttarget_compile_definitions(winafl PUBLIC LINUX)\nendif (WIN32)\n\nif( CMAKE_SIZEOF_VOID_P EQUAL 8 ) # 64-bit\n\ttarget_compile_definitions(winafl PUBLIC X86_64)\nelse( CMAKE_SIZEOF_VOID_P EQUAL 8 ) # 32-bit\n\ttarget_compile_definitions(winafl PUBLIC X86_32)\nendif (CMAKE_SIZEOF_VOID_P EQUAL 8)\n\ntarget_link_libraries(winafl drx.lib)\ntarget_link_libraries(winafl drcontainers.lib)\ntarget_link_libraries(winafl drreg.lib)\ntarget_link_libraries(winafl drwrap.lib)\ntarget_link_libraries(winafl drsyms.lib)\ntarget_link_libraries(winafl drmgr.lib)\ntarget_link_libraries(winafl drcontainers.lib)\ntarget_link_libraries(winafl ntdll_imports.lib)\ntarget_link_libraries(winafl dynamorio.lib)\n"
  },
  {
    "path": "winafl/modules.c",
    "content": "/* ***************************************************************************\n * Copyright (c) 2012-2013 Google, Inc.  All rights reserved.\n * ***************************************************************************/\n\n/*\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * * Redistributions of source code must retain the above copyright notice,\n *   this list of conditions and the following disclaimer.\n *\n * * Redistributions in binary form must reproduce the above copyright notice,\n *   this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * * Neither the name of Google, Inc. nor the names of its contributors may be\n *   used to endorse or promote products derived from this software without\n *   specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE, INC. OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n *\n * This file has been modified from the original to suit the purposes of this\n * project.\n */\n\n/*\n Utilities for keeping track of (un)loaded modules in DynamoRIO clients.\n Copied from the DyanmoRIO project, http://dynamorio.org/ clients/common/modules.c\n*/\n\n#include \"modules.h\"\n#include \"utils.h\"\n\n#include <string.h>\n\n/* we use direct map cache to avoid locking */\nstatic inline void\nglobal_module_cache_add(module_entry_t **cache, module_entry_t *entry)\n{\n    cache[entry->id % NUM_GLOBAL_MODULE_CACHE] = entry;\n}\n\n/* Maintains LRU order in thread-private caches. A new/recent entry is moved to\n * the front, and all other entries are shifted back to make place. For new\n * entries, shifting results in the oldest entry being discarded.\n */\nstatic inline void\nthread_module_cache_adjust(module_entry_t **cache,\n                           module_entry_t  *entry,\n                           uint pos,\n                           uint max_pos)\n{\n    uint i;\n    ASSERT(pos < max_pos, \"wrong pos\");\n    for (i = pos; i > 0; i--)\n        cache[i] = cache[i-1];\n    cache[0] = entry;\n}\n\nstatic inline void\nthread_module_cache_add(module_entry_t **cache, uint cache_size,\n                        module_entry_t *entry)\n{\n    thread_module_cache_adjust(cache, entry, cache_size - 1, cache_size);\n}\n\nstatic void\nmodule_table_entry_free(void *entry)\n{\n    dr_free_module_data(((module_entry_t *)entry)->data);\n    dr_global_free(entry, sizeof(module_entry_t));\n}\n\nvoid\nmodule_table_load(module_table_t *table, const module_data_t *data)\n{\n    module_entry_t *entry = NULL;\n    module_data_t  *mod;\n    int i;\n    /* Some apps repeatedly unload and reload the same module,\n     * so we will try to re-use the old one.\n     */\n    ASSERT(data != NULL, \"data must not be NULL\");\n    drvector_lock(&table->vector);\n    /* Assuming most recently loaded entries are most likely to be unloaded,\n     * we iterate the module table in a backward way for better performance.\n     */\n    for (i = table->vector.entries-1; i >= 0; i--) {\n        entry = drvector_get_entry(&table->vector, i);\n        mod   = entry->data;\n        if (entry->unload &&\n            /* If the same module is re-loaded at the same address,\n             * we will try to use the existing entry.\n             */\n            mod->start       == data->start        &&\n            mod->end         == data->end          &&\n            mod->entry_point == data->entry_point  &&\n#ifdef WINDOWS\n            mod->checksum    == data->checksum     &&\n            mod->timestamp   == data->timestamp    &&\n#endif\n            /* If a module w/ no name (there are some) is loaded, we will\n             * keep making new entries.\n             */\n            dr_module_preferred_name(data) != NULL &&\n            dr_module_preferred_name(mod)  != NULL &&\n            strcmp(dr_module_preferred_name(data),\n                   dr_module_preferred_name(mod)) == 0) {\n            entry->unload = false;\n            break;\n        }\n        entry = NULL;\n    }\n    if (entry == NULL) {\n        entry = dr_global_alloc(sizeof(*entry));\n        entry->id = table->vector.entries;\n        entry->unload = false;\n        entry->data = dr_copy_module_data(data);\n        drvector_append(&table->vector, entry);\n    }\n    drvector_unlock(&table->vector);\n    global_module_cache_add(table->cache, entry);\n}\n\nstatic inline bool\npc_is_in_module(module_entry_t *entry, app_pc pc)\n{\n    if (entry != NULL && !entry->unload && entry->data != NULL) {\n        module_data_t *mod = entry->data;\n        if (pc >= mod->start && pc < mod->end)\n            return true;\n    }\n    return false;\n}\n\nmodule_entry_t *\nmodule_table_lookup(module_entry_t **cache, int cache_size,\n                    module_table_t *table, app_pc pc)\n{\n    module_entry_t *entry;\n    int i;\n\n    /* We assume we never change an entry's data field, even on unload,\n     * and thus it is ok to check its value without a lock.\n     */\n    /* lookup thread module cache */\n    if (cache != NULL) {\n        for (i = 0; i < cache_size; i++) {\n            entry = cache[i];\n            if (pc_is_in_module(entry, pc)) {\n                if (i > 0)\n                    thread_module_cache_adjust(cache, entry, i, cache_size);\n                return entry;\n            }\n        }\n    }\n    /* lookup global module cache */\n    /* we use a direct map cache, so it is ok to access it without lock */\n    for (i = 0; i < NUM_GLOBAL_MODULE_CACHE; i++) {\n        entry = table->cache[i];\n        if (pc_is_in_module(entry, pc))\n            return entry;\n    }\n    /* lookup module table */\n    entry = NULL;\n    drvector_lock(&table->vector);\n    for (i = table->vector.entries - 1; i >= 0; i--) {\n        entry = drvector_get_entry(&table->vector, i);\n        ASSERT(entry != NULL, \"fail to get module entry\");\n        if (pc_is_in_module(entry, pc)) {\n            global_module_cache_add(table->cache, entry);\n            if (cache != NULL)\n                thread_module_cache_add(cache, cache_size, entry);\n            break;\n        }\n        entry = NULL;\n    }\n    drvector_unlock(&table->vector);\n    return entry;\n}\n\nvoid\nmodule_table_unload(module_table_t *table, const module_data_t *data)\n{\n    module_entry_t *entry = module_table_lookup(NULL, 0, table, data->start);\n    if (entry != NULL) {\n        entry->unload = true;\n    } else {\n        ASSERT(false, \"fail to find the module to be unloaded\");\n    }\n}\n\n/* assuming caller holds the lock */\nvoid\nmodule_table_entry_print(module_entry_t *entry, file_t log, bool print_all_info)\n{\n    const char *name;\n    module_data_t *data;\n    const char *full_path = \"<unknown>\";\n    data = entry->data;\n    name = dr_module_preferred_name(data);\n    if (data->full_path != NULL && data->full_path[0] != '\\0')\n        full_path = data->full_path;\n\n    if (print_all_info) {\n        dr_fprintf(log, \"%3u, \"PFX\", \"PFX\", \"PFX\", %s, %s\",\n                   entry->id, data->start, data->end, data->entry_point,\n                   (name == NULL || name[0] == '\\0') ? \"<unknown>\" : name,\n                   full_path);\n#ifdef WINDOWS\n        dr_fprintf(log, \", 0x%08x, 0x%08x\", data->checksum, data->timestamp);\n#endif /* WINDOWS */\n        dr_fprintf(log, \"\\n\");\n    } else {\n        dr_fprintf(log, \" %u, %llu, %s\\n\", entry->id,\n                   (uint64)(data->end - data->start), full_path);\n    }\n}\n\nvoid\nmodule_table_print(module_table_t *table, file_t log, bool print_all_info)\n{\n    uint i;\n    module_entry_t *entry;\n    if (log == INVALID_FILE) {\n        /* It is possible that failure on log file creation is caused by the\n         * running process not having enough privilege, so this is not a\n         * release-build fatal error\n         */\n        ASSERT(false, \"invalid log file\");\n        return;\n    }\n    drvector_lock(&table->vector);\n    dr_fprintf(log, \"Module Table: %u\\n\", table->vector.entries);\n\n    if (print_all_info) {\n        dr_fprintf(log, \"Module Table: id, base, end, entry, unload, name, path\");\n#ifdef WINDOWS\n        dr_fprintf(log, \", checksum, timestamp\");\n#endif\n        dr_fprintf(log, \"\\n\");\n    }\n\n    for (i = 0; i < table->vector.entries; i++) {\n        entry = drvector_get_entry(&table->vector, i);\n        module_table_entry_print(entry, log, print_all_info);\n    }\n    drvector_unlock(&table->vector);\n}\n\nmodule_table_t *\nmodule_table_create()\n{\n    module_table_t *table = dr_global_alloc(sizeof(*table));\n    memset(table->cache, 0, sizeof(table->cache));\n    drvector_init(&table->vector, 16, false, module_table_entry_free);\n    return table;\n}\n\nvoid\nmodule_table_destroy(module_table_t *table)\n{\n    drvector_delete(&table->vector);\n    dr_global_free(table, sizeof(*table));\n}\n"
  },
  {
    "path": "winafl/modules.h",
    "content": "/* ***************************************************************************\n * Copyright (c) 2012-2013 Google, Inc.  All rights reserved.\n * ***************************************************************************/\n\n/*\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * * Redistributions of source code must retain the above copyright notice,\n *   this list of conditions and the following disclaimer.\n *\n * * Redistributions in binary form must reproduce the above copyright notice,\n *   this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * * Neither the name of Google, Inc. nor the names of its contributors may be\n *   used to endorse or promote products derived from this software without\n *   specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE, INC. OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n *\n * This file has been modified from the original to suit the purposes of this\n * project.\n */\n\n/*\nUtilities for keeping track of (un)loaded modules in DynamoRIO clients.\nCopied from the DyanmoRIO project, http://dynamorio.org/\n*/\n\n#ifndef CLIENTS_COMMON_MODULES_H_\n#define CLIENTS_COMMON_MODULES_H_\n\n#include <dr_api.h>\n#include <drvector.h>\n\n#define NUM_GLOBAL_MODULE_CACHE 8\n\ntypedef struct _module_entry_t {\n    int  id;\n    bool unload; /* if the module is unloaded */\n    module_data_t *data;\n} module_entry_t;\n\ntypedef struct _module_table_t {\n    drvector_t vector;\n    /* for quick query without lock, assuming pointer-aligned */\n    module_entry_t *cache[NUM_GLOBAL_MODULE_CACHE];\n} module_table_t;\n\nvoid\nmodule_table_load(module_table_t *table, const module_data_t *data);\n\n/* To avoid data race, proper sychronization on module table is required for\n * accessing module table entry.\n */\nmodule_entry_t *\nmodule_table_lookup(module_entry_t **cache, int cache_size,\n                    module_table_t *table, app_pc pc);\n\n/* To avoid data race, proper sychronization on module table is required for\n * accessing module table entry.\n */\nvoid\nmodule_table_entry_print(module_entry_t *entry, file_t log, bool print_all_info);\n\nvoid\nmodule_table_unload(module_table_t *table, const module_data_t *data);\n\nvoid\nmodule_table_print(module_table_t *table, file_t log, bool print_all_info);\n\nmodule_table_t *\nmodule_table_create();\n\nvoid\nmodule_table_destroy(module_table_t *table);\n\n#endif /* CLIENTS_COMMON_MODULES_H_ */\n"
  },
  {
    "path": "winafl/utils.h",
    "content": "/* ***************************************************************************\n * Copyright (c) 2012-2013 Google, Inc.  All rights reserved.\n * ***************************************************************************/\n\n/*\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * * Redistributions of source code must retain the above copyright notice,\n *   this list of conditions and the following disclaimer.\n *\n * * Redistributions in binary form must reproduce the above copyright notice,\n *   this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * * Neither the name of Google, Inc. nor the names of its contributors may be\n *   used to endorse or promote products derived from this software without\n *   specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE, INC. OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n *\n * This file has been modified from the original to suit the purposes of this\n * project.\n */\n\n/*\nDynamoRIO utility macros. Copied from the DyanmoRIO project,\nhttp://dynamorio.org/\n*/\n\n\n#ifndef CLIENTS_COMMON_UTILS_H_\n#define CLIENTS_COMMON_UTILS_H_\n\n#include <dr_api.h>\n\n#ifdef DEBUG\n# define ASSERT(x, msg) DR_ASSERT_MSG(x, msg)\n# define IF_DEBUG(x) x\n#else\n# define ASSERT(x, msg) /* nothing */\n# define IF_DEBUG(x) /* nothing */\n#endif\n\n/* XXX: should be moved to DR API headers? */\n#define BUFFER_SIZE_BYTES(buf)      sizeof(buf)\n#define BUFFER_SIZE_ELEMENTS(buf)   (BUFFER_SIZE_BYTES(buf) / sizeof((buf)[0]))\n#define BUFFER_LAST_ELEMENT(buf)    (buf)[BUFFER_SIZE_ELEMENTS(buf) - 1]\n#define NULL_TERMINATE_BUFFER(buf)  BUFFER_LAST_ELEMENT(buf) = 0\n#define ALIGNED(x, alignment) ((((ptr_uint_t)x) & ((alignment)-1)) == 0)\n#define TESTANY(mask, var) (((mask) & (var)) != 0)\n#define TEST  TESTANY\n\n#ifdef WINDOWS\n# define IF_WINDOWS(x) x\n# define IF_UNIX_ELSE(x,y) y\n#else\n# define IF_WINDOWS(x)\n# define IF_UNIX_ELSE(x,y) x\n#endif\n\n/* Checks for both debug and release builds: */\n#define USAGE_CHECK(x, msg) DR_ASSERT_MSG(x, msg)\n\nstatic inline generic_func_t\ncast_to_func(void *p)\n{\n#ifdef WINDOWS\n#  pragma warning(push)\n#  pragma warning(disable : 4055)\n#endif\n    return (generic_func_t) p;\n#ifdef WINDOWS\n#  pragma warning(pop)\n#endif\n}\n\n#endif /* CLIENTS_COMMON_UTILS_H_ */\n"
  },
  {
    "path": "winafl/winafl.c",
    "content": "/*\n   WinAFL - DynamoRIO client (instrumentation) code\n   ------------------------------------------------\n\n   Written and maintained by Ivan Fratric <ifratric@google.com>\n\n   Copyright 2016 Google Inc. All Rights Reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n\t   http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n   This file has been modified from the original to suit the purposes of this\n   project.\n*/\n\n#include <fcntl.h>\n#include <limits.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <dr_api.h>\n#include <drmgr.h>\n#include <drx.h>\n#include <drreg.h>\n#include <drwrap.h>\n#include <drsyms.h>\n#include <drtable.h>\n#include <hashtable.h>\n\n#include \"modules.h\"\n#include \"utils.h\"\n#include <winafl_config.h>\n\n\n#define NOTIFY(level, fmt, ...) do {          \\\n    if (verbose >= (level))                   \\\n        dr_fprintf(STDERR, fmt, __VA_ARGS__); \\\n} while (0)\n\n//////////////////////////////////////////////////////////////////////////////////////\n// Enums and Struct Definitions //////////////////////////////////////////////////////\n//////////////////////////////////////////////////////////////////////////////////////\n\n#define UNKNOWN_MODULE_ID USHRT_MAX\n#define OPTION_MAX_LENGTH MAXIMUM_PATH\n\n#define COVERAGE_BB 0\n#define COVERAGE_EDGE 1\n\n#define NUM_THREAD_MODULE_CACHE 8\n\ntypedef struct _target_module_t {\n\tchar module_name[MAXIMUM_PATH];\n\tint index;\n\tstruct _target_module_t *next;\n\tunsigned char *afl_area;\n} target_module_t;\n\ntypedef struct _winafl_option_t {\n\t/* Use nudge to notify the process for termination so that\n\t * event_exit will be called.\n\t */\n\tbool verbose_edges;\n\tbool nudge_kills;\n\tbool debug_mode;\n\tbool write_log;\n\tint coverage_kind;\n\tchar logdir[MAXIMUM_PATH];\n\ttarget_module_t *target_modules;\n\tchar fuzz_module[MAXIMUM_PATH];\n\tchar fuzz_method[MAXIMUM_PATH];\n\tchar pipe_name[MAXIMUM_PATH];\n\tchar shm_name[MAXIMUM_PATH];\n\tunsigned long fuzz_offset;\n\tint fuzz_iterations;\n\tvoid **func_args;\n\tint num_fuz_args;\n\tdrwrap_callconv_t callconv;\n\tbool thread_coverage;\n\tbool per_module_coverage;\n} winafl_option_t;\n\ntypedef struct _winafl_data_t {\n\tmodule_entry_t *cache[NUM_THREAD_MODULE_CACHE];\n\tfile_t  log;\n\tbool instrumentation_enabled;\n\tbool exception_hit;\n\n\t//Because we instrument the code once, and multiple threads\n\t//all access that code.  We point the instrumented code at this area\n\t//for threads we don't care to record the coverage info for (when\n\t//thread_coverage is on).\n\tunsigned char *fake_afl_area;\n\n\t//The real coverage info area (when per-module coverage is off)\n\tunsigned char *afl_area;\n} winafl_data_t;\n\ntypedef struct _debug_data_t {\n\tint pre_hanlder_called;\n\tint post_handler_called;\n} debug_data_t;\n\ntypedef struct _fuzz_target_t {\n\treg_t xsp;            /* stack level at entry to the fuzz target */\n\tapp_pc func_pc;\n\tint iteration;\n} fuzz_target_t;\n\nenum {\n\tNUDGE_TERMINATE_PROCESS = 1,\n\tNUDGE_DONE_PROCESSING_INPUT = 2,\n};\n\n//////////////////////////////////////////////////////////////////////////////////////\n// Global Variables //////////////////////////////////////////////////////////////////\n//////////////////////////////////////////////////////////////////////////////////////\n\nstatic uint verbose;\n\nstatic winafl_option_t options;\n\nstatic winafl_data_t winafl_data;\n\nstatic int winafl_tls_field;\n\nstatic fuzz_target_t fuzz_target;\n\nstatic debug_data_t debug_data;\n\nstatic module_table_t *module_table;\nstatic client_id_t client_id;\n\nstatic volatile bool go_native;\n\nstatic HANDLE pipe = NULL;\n\n//////////////////////////////////////////////////////////////////////////////////////\n// Function Prototypes ///////////////////////////////////////////////////////////////\n//////////////////////////////////////////////////////////////////////////////////////\n\nstatic void event_exit(void);\nstatic void event_thread_exit(void *drcontext);\n\nstatic void setup_shm_and_tls_regions_for_coverage(void *drcontext);\nstatic void read_start_fuzz_command();\n\n//////////////////////////////////////////////////////////////////////////////////////\n// Function Definitions //////////////////////////////////////////////////////////////\n//////////////////////////////////////////////////////////////////////////////////////\n\n/**\n * This function calculates the number of modules in a linked list of modules.\n * @param target_module - a linked list of modules\n * @return - the number of modules in the specified linked list\n */\nstatic int get_target_modules_length(target_module_t * target_module)\n{\n\tint count = 0;\n\twhile (target_module)\n\t{\n\t\tcount++;\n\t\ttarget_module = target_module->next;\n\t}\n\treturn count;\n}\n\n/**\n * This function is the registered nudge handler.  It will handle DynamoRIO's nudges.\n * @param drcontext - a pointer to the input program's machine context.  This parameter should not be\n * inspected or modified, and should only be used to be passed to the DynamoRIO API routines.\n * @param argument - The argument that the nudging process gave\n */\nstatic void event_nudge(void *drcontext, uint64 argument)\n{\n\tint nudge_arg = (int)argument;\n\tint exit_arg = (int)(argument >> 32);\n\tchar buffer[200];\n\n\tif (nudge_arg == NUDGE_TERMINATE_PROCESS) {\n\t\tstatic int nudge_term_count;\n\t\t/* handle multiple from both NtTerminateProcess and NtTerminateJobObject */\n\t\tuint count = dr_atomic_add32_return_sum(&nudge_term_count, 1);\n\t\tif (count == 1) {\n\t\t\tdr_exit_process(exit_arg);\n\t\t}\n\t}\n\telse if (nudge_arg == NUDGE_DONE_PROCESSING_INPUT)\n\t{\n\n\t}\n\telse\n\t{\n\t\tsnprintf(buffer, sizeof(buffer), \"Unknown nudge argument: %d\", nudge_arg);\n\t\tDR_ASSERT_MSG(false, buffer);\n\t}\n}\n\n/**\n * This function cleans up the winafl instrumentation prior to the process being killed\n * @param pid - the pid of the process about to be killed\n * @param exit_code - The exit code of the process about to be killed\n * @return - whether to skip the termination action by the application: i.e., true indicates\n * to skip it (the usual case) and false indicates to continue with the application action\n */\nstatic bool event_soft_kill(process_id_t pid, int exit_code)\n{\n\t/* we pass [exit_code, NUDGE_TERMINATE_PROCESS] to target process */\n\tdr_config_status_t res;\n\tres = dr_nudge_client_ex(pid, client_id,\n\t\tNUDGE_TERMINATE_PROCESS | (uint64)exit_code << 32,\n\t\t0);\n\tif (res == DR_SUCCESS) {\n\t\t/* skip syscall since target will terminate itself */\n\t\treturn true;\n\t}\n\t/* else failed b/c target not under DR control or maybe some other\n\t * error: let syscall go through\n\t */\n\treturn false;\n}\n\n\n/**\n * This function writes the afl bitmap of edges to the log file\n */\nstatic void dump_winafl_data()\n{\n\tdr_write_file(winafl_data.log, winafl_data.afl_area, MAP_SIZE);\n}\n\n/**\n * This function is the registered exception handler.  It will handle exceptions passed to it by DynamoRIO,\n * whenever the instrumented application throws an exception.\n * @param drcontext - a pointer to the input program's machine context.  This parameter should not be\n * inspected or modified, and should only be used to be passed to the DynamoRIO API routines.\n * @param excpt - A DynamoRIO exceptions struct that contains details of the exception was generated.\n * @return - whether the exception should be passed on to the client\n */\nstatic bool onexception(void *drcontext, dr_exception_t *excpt) {\n\tDWORD num_written;\n\tDWORD exception_code = excpt->record->ExceptionCode;\n\n\tif (options.debug_mode || options.write_log)\n\t\tdr_fprintf(winafl_data.log, \"Exception caught: %x\\n\", exception_code);\n\n\tif ((exception_code == EXCEPTION_ACCESS_VIOLATION) ||\n\t\t(exception_code == EXCEPTION_ILLEGAL_INSTRUCTION) ||\n\t\t(exception_code == EXCEPTION_PRIV_INSTRUCTION) ||\n\t\t(exception_code == STATUS_HEAP_CORRUPTION) ||\n\t\t(exception_code == EXCEPTION_STACK_OVERFLOW)) {\n\t\tif (options.debug_mode) {\n\t\t\tdr_fprintf(winafl_data.log, \"crashed\\n\");\n\t\t}\n\t\telse {\n\t\t\twinafl_data.exception_hit = true;\n\t\t\tWriteFile(pipe, \"C\", 1, &num_written, NULL);\n\t\t}\n\t\tdr_exit_process(1);\n\t}\n\treturn true;\n}\n\n/**\n * This function is the callback for a new thread being created by the instrumented application.\n * @param drcontext - a pointer to the input program's machine context.  This parameter should not be\n * inspected or modified, and should only be used to be passed to the DynamoRIO API routines.\n */\nstatic void event_thread_init(void *drcontext)\n{\n\tvoid **thread_data;\n\tint i, num_modules, size;\n\n\t//Calculate size of tls data\n\tnum_modules = get_target_modules_length(options.target_modules);\n\tsize = (num_modules + 1) * sizeof(void *);\n\n\t//Allocate tls data\n\tthread_data = (void **)dr_thread_alloc(drcontext, size);\n\tmemset(thread_data, 0, size);\n\n\tif (options.thread_coverage) {\n\t\tif (options.per_module_coverage)\n\t\t{\n\t\t\tfor (i = 0; i < num_modules; i++)\n\t\t\t\tthread_data[i + 1] = winafl_data.fake_afl_area;\n\t\t}\n\t\telse\n\t\t\tthread_data[1] = winafl_data.fake_afl_area;\n\t}\n\tdrmgr_set_tls_field(drcontext, winafl_tls_field, thread_data);\n\n\t//If we haven't set a target module, then just enable instrumentation now\n\tif (!options.fuzz_module[0]) {\n\t\tif (!winafl_data.instrumentation_enabled) {\n\t\t\twinafl_data.instrumentation_enabled = true;\n\t\t\tread_start_fuzz_command();\n\t\t}\n\t\tsetup_shm_and_tls_regions_for_coverage(drcontext);\n\t}\n}\n\n/**\n * This function is the callback for a thread exiting in the instrumented application.\n * @param drcontext - a pointer to the input program's machine context.  This parameter should not be\n * inspected or modified, and should only be used to be passed to the DynamoRIO API routines.\n */\nstatic void event_thread_exit(void *drcontext)\n{\n\tint num_modules, size;\n\tvoid *data;\n\n\t//Calculate size of tls data\n\tnum_modules = get_target_modules_length(options.target_modules);\n\tsize = (num_modules + 1) * sizeof(void *);\n\n\t//Free tls data\n\tdata = drmgr_get_tls_field(drcontext, winafl_tls_field);\n\tdr_thread_free(drcontext, data, size);\n}\n\n/**\n * This function looks up a module in the target module linked list by the module name\n * @param module_name - the module to find in the target module linked list\n * @return - A pointer to the target_module_t struct describing the requested module, or NULL if the\n * module was not found\n */\nstatic target_module_t * find_target_module(const char * module_name)\n{\n\ttarget_module_t * target_module = options.target_modules;\n\twhile (target_module) {\n\t\tif (_stricmp(module_name, target_module->module_name) == 0)\n\t\t\treturn target_module;\n\t\ttarget_module = target_module->next;\n\t}\n\treturn NULL;\n}\n\n/**\n * This function adds a module to the linked list of target modules.\n * @param the name of the module to add\n */\nstatic void add_target_module(const char * name)\n{\n\ttarget_module_t *target_modules;\n\n\ttarget_modules = options.target_modules;\n\toptions.target_modules = (target_module_t *)dr_global_alloc(sizeof(target_module_t));\n\toptions.target_modules->index = get_target_modules_length(target_modules);\n\toptions.target_modules->next = target_modules;\n\tstrncpy(options.target_modules->module_name, name, BUFFER_SIZE_ELEMENTS(options.target_modules->module_name));\n}\n\n/**\n * This function is a callback for DynamoRIO's instrumentation insertion phase.  Depending on the module of the\n * passed in instruction, it will instrument the application's code to track the hit count for each\n * basic block.\n * @param drcontext - a pointer to the input program's machine context.  This parameter should not be\n * inspected or modified, and should only be used to be passed to the DynamoRIO API routines.\n * @param tag - tag is a unique identifier for the basic block fragment\n * @param bb - tag is a unique identifier for the basic block fragment\n * @param inst - The current instruction being instrumented\n * @param for_trace - for_trace indicates whether this callback is for a new basic block (false) or for adding a\n * basic block to a trace being created (true). The client has the opportunity to either include the same modifications\n * made to the standalone basic block, or to use different modifications, for the code in the trace.\n * @param translating - whether this callback is for basic block creation (false) or is for address translation (true).\n * @param user_data - User data passed from the previous DynamoRIO instrumentation phase, currently unused\n * @return - emit flags that control the behavior of basic blocks and traces when emitted into the code cache\n */\nstatic dr_emit_flags_t instrument_bb_coverage(void *drcontext, void *tag, instrlist_t *bb, instr_t *inst,\n\tbool for_trace, bool translating, void *user_data)\n{\n\tapp_pc start_pc;\n\tmodule_entry_t *mod_entry;\n\tconst char *module_name;\n\tuint offset;\n\ttarget_module_t *target_module;\n\tunsigned char *afl_map;\n\n\tif (!drmgr_is_first_instr(drcontext, inst))\n\t\treturn DR_EMIT_DEFAULT;\n\n\t//Find the module\n\tstart_pc = dr_fragment_app_pc(tag);\n\tmod_entry = module_table_lookup(winafl_data.cache, NUM_THREAD_MODULE_CACHE, module_table, start_pc);\n\tif (mod_entry == NULL || mod_entry->data == NULL)\n\t\treturn DR_EMIT_DEFAULT;\n\n\t//Find the module in our list of target modules\n\tmodule_name = dr_module_preferred_name(mod_entry->data);\n\ttarget_module = find_target_module(module_name);\n\tif (!target_module)\n\t\treturn DR_EMIT_DEFAULT;\n\n\toffset = (uint)(start_pc - mod_entry->data->start);\n\tif (options.write_log)\n\t\tdr_fprintf(winafl_data.log, \"Instrumenting module %s for bb coverage at offset %lx\\n\", module_name, offset);\n\toffset &= MAP_SIZE - 1;\n\n\tdrreg_reserve_aflags(drcontext, bb, inst);\n\n\tif (options.thread_coverage) {\n\t\treg_id_t reg;\n\t\topnd_t opnd1, opnd2;\n\t\tinstr_t *new_instr;\n\n\t\tdrreg_reserve_register(drcontext, bb, inst, NULL, &reg);\n\n\t\tdrmgr_insert_read_tls_field(drcontext, winafl_tls_field, bb, inst, reg);\n\n\t\topnd1 = opnd_create_reg(reg);\n\t\tif (options.per_module_coverage)\n\t\t\topnd2 = OPND_CREATE_MEMPTR(reg, (target_module->index + 1) * sizeof(void *));\n\t\telse\n\t\t\topnd2 = OPND_CREATE_MEMPTR(reg, sizeof(void *));\n\t\tnew_instr = INSTR_CREATE_mov_ld(drcontext, opnd1, opnd2);\n\t\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\n\t\topnd1 = OPND_CREATE_MEM8(reg, offset);\n\t\tnew_instr = INSTR_CREATE_inc(drcontext, opnd1);\n\t\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\n\t\tdrreg_unreserve_register(drcontext, bb, inst, reg);\n\t}\n\telse {\n\t\tafl_map = winafl_data.afl_area;\n\t\tif (options.per_module_coverage)\n\t\t\tafl_map = target_module->afl_area;\n\n\t\tinstrlist_meta_preinsert(bb, inst,\n\t\t\tINSTR_CREATE_inc(drcontext, OPND_CREATE_ABSMEM\n\t\t\t(&(afl_map[offset]), OPSZ_1)));\n\t}\n\n\tdrreg_unreserve_aflags(drcontext, bb, inst);\n\n\treturn DR_EMIT_DEFAULT;\n}\n\n/**\n * This function is a callback for DynamoRIO's instrumentation insertion phase.  Depending on the module of the\n * passed in instruction, it will instrument the application's code to track the hit count for each\n * basic block edge.\n * @param drcontext - a pointer to the input program's machine context.  This parameter should not be\n * inspected or modified, and should only be used to be passed to the DynamoRIO API routines.\n * @param tag - tag is a unique identifier for the basic block fragment\n * @param bb - tag is a unique identifier for the basic block fragment\n * @param inst - The current instruction being instrumented\n * @param for_trace - for_trace indicates whether this callback is for a new basic block (false) or for adding a\n * basic block to a trace being created (true). The client has the opportunity to either include the same modifications\n * made to the standalone basic block, or to use different modifications, for the code in the trace.\n * @param translating - whether this callback is for basic block creation (false) or is for address translation (true).\n * @param user_data - User data passed from the previous DynamoRIO instrumentation phase, currently unused\n * @return - emit flags that control the behavior of basic blocks and traces when emitted into the code cache\n */\nstatic dr_emit_flags_t instrument_edge_coverage(void *drcontext, void *tag, instrlist_t *bb, instr_t *inst,\n\tbool for_trace, bool translating, void *user_data)\n{\n\tstatic bool debug_information_output = false;\n\tapp_pc start_pc;\n\tmodule_entry_t *mod_entry;\n\treg_id_t reg, reg2, reg3;\n\topnd_t opnd1, opnd2;\n\tinstr_t *new_instr;\n\tconst char *module_name;\n\tuint offset;\n\ttarget_module_t *target_module;\n\n\tif (!drmgr_is_first_instr(drcontext, inst))\n\t\treturn DR_EMIT_DEFAULT;\n\n\t//Find the module\n\tstart_pc = dr_fragment_app_pc(tag);\n\tmod_entry = module_table_lookup(winafl_data.cache, NUM_THREAD_MODULE_CACHE, module_table, start_pc);\n\tif (mod_entry == NULL || mod_entry->data == NULL)\n\t\treturn DR_EMIT_DEFAULT;\n\n\t//Find the module in our list of target modules\n\tmodule_name = dr_module_preferred_name(mod_entry->data);\n\ttarget_module = find_target_module(module_name);\n\tif (!target_module)\n\t\treturn DR_EMIT_DEFAULT;\n\n\toffset = (uint)(start_pc - mod_entry->data->start);\n\tif (options.write_log)\n\t\tdr_fprintf(winafl_data.log, \"Instrumenting module %s for edge coverage at offset %lx\\n\", module_name, offset);\n\toffset &= MAP_SIZE - 1;\n\n\tdrreg_reserve_aflags(drcontext, bb, inst);\n\tdrreg_reserve_register(drcontext, bb, inst, NULL, &reg);\n\tdrreg_reserve_register(drcontext, bb, inst, NULL, &reg2);\n\tdrreg_reserve_register(drcontext, bb, inst, NULL, &reg3);\n\n\t//reg2 stores AFL area, reg 3 stores previous offset\n\n\t//load the pointer to previous offset in reg3\n\tdrmgr_insert_read_tls_field(drcontext, winafl_tls_field, bb, inst, reg3);\n\n\t//load address of shm into reg2\n\tif (options.thread_coverage) {\n\t\topnd1 = opnd_create_reg(reg2);\n\t\tif (options.per_module_coverage)\n\t\t\topnd2 = OPND_CREATE_MEMPTR(reg3, (target_module->index + 1) * sizeof(void *));\n\t\telse\n\t\t\topnd2 = OPND_CREATE_MEMPTR(reg3, sizeof(void *));\n\t\tnew_instr = INSTR_CREATE_mov_ld(drcontext, opnd1, opnd2);\n\t\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\t}\n\telse {\n\t\topnd1 = opnd_create_reg(reg2);\n\t\tif(options.per_module_coverage)\n\t\t\topnd2 = OPND_CREATE_INTPTR((uint64)target_module->afl_area);\n\t\telse\n\t\t\topnd2 = OPND_CREATE_INTPTR((uint64)winafl_data.afl_area);\n\t\tnew_instr = INSTR_CREATE_mov_imm(drcontext, opnd1, opnd2);\n\t\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\t}\n\n\t//load previous offset into register\n\topnd1 = opnd_create_reg(reg);\n\topnd2 = OPND_CREATE_MEMPTR(reg3, 0);\n\tnew_instr = INSTR_CREATE_mov_ld(drcontext, opnd1, opnd2);\n\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\n\t//xor register with the new offset\n\topnd1 = opnd_create_reg(reg);\n\topnd2 = OPND_CREATE_INT32(offset);\n\tnew_instr = INSTR_CREATE_xor(drcontext, opnd1, opnd2);\n\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\n\t//increase the counter at reg (offset ^ previous) + reg2 (afl area)\n\topnd1 = opnd_create_base_disp(reg2, reg, 1, 0, OPSZ_1);\n\tnew_instr = INSTR_CREATE_inc(drcontext, opnd1);\n\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\n\t//store the new previous offset value\n\toffset = (offset >> 1) & (MAP_SIZE - 1);\n\topnd1 = OPND_CREATE_MEMPTR(reg3, 0);\n\topnd2 = OPND_CREATE_INT32(offset);\n\tnew_instr = INSTR_CREATE_mov_st(drcontext, opnd1, opnd2);\n\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\n\tdrreg_unreserve_register(drcontext, bb, inst, reg3);\n\tdrreg_unreserve_register(drcontext, bb, inst, reg2);\n\tdrreg_unreserve_register(drcontext, bb, inst, reg);\n\tdrreg_unreserve_aflags(drcontext, bb, inst);\n\n\treturn DR_EMIT_DEFAULT;\n}\n\nstatic dr_emit_flags_t\ninstrument_verbose_edge_coverage(void *drcontext, void *tag, instrlist_t *bb, instr_t *inst,\n\tbool for_trace, bool translating, void *user_data)\n{\n\tstatic bool debug_information_output = false;\n\tapp_pc start_pc;\n\tmodule_entry_t *mod_entry;\n\treg_id_t index_register, shm_reg, tls_reg, previous_reg;\n\topnd_t opnd1, opnd2;\n\tinstr_t *new_instr;\n\tconst char *module_name;\n\tuint offset;\n\ttarget_module_t *target_module;\n\t\n\tif (!drmgr_is_first_instr(drcontext, inst))\n\t\treturn DR_EMIT_DEFAULT;\n\n\t//Find the module\n\tstart_pc = dr_fragment_app_pc(tag);\n\tmod_entry = module_table_lookup(winafl_data.cache, NUM_THREAD_MODULE_CACHE, module_table, start_pc);\n\tif (mod_entry == NULL || mod_entry->data == NULL)\n\t\treturn DR_EMIT_DEFAULT;\n\n\t//Find the module in our list of target modules\n\tmodule_name = dr_module_preferred_name(mod_entry->data);\n\ttarget_module = find_target_module(module_name);\n\tif (!target_module)\n\t\treturn DR_EMIT_DEFAULT;\n\n\toffset = (uint)(start_pc - mod_entry->data->start);\n\tif(options.write_log)\n\t\tdr_fprintf(winafl_data.log, \"Instrumenting module %s for verbose edge recording at offset %lx\\n\", module_name, offset);\n\n\tdrreg_reserve_aflags(drcontext, bb, inst);\n\tdrreg_reserve_register(drcontext, bb, inst, NULL, &index_register); //used to hold the offset to the current index in the from/to array\n\tdrreg_reserve_register(drcontext, bb, inst, NULL, &previous_reg); //used to hold the previous basic block's offset\n\tdrreg_reserve_register(drcontext, bb, inst, NULL, &shm_reg); //used to hold the pointer to the shm region\n\tdrreg_reserve_register(drcontext, bb, inst, NULL, &tls_reg); //used to hold the pointer to the tls structure\n\n\t//shm_reg stores AFL area, previous_reg stores previous offset\n\n\t//the thread local area when in non-per module coverage mode is of the form:\n\t//  void * previous_block_address;\n\t//  void * shm pointer;\n\t//\n\t//the thread local area when in per module coverage mode is of the form:\n\t//  void * previous_block_address;\n\t//  void * shm pointer for first target module;\n\t//  void * shm pointer for second target module;\n\t//  ...\n\t//\n\t//And the shm area is of the form (depending on whether we're compiled to 32/64-bit):\n\t//  uint32_t/uint64_t num_items\n\t//  void * from1\n\t//  void * to1\n\t//  void * from2\n\t//  void * to2\n\t//  ...\n\n\t//load the address of the thread local storage in tls_reg\n\tdrmgr_insert_read_tls_field(drcontext, winafl_tls_field, bb, inst, tls_reg);\n\n\t//Get the address of the shm region into shm_reg\n\topnd1 = opnd_create_reg(shm_reg);\n\tif (options.per_module_coverage)\n\t\topnd2 = OPND_CREATE_MEMPTR(tls_reg, (target_module->index + 1) * sizeof(void *));\n\telse\n\t\topnd2 = OPND_CREATE_MEMPTR(tls_reg, sizeof(void *));\n\tnew_instr = INSTR_CREATE_mov_ld(drcontext, opnd1, opnd2);\n\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\n\t//load index to write to into a register and increment it atomically\n\t\n\t//First we set index_register to 1\n\topnd1 = opnd_create_reg(index_register);\n\topnd2 = OPND_CREATE_INTPTR(1);\n\tnew_instr = INSTR_CREATE_mov_imm(drcontext, opnd1, opnd2);\n\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\t\n\t//Then we use xadd with a lock to atomically read the index and increment it\n\topnd1 = OPND_CREATE_MEMPTR(shm_reg, 0);\n\topnd2 = opnd_create_reg(index_register);\n\tnew_instr = LOCK(INSTR_CREATE_xadd(drcontext, opnd1, opnd2));\n\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\t\n\t//load previous offset into register\n\topnd1 = opnd_create_reg(previous_reg);\n\topnd2 = OPND_CREATE_MEMPTR(tls_reg, 0);\n\tnew_instr = INSTR_CREATE_mov_ld(drcontext, opnd1, opnd2);\n\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\t\n\t//times the index register by 2\n\topnd1 = opnd_create_reg(index_register);\n\topnd2 = OPND_CREATE_INT8(1);\n\tnew_instr = INSTR_CREATE_shl(drcontext, opnd1, opnd2);\n\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\n\t//Now index_register contains the offset in the array to write to and previous_reg contains the previous basic block's offset\n\t//Let's write the previous basic basic block's edge to the array\n#ifdef _M_X64\n\topnd1 = opnd_create_base_disp(shm_reg, index_register, 8, 8, OPSZ_8);\n#else\n\topnd1 = opnd_create_base_disp(shm_reg, index_register, 4, 4, OPSZ_4);\n#endif\n\topnd2 = opnd_create_reg(previous_reg);\n\tnew_instr = INSTR_CREATE_mov_st(drcontext, opnd1, opnd2);\n\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\n\t//Now let's write the current basic block's offset to the array\n#ifdef _M_X64\n\topnd1 = opnd_create_base_disp(shm_reg, index_register, 8, 0x10, OPSZ_8);\n\topnd2 = OPND_CREATE_INT64(offset);\n#else\n\topnd1 = opnd_create_base_disp(shm_reg, index_register, 4, 8, OPSZ_4);\n\topnd2 = OPND_CREATE_INT32(offset);\n#endif\n\tnew_instr = INSTR_CREATE_mov_st(drcontext, opnd1, opnd2);\n\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\n\t//store the current basic block's offset to the previous slot\n\topnd1 = OPND_CREATE_MEMPTR(tls_reg, 0);\n#ifdef _M_X64\n\topnd2 = OPND_CREATE_INT64(offset);\n#else\n\topnd2 = OPND_CREATE_INT32(offset);\n#endif\n\tnew_instr = INSTR_CREATE_mov_st(drcontext, opnd1, opnd2);\n\tinstrlist_meta_preinsert(bb, inst, new_instr);\n\t\n\tdrreg_unreserve_register(drcontext, bb, inst, tls_reg);\n\tdrreg_unreserve_register(drcontext, bb, inst, shm_reg);\n\tdrreg_unreserve_register(drcontext, bb, inst, previous_reg);\n\tdrreg_unreserve_register(drcontext, bb, inst, index_register);\n\tdrreg_unreserve_aflags(drcontext, bb, inst);\n\n\treturn DR_EMIT_DEFAULT;\n}\n\n/**\n * This function is called prior to the application's function being fuzzed.  It records the application's state\n * (rsp and rip values), so that post_fuzz_handler can snap the application state back and continue fuzzing\n * without restarting the process.  It also initializes the afl_area edges bitmap that will be used by the\n * basic block instrumentations.\n * @param wrapcxt - An opaque pointer to the DynamoRIO context that this function is called in.  Should only\n * be passed to the DynamoRIO API routines.\n * @param user_data - User data field that can be assigned and passed on to the post_fuzz_handler. Currently unused.\n */\nstatic void pre_fuzz_handler(void *wrapcxt, INOUT void **user_data)\n{\n\tint i;\n\tvoid *drcontext;\n\n\tif (options.debug_mode || options.write_log)\n\t\tdr_fprintf(winafl_data.log, \"pre_fuzz_handler started\\n\");\n\n\tapp_pc target_to_fuzz = drwrap_get_func(wrapcxt);\n\tdr_mcontext_t *mc = drwrap_get_mcontext_ex(wrapcxt, DR_MC_ALL);\n\tdrcontext = drwrap_get_drcontext(wrapcxt);\n\n\t//Save the PC and stack\n\tfuzz_target.xsp = mc->xsp;\n\tfuzz_target.func_pc = target_to_fuzz;\n\n\t//save or restore arguments\n\tif (fuzz_target.iteration == 0) {\n\t\tfor (i = 0; i < options.num_fuz_args; i++) {\n\t\t\toptions.func_args[i] = drwrap_get_arg(wrapcxt, i);\n\t\t}\n\t}\n\telse {\n\t\tfor (i = 0; i < options.num_fuz_args; i++) {\n\t\t\tdrwrap_set_arg(wrapcxt, i, options.func_args[i]);\n\t\t}\n\t}\n\n\t//Wait for the fuzzer to tell us to start\n\tread_start_fuzz_command();\n\n\t//Setup the SHM and TLS regions before we start tracking coverage\n\tsetup_shm_and_tls_regions_for_coverage(drcontext);\n\n\tif (options.debug_mode || options.write_log)\n\t\tdr_fprintf(winafl_data.log, \"pre_fuzz_handler finished\\n\");\n}\n\nstatic void read_start_fuzz_command()\n{\n\tchar command = 0;\n\tDWORD num_read;\n\tchar buffer[256];\n\n\t//Wait for orders from the fuzzer\n\tif (!options.debug_mode) {\n\t\tDR_ASSERT_MSG(ReadFile(pipe, &command, 1, &num_read, NULL), \"Failed to read from comms pipe\");\n\t\tdr_fprintf(winafl_data.log, \"Got %c from pipe\\n\", command);\n\n\t\tif (command != 'F') {\n\t\t\tif (command == 'Q') {\n\t\t\t\tdr_exit_process(0);\n\t\t\t}\n\t\t\telse if (command != 0) {\n\t\t\t\tmemset(buffer, 0, sizeof(buffer));\n\t\t\t\tsnprintf(buffer, sizeof(buffer) - 1, \"unrecognized command received over pipe: %02x (%c)\", command, command);\n\t\t\t\tDR_ASSERT_MSG(false, buffer);\n\t\t\t}\n\t\t}\n\t}\n\telse {\n\t\tdebug_data.pre_hanlder_called++;\n\t}\n}\n\nstatic void setup_shm_and_tls_regions_for_coverage(void *drcontext)\n{\n\ttarget_module_t * cur;\n\n\tif (options.write_log)\n\t\tdr_fprintf(winafl_data.log, \"Initializing shm area\\n\");\n\n\t//Zeroize the shm memory area\n\tif (options.per_module_coverage)\n\t{\n\t\tfor (cur = options.target_modules; cur; cur = cur->next)\n\t\t{\n\t\t\tif (cur->afl_area)\n\t\t\t\tmemset(cur->afl_area, 0, options.verbose_edges ? EDGES_SHM_SIZE : MAP_SIZE);\n\t\t}\n\t}\n\telse if (winafl_data.afl_area)\n\t\tmemset(winafl_data.afl_area, 0, options.verbose_edges ? EDGES_SHM_SIZE : MAP_SIZE);\n\n\tif(options.write_log)\n\t\tdr_fprintf(winafl_data.log, \"initializing thread local data\\n\");\n\n\t//If needed fill in the thread local storage\n\tif (options.coverage_kind == COVERAGE_EDGE || options.thread_coverage || options.verbose_edges) {\n\t\tvoid **thread_data = (void **)drmgr_get_tls_field(drcontext, winafl_tls_field);\n\t\tthread_data[0] = 0; //previous basic block offset\n\t\tif (options.per_module_coverage)\n\t\t{\n\t\t\tfor (cur = options.target_modules; cur; cur = cur->next)\n\t\t\t\tthread_data[cur->index + 1] = cur->afl_area;\n\t\t}\n\t\telse\n\t\t\tthread_data[1] = winafl_data.afl_area;\n\t}\n}\n\n/**\n * This function is called after to the application's function being fuzzed.  It snaps the application state back\n * and continue fuzzing without restarting the process. However, if the fuzz_iterations count has been hit, the process\n * will be ended.\n * @param wrapcxt - An opaque pointer to the DynamoRIO context that this function is called in.  Should only\n * be passed to the DynamoRIO API routines.\n * @param user_data - User data from the post_fuzz_handler. Currently unused.\n */\nstatic void post_fuzz_handler(void *wrapcxt, void *user_data)\n{\n\tDWORD num_written;\n\tDWORD num_bytes = 0;\n\tdr_mcontext_t *mc;\n\n\tif(options.debug_mode || options.write_log)\n\t\tdr_fprintf(winafl_data.log, \"post_fuzz_handler started\\n\");\n\n\tif (!options.debug_mode) {\n\t\tWriteFile(pipe, \"K\", 1, &num_written, NULL);\n\t} else {\n\t\tdebug_data.post_handler_called++;\n\t}\n\n\tfuzz_target.iteration++;\n\tif (fuzz_target.iteration == options.fuzz_iterations) {\n\t\tif (options.debug_mode || options.write_log)\n\t\t\tdr_fprintf(winafl_data.log, \"Exiting due to iteration count (iteration %d max %d)\", fuzz_target.iteration, options.fuzz_iterations);\n\t\tdr_exit_process(0);\n\t}\n\n\tmc = drwrap_get_mcontext(wrapcxt);\n\tmc->xsp = fuzz_target.xsp;\n\tmc->pc = fuzz_target.func_pc;\n\n\tdrwrap_redirect_execution(wrapcxt);\n\n\tif (options.debug_mode || options.write_log)\n\t\tdr_fprintf(winafl_data.log , \"post_fuzz_handler finished\\n\");\n}\n\n/**\n * This function is prior to the CreateFileW Windows API function to help determine what\n * files are being opened by the target application.\n * @param wrapcxt - An opaque pointer to the DynamoRIO context that this function is called in.  Should only\n * be passed to the DynamoRIO API routines.\n * @param user_data - User data pointer. Currently unused.\n */\nstatic void createfilew_interceptor(void *wrapcxt, INOUT void **user_data)\n{\n\twchar_t *filenamew = (wchar_t *)drwrap_get_arg(wrapcxt, 0);\n\n\tif (options.debug_mode || options.write_log)\n\t\tdr_fprintf(winafl_data.log, \"In OpenFileW, reading %ls\\n\", filenamew);\n}\n\n/**\n * This function is prior to the CreateFileA Windows API function to help determine what\n * files are being opened by the target application.\n * @param wrapcxt - An opaque pointer to the DynamoRIO context that this function is called in.  Should only\n * be passed to the DynamoRIO API routines.\n * @param user_data - User data pointer. Currently unused.\n */\nstatic void createfilea_interceptor(void *wrapcxt, INOUT void **user_data)\n{\n\tchar *filename = (char *)drwrap_get_arg(wrapcxt, 0);\n\n\tif (options.debug_mode || options.write_log)\n\t\tdr_fprintf(winafl_data.log, \"In OpenFileA, reading %s\\n\", filename);\n}\n\nstatic void\nverfierstopmessage_interceptor_pre(void *wrapctx, INOUT void **user_data)\n{\n\tEXCEPTION_RECORD exception_record = { 0 };\n\tdr_exception_t dr_exception = { 0 };\n\tdr_exception.record = &exception_record;\n\texception_record.ExceptionCode = STATUS_HEAP_CORRUPTION;\n\n\tonexception(NULL, &dr_exception);\n}\n\n\n/**\n * This function is a callback for when a module is unloaded.  We remove it from the module_table so\n * we don't try to instrument it anymore.\n * @param drcontext - a pointer to the input program's machine context.  This parameter should not be\n * inspected or modified, and should only be used to be passed to the DynamoRIO API routines.\n * @param info - a module_data_t structure describing the module that was unloaded\n */\nstatic void event_module_unload(void *drcontext, const module_data_t *info)\n{\n\tmodule_table_unload(module_table, info);\n}\n\n/**\n* This function is a callback for when a module is loaded.  We remove it from the module_table so\n* we don't try to instrument it anymore.\n* @param drcontext - a pointer to the input program's machine context.  This parameter should not be\n* inspected or modified, and should only be used to be passed to the DynamoRIO API routines.\n* @param info - a module_data_t structure describing the module that was unloaded\n* @param loaded - whether the module is fully initialized by the loader or in the process of being loaded\n*/\nstatic void event_module_load(void *drcontext, const module_data_t *info, bool loaded)\n{\n\tconst char *module_name = info->names.exe_name;\n\tapp_pc to_wrap = 0;\n\n\tif (module_name == NULL) {\n\t\t// In case exe_name is not defined, we will fall back on the preferred name.\n\t\tmodule_name = dr_module_preferred_name(info);\n\t}\n\n\tif (options.debug_mode)\n\t\tdr_fprintf(winafl_data.log, \"Module loaded, %s\\n\", module_name);\n\n\tif (options.fuzz_module[0]) {\n\t\tif (strcmp(module_name, options.fuzz_module) == 0) {\n\t\t\tif (options.fuzz_offset) {\n\t\t\t\tto_wrap = info->start + options.fuzz_offset;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t//first try exported symbols\n\t\t\t\tto_wrap = (app_pc)dr_get_proc_address(info->handle, options.fuzz_method);\n\t\t\t\tif (!to_wrap) {\n\t\t\t\t\t//if that fails, try with the symbol access library\n\t\t\t\t\tdrsym_init(0);\n\t\t\t\t\tdrsym_lookup_symbol(info->full_path, options.fuzz_method, (size_t *)(&to_wrap), 0);\n\t\t\t\t\tdrsym_exit();\n\t\t\t\t\tDR_ASSERT_MSG(to_wrap, \"Can't find specified method in fuzz_module\");\n\t\t\t\t\tto_wrap += (size_t)info->start;\n\t\t\t\t}\n\t\t\t}\n\t\t\tdrwrap_wrap_ex(to_wrap, pre_fuzz_handler, post_fuzz_handler, NULL, options.callconv);\n\t\t}\n\n\t\tif (options.debug_mode && (_stricmp(module_name, \"KERNEL32.dll\") == 0)) {\n\t\t\tto_wrap = (app_pc)dr_get_proc_address(info->handle, \"CreateFileW\");\n\t\t\tdrwrap_wrap(to_wrap, createfilew_interceptor, NULL);\n\t\t\tto_wrap = (app_pc)dr_get_proc_address(info->handle, \"CreateFileA\");\n\t\t\tdrwrap_wrap(to_wrap, createfilea_interceptor, NULL);\n\t\t}\n\t}\n\n\tif (_stricmp(module_name, \"verifier.dll\") == 0) {\n\t\tto_wrap = (app_pc)dr_get_proc_address(info->handle, \"VerifierStopMessage\");\n\t\tdrwrap_wrap(to_wrap, verfierstopmessage_interceptor_pre, NULL);\n\t}\n\n\tmodule_table_load(module_table, info);\n}\n\n/**\n * This function is called prior to the application exiting.  It cleans up the DynamoRIO releated resources.\n */\nstatic void event_exit(void)\n{\n\tDWORD num_written;\n\tif (options.debug_mode) {\n\t\tif (debug_data.pre_hanlder_called == 0) {\n\t\t\tdr_fprintf(winafl_data.log, \"WARNING: Target function was never called. Incorrect target_offset?\\n\");\n\t\t}\n\t\telse if (debug_data.post_handler_called == 0) {\n\t\t\tdr_fprintf(winafl_data.log, \"WARNING: Post-fuzz handler was never reached. Did the target function return normally?\\n\");\n\t\t}\n\t\telse {\n\t\t\tdr_fprintf(winafl_data.log, \"Everything appears to be running normally.\\n\");\n\t\t}\n\n\t\tdr_fprintf(winafl_data.log, \"Coverage map follows:\\n\");\n\t\tdump_winafl_data();\n\t\tdr_close_file(winafl_data.log);\n\t}\n\n\tif (!options.fuzz_module[0] && !winafl_data.exception_hit) {\n\t\t//if we're not using the pre/post fuzz handler functions, we should let the fuzzer know we didn't crash\n\t\tWriteFile(pipe, \"K\", 1, &num_written, NULL);\n\t}\n\n\t/* destroy module table */\n\tmodule_table_destroy(module_table);\n\n\tdrx_exit();\n\tdrmgr_exit();\n}\n\n/**\n * This function is called at the time DynamoRIO is started.  It initializes the AFL bitmaps and sets up the instrumentation.\n */\nstatic void event_init(void)\n{\n\tchar buffer[MAXIMUM_PATH];\n\n\tif (options.debug_mode || options.write_log) {\n\t\tdebug_data.pre_hanlder_called = 0;\n\t\tdebug_data.post_handler_called = 0;\n\n\t\twinafl_data.log =\n\t\t\tdrx_open_unique_appid_file(options.logdir, dr_get_process_id(),\n\t\t\t\t\"afl\", \"proc.log\",\n\t\t\t\tDR_FILE_ALLOW_LARGE,\n\t\t\t\tbuffer, BUFFER_SIZE_ELEMENTS(buffer));\n\t\tif (winafl_data.log != INVALID_FILE) {\n\t\t\tdr_log(NULL, LOG_ALL, 1, \"winafl: log file is %s\\n\", buffer);\n\t\t\tNOTIFY(1, \"<created log file %s>\\n\", buffer);\n\t\t}\n\t}\n\n\tmodule_table = module_table_create();\n\n\tmemset(winafl_data.cache, 0, sizeof(winafl_data.cache));\n\tif (options.per_module_coverage)\n\t{\n\t\ttarget_module_t * target_module;\n\t\tfor (target_module = options.target_modules; target_module; target_module = target_module->next)\n\t\t{\n\t\t\tDR_ASSERT_MSG(target_module->afl_area != NULL, \"afl_area not properly setup\");\n\t\t\tmemset(target_module->afl_area, 0, options.verbose_edges  ? EDGES_SHM_SIZE : MAP_SIZE);\n\t\t}\n\t}\n\telse\n\t{\n\t\tDR_ASSERT_MSG(winafl_data.afl_area != NULL, \"afl_area not properly setup\");\n\t\tmemset(winafl_data.afl_area, 0, options.verbose_edges ? EDGES_SHM_SIZE : MAP_SIZE);\n\t}\n\n\tfuzz_target.iteration = 0;\n}\n\n/**\n * This function sets up a pipe to communicate to the main fuzzing process.\n * @param pipe_name - the name of the pipe to setup\n * @param access - the type of access required to the pipe\n * @return - a HANDLE to the pipe that was setup\n */\nstatic HANDLE setup_pipe(const char * pipe_name, DWORD access)\n{\n\tchar buffer[512];\n\tHANDLE pipe_handle;\n\n\tpipe_handle = CreateFile(\n\t\tpipe_name,      // pipe name\n\t\taccess,\n\t\t0,              // no sharing\n\t\tNULL,           // default security attributes\n\t\tOPEN_EXISTING,  // opens existing pipe\n\t\t0,              // default attributes\n\t\tNULL);          // no template file\n\n\tif (pipe_handle == INVALID_HANDLE_VALUE)\n\t{\n\t\tsnprintf(buffer, sizeof(buffer) - 1, \"Error connecting to pipe '%s'\", pipe_name);\n\t\tbuffer[sizeof(buffer) - 1] = 0;\n\t\tDR_ASSERT_MSG(false, buffer);\n\t}\n\treturn pipe_handle;\n}\n\n/**\n * Sets up the pipe used for communication to the main fuzzing process\n */\nstatic void setup_comms_pipe()\n{\n\tpipe = setup_pipe(options.pipe_name, GENERIC_READ | GENERIC_WRITE);\n}\n\n/**\n * This function maps a shared memory region and returns a pointer it\n * @param name - the name of the shared memory region to map\n * @param for_edges - whether the shm region is for the full edge recording or not\n * @return - a pointer to the shared memory region\n */\nstatic unsigned char * get_shmem_region(char * name, int for_edges)\n{\n\tHANDLE map_file;\n\tchar buffer[512];\n\tchar * ret;\n\tDWORD size;\n\n\tif (for_edges)\n\t\tsize = EDGES_SHM_SIZE;\n\telse\n\t\tsize = MAP_SIZE;\n\n\tmap_file = OpenFileMapping(\n\t\tFILE_MAP_ALL_ACCESS,   // read/write access\n\t\tFALSE,                 // do not inherit the name\n\t\tname);                 // name of mapping object\n\n\tif (map_file == NULL)\n\t{\n\t\tsnprintf(buffer, sizeof(buffer) - 1, \"OpenFileMapping Failed for shm_name %s (GLE=%d)\",\n\t\t\tname, GetLastError());\n\t\tDR_ASSERT_MSG(false, buffer);\n\t}\n\n\tret = (unsigned char *)MapViewOfFile(map_file, // handle to map object\n\t\tFILE_MAP_ALL_ACCESS,  // read/write permission\n\t\t0,\n\t\t0,\n\t\tsize);\n\n\tif (ret == NULL)\n\t{\n\t\tsnprintf(buffer, sizeof(buffer) - 1, \"MapViewOfFile Failed for shm_name %s (GLE=%d)\",\n\t\t\tname, GetLastError());\n\t\tDR_ASSERT_MSG(false, buffer);\n\t}\n\treturn ret;\n}\n\n/**\n * Sets up the shared memory regions for all of the target modules being tracked.\n */\nstatic void setup_per_module_shmem() {\n\ttarget_module_t * cur;\n\tchar name[512];\n\n\tDR_ASSERT_MSG(options.per_module_coverage, \"setup_per_module_shmem should only be called when options.per_module_coverage is true\");\n\tfor (cur = options.target_modules; cur; cur = cur->next)\n\t{\n\t\tmemset(name, 0, sizeof(name));\n\t\tsnprintf(name, sizeof(name) - 1, \"%s_%d\", options.shm_name, cur->index);\n\t\tcur->afl_area = get_shmem_region(name, options.verbose_edges);\n\t}\n}\n\n/**\n* Sets up the shared memory region when not tracking per module coverage.\n */\nstatic void\nsetup_shmem() {\n\tDR_ASSERT_MSG(!options.per_module_coverage, \"setup_shmem should only be called when options.per_module_coverage is false\");\n\twinafl_data.afl_area = get_shmem_region(options.shm_name, options.verbose_edges);\n}\n\n/**\n * Opens the module file and adds the modules listed in it to the target_module linked list\n */\nstatic void read_module_file(const char * filename)\n{\n\tFILE *fp;\n\tchar line[1024];\n\n\tfp = fopen(filename, \"rb\");\n\tUSAGE_CHECK(fp, \"Couldn't open module file\");\n\n\twhile (fgets(line, sizeof(line), fp))\n\t{\n\t\tif (line[strlen(line) - 1] == '\\n')\n\t\t\tline[strlen(line) - 1] = 0;\n\t\tif (line[strlen(line) - 1] == '\\r')\n\t\t\tline[strlen(line) - 1] = 0;\n\t\tadd_target_module(line);\n\t}\n\n\tfclose(fp);\n}\n\n/**\n * Parses the command line arguments passed to DynamoRIO and sets up the global options struct\n * @param id - The client_id assigned by DynamoRIO to this instrance\n * @param argc - the number of arguments in the argv parameter\n * @param argv - the command line arguments passed to DynamoRIO\n */\nstatic void options_init(client_id_t id, int argc, const char *argv[])\n{\n\tint i;\n\tconst char *token;\n\tchar buffer[512];\n\t/* default values */\n\toptions.nudge_kills = true;\n\toptions.verbose_edges = false;\n\toptions.debug_mode = false;\n\toptions.write_log = false;\n\toptions.thread_coverage = true;\n\toptions.per_module_coverage = false;\n\toptions.coverage_kind = COVERAGE_EDGE;\n\toptions.target_modules = NULL;\n\toptions.fuzz_module[0] = 0;\n\toptions.fuzz_method[0] = 0;\n\toptions.fuzz_offset = 0;\n\toptions.fuzz_iterations = 1;\n\toptions.func_args = NULL;\n\toptions.num_fuz_args = 0;\n\toptions.callconv = DRWRAP_CALLCONV_DEFAULT;\n\tdr_snprintf(options.logdir, BUFFER_SIZE_ELEMENTS(options.logdir), \".\");\n\n\tstrcpy(options.pipe_name, \"\\\\\\\\.\\\\pipe\\\\afl_pipe_default\");\n\tstrcpy(options.shm_name, \"afl_shm_default\");\n\n\tfor (i = 1/*skip client*/; i < argc; i++) {\n\t\ttoken = argv[i];\n\t\tif (strcmp(token, \"-no_nudge_kills\") == 0)\n\t\t\toptions.nudge_kills = false;\n\t\telse if (strcmp(token, \"-verbose_edges\") == 0)\n\t\t{\n\t\t\toptions.verbose_edges = true;\n\t\t\toptions.coverage_kind = COVERAGE_EDGE;\n\t\t\toptions.thread_coverage = true;\n\t\t}\n\t\telse if (strcmp(token, \"-nudge_kills\") == 0)\n\t\t\toptions.nudge_kills = true;\n\t\telse if (strcmp(token, \"-no_thread_coverage\") == 0)\n\t\t\toptions.thread_coverage = false;\n\t\telse if (strcmp(token, \"-per_module_coverage\") == 0)\n\t\t\toptions.per_module_coverage = true;\n\t\telse if (strcmp(token, \"-debug\") == 0)\n\t\t\toptions.debug_mode = true;\n\t\telse if (strcmp(token, \"-write_log\") == 0)\n\t\t\toptions.write_log = true;\n\t\telse if (strcmp(token, \"-logdir\") == 0) {\n\t\t\tUSAGE_CHECK((i + 1) < argc, \"missing logdir path\");\n\t\t\tstrncpy(options.logdir, argv[++i], BUFFER_SIZE_ELEMENTS(options.logdir));\n\t\t}\n\t\telse if (strcmp(token, \"-fuzzer_id\") == 0) {\n\t\t\tUSAGE_CHECK((i + 1) < argc, \"missing fuzzer id\");\n\t\t\tstrcpy(options.pipe_name, \"\\\\\\\\.\\\\pipe\\\\afl_pipe_\");\n\t\t\tstrcat(options.pipe_name, argv[i + 1]);\n\t\t\tstrcpy(options.shm_name, \"afl_shm_\");\n\t\t\tstrcat(options.shm_name, argv[i + 1]);\n\t\t\ti++;\n\t\t}\n\t\telse if (strcmp(token, \"-covtype\") == 0) {\n\t\t\tUSAGE_CHECK((i + 1) < argc, \"missing coverage type\");\n\t\t\ttoken = argv[++i];\n\t\t\tif (strcmp(token, \"bb\") == 0) options.coverage_kind = COVERAGE_BB;\n\t\t\telse if (strcmp(token, \"edge\") == 0) options.coverage_kind = COVERAGE_EDGE;\n\t\t\telse USAGE_CHECK(false, \"invalid coverage type\");\n\t\t}\n\t\telse if (strcmp(token, \"-coverage_module\") == 0) {\n\t\t\tUSAGE_CHECK((i + 1) < argc, \"missing module\");\n\t\t\tadd_target_module(argv[++i]);\n\t\t}\n\t\telse if (strcmp(token, \"-coverage_module_file\") == 0) {\n\t\t\tUSAGE_CHECK((i + 1) < argc, \"missing module file\");\n\t\t\tread_module_file(argv[++i]);\n\t\t}\n\t\telse if (strcmp(token, \"-target_module\") == 0) {\n\t\t\tUSAGE_CHECK((i + 1) < argc, \"missing module\");\n\t\t\tstrncpy(options.fuzz_module, argv[++i], BUFFER_SIZE_ELEMENTS(options.fuzz_module));\n\t\t}\n\t\telse if (strcmp(token, \"-target_method\") == 0) {\n\t\t\tUSAGE_CHECK((i + 1) < argc, \"missing method\");\n\t\t\tstrncpy(options.fuzz_method, argv[++i], BUFFER_SIZE_ELEMENTS(options.fuzz_method));\n\t\t}\n\t\telse if (strcmp(token, \"-fuzz_iterations\") == 0) {\n\t\t\tUSAGE_CHECK((i + 1) < argc, \"missing number of iterations\");\n\t\t\toptions.fuzz_iterations = atoi(argv[++i]);\n\t\t}\n\t\telse if (strcmp(token, \"-nargs\") == 0) {\n\t\t\tUSAGE_CHECK((i + 1) < argc, \"missing number of arguments\");\n\t\t\toptions.num_fuz_args = atoi(argv[++i]);\n\t\t}\n\t\telse if (strcmp(token, \"-target_offset\") == 0) {\n\t\t\tUSAGE_CHECK((i + 1) < argc, \"missing offset\");\n\t\t\toptions.fuzz_offset = strtoul(argv[++i], NULL, 0);\n\t\t}\n\t\telse if (strcmp(token, \"-verbose\") == 0) {\n\t\t\tUSAGE_CHECK((i + 1) < argc, \"missing -verbose number\");\n\t\t\ttoken = argv[++i];\n\t\t\tif (dr_sscanf(token, \"%u\", &verbose) != 1) {\n\t\t\t\tUSAGE_CHECK(false, \"invalid -verbose number\");\n\t\t\t}\n\t\t}\n\t\telse if (strcmp(token, \"-call_convention\") == 0) {\n\t\t\tUSAGE_CHECK((i + 1) < argc, \"missing calling convention\");\n\t\t\t++i;\n\t\t\tif (strcmp(argv[i], \"stdcall\") == 0)\n\t\t\t\toptions.callconv = DRWRAP_CALLCONV_CDECL;\n\t\t\telse if (strcmp(argv[i], \"fastcall\") == 0)\n\t\t\t\toptions.callconv = DRWRAP_CALLCONV_FASTCALL;\n\t\t\telse if (strcmp(argv[i], \"thiscall\") == 0)\n\t\t\t\toptions.callconv = DRWRAP_CALLCONV_THISCALL;\n\t\t\telse if (strcmp(argv[i], \"ms64\") == 0)\n\t\t\t\toptions.callconv = DRWRAP_CALLCONV_MICROSOFT_X64;\n\t\t\telse\n\t\t\t\tNOTIFY(0, \"Unknown calling convention, using default value instead.\\n\");\n\t\t}\n\t\telse {\n\t\t\tNOTIFY(0, \"UNRECOGNIZED OPTION: \\\"%s\\\"\\n\", token);\n\t\t\tmemset(buffer, 0, sizeof(buffer));\n\t\t\tsnprintf(buffer, sizeof(buffer) - 1, \"Invalid option: %s\", token);\n\t\t\tUSAGE_CHECK(false, buffer);\n\t\t}\n\t}\n\n\tif (options.verbose_edges && (options.coverage_kind != COVERAGE_EDGE || options.thread_coverage != true)) {\n\t\tUSAGE_CHECK(false, \"If verbose_edges is specified, then the coverage kind must be edge and thread coverage must be on\");\n\t}\n\n\tif (options.fuzz_module[0] && (options.fuzz_offset == 0) && (options.fuzz_method[0] == 0)) {\n\t\tUSAGE_CHECK(false, \"If fuzz_module is specified, then either fuzz_method or fuzz_offset must be as well\");\n\t}\n\n\tif (options.num_fuz_args) {\n\t\toptions.func_args = (void **)dr_global_alloc(options.num_fuz_args * sizeof(void *));\n\t}\n\n\tif (strlen(options.fuzz_module) == 0 && strlen(options.fuzz_method) == 0 && options.fuzz_offset == 0\n\t\t&& options.fuzz_iterations != 1) {\n\t\tUSAGE_CHECK(false, \"If fuzz_module is specified, then either fuzz_method or fuzz_offset must be as well\");\n\t}\n}\n\n/**\n * The main entrypoint from DynamoRIO\n * @param id - The client_id assigned by DynamoRIO to this instrance\n * @param argc - the number of command line arguments in the argv parameter\n * @param argv - the command line arguments passed to DynamoRIO\n */\nDR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[])\n{\n\ttarget_module_t * cur;\n\tdrreg_options_t ops = { sizeof(ops), 2 /*max slots needed: aflags*/, false };\n\tsize_t size;\n\n\tdr_set_client_name(\"WinAFL\", \"\");\n\n\tdrmgr_init();\n\tdrx_init();\n\tdrreg_init(&ops);\n\tdrwrap_init();\n\n\toptions_init(id, argc, argv);\n\n\tdr_register_exit_event(event_exit);\n\n\tdrmgr_register_exception_event(onexception);\n\n\tif (options.verbose_edges) {\n\t\tdrmgr_register_bb_instrumentation_event(NULL, instrument_verbose_edge_coverage, NULL);\n\t}\n\telse  if (options.coverage_kind == COVERAGE_BB) {\n\t\tdrmgr_register_bb_instrumentation_event(NULL, instrument_bb_coverage, NULL);\n\t}\n\telse if (options.coverage_kind == COVERAGE_EDGE) {\n\t\tdrmgr_register_bb_instrumentation_event(NULL, instrument_edge_coverage, NULL);\n\t}\n\n\tdrmgr_register_module_load_event(event_module_load);\n\tdrmgr_register_module_unload_event(event_module_unload);\n\tdr_register_nudge_event(event_nudge, id);\n\n\tclient_id = id;\n\n\tif (options.nudge_kills)\n\t\tdrx_register_soft_kills(event_soft_kill);\n\n\twinafl_data.instrumentation_enabled = false;\n\twinafl_data.exception_hit = false;\n\n\tif (options.thread_coverage || options.coverage_kind == COVERAGE_EDGE) {\n\t\tsize = MAP_SIZE;\n\t\tif (options.verbose_edges)\n\t\t\tsize = EDGES_SHM_SIZE;\n\t\twinafl_data.fake_afl_area = (unsigned char *)dr_global_alloc(size);\n\t\tmemset(winafl_data.fake_afl_area, 0, size);\n\t}\n\n\t//Allocate the afl area\n\tif (!options.debug_mode) {\n\t\tsetup_comms_pipe();\n\t\tif (options.per_module_coverage)\n\t\t\tsetup_per_module_shmem();\n\t\telse\n\t\t\tsetup_shmem();\n\t}\n\telse\n\t{\n\t\tif (options.per_module_coverage)\n\t\t{\n\t\t\tfor (cur = options.target_modules; cur; cur = cur->next)\n\t\t\t\tcur->afl_area = (unsigned char *)dr_global_alloc(MAP_SIZE);\n\t\t}\n\t\telse\n\t\t\twinafl_data.afl_area = (unsigned char *)dr_global_alloc(MAP_SIZE);\n\t}\n\n\tif (options.coverage_kind == COVERAGE_EDGE || options.thread_coverage) {\n\t\twinafl_tls_field = drmgr_register_tls_field();\n\t\tif (winafl_tls_field == -1) {\n\t\t\tDR_ASSERT_MSG(false, \"error reserving TLS field\");\n\t\t}\n\t\tdrmgr_register_thread_init_event(event_thread_init);\n\t\tdrmgr_register_thread_exit_event(event_thread_exit);\n\t}\n\n\tevent_init();\n\n\tif(options.write_log)\n\t\tdr_fprintf(winafl_data.log, \"Done with dr_client_main\\n\");\n}\n"
  }
]