├── .gitignore ├── AUTHORS ├── Makefile ├── Makefile.dep ├── README.md ├── buildtools └── depcheck.sh ├── data └── minbit.csv ├── fetch-pin.sh └── src ├── Makefile ├── analyzer ├── analysis.ml ├── analysis.mli ├── bapmisc.ml ├── bapmisc.mli ├── comm.ml ├── context.ml ├── context.mli ├── dependency.ml ├── depreader.ml ├── eArray.ml ├── interpretation.ml ├── localsock.ml ├── log_analysis.ml ├── log_interface.ml ├── memory.ml ├── misc.ml ├── misc.mli ├── options.ml ├── pin.ml ├── pinapi.idl ├── printer.ml ├── process.ml ├── protocol.ml ├── rcfg.ml ├── state.ml ├── state.mli ├── symfuzz.ml ├── symfuzz_protocol.ml ├── symfuzz_protocol.mli └── syscall.ml ├── instrumentor ├── Makefile ├── analysis_api.cpp ├── analysis_api.hpp ├── bbl_cache.cpp ├── bbl_cache.hpp ├── callbacks.cpp ├── callbacks.hpp ├── context.cpp ├── context.hpp ├── logger.cpp ├── logger.hpp ├── main.cpp ├── makefile.rules ├── memorylog.cpp ├── memorylog.hpp ├── misc.cpp ├── misc.hpp ├── tls.cpp └── tls.hpp ├── libanalysis.clib ├── myocamlbuild.ml └── pinapi ├── Makefile ├── makefile.rules ├── pinapi.cpp └── pinapi.h /.gitignore: -------------------------------------------------------------------------------- 1 | bap 2 | stamp 3 | pin 4 | src/_build 5 | *.native 6 | src/symfuzz 7 | src/depreader 8 | src/instrumentor/obj-ia32 9 | src/pinapi/obj-ia32 10 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Sang Kil Cha 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # symfuzz Makefile # 3 | # # 4 | # Copyright (c) 2014, Sang Kil Cha # 5 | # All rights reserved. # 6 | # This software is free software; you can redistribute it and/or # 7 | # modify it under the terms of the GNU Library General Public # 8 | # License version 2, with the special exception on linking # 9 | # described in file LICENSE. # 10 | # # 11 | # This software is distributed in the hope that it will be useful, # 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # 14 | ############################################################################### 15 | 16 | all: depcheck src 17 | 18 | src: 19 | make -C src 20 | 21 | depcheck: Makefile.dep 22 | @buildtools/depcheck.sh $< 23 | 24 | clean: 25 | make -C src clean 26 | 27 | .PHONY: all src depcheck clean 28 | -------------------------------------------------------------------------------- /Makefile.dep: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # symfuzz build dependency file # 3 | # # 4 | # Copyright (c) 2014, Sang Kil Cha # 5 | # All rights reserved. # 6 | # This software is free software; you can redistribute it and/or # 7 | # modify it under the terms of the GNU Library General Public # 8 | # License version 2, with the special exception on linking # 9 | # described in file LICENSE. # 10 | # # 11 | # This software is distributed in the hope that it will be useful, # 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # 14 | ############################################################################### 15 | 16 | # check binaries 17 | bin,ocamlbuild 18 | bin,camlidl 19 | bin,g++ 20 | # check libraries 21 | lib,unix 22 | lib,str 23 | lib,libbil,0.8 24 | lib,libinput 25 | lib,yojson 26 | # check headers 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SymFuzz 2 | ======= 3 | 4 | This is an input-bit dependence inference prototype. See our Oakland 2015 paper 5 | for more details. 6 | 7 | The paper used 3 components: 8 | 9 | 1. The software contained in this repository (`symfuzz`). 10 | 2. [`ofuzz`](https://github.com/sangkilc/ofuzz) 11 | 3. A [patch](https://github.com/maurer/nixlocal/blob/master/pkgs/afl-symfuzz/symfuzz.patch) to `afl-fuzz` 12 | 13 | Install 14 | ======= 15 | 16 | VirtualBox 17 | ------- 18 | Probably the easiest way to try `symfuzz` is to use our VirtualBox [appliance](https://mirrors.aegis.cylab.cmu.edu/aegis/symfuzz.ova). 19 | 20 | Nix-based 21 | ------- 22 | If using Nix on your system, feel free to use my [repository](https://github.com/maurer/nixlocal/) used in the production of the VirtualBox image. 23 | 24 | Manual 25 | ------- 26 | 27 | We recommend using OPAM for building SymFuzz. 28 | 29 | 1. Install [OPAM](https://opam.ocaml.org/) with OCaml version *4.02.1* or higher. 30 | 31 | 2. Install [libBIL](https://github.com/sangkilc/libbil) 32 | ``` 33 | git clone https://github.com/sangkilc/libbil.git 34 | cd libbil; make install; cd .. 35 | ``` 36 | 37 | 3. Install [libInput](https://github.com/sangkilc/libinput) 38 | ``` 39 | git clone https://github.com/sangkilc/libinput.git 40 | cd libinput; make install; cd .. 41 | ``` 42 | 43 | 4. Build SymFuzz 44 | ``` 45 | ./fetch-pin.sh 46 | make 47 | ``` 48 | 49 | Usage 50 | ====== 51 | 52 | Use of this tool is largely undocumented. 53 | If you want to provide documentation, feel free to write a wiki entry or submit 54 | a pull request. 55 | -------------------------------------------------------------------------------- /buildtools/depcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################### 4 | # OCaml dependency checker # 5 | # # 6 | # Copyright (c) 2014, Sang Kil Cha # 7 | # All rights reserved. # 8 | # This software is free software; you can redistribute it and/or # 9 | # modify it under the terms of the GNU Library General Public # 10 | # License version 2, with the special exception on linking # 11 | # described in file LICENSE. # 12 | # # 13 | # This software is distributed in the hope that it will be useful, # 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # 16 | ############################################################################### 17 | 18 | bincheck () { 19 | type "$1" > /dev/null 2> /dev/null 20 | if (( $? > 0 )); then 21 | echo "Error: $1 does not exist." 22 | echo " Please see the installation instruction for more information." 23 | exit 1 24 | else 25 | return 0 26 | fi 27 | } 28 | 29 | libcheck () { 30 | libname=$1 31 | libversion=$2 32 | 33 | if [ -z $libversion ]; then 34 | libversion=0.0 35 | fi 36 | 37 | libstring=$(ocamlfind list | 38 | sed 's,\[internal\],,' | sed 's,\[distributed with Ocaml\],,' | tr -d ')' | 39 | awk '{if (length($3) == 0) {print $1",0.0"} else {print $1","$3}}' | 40 | grep "^$libname," 2> /dev/null) 41 | 42 | if (( $? > 0 )); then 43 | echo "Error: ocaml library [$1] does not exist." 44 | echo " Please see the installation instruction for more information." 45 | exit 1 46 | fi 47 | 48 | echo $libstring | 49 | awk -F',' '{dif= $2 - '$libversion'; if (dif >= 0) {exit 0} else {exit 1}}' \ 50 | 2> /dev/null 51 | 52 | if (( $? > 0 )); then 53 | echo "Error: the version of ocaml library [$1] must be >= $libversion" 54 | echo " Please see the installation instruction for more information." 55 | exit 1 56 | fi 57 | 58 | return 0 59 | } 60 | 61 | headercheck () { 62 | headerfile=$1 63 | cc=$2 64 | tmpdir=tmp.$RANDOM 65 | if [ "$cc" == "g++" ]; then 66 | tmpfile=$tmpdir/tmp.cc 67 | else 68 | tmpfile=$tmpdir/tmp.c 69 | fi 70 | mkdir $tmpdir 71 | cat << EOF > $tmpfile 72 | #include "$headerfile" 73 | int main() {return 0;} 74 | EOF 75 | if (( $? > 0 )); then 76 | rm -rf $tmpdir 77 | echo "Error: Failed to create $tmpfile" 78 | exit 1 79 | fi 80 | 81 | $cc -Wall -Werror -I/usr/local/include $tmpfile -o $tmpdir/a.out 82 | success=$? 83 | rm -rf $tmpdir 84 | 85 | if (( $success > 0 )); then 86 | echo "Error: failed to find [$headerfile]" 87 | exit 1 88 | fi 89 | } 90 | 91 | ### self sanitization 92 | bincheck "awk" 93 | bincheck "sed" 94 | bincheck "tr" 95 | bincheck "cut" 96 | bincheck "gcc" 97 | bincheck "g++" 98 | bincheck "ocamlfind" 99 | 100 | ### reading input 101 | depfile=$1 102 | 103 | if [ -z $depfile ];then 104 | echo "Error: Must provide a dependency file to $0" 105 | echo "" 106 | cat << EOF 107 | Usage: $0 108 | 109 | Dependency files must include a dependency command per line. A 110 | dependency command is a comma-separated tuple, which checks 111 | a binary dependency, a library dependency, or a header file 112 | dependency. 113 | 114 | A binary dependency is a 2-tuple (bin, binary name). The first 115 | field specifies a command, thus it should not be changed. 116 | 117 | A library dependency can be specified either by: 118 | 2-tuple (lib, library name) 119 | or 120 | 3-tuple (lib, library name, required version). 121 | 122 | A header file dependency is a 2-tuple (header, file name). 123 | 124 | The following example dependency file checks the followings: 125 | (1) check if the binary "ocaml" presents in the system; 126 | (2) check if the library (batteries) exists in the system and if 127 | the library has a version greater or equal to 2.1; 128 | (3) check if the header file (bfd.h) exists 129 | 130 | (An example dependency file) 131 | bin,ocaml 132 | lib,batteries,2.1 133 | header,bfd.h 134 | 135 | EOF 136 | exit 1 137 | fi 138 | 139 | IFS=$'\n' 140 | ### parsing the dependency file 141 | for line in $(cat $depfile | grep -v '^#' | grep -v '^\s*$'); do 142 | cmd=$(echo $line | cut -d, -f1 | sed -e 's/^ *//' -e 's/ *$//') 143 | name=$(echo $line | cut -d, -f2 | sed -e 's/^ *//' -e 's/ *$//') 144 | ver=$(echo $line | cut -d, -f3 | sed -e 's/^ *//' -e 's/ *$//') 145 | 146 | if [[ $cmd == "bin" ]]; then 147 | bincheck $name 148 | elif [[ $cmd == "lib" ]]; then 149 | libcheck $name $ver 150 | elif [[ $cmd == "header+" ]]; then 151 | headercheck $name g++ 152 | elif [[ $cmd == "header" ]]; then 153 | headercheck $name gcc 154 | fi 155 | done 156 | -------------------------------------------------------------------------------- /fetch-pin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | wget 'http://software.intel.com/sites/landingpage/pintool/downloads/pin-2.14-67254-gcc.4.4.7-linux.tar.gz' 3 | tar xfz pin-2.14-67254-gcc.4.4.7-linux.tar.gz 4 | mv pin-2.14-67254-gcc.4.4.7-linux pin 5 | rm pin-2.14-67254-gcc.4.4.7-linux.tar.gz 6 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # SymFuzz Makefile # 3 | # # 4 | # Copyright (c) 2014, Sang Kil Cha # 5 | # All rights reserved. # 6 | # This software is free software; you can redistribute it and/or # 7 | # modify it under the terms of the GNU Library General Public # 8 | # License version 2, with the special exception on linking # 9 | # described in file LICENSE. # 10 | # # 11 | # This software is distributed in the hope that it will be useful, # 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # 14 | ############################################################################### 15 | 16 | OCAMLBUILD=ocamlbuild 17 | 18 | OFUZZ_SUBDIRS=-Is libinput,analyzer \ 19 | -Xs buildtools,pinapi,instrumentor,unittest 20 | 21 | TARGET_BINARY=symfuzz 22 | 23 | all: depcheck 24 | make -C pinapi 25 | $(OCAMLBUILD) -no-links $(OFUZZ_SUBDIRS) \ 26 | -lflag -runtime-variant -lflag _pic \ 27 | symfuzz.native libanalysis.native depreader.native 28 | make -C instrumentor 29 | ln -sf _build/analyzer/symfuzz.native $(TARGET_BINARY) 30 | ln -sf _build/analyzer/depreader.native depreader 31 | 32 | unittest: unittest/Makefile 33 | @make -C unittest 34 | 35 | clean: depcheck 36 | make -C pinapi clean 37 | $(OCAMLBUILD) -clean 38 | rm -f $(TARGET_BINARY) depreader 39 | make -C instrumentor clean 40 | 41 | clean-log: 42 | @rm -rf *.log 43 | @rm -rf symfuzzlog-* 44 | 45 | depcheck: ../Makefile.dep 46 | @../buildtools/depcheck.sh $< 47 | 48 | .PHONY: all clean clean-log depcheck 49 | -------------------------------------------------------------------------------- /src/analyzer/analysis.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** analyzer main 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Symfuzz_protocol 37 | open Interpretation 38 | open Context 39 | open Misc 40 | open Log_analysis 41 | 42 | (* local socket *) 43 | let local_ic = ref stdin 44 | let local_oc = ref stdout 45 | 46 | (* new logfile using analysis id *) 47 | let get_logfile prefix lognum logdir = 48 | let logfile = Printf.sprintf "%s-%ld.log" prefix lognum in 49 | Filename.concat logdir logfile 50 | 51 | let get_input_vector ic oc st = 52 | let () = send oc IVReq in 53 | match recv ic with 54 | | IVResponse vector -> State.new_vector st vector 55 | | _ -> raise Protocol.ProtocolError 56 | 57 | let get_option logpath ic oc st = 58 | let () = send oc OptionReq in 59 | match recv ic with 60 | | OptionResponse opt -> 61 | init_log logpath; 62 | set_flag_from_option opt; 63 | Options.option_check opt; 64 | State.new_option st opt 65 | | _ -> raise Protocol.ProtocolError 66 | 67 | let send_result _st = 68 | let oc = !local_oc in 69 | let ic = !local_ic in 70 | send oc (Result 0); (* XXX we currently ignore the result *) 71 | match recv ic with 72 | | Response -> () 73 | | _ -> raise Protocol.ProtocolError 74 | 75 | (* called once at start *) 76 | let proc_start logdir id sockname debug_flag tid argvp envc envp = 77 | let () = Printexc.record_backtrace true in (* XXX *) 78 | let logpath = get_logfile "analysis" id logdir in 79 | let sock = Localsock.create_client sockname 2 in 80 | let ic, oc = client_prepare sock in 81 | let st = 82 | State.get_state () 83 | |> State.set_logdir logdir 84 | |> State.set_debugging debug_flag 85 | |> get_input_vector ic oc 86 | |> get_option logpath ic oc 87 | |> State.introduce_arguments tid argvp 0 88 | in 89 | (* let st = State.introduce_environment st envc envp in *) 90 | let () = State.set_state st in 91 | local_ic := ic; 92 | local_oc := oc 93 | 94 | (* callend once before finish *) 95 | let proc_end bblcnt = 96 | let st = State.get_state () in 97 | let chan = get_chan () in 98 | State.dump_gamma st chan; 99 | State.dump_stats st chan bblcnt; 100 | send_result st; 101 | fin_log () 102 | 103 | (* basic block instrumentation *) 104 | let bbl_instrument addr size bytes context tid = 105 | let block, blksize = (* list of (stmt list) *) 106 | try jit addr bytes size 107 | with Failure s -> failwith ("IL translation failure: "^s) 108 | in 109 | Interpretation.execute block blksize context addr tid 110 | 111 | (* right after read, we introduce taint *) 112 | let symbolic_read bufaddr byte_pos len totalsize path = 113 | if len > 0 then begin 114 | logtimef "read into buffer @ %nx (%d) [%nd / %d]" 115 | bufaddr len byte_pos totalsize; 116 | let st = State.get_state () in 117 | let st = State.introduce_files st bufaddr len totalsize byte_pos path in 118 | State.set_state st 119 | end else () 120 | 121 | let eflag_taint st = 122 | Dependency.is_tainted (State.get_vdelta st Disasm_i386.cf) 123 | || Dependency.is_tainted (State.get_vdelta st Disasm_i386.pf) 124 | || Dependency.is_tainted (State.get_vdelta st Disasm_i386.af) 125 | || Dependency.is_tainted (State.get_vdelta st Disasm_i386.zf) 126 | || Dependency.is_tainted (State.get_vdelta st Disasm_i386.sf) 127 | || Dependency.is_tainted (State.get_vdelta st Disasm_i386.df) 128 | || Dependency.is_tainted (State.get_vdelta st Disasm_i386.oF) 129 | 130 | let check_reg_taint_32 st' = 131 | let open Disasm_i386 in function 132 | | 0 -> Dependency.is_tainted (State.get_vdelta st' R32.eax) 133 | | 1 -> Dependency.is_tainted (State.get_vdelta st' R32.ebx) 134 | | 2 -> Dependency.is_tainted (State.get_vdelta st' R32.ecx) 135 | | 3 -> Dependency.is_tainted (State.get_vdelta st' R32.edx) 136 | | 4 -> Dependency.is_tainted (State.get_vdelta st' R32.edi) 137 | | 5 -> Dependency.is_tainted (State.get_vdelta st' R32.esi) 138 | | 6 -> Dependency.is_tainted (State.get_vdelta st' R32.ebp) 139 | | 7 -> Dependency.is_tainted (State.get_vdelta st' R32.esp) 140 | | 8 -> Dependency.is_tainted (State.get_vdelta st' R32.eip) 141 | | 9 -> eflag_taint st' 142 | | 10 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(0)) 143 | | 11 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(1)) 144 | | 12 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(2)) 145 | | 13 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(3)) 146 | | 14 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(4)) 147 | | 15 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(5)) 148 | | 16 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(6)) 149 | | 17 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(7)) 150 | | _ -> false 151 | 152 | let check_reg_taint_64 st' = 153 | let open Disasm_i386 in function (* FIXME : add more regs *) 154 | | 0 -> Dependency.is_tainted (State.get_vdelta st' R64.rax) 155 | | 1 -> Dependency.is_tainted (State.get_vdelta st' R64.rbx) 156 | | 2 -> Dependency.is_tainted (State.get_vdelta st' R64.rcx) 157 | | 3 -> Dependency.is_tainted (State.get_vdelta st' R64.rdx) 158 | | 4 -> Dependency.is_tainted (State.get_vdelta st' R64.rdi) 159 | | 5 -> Dependency.is_tainted (State.get_vdelta st' R64.rsi) 160 | | 6 -> Dependency.is_tainted (State.get_vdelta st' R64.rbp) 161 | | 7 -> Dependency.is_tainted (State.get_vdelta st' R64.rsp) 162 | | 8 -> Dependency.is_tainted (State.get_vdelta st' R64.rip) 163 | | 9 -> eflag_taint st' 164 | | 10 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(0)) 165 | | 11 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(1)) 166 | | 12 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(2)) 167 | | 13 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(3)) 168 | | 14 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(4)) 169 | | 15 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(5)) 170 | | 16 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(6)) 171 | | 17 -> Dependency.is_tainted (State.get_vdelta st' R64.ymms.(7)) 172 | | _ -> false 173 | 174 | let check = 175 | if Sys.word_size = 32 then check_reg_taint_32 176 | else check_reg_taint_64 177 | 178 | let check_reg_taint used_regs idx st = 179 | if Int64.logand Int64.one used_regs <= Int64.zero then false 180 | else check st idx 181 | 182 | let check_regs_taint used_regs = 183 | let st = State.get_state () in 184 | let rec check_loop idx used_regs = 185 | if idx > 17 then false 186 | else if check_reg_taint used_regs idx st then true 187 | else check_loop (idx+1) (Int64.shift_right used_regs 1) 188 | in 189 | check_loop 0 used_regs 190 | 191 | let check_mems_taint addrs = 192 | let st = State.get_state () in 193 | List.exists (fun ((addr: nativeint), (size: int)) -> 194 | Dependency.is_tainted (State.get_abstr_mu st addr (Type.Reg size)) 195 | ) addrs 196 | 197 | let check_postdom () = 198 | let st = State.get_state () in 199 | let idstack = State.get_idstack st in 200 | if Stack.is_empty idstack then 0n 201 | else let nextaddr, _ = Stack.top idstack in nextaddr 202 | 203 | let push_to_stack retaddr stack = 204 | let _, dep = Stack.top stack in 205 | Stack.push (retaddr, dep) stack 206 | 207 | let handle_call _tid retaddr = 208 | let st = State.get_state () in 209 | let stack = State.get_idstack st in 210 | if Stack.is_empty stack then Stack.push (retaddr, Dependency.dep_empty) stack 211 | else push_to_stack retaddr stack 212 | 213 | let is_updatable abstr st = 214 | let inputsize = State.get_input_size st in 215 | let depsize = Dependency.dep_cardinal abstr in 216 | (* ignore all-byte correlation, e.g., strlen before parsing *) 217 | let threshold = 1.0 in 218 | (float_of_int depsize) /. (float_of_int inputsize) < threshold 219 | 220 | let handle_ret _tid retaddr = 221 | let st = State.get_state () in 222 | let idstack = State.get_idstack st in 223 | let rec pop_loop st = 224 | let addr, abstr = Stack.pop idstack in 225 | let st = 226 | if is_updatable abstr st then 227 | State.update_gamma_from_stashed st 228 | else 229 | State.clear_stash st 230 | in 231 | if (addr = retaddr) then st 232 | else if Stack.is_empty idstack then st 233 | else pop_loop st 234 | in 235 | let st = if Stack.is_empty idstack then st else pop_loop st in 236 | State.set_state st 237 | 238 | (* unlike other instructions, we always instrument call and ret instructions 239 | even though the corresponding bbl is not tainted. *) 240 | let handle_callret retaddr tid ty = 241 | if ty = 0 (* call *) then handle_call tid retaddr 242 | else handle_ret tid retaddr 243 | 244 | (* callback registration *) 245 | let () = Callback.register "proc_start" proc_start 246 | let () = Callback.register "proc_end" proc_end 247 | let () = Callback.register "bbl_instrument" bbl_instrument 248 | let () = Callback.register "symbolic_read" symbolic_read 249 | let () = Callback.register "check_regs_taint" check_regs_taint 250 | let () = Callback.register "check_mems_taint" check_mems_taint 251 | let () = Callback.register "check_postdom" check_postdom 252 | let () = Callback.register "handle_callret" handle_callret 253 | 254 | -------------------------------------------------------------------------------- /src/analyzer/analysis.mli: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** analyzer main 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Dependency 37 | open Context 38 | 39 | val proc_start : string (* log director *) 40 | -> int32 (* current analysis id *) 41 | -> string (* local socket name *) 42 | -> bool (* debug flag *) 43 | -> int (* tid *) 44 | -> address_t (* argvp *) 45 | -> int32 (* envc *) 46 | -> address_t (* envp *) 47 | -> unit 48 | 49 | val proc_end : int32 -> unit 50 | 51 | val bbl_instrument : address_t 52 | -> int32 53 | -> string 54 | -> raw_context_t 55 | -> int 56 | -> int 57 | 58 | -------------------------------------------------------------------------------- /src/analyzer/bapmisc.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** misc functions for BAP 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Big_int_Z 37 | open Big_int_convenience 38 | 39 | type seek_label_t = 40 | | KeepDoing 41 | | StopIt 42 | 43 | let bigguy = 44 | if Nativeint.size = 32 then biconst64 0x100000000L 45 | else (* 64-bit *) big_int_of_string "18446744073709552000" 46 | 47 | let maxint = big_int_of_nativeint Nativeint.max_int 48 | 49 | let safe_bigint_to_native bigint = 50 | assert ( bigint < bigguy ); 51 | if bigint >% maxint then 52 | nativeint_of_big_int (minus_big_int (bigguy -% bigint)) 53 | else 54 | nativeint_of_big_int bigint 55 | 56 | let safe_bigint_of_native n = 57 | if n < 0n then (big_int_of_nativeint n) +% bigguy 58 | else big_int_of_nativeint n 59 | 60 | let undef_regexp = Str.regexp "[uU]ndefined" 61 | 62 | let is_undefined_msg msg = 63 | try ignore (Str.search_forward undef_regexp msg 0); true 64 | with Not_found -> false 65 | 66 | let is_the_label target_lbl = function 67 | | Ast.Label (lbl, _) -> (Ast.exp_of_lab lbl) = target_lbl 68 | | _ -> false 69 | 70 | let seek_lbl nextlbl stmt = 71 | match nextlbl with 72 | | None -> StopIt 73 | | Some lbl -> 74 | if is_the_label lbl stmt then StopIt 75 | else KeepDoing 76 | 77 | let is_call attrb = List.mem (Type.StrAttr "call") attrb 78 | let is_ret attrb = List.mem (Type.StrAttr "ret") attrb 79 | 80 | -------------------------------------------------------------------------------- /src/analyzer/bapmisc.mli: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** misc functions for BAP 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | type seek_label_t = 37 | | KeepDoing 38 | | StopIt 39 | 40 | val safe_bigint_to_native : Big_int_Z.big_int -> nativeint 41 | val safe_bigint_of_native : nativeint -> Big_int_Z.big_int 42 | val is_undefined_msg : string -> bool 43 | val seek_lbl : Ast.exp option -> Ast.stmt -> seek_label_t 44 | val is_call : Type.attribute list -> bool 45 | val is_ret : Type.attribute list -> bool 46 | 47 | -------------------------------------------------------------------------------- /src/analyzer/comm.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** communicator 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Symfuzz_protocol 37 | open Misc 38 | 39 | type db_type = 40 | { 41 | vector : Libinput_type.input_vector list; 42 | results : int list 43 | } 44 | 45 | let empty_db = {vector=[]; results=[]} 46 | 47 | let fd_to_chans fd = 48 | Unix.in_channel_of_descr fd, Unix.out_channel_of_descr fd 49 | 50 | let pop_vector db = 51 | let vector, rest = 52 | match db.vector with 53 | | vector::rest -> vector, rest 54 | | [] -> failwith "input vector does not exist" 55 | in 56 | vector, {db with vector=rest} 57 | 58 | let push_result db numcor = 59 | {db with results=(numcor::db.results)} 60 | 61 | let pop_result db = 62 | let result, rest = 63 | match db.results with 64 | | r::rest -> r, rest 65 | | [] -> failwith "result does not exist" 66 | in 67 | result, {db with results=rest} 68 | 69 | let process_inter_sock db ic oc = 70 | match recv ic with 71 | | Register s -> {db with vector=(s::(db.vector))} 72 | | ReqResult -> 73 | let res, db' = pop_result db in 74 | let () = send oc (Result res) in 75 | db' 76 | | _ -> failwith "inter_sock unhandled message" 77 | 78 | let process_intra_sock db ic oc = 79 | match recv ic with 80 | | IVReq -> 81 | let vec, db' = pop_vector db in 82 | let () = send oc (IVResponse vec) in 83 | db' 84 | | OptionReq -> 85 | let opt = !Options.options in 86 | let () = send oc (OptionResponse opt) in 87 | db 88 | | Result numcor -> 89 | let db' = push_result db numcor in 90 | let () = send oc Response in 91 | db' 92 | | _ -> failwith "intra_sock unhandled message" 93 | 94 | (* internal service loop that manipulates global data *) 95 | let server_loop (inter_sock, intra_sock) = 96 | let inter_ic, inter_oc = fd_to_chans inter_sock in 97 | let intra_ic, intra_oc = fd_to_chans intra_sock in 98 | let rec main_loop db cnt = 99 | let fds, _, _ = Unix.select [inter_sock; intra_sock] [] [] neg_infinity in 100 | let rec process_fds db = function 101 | | fd::tl when fd = inter_sock -> 102 | let db = process_inter_sock db inter_ic inter_oc in 103 | process_fds db tl 104 | | fd::tl when fd = intra_sock -> 105 | let db = process_intra_sock db intra_ic intra_oc in 106 | process_fds db tl 107 | | _::tl -> failwith "unknown file descriptor" 108 | | [] -> db 109 | in 110 | let db = process_fds db fds in 111 | main_loop db (cnt+1) 112 | in 113 | (* protocol starts after getting a ping message *) 114 | let () = wait_for_ping inter_ic inter_oc in 115 | try 116 | main_loop empty_db 0 117 | with 118 | | End_of_file -> exit 1 119 | | e -> 120 | begin 121 | Printf.eprintf "exception@server: %s\n" (Printexc.to_string e); 122 | Printf.eprintf "%s\n" (Printexc.get_backtrace ()); 123 | flush stderr; exit 1 124 | end 125 | 126 | let relay_packets packet inter_oc intra_ic intra_oc = 127 | send intra_oc packet; 128 | match recv intra_ic with 129 | | NoResponse -> () 130 | | msg -> send inter_oc msg 131 | 132 | (* communication link between pin instrumentor *) 133 | let rec client_accept_loop (inter_sock, intra_sock) = 134 | let client_sock, _client_addr = Localsock.accept_client inter_sock in 135 | let inter_ic, inter_oc = fd_to_chans client_sock in 136 | let intra_ic, intra_oc = fd_to_chans intra_sock in 137 | let rec main_loop inter_ic = 138 | let () = 139 | match recv inter_ic with 140 | | p -> relay_packets p inter_oc intra_ic intra_oc 141 | in 142 | main_loop inter_ic 143 | in 144 | let () = wait_for_ping inter_ic inter_oc in 145 | try 146 | main_loop inter_ic 147 | with 148 | | Protocol.ProtocolError -> Printf.eprintf "protocol error\n"; exit 1 149 | | _ -> client_accept_loop (inter_sock, intra_sock) 150 | 151 | -------------------------------------------------------------------------------- /src/analyzer/context.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** program context 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Dependency 37 | open Log_analysis 38 | 39 | type raw_context_t = 40 | address_t * address_t * address_t * address_t * (* eax, ebx, ecx, edx *) 41 | address_t * address_t * address_t * address_t * (* edi, esi, esp, ebp *) 42 | address_t * address_t * address_t * address_t * (* eip, eflags, ldtr, gdtr *) 43 | address_t * address_t * address_t * address_t * (* cs, ds, es, fs *) 44 | address_t * address_t * address_t * address_t * (* gs, ss, fs_base, gs_base *) 45 | bool * bool * bool * bool * (* cf, pf, af, zf *) 46 | bool * bool * bool * bool * (* sf, df, of, acf *) 47 | bool * (* idf *) 48 | int64 * int64 * (* xmm0 *) 49 | int64 * int64 * (* xmm1 *) 50 | int64 * int64 * (* xmm2 *) 51 | int64 * int64 * (* xmm3 *) 52 | int64 * int64 * (* xmm4 *) 53 | int64 * int64 * (* xmm5 *) 54 | int64 * int64 * (* xmm6 *) 55 | int64 * int64 (* xmm7 *) 56 | 57 | type xmm_t = 58 | { 59 | low : int64; 60 | high : int64; 61 | } 62 | 63 | type t = 64 | { 65 | eax : address_t; 66 | ebx : address_t; 67 | ecx : address_t; 68 | edx : address_t; 69 | edi : address_t; 70 | esi : address_t; 71 | ebp : address_t; 72 | esp : address_t; 73 | eip : address_t; 74 | eflags : address_t; 75 | ldtr : address_t; 76 | gdtr : address_t; 77 | cs : address_t; 78 | ds : address_t; 79 | es : address_t; 80 | fs : address_t; 81 | gs : address_t; 82 | ss : address_t; 83 | fs_base : address_t; 84 | gs_base : address_t; 85 | cflag : bool; 86 | pflag : bool; 87 | aflag : bool; 88 | zflag : bool; 89 | sflag : bool; 90 | dflag : bool; 91 | oflag : bool; 92 | acflag : bool; 93 | idflag : bool; 94 | xmm0 : xmm_t; 95 | xmm1 : xmm_t; 96 | xmm2 : xmm_t; 97 | xmm3 : xmm_t; 98 | xmm4 : xmm_t; 99 | xmm5 : xmm_t; 100 | xmm6 : xmm_t; 101 | xmm7 : xmm_t; 102 | } 103 | 104 | let get_context = function 105 | | eax,ebx,ecx,edx,edi,esi,ebp,esp,eip,eflags,ldtr,gdtr, 106 | cs,ds,es,fs,gs,ss,fs_base,gs_base, 107 | cflag,pflag,aflag,zflag,sflag,dflag,oflag,acflag,idflag, 108 | xmm0_l,xmm0_h,xmm1_l,xmm1_h,xmm2_l,xmm2_h,xmm3_l,xmm3_h, 109 | xmm4_l,xmm4_h,xmm5_l,xmm5_h,xmm6_l,xmm6_h,xmm7_l,xmm7_h -> 110 | (* let () = 111 | logf "---CTXT---\nEAX:%nx; EBX:%nx; ECX:%nx; EDX:%nx\nEDI:%nx; ESI:%nx; EBP:%nx; ESP:%nx\nXMM0:%Lx;%Lx\n" 112 | eax ebx ecx edx edi esi ebp esp xmm0_l xmm0_h 113 | in *) 114 | { 115 | eax=eax; ebx=ebx; ecx=ecx; edx=edx; 116 | edi=edi; esi=esi; ebp=ebp; esp=esp; 117 | eip=eip; eflags=eflags; ldtr=ldtr; gdtr=gdtr; 118 | cs=cs; ds=ds; es=es; fs=fs; gs=gs; ss=ss; 119 | fs_base=fs_base; gs_base=gs_base; 120 | cflag=cflag; pflag=pflag; aflag=aflag; zflag=zflag; 121 | sflag=sflag; dflag=dflag; oflag=oflag; acflag=acflag; 122 | idflag=idflag; 123 | xmm0={low=xmm0_l; high=xmm0_h}; xmm1={low=xmm1_l; high=xmm1_h}; 124 | xmm2={low=xmm2_l; high=xmm2_h}; xmm3={low=xmm3_l; high=xmm3_h}; 125 | xmm4={low=xmm4_l; high=xmm4_h}; xmm5={low=xmm5_l; high=xmm5_h}; 126 | xmm6={low=xmm6_l; high=xmm6_h}; xmm7={low=xmm7_l; high=xmm7_h}; 127 | } 128 | 129 | -------------------------------------------------------------------------------- /src/analyzer/context.mli: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** program context 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Dependency 37 | 38 | type raw_context_t 39 | 40 | type xmm_t = 41 | { 42 | low : int64; 43 | high : int64; 44 | } 45 | 46 | type t = 47 | { 48 | eax : address_t; 49 | ebx : address_t; 50 | ecx : address_t; 51 | edx : address_t; 52 | edi : address_t; 53 | esi : address_t; 54 | ebp : address_t; 55 | esp : address_t; 56 | eip : address_t; 57 | eflags : address_t; 58 | ldtr : address_t; 59 | gdtr : address_t; 60 | cs : address_t; 61 | ds : address_t; 62 | es : address_t; 63 | fs : address_t; 64 | gs : address_t; 65 | ss : address_t; 66 | fs_base : address_t; 67 | gs_base : address_t; 68 | cflag : bool; 69 | pflag : bool; 70 | aflag : bool; 71 | zflag : bool; 72 | sflag : bool; 73 | dflag : bool; 74 | oflag : bool; 75 | acflag : bool; 76 | idflag : bool; 77 | xmm0 : xmm_t; 78 | xmm1 : xmm_t; 79 | xmm2 : xmm_t; 80 | xmm3 : xmm_t; 81 | xmm4 : xmm_t; 82 | xmm5 : xmm_t; 83 | xmm6 : xmm_t; 84 | xmm7 : xmm_t; 85 | } 86 | 87 | val get_context : raw_context_t -> t 88 | 89 | -------------------------------------------------------------------------------- /src/analyzer/dependency.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** input-byte dependency 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Misc 37 | 38 | type address_t = nativeint 39 | 40 | type postidom_t = 41 | | UnknownPdom 42 | | Pdom of nativeint 43 | | Return 44 | 45 | module DepSet = IntSet 46 | type inputdep = DepSet.t 47 | 48 | let dep_cache : (int, inputdep) Hashtbl.t = Hashtbl.create 7919 49 | 50 | let dep_id cor = DepSet.fold (fun i acc -> acc + i) cor 0 51 | 52 | let dep_memoize cor = 53 | let id = dep_id cor in 54 | try 55 | List.find (fun e -> DepSet.equal e cor) (Hashtbl.find_all dep_cache id) 56 | with Not_found -> 57 | Hashtbl.add dep_cache id cor; cor 58 | 59 | let dep_to_string v = 60 | let fill_buf buf p off = 61 | let pos = string_of_int p in 62 | let len = String.length pos in 63 | String.blit pos 0 buf off len; 64 | Bytes.set buf (off+len) ';'; 65 | off + len + 1, false 66 | in 67 | let bufsize = 1024 in 68 | let buf = Bytes.create bufsize in 69 | let len, cut = 70 | DepSet.fold (fun p (off, cut) -> 71 | if off >= (bufsize - 32) then off, true else fill_buf buf p off 72 | ) v (0, false) 73 | in 74 | let str = String.sub buf 0 len in 75 | if cut then str ^ "..." else str 76 | 77 | let dep_is_bottom = DepSet.is_empty 78 | let dep_union a b = dep_memoize (DepSet.union a b) 79 | let dep_empty = dep_memoize (DepSet.empty) 80 | let dep_equal = DepSet.equal 81 | let dep_cardinal = DepSet.cardinal 82 | let dep_iter = DepSet.iter 83 | let dep_fold = DepSet.fold 84 | let dep_singleton e = dep_memoize (DepSet.singleton e) 85 | 86 | module rec AbstrVal : sig 87 | 88 | type t = inputdep list (* inputdep per each byte *) 89 | 90 | val bottom : t 91 | 92 | val value_to_string : t -> string 93 | 94 | val value_merge : t -> inputdep 95 | 96 | val equal : t -> t -> bool 97 | 98 | val is_bottom : t -> bool 99 | 100 | val is_tainted : t -> bool 101 | 102 | end = 103 | struct 104 | 105 | type t = inputdep list 106 | 107 | let bottom = [] 108 | 109 | let value_to_string v = 110 | let to_string hd v = 111 | Printf.sprintf "%s, ...(%d)" 112 | (if dep_is_bottom hd then "Bot" else dep_to_string hd) 113 | (List.length v) 114 | in 115 | match v with 116 | | [] -> "Bot" 117 | | hd::_ -> to_string hd v 118 | 119 | let value_merge v = 120 | List.fold_left (fun acc v -> dep_union acc v) dep_empty v 121 | 122 | let equal a b = 123 | match a, b with 124 | | [], [] -> true 125 | | [], _ -> false 126 | | _, [] -> false 127 | | a, b -> List.for_all2 dep_equal a b 128 | 129 | let is_bottom = function 130 | | [] -> true 131 | | a -> List.for_all dep_is_bottom a 132 | 133 | let is_tainted c = not (is_bottom c) 134 | 135 | end 136 | 137 | include AbstrVal 138 | 139 | module MemMap = Map.Make(Nativeint) 140 | 141 | -------------------------------------------------------------------------------- /src/analyzer/depreader.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** Dependency Reader 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Dependency 37 | open Misc 38 | open EArray 39 | 40 | type pred = inputdep EArray.t 41 | 42 | let get_dist file = 43 | (* distribution of b, derived from a large-scale fuzzing experiment *) 44 | let dist = readlines file |> List.map int_of_string in 45 | let maxb = List.fold_left (fun max b -> if max < b then b else max) 0 dist in 46 | let avg = (List.fold_left (fun acc b -> float b +. acc) 0.0 dist) 47 | /. (float (List.length dist)) 48 | in 49 | let howmany i dist = 50 | List.fold_left (fun cnt b -> if b=i then cnt+1 else cnt) 0 dist 51 | in 52 | let rec probloop acc i = 53 | if i > maxb then acc 54 | else 55 | let p = float (howmany i dist) /. float (List.length dist) in 56 | if p > 0.0 then probloop (p::acc) (i+1) else probloop acc (i+1) 57 | in 58 | let distprob = probloop [] 1 in 59 | distprob, maxb, avg 60 | 61 | let get_b_from_dist distprob maxb = 62 | let r = Random.float 1.0 in 63 | let rec get_b (acc, b) = function 64 | | [] -> b 65 | | _::[] -> b 66 | | p::tl -> let p = p +. acc in if p >= r then b else get_b (p, b+1) tl 67 | in 68 | get_b (0.0, 1) distprob 69 | 70 | let read_pred fname = 71 | let ch = open_in fname in 72 | let pred = Marshal.from_channel ch in 73 | close_in ch; 74 | pred 75 | 76 | let print_d pred = 77 | let idx = ref 0 in 78 | EArray.iter (fun dep -> 79 | idx := !idx + 1; 80 | Printf.printf "%4d -> %d\n" !idx ((dep_cardinal dep)) 81 | ) pred 82 | 83 | let sqr x = x *. x 84 | 85 | let stddev l = 86 | let n, sx, sx2 = 87 | List.fold_left 88 | (fun (n, sx, sx2) x -> succ n, sx +. x, sx2 +. sqr x) 89 | (0, 0., 0.) l 90 | in 91 | sqrt ((sx2 -. sqr sx /. float n) /. float n) 92 | 93 | (* how close to the average? *) 94 | let within_range avg sdv lst total = 95 | let total = Int64.to_int total in 96 | let cnt = 97 | List.fold_left (fun (cnt) x -> 98 | if x >= (avg -. sdv) && x <= (avg +. sdv) then cnt + 1 99 | else cnt 100 | ) (0) lst 101 | in 102 | float cnt /. float total *. 100.0 103 | 104 | let print_stat n (pred:pred) bar_d avgb = 105 | let total, lst, nz_cnt = 106 | EArray.fold_left (fun (total, lst, nz_cnt) dep -> 107 | let n = (dep_cardinal dep) |> Int64.of_int in 108 | Int64.add n total, 109 | (Int64.to_float n)::lst, 110 | if n > 0L then nz_cnt + 1 else nz_cnt 111 | ) (0L, [], 0) pred 112 | in 113 | let nb = Int64.mul n 8L in 114 | let avgf = (Int64.to_float total) /. (Int64.to_float n) in 115 | let nzavg = (Int64.to_float total) /. (float nz_cnt) in 116 | let sdv = stddev lst in 117 | let rate = within_range avgf sdv lst n in 118 | Printf.printf "total_d: %Ld, N: %Ld(%Ld), avg: %.1f(%.1f), nzavg: %.1f(%.1f), std.dev: %.2f(%.1f), rate: %.2f\n" 119 | total (n) (nb) (avgf) (avgf *. 8.0) nzavg (nzavg *. 8.0) 120 | (sdv) (sdv *. 8.0) rate; 121 | let n = Int64.to_float n in 122 | let r = 123 | if bar_d < avgb then avgb /. n else ((1.0) *. (n +. 1.0) /. n /. bar_d) 124 | in 125 | print_endline "bar_d,r"; 126 | Printf.printf "%.f,%.3f\n" bar_d r 127 | 128 | let set = Hashtbl.create 7901 129 | (** floyd's algorithm for random k subset *) 130 | let floyds_sampling n k = 131 | Hashtbl.clear set; 132 | for j = n - k + 1 to n do 133 | let t = (Random.int j) + 1 in 134 | if Hashtbl.mem set t then (Hashtbl.add set j true) 135 | else (Hashtbl.add set t true) 136 | done; 137 | set 138 | 139 | let _ = 140 | let () = Printexc.record_backtrace true in 141 | let fname = try Sys.argv.(1) with _ -> failwith "filename not given" in 142 | let distfile = try Sys.argv.(2) with _ -> failwith "distfile not given" in 143 | let prog = try Sys.argv.(3) with _ -> failwith "prog name not given" in 144 | let pred : pred = read_pred fname in 145 | Printf.printf "Read gamma for %s ..." prog; flush stdout; 146 | let distprob, maxb, avgb = get_dist distfile in 147 | print_endline "Got probability distribution of b..."; flush stdout; 148 | (* print_d pred; *) 149 | let n = (Array.fold_left (fun n a -> (Array.length a) + n) 0 pred) 150 | |> Int64.of_int 151 | in 152 | (* compute average d from the distribution *) 153 | let rec average_loop () = 154 | let n = (Int64.to_int n) in 155 | let avg, cnt = estimation_loop 0.0 1.0 n in 156 | Printf.printf "%f, %d\n" avg cnt; avg 157 | and estimation_loop sum cnt n = 158 | let b = get_b_from_dist distprob maxb in 159 | let bs = floyds_sampling (n*8) b in 160 | let dep = Hashtbl.fold (fun k v acc -> dep_union (EArray.get pred ((k-1)/8)) acc 161 | ) bs dep_empty 162 | in 163 | let c = dep_cardinal dep in 164 | if c = 0 then 165 | estimation_loop sum cnt n 166 | else begin 167 | let d = float_of_int c in 168 | let b = float_of_int b in 169 | let nextsum = sum +. d in 170 | let nextcnt = cnt +. b in 171 | let next = nextsum /. nextcnt in 172 | let prev = sum /. cnt in 173 | (* Printf.printf "%f, %f, b: %f, next: %f, prev: %f\n" nextcnt d b next prev; 174 | flush stdout; *) 175 | if abs_float (next -. prev) < 0.0000001 then next, int_of_float nextcnt 176 | else estimation_loop nextsum nextcnt n 177 | end 178 | in 179 | let avg = average_loop () in 180 | Printf.printf "Got the average d ... %f\n" avg; flush stdout; 181 | print_stat n pred avg avgb 182 | 183 | -------------------------------------------------------------------------------- /src/analyzer/eArray.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** extended array to handle large number of array entries in 32-bit platform 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | module EArray = struct 37 | type 'a t = 'a array array 38 | 39 | let maxlen = 1048576 40 | 41 | let getpos pos = 42 | let idx = pos / maxlen in 43 | let rem = pos mod maxlen in 44 | idx, rem 45 | 46 | let get arr pos : 'a = 47 | let idx, rem = getpos pos in 48 | Array.get (Array.get arr idx) rem 49 | 50 | let set arr pos v = 51 | let idx, rem = getpos pos in 52 | Array.set (Array.get arr idx) rem v 53 | 54 | let fold_left fn acc arr = 55 | Array.fold_left (fun acc arr -> 56 | Array.fold_left fn acc arr 57 | ) acc arr 58 | 59 | let iter fn arr = 60 | Array.iter (fun arr -> 61 | Array.iter fn arr 62 | ) arr 63 | 64 | let make size v = 65 | let lastidx, lastsize = getpos size in 66 | Array.init (lastidx+1) (fun idx -> 67 | if idx = lastidx then Array.make lastsize v 68 | else Array.make maxlen v 69 | ) 70 | 71 | end 72 | 73 | -------------------------------------------------------------------------------- /src/analyzer/interpretation.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** main interpretation 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Ast 37 | open Type 38 | open Big_int_Z 39 | open Big_int_convenience 40 | open Dependency 41 | open Log_analysis 42 | open State 43 | open Misc 44 | open Bapmisc 45 | open LibBil 46 | 47 | let jitting (addr, bytes, size) = 48 | let total_size = String.length bytes in 49 | let () = assert (Int32.of_int total_size = size) in 50 | of_bytesequence bil_handle bytes addr, big_int_of_int total_size 51 | 52 | let jit = 53 | let cache = BatCache.lru_cache ~gen:jitting ~cap:6217 in 54 | fun addr bytes size -> 55 | let addr = biconst64 (get_clean_addr addr) in 56 | cache (addr, bytes, size) 57 | 58 | let print_stmt stmt = 59 | logf "%s" (Pp.ast_stmt_to_string stmt) 60 | 61 | let get_concrete_tuple = function 62 | | Int (v,t) -> v,t 63 | | e -> 64 | failwith (Printf.sprintf "invalid concrete value: %s" 65 | (Pp.ast_exp_to_string e)) 66 | 67 | let load_mem st tid index typ = 68 | let open Memory in 69 | let index = 70 | match index with | Int (n,_) -> n | _ -> failwith "symbolic index" 71 | in 72 | let index = Bapmisc.safe_bigint_to_native index in 73 | let conc = 74 | try 75 | get_conc_mu st index typ 76 | with Not_found -> 77 | let i = 78 | match typ with 79 | | Type.Reg b when b = 8 -> 80 | big_int_of_int (int_of_char (get_memory_byte tid index)) 81 | | Type.Reg b -> 82 | bytes_to_big_int (get_memory tid index (b/8)) 83 | | _ -> failwith "do not support other index type" 84 | in 85 | Ast.Int (i, typ) 86 | in 87 | let abstr = get_abstr_mu st index typ in 88 | conc, abstr 89 | 90 | let store_mem st index conc abstr typ = 91 | let index, _ = get_concrete_tuple index in 92 | let index = Bapmisc.safe_bigint_to_native index in 93 | let size = (Arithmetic.bits_of_width typ) / 8 in 94 | let st = set_abstr_mu st index abstr size in 95 | match conc with 96 | | Ast.Int (n,t) as e -> 97 | set_conc_mu st index e 98 | | _ -> st 99 | 100 | let binop_abstract nbyte op e1 e2 a1 a2 = 101 | (* abstract binop semantic *) 102 | let binop a b = 103 | match a, b with 104 | | [], a -> a 105 | | b, [] -> b 106 | | a, b -> List.map2 dep_union a b 107 | in 108 | match op with 109 | | XOR when e1 = e2 -> repeat dep_empty nbyte 110 | | _ -> binop a1 a2 111 | 112 | let take_n n lst = 113 | let rec loop acc n = function 114 | | [] -> 115 | if n <= 0 then List.rev acc else failwith "cannot take N" 116 | | hd::tl -> 117 | if n <= 0 then List.rev acc else loop (hd::acc) (n-1) tl 118 | in 119 | loop [] n lst 120 | 121 | let cast_abstract abstr t = 122 | let nbytes = get_nbytes_from_typ t in 123 | let existing = List.length abstr in 124 | if nbytes > existing then 125 | let merged = value_merge abstr in 126 | let more = repeat merged (nbytes-existing) in 127 | abstr @ more 128 | else 129 | take_n nbytes abstr 130 | 131 | let extract_abstr h l abstr = 132 | let n = (h -% l) +% bi1 in 133 | let nt = Type.Reg (int_of_big_int n) in 134 | cast_abstract abstr nt 135 | 136 | let concat_abstract a1 a2 = a1 @ a2 137 | 138 | let symbolic_memory st idx value = 139 | let idx = value_merge idx in 140 | (* overtainting policy *) 141 | let value = List.map (fun dep -> dep_union idx dep) value in 142 | update_gamma st idx idx, value 143 | 144 | let is_true_condition = function 145 | | Ast.Int (i,t) when i = bi0 && t = Type.reg_1 -> false 146 | | Ast.Int (i,t) when t = Type.reg_1 -> true 147 | | e -> 148 | Printf.eprintf "WHY: %s\n" (Pp.ast_exp_to_string e); 149 | failwith "wrong conditional exp" 150 | 151 | let merge_push idstack addr dep = 152 | if Stack.is_empty idstack then 153 | Stack.push (addr, dep) idstack 154 | else begin 155 | let top_addr, top_dep = Stack.top idstack in 156 | if top_addr = 0n || (top_addr = addr) then 157 | let _ = Stack.pop idstack in 158 | Stack.push (addr, dep_union dep top_dep) idstack 159 | else if addr = 0n then 160 | let _ = Stack.pop idstack in 161 | Stack.push (top_addr, dep_union dep top_dep) idstack 162 | else 163 | Stack.push (addr, dep) idstack 164 | end 165 | 166 | let merge_dependence idstack dep = 167 | if Stack.is_empty idstack then 168 | dep 169 | else begin 170 | let _old_addr, old_dep = Stack.top idstack in 171 | let new_dep = dep_union old_dep dep in 172 | new_dep 173 | end 174 | 175 | let update_pdom_stack postidoms abstr idstack st = 176 | match postidoms with 177 | | Pdom pd -> 178 | if Stack.is_empty idstack then 179 | let () = Stack.push (pd, abstr) idstack in st 180 | else 181 | let () = merge_push idstack pd abstr in st 182 | | UnknownPdom -> 183 | let () = merge_push idstack 0n abstr in st 184 | | Return -> 185 | let () = merge_push idstack 0n abstr in st 186 | 187 | let conditional_update tid st abstr target1 target2 = 188 | if is_tainted abstr then begin 189 | let abstr = value_merge abstr in 190 | let idstack = get_idstack st in 191 | let abstr' = merge_dependence idstack abstr in 192 | let postidoms = Rcfg.get_postidoms tid (get_pc st) target1 target2 in 193 | let st = stash_gamma st abstr abstr' in 194 | update_pdom_stack postidoms abstr' idstack st 195 | end else 196 | st 197 | 198 | let eval_stmts stmts tid st = 199 | (* eval statement *) 200 | let rec eval_stmt st = function 201 | | Move (v,e,_) -> 202 | let conc, abstr, st = eval_expr st e in 203 | let st = set_delta st v conc in 204 | let st = update_vdelta st v abstr in 205 | st, None, is_tainted abstr 206 | | Jmp (e,attrb) -> 207 | let target, _abstr, st = eval_expr st e in 208 | st, None, false 209 | | CJmp (c,e1,e2,_) -> 210 | let cond, abstr, st = eval_expr st c in 211 | let target1, _, st = eval_expr st e1 in 212 | let target2, _, st = eval_expr st e2 in 213 | let st = conditional_update tid st abstr target1 target2 in 214 | let nextlbl = if is_true_condition cond then e1 else e2 in 215 | st, Some nextlbl, false 216 | | Label (lbl,_) as stmt -> 217 | let addr = label_address lbl in 218 | (match addr with 219 | | Some addr -> 220 | let st = set_last_lbl st stmt in 221 | set_pc st addr 222 | | None -> st 223 | ), None, false 224 | | Special (s,_,_) -> 225 | st, None, false 226 | | Assert (_,_) -> 227 | st, None, false 228 | | s -> 229 | failwith ("unsupported statements: "^(Pp.ast_stmt_to_string s)) 230 | (* eval expression : returns (concrete value, abstract value, state) *) 231 | and eval_expr st = function 232 | | Load (mem,idx,_endian,typ) -> 233 | let index, abstr_idx, st = eval_expr st idx in 234 | let loaded, abstr = load_mem st tid index typ in 235 | let st, abstr = 236 | if is_tainted abstr_idx then symbolic_memory st abstr_idx abstr 237 | else st, abstr 238 | in 239 | loaded, abstr, st 240 | | Store (mem,idx,v,_endian,typ) -> 241 | let index, abstr_idx, st = eval_expr st idx in 242 | let conc, abstr, st = eval_expr st v in 243 | let st, abstr = 244 | if is_tainted abstr_idx then symbolic_memory st abstr_idx abstr 245 | else st, abstr 246 | in 247 | let st = store_mem st index conc abstr typ in 248 | Ast.exp_false, AbstrVal.bottom, st 249 | | BinOp (op,e1,e2) -> 250 | let conc1, abstr1, st = eval_expr st e1 in 251 | let conc2, abstr2, st = eval_expr st e2 in 252 | let conc1 = get_concrete_tuple conc1 in 253 | let conc2 = get_concrete_tuple conc2 in 254 | let conc, typ = Arithmetic.binop op conc1 conc2 in 255 | let conc = Int (conc, typ) in 256 | let nbyte = get_nbytes_from_typ typ in 257 | let abstr = binop_abstract nbyte op e1 e2 abstr1 abstr2 in 258 | conc, abstr, st 259 | | UnOp (typ,e) -> 260 | let conc, abstr, st = eval_expr st e in 261 | let conc = get_concrete_tuple conc in 262 | let conc, typ' = Arithmetic.unop typ conc in 263 | Int (conc, typ'), abstr, st 264 | | Var v -> 265 | let conc, abstr = State.get_var_value st v in 266 | conc, abstr, st 267 | | Lab _ as l -> 268 | l, AbstrVal.bottom, st 269 | | Int (v,typ) as e -> 270 | let nbyte = get_nbytes_from_typ typ in 271 | e, repeat dep_empty nbyte, st 272 | | Cast (cast,typ,e) -> 273 | let conc,abstr,st = eval_expr st e in 274 | let conc = get_concrete_tuple conc in 275 | let conc, typ' = Arithmetic.cast cast conc typ in 276 | let abstr = cast_abstract abstr typ in 277 | Int (conc,typ'), abstr, st 278 | | Let (v,e1,e2) -> (* let v = e1 in e2 *) 279 | let conc1,abstr1,st = eval_expr st e1 in 280 | let st = set_delta st v conc1 in 281 | let st = update_vdelta st v abstr1 in 282 | eval_expr st e2 283 | | Ite (cond,e1,e2) -> 284 | let cond,_abstr,st = eval_expr st cond in 285 | if is_true_condition cond then 286 | eval_expr st e1 287 | else 288 | eval_expr st e2 289 | | Extract (h,l,e) -> 290 | let conc,abstr,st = eval_expr st e in 291 | let conc = get_concrete_tuple conc in 292 | let conc,typ = Arithmetic.extract h l conc in 293 | let abstr = extract_abstr h l abstr in 294 | Int (conc,typ), abstr, st 295 | | Concat (e1,e2) -> 296 | let conc1,abstr1,st = eval_expr st e1 in 297 | let conc2,abstr2,st = eval_expr st e2 in 298 | let conc1 = get_concrete_tuple conc1 in 299 | let conc2 = get_concrete_tuple conc2 in 300 | let conc,typ = Arithmetic.concat conc1 conc2 in 301 | let conc = Int (conc, typ) in 302 | let abstr = concat_abstract abstr1 abstr2 in 303 | conc, abstr, st 304 | | Unknown (_,_) -> 305 | Ast.exp_false, AbstrVal.bottom, st 306 | in 307 | 308 | let rec eval_loop st nextlbl tainted = function 309 | | stmt::tl -> 310 | if seek_lbl nextlbl stmt = KeepDoing then 311 | eval_loop st nextlbl tainted tl 312 | else 313 | let st, nextlbl, newtaint = eval_stmt st stmt in 314 | eval_loop st nextlbl (tainted || newtaint) tl 315 | | [] -> st, tainted 316 | in 317 | eval_loop st None false stmts 318 | 319 | let continue = 0 320 | let stop_and_debug = 1 321 | 322 | let flushall () = 323 | Printexc.print_backtrace stderr; 324 | flush stderr; 325 | flush (get_chan ()) 326 | 327 | let flatten_block block blksize = 328 | let blksize = int_of_big_int blksize in 329 | let rec loop acc total = function 330 | | (stmt_lst, size)::rest -> 331 | let size = int_of_big_int size in 332 | if total >= blksize then acc 333 | else loop (List.rev_append stmt_lst acc) (total+size) rest 334 | | [] -> acc 335 | in 336 | loop [] 0 block |> List.rev 337 | 338 | let execute block blksize raw_context block_addr tid = 339 | let inscount = List.length block in 340 | let stmts = flatten_block block blksize in 341 | (* List.iter print_stmt stmts *) 342 | let ctxt = Context.get_context raw_context in 343 | let st = State.update_context ctxt in 344 | let st = State.update_bblcount st inscount (List.length stmts) in 345 | try 346 | let st = cleanup_context st in 347 | let st, tainted = eval_stmts stmts tid st in 348 | let st = State.update_taintbbl tainted st in 349 | let () = set_state st in 350 | continue 351 | with 352 | | Memory.Invalid_memory addr -> 353 | Printf.eprintf "FATAL ERROR: Invalid Memory Access @ %nx\n" addr; 354 | logf "@ blk addr: %nx\n" (block_addr); 355 | flushall (); 356 | stop_and_debug 357 | | e -> 358 | Printf.eprintf "FATAL ERROR: %s\n" (Printexc.to_string e); 359 | logf "@ blk addr: %nx\n" (block_addr); 360 | flushall (); 361 | stop_and_debug 362 | 363 | -------------------------------------------------------------------------------- /src/analyzer/localsock.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** local socket 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | let clear_socket name = 37 | try Unix.unlink name 38 | with Unix.Unix_error _ -> () 39 | 40 | let create_server socket_name = 41 | let server = Unix.socket Unix.PF_UNIX Unix.SOCK_STREAM 0 in 42 | (* Printf.printf "server create\n"; flush stdout; *) 43 | let () = clear_socket socket_name in 44 | let () = Unix.bind server (Unix.ADDR_UNIX socket_name) in 45 | let () = Unix.listen server 10 in 46 | server 47 | 48 | let accept_client socket = 49 | Unix.accept socket 50 | 51 | let create_client socket_name trial = 52 | let client = Unix.socket Unix.PF_UNIX Unix.SOCK_STREAM 0 in 53 | (* Printf.printf "client create\n"; flush stdout; *) 54 | let rec loop cnt = 55 | if cnt > 0 then 56 | try 57 | Unix.connect client (Unix.ADDR_UNIX socket_name) 58 | with _ -> 59 | let () = Unix.sleep 1 in loop (cnt-1) 60 | else 61 | failwith "failed to connect to local socket" 62 | in 63 | let () = loop trial in 64 | client 65 | 66 | -------------------------------------------------------------------------------- /src/analyzer/log_analysis.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** log printer 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | module Print = Printer.Make(struct 37 | 38 | let chan = stderr 39 | 40 | end) 41 | 42 | include Print 43 | 44 | let set_flag_from_option opt = 45 | let open Options in 46 | match opt with 47 | | {debug_flag=f;} -> set_debug_flag f 48 | 49 | -------------------------------------------------------------------------------- /src/analyzer/log_interface.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** log interface 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | module L = Printer.Make(struct let chan = stderr end) 37 | 38 | include L 39 | 40 | -------------------------------------------------------------------------------- /src/analyzer/memory.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** memory handling 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Pinapi 37 | open Dependency 38 | open Big_int_Z 39 | open Big_int_convenience 40 | open Log_analysis 41 | 42 | exception Invalid_memory of address_t 43 | 44 | let get_memory_byte tid addr = 45 | let memval = get_mem_byte tid addr in 46 | if memval.valid = '\x01' then memval.value 47 | else raise (Invalid_memory addr) 48 | 49 | let get_memory tid addr len = 50 | let v = get_mem tid addr len in 51 | if String.length v = 0 then raise (Invalid_memory addr) 52 | else v 53 | 54 | let get_string tid addr = 55 | get_mem_string tid addr 56 | 57 | let bytes_to_native str = 58 | let len = String.length str in 59 | assert (len = Misc.addr_size); 60 | let rec loop i acc = 61 | if i < 0 then acc 62 | else ( 63 | let v = Nativeint.of_int (int_of_char str.[i]) in 64 | let v = Nativeint.shift_left v (i*8) in 65 | loop (i-1) (Nativeint.logor acc v)) 66 | in 67 | loop (len - 1) 0n 68 | 69 | let bytes_to_big_int str = 70 | let len = String.length str in 71 | let rec loop i acc = 72 | if i < 0 then acc 73 | else ( 74 | let v = big_int_of_int (int_of_char str.[i]) in 75 | let v = shift_left_big_int v (i*8) in 76 | loop (i-1) (or_big_int acc v)) 77 | in 78 | loop (len - 1) bi0 79 | 80 | let get_nativeint_from_addr tid addr = 81 | let s = get_memory tid addr Misc.addr_size in 82 | bytes_to_native s 83 | 84 | -------------------------------------------------------------------------------- /src/analyzer/misc.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** misc 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | exception Overflow 37 | 38 | module AddrSet = Set.Make(Nativeint) 39 | module AddrMap = Map.Make(Nativeint) 40 | module StringSet = Set.Make(String) 41 | module StringMap = Map.Make(String) 42 | module IntMap = Map.Make(struct type t = int let compare = compare end) 43 | module IntSet = Set.Make(struct type t = int let compare = compare end) 44 | 45 | let addr_size = Sys.word_size / 8 46 | let addr_sizen = Nativeint.of_int addr_size 47 | 48 | let bytes_to_list bytes = 49 | let rec loop i acc = 50 | if i < 0 then acc else loop (i-1) (bytes.[i] :: acc) 51 | in 52 | loop (String.length bytes - 1) [] 53 | 54 | let bytes_to_array bytes = 55 | let lst = bytes_to_list bytes in 56 | Array.of_list lst 57 | 58 | let get_clean_addr addr = 59 | let addr = Int64.of_nativeint addr in 60 | if Sys.word_size = 32 then Int64.logand 0xffffffffL addr 61 | else addr 62 | 63 | let readlines file = 64 | let chan = open_in file in 65 | let lines = ref [] in 66 | try 67 | while true do 68 | lines := input_line chan :: !lines 69 | done; [] 70 | with End_of_file -> 71 | close_in chan; 72 | List.rev !lines 73 | 74 | let chomp str = 75 | if str = "" then "" 76 | else 77 | let search_pos init p next = 78 | let rec search i = 79 | if p i then raise(Failure "empty") 80 | else 81 | match str.[i] with 82 | | ' ' | '\n' | '\r' | '\t' -> search (next i) 83 | | _ -> i 84 | in 85 | search init 86 | in 87 | let len = String.length str in 88 | try 89 | let left = search_pos 0 (fun i -> i >= len) (succ) 90 | and right = search_pos (len - 1) (fun i -> i < 0) (pred) 91 | in 92 | String.sub str left (right - left + 1) 93 | with 94 | Failure "empty" -> "" 95 | 96 | let ( +< ) = Nativeint.add 97 | let ( -< ) = Nativeint.sub 98 | let ( *< ) = Nativeint.mul 99 | let ( /< ) = Nativeint.div 100 | let ( <<< ) = Nativeint.shift_left 101 | let ( >>< ) = Nativeint.shift_right 102 | 103 | type op_t = 104 | | Plus 105 | | Minus 106 | | Mul 107 | | Div 108 | 109 | type sign_t = 110 | | Pos 111 | | Neg 112 | | Zero 113 | 114 | let sign_to_string = function 115 | | Pos -> "positive" 116 | | Neg -> "negative" 117 | | Zero -> "zero" 118 | 119 | let abs = Nativeint.abs 120 | 121 | let plus_expectation s1 s2 = 122 | match s1, s2 with 123 | | Pos, Pos -> Pos 124 | | Neg, Neg -> raise Overflow 125 | | Pos, Neg -> Neg 126 | | Neg, Pos -> Neg 127 | | s, Zero -> s 128 | | Zero, s -> s 129 | 130 | let minus_expectation = plus_expectation 131 | 132 | let mul_expectation s1 s2 = 133 | match s1, s2 with 134 | | Pos, Pos -> Pos 135 | | Neg, Neg -> Pos 136 | | Pos, Neg -> Neg 137 | | Neg, Pos -> Neg 138 | | _, Zero -> Zero 139 | | Zero, _ -> Zero 140 | 141 | let div_expectation = mul_expectation 142 | 143 | let sign_of x = if x < 0n then Neg else if x = 0n then Zero else Pos 144 | 145 | let get_expected_sign op x y = 146 | match op with 147 | | Plus -> plus_expectation (sign_of x) (sign_of y) 148 | | Minus -> minus_expectation (sign_of x) (sign_of y) 149 | | Mul -> mul_expectation (sign_of x) (sign_of y) 150 | | Div -> div_expectation (sign_of x) (sign_of y) 151 | 152 | let assert_sign v op expectation = 153 | match expectation with 154 | | Pos -> if sign_of v <> Pos then raise Overflow else () 155 | | Neg -> if sign_of v <> Neg then raise Overflow else () 156 | | Zero -> if sign_of v <> Zero then raise Overflow else () 157 | 158 | let sign_check fn op x y = 159 | let expected_sign = get_expected_sign op x y in 160 | let v = fn x y in 161 | assert_sign v op expected_sign; 162 | v 163 | 164 | let ( +! ) x y = sign_check Nativeint.add Plus x y 165 | let ( -! ) x y = sign_check Nativeint.sub Minus x y 166 | let ( *! ) x y = sign_check Nativeint.mul Mul x y 167 | let ( /! ) x y = sign_check Nativeint.div Div x y 168 | 169 | let error_exit msg = 170 | Printf.eprintf "%s\n" msg; 171 | exit 1 172 | 173 | let repeat x num = 174 | let rec loop acc num = 175 | if num <= 0 then acc 176 | else loop (x::acc) (num-1) 177 | in 178 | loop [] num 179 | 180 | -------------------------------------------------------------------------------- /src/analyzer/misc.mli: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** misc 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | exception Overflow 37 | 38 | module AddrSet : Set.S with type elt = nativeint 39 | module AddrMap : Map.S with type key = nativeint 40 | module StringSet : Set.S with type elt = string 41 | module StringMap : Map.S with type key = string 42 | module IntMap : Map.S with type key = int 43 | module IntSet : Set.S with type elt = int 44 | 45 | val bytes_to_list : string -> char list 46 | val bytes_to_array : string -> char array 47 | val get_clean_addr : nativeint -> int64 48 | val readlines : string -> string list 49 | val addr_size: int 50 | val addr_sizen: nativeint 51 | val chomp : string -> string 52 | 53 | (* nativeint convenience *) 54 | val ( +< ) : nativeint -> nativeint -> nativeint 55 | val ( -< ) : nativeint -> nativeint -> nativeint 56 | val ( *< ) : nativeint -> nativeint -> nativeint 57 | val ( /< ) : nativeint -> nativeint -> nativeint 58 | val ( <<< ) : nativeint -> int -> nativeint 59 | val ( >>< ) : nativeint -> int -> nativeint 60 | 61 | (* unsigned nativeint convenience with overflow detection *) 62 | val ( +! ) : nativeint -> nativeint -> nativeint 63 | val ( -! ) : nativeint -> nativeint -> nativeint 64 | val ( *! ) : nativeint -> nativeint -> nativeint 65 | val ( /! ) : nativeint -> nativeint -> nativeint 66 | 67 | (* exit with showing an error message *) 68 | val error_exit : string -> 'a 69 | 70 | val repeat : 'a -> int -> 'a list 71 | 72 | -------------------------------------------------------------------------------- /src/analyzer/options.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** command line options 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Libinput 37 | 38 | let anon x = raise(Arg.Bad("Bad argument: '"^x^"'")) 39 | 40 | let usage = "Usage: "^Sys.argv.(0)^" -recipe [conf]\n" 41 | 42 | type t = 43 | { 44 | recipe_file : string; 45 | recipe_string : string list; 46 | target : string option; 47 | socket_name : string; 48 | binname : string option; 49 | debug_flag : bool; 50 | } 51 | 52 | let options = ref 53 | { 54 | recipe_file=""; 55 | recipe_string=[]; 56 | target=None; 57 | socket_name="/tmp/symfuzz"; 58 | binname=None; 59 | debug_flag=false; 60 | } 61 | 62 | let specs = 63 | [ 64 | ("-json", 65 | Arg.String (fun s -> 66 | options := {!options with recipe_file=s}), 67 | " specify json file as a seed"); 68 | ("-debug", 69 | Arg.Unit (fun () -> 70 | options := {!options with debug_flag=true;} 71 | ), 72 | " enable debugging mode (iterate upto count)"); 73 | ] 74 | 75 | let read_json json = 76 | if json = "" then failwith "Must specify a configuration file." else (); 77 | let ic = open_in json in 78 | let n = in_channel_length ic in 79 | let s = Bytes.create n in 80 | really_input ic s 0 n; 81 | close_in ic; 82 | of_json s 83 | 84 | let get_input_vector () = 85 | let input_vector = read_json !options.recipe_file in 86 | let bin_target = 87 | try get_binary_target input_vector 88 | with Not_found -> 89 | (Printf.eprintf "need to specify binary target\n"; exit 1) 90 | in 91 | let bin_target = 92 | match !options.target with 93 | | Some target -> 94 | assert (bin_target = target); 95 | target 96 | | None -> 97 | bin_target 98 | in 99 | input_vector, bin_target 100 | 101 | let replace_options opts = options := opts 102 | 103 | let option_check opts = 104 | if opts.debug_flag then Printexc.record_backtrace true 105 | else () 106 | 107 | let optparse () = 108 | let () = Arg.parse (Arg.align specs) anon usage in 109 | let () = option_check !options in 110 | !options 111 | 112 | -------------------------------------------------------------------------------- /src/analyzer/pin.ml: -------------------------------------------------------------------------------- 1 | (* Abstract Interpretation-based Fuzz Testing *) 2 | 3 | open Libinput 4 | 5 | let toolroot = try Sys.getenv "AFUZZ_PATH" with Not_found -> ".." 6 | 7 | let pin_path = 8 | let pinpath = Filename.concat toolroot "pin/pin" in 9 | if Sys.file_exists pinpath then pinpath 10 | else failwith "pin is not found. try to set AFUZZ_PATH environment variable." 11 | 12 | let instrumentor_path = 13 | let path = 14 | if Nativeint.size = 64 then 15 | Filename.concat toolroot "src/instrumentor/obj-intel64/symfuzz.so" 16 | else 17 | Filename.concat toolroot "src/instrumentor/obj-ia32/symfuzz.so" 18 | in 19 | if Sys.file_exists path then path 20 | else failwith "instrumentor is not found." 21 | 22 | let execute vector logdir id sockname filenames debug_flag binname = 23 | let cmdlines = get_commandline vector in 24 | let instrumentor_logpath = Filename.concat logdir "instrument.log" in 25 | let filenames = 26 | List.fold_left (fun acc path -> "-filename"::path::acc) [] filenames 27 | in 28 | let binname = match binname with 29 | | Some name -> ["-binname"; name] 30 | | None -> [] 31 | in 32 | let cmd = 33 | [ 34 | pin_path; 35 | (* "-pause_tool"; "10"; *) 36 | "-t"; instrumentor_path; 37 | "-d"; logdir; 38 | "-o"; instrumentor_logpath; 39 | "-id"; string_of_int id; 40 | "-sock"; sockname; 41 | ] 42 | @ binname 43 | @ filenames 44 | @ (if debug_flag then ["-debug"] else []) @ 45 | [ 46 | "--"; 47 | ] @ cmdlines 48 | in 49 | let cmdstring = String.concat " " cmd in 50 | let () = Printf.printf "cmd = (%s)\n" cmdstring in 51 | let () = flush stdout in 52 | let () = Unix.putenv "LD_LIBRARY_PATH" "_build" in (* TODO *) 53 | let _ = Process.fork_and_exec cmd in 54 | () 55 | 56 | -------------------------------------------------------------------------------- /src/analyzer/pinapi.idl: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: several useful Pin-related functions 3 | /// @file: pinapi.idl 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | struct byte_val { 34 | char valid; 35 | char value; 36 | }; 37 | 38 | struct byte_val get_mem_byte( [in] unsigned int tid, [in,nativeint] unsigned long addr ); 39 | 40 | [string] char * get_mem( [in] unsigned int tid, [in,nativeint] unsigned long addr, [in] unsigned int size ) 41 | quote(call, " _res = get_mem(tid,addr,size);\n if(!_res) {\n size = 0;\n }\n _vres = caml_alloc_string(size);\n memcpy( (char*)String_val(_vres), _res, size );\n#if 0") 42 | quote(dealloc, "#endif\n free(_res);"); 43 | 44 | [string] char * get_mem_string( [in] unsigned int tid, [in,nativeint] unsigned long addr ) 45 | quote(dealloc, " free(_res);"); 46 | -------------------------------------------------------------------------------- /src/analyzer/printer.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** log printer 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | type out_color_t = 37 | | ColorRed 38 | | ColorGreen 39 | 40 | module type LogInfo = 41 | sig 42 | 43 | val chan : out_channel 44 | 45 | end 46 | 47 | module type Make = 48 | functor (L: LogInfo) -> 49 | sig 50 | 51 | val init_log : string -> unit 52 | val fin_log : unit -> unit 53 | val set_debug_flag : bool -> unit 54 | val debugf : ('a, out_channel, unit) format -> unit 55 | val logf : ('a, out_channel, unit) format -> unit 56 | val logtimef : ('a, out_channel, unit) format -> unit 57 | val errf : out_color_t -> ('a, out_channel, unit) format -> unit 58 | val get_chan : unit -> out_channel 59 | 60 | end 61 | 62 | module Make(L: LogInfo) = 63 | struct 64 | 65 | let debug_flag = ref false 66 | 67 | let chan = ref L.chan 68 | 69 | let logprint s = 70 | if !debug_flag then 71 | Printf.fprintf !chan "%s\n" s 72 | else 73 | () 74 | 75 | let init_log file = 76 | let () = assert (!chan = L.chan) in 77 | chan := (open_out file) 78 | 79 | let fin_log () = 80 | if !chan <> L.chan then close_out !chan 81 | else () 82 | 83 | let set_debug_flag flag = debug_flag := flag 84 | 85 | let time_print s = 86 | let t = Unix.localtime (Unix.time ()) in 87 | let s = Printf.sprintf "[%02d:%02d:%02d-%02d/%02d] %s" 88 | t.Unix.tm_hour 89 | t.Unix.tm_min 90 | t.Unix.tm_sec 91 | (t.Unix.tm_mon + 1) 92 | t.Unix.tm_mday 93 | s 94 | in 95 | Printf.sprintf "%s" s 96 | 97 | let time_log s = 98 | Printf.fprintf !chan "%s\n" s 99 | 100 | let debugf format = 101 | Printf.ksprintf (fun s -> logprint s) format 102 | let logf format = 103 | Printf.ksprintf (fun s -> Printf.fprintf !chan "%s\n" s) format 104 | let logtimef format = 105 | Printf.ksprintf (fun s -> let s = time_print s in time_log s) format 106 | 107 | let print_color chan color = 108 | let colorcode = match color with 109 | | ColorRed -> "\x1b[31m" 110 | | ColorGreen -> "\x1b[32m" 111 | in 112 | Printf.fprintf chan "%s" colorcode 113 | 114 | let clear_color chan = 115 | Printf.fprintf chan "\x1b[m" 116 | 117 | let errf color format = 118 | Printf.ksprintf (fun s -> 119 | print_color stderr color; 120 | prerr_string s; 121 | clear_color stderr) format 122 | 123 | let get_chan () = !chan 124 | 125 | end 126 | 127 | -------------------------------------------------------------------------------- /src/analyzer/process.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** process handling 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Misc 37 | 38 | (* simple fork and exec *) 39 | let fork_and_exec cmds = 40 | let pid = Unix.fork () in 41 | let path = 42 | try List.hd cmds with Not_found -> failwith "fork_and_exec: wrong cmds" 43 | in 44 | match pid with 45 | | 0 -> (* child *) 46 | Unix.execvp path (Array.of_list cmds) 47 | | -1 -> failwith "failed to fork" 48 | | _ -> (* parent *) 49 | ignore( Unix.wait () ) 50 | 51 | (* proc map parsing *) 52 | let read_proc_map pid = 53 | let procfile = Printf.sprintf "/proc/%d/maps" pid in 54 | readlines procfile 55 | 56 | (* get loaded shared object *) 57 | let get_loaded_so ?filterout:(filterout=fun _ -> false) pid = 58 | let proclist = read_proc_map pid in 59 | List.fold_left (fun acc line -> 60 | (* Printf.printf "%s\n" line; *) 61 | try 62 | let saddr, perm, inode, name = Scanf.sscanf line "%nx-%lx %4s %lx %5s %ld %s" 63 | (fun saddr _end perm _ _dev inode name -> 64 | saddr, perm, inode, name 65 | ) 66 | in 67 | if perm.[0] = 'r' && perm.[2] = 'x' && inode > 0l then 68 | if filterout name then acc 69 | else 70 | if StringMap.mem name acc then acc 71 | else StringMap.add name saddr acc 72 | else 73 | acc 74 | with Scanf.Scan_failure _ -> 75 | acc 76 | ) StringMap.empty proclist 77 | 78 | -------------------------------------------------------------------------------- /src/analyzer/protocol.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** protocol between processes 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | exception ProtocolVersionMismatch 37 | exception ProtocolError 38 | 39 | module type Protocol = 40 | sig 41 | 42 | type t 43 | val version : int 44 | 45 | end 46 | 47 | module ProtocolMake = 48 | functor (T: sig 49 | type t 50 | val version : int 51 | end) -> 52 | struct 53 | 54 | type t = T.t 55 | let version = T.version 56 | 57 | end 58 | 59 | module Communicate = 60 | functor (P: Protocol) -> 61 | struct 62 | let send oc msg = 63 | let () = 64 | try 65 | Marshal.to_channel oc msg [] 66 | with _ -> 67 | failwith "TO BIG MESSAGE" 68 | in 69 | flush oc 70 | 71 | let recv ic = 72 | Marshal.from_channel ic 73 | end 74 | 75 | -------------------------------------------------------------------------------- /src/analyzer/rcfg.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** CFG recovery 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Bapmisc 37 | open Misc 38 | open Dependency 39 | open Pinapi 40 | open Log_analysis 41 | open Big_int_convenience 42 | open Ast 43 | open LibBil 44 | 45 | type recovery_st = 46 | { 47 | tid : int; 48 | cfg : Cfg.AST.G.t; 49 | entry : Cfg.AST.G.vertex; 50 | exit : Cfg.AST.G.vertex; 51 | ret : Cfg.AST.G.vertex; 52 | } 53 | 54 | let get_stmt (buf, addr) = 55 | stmt_of_seq State.bil_handle buf (safe_bigint_of_native addr) 56 | 57 | let get_bap_stmt_from_buf = 58 | let stmt_cache = BatCache.lru_cache ~gen:get_stmt ~cap:61 in 59 | fun buf (naddr: nativeint) -> 60 | try let bap = stmt_cache (buf, naddr) in Some bap 61 | with _ -> None 62 | 63 | let maxins_len = 32 64 | 65 | let contains_jump prog = 66 | let jmp = function 67 | | Jmp (_,_) | CJmp (_,_,_,_) | Halt (_,_) -> true 68 | | _ -> false 69 | in 70 | List.exists jmp prog 71 | 72 | let rec block_loop acc sizeacc buf addr naddr = 73 | match get_bap_stmt_from_buf buf naddr with 74 | | Some (il, size) -> 75 | let bufsize = String.length buf in 76 | if contains_jump il then ((il, size)::acc), (sizeacc +% size) 77 | else if bufsize < maxins_len then acc, sizeacc 78 | else 79 | let sizei = Big_int_Z.int_of_big_int size in 80 | let buf' = String.sub buf sizei (bufsize - sizei) in 81 | block_loop 82 | ((il, size)::acc) 83 | (sizeacc +% size) 84 | (buf') 85 | (addr +% size) 86 | (naddr +! (Nativeint.of_int sizei)) 87 | | None -> 88 | acc, sizeacc 89 | 90 | let get_block (tid, maxbuf, addr) = 91 | let naddr = safe_bigint_to_native addr in 92 | let buf = get_mem tid naddr maxbuf in 93 | let ils, size = block_loop [] bi0 buf addr naddr in 94 | List.rev ils, size 95 | 96 | let get_bap_block = 97 | let maxbuf = 512 in (* XXX: this is large enough in most cases *) 98 | let cache = BatCache.lru_cache ~gen:get_block ~cap:1117 in 99 | fun tid addr -> cache (tid, maxbuf, addr) 100 | 101 | let get_next_addrs addr size target1 target2 = 102 | let next = addr +% size in 103 | match target1, target2 with 104 | | Int (t1, _), Int (t2, _) -> 105 | if t1 = next then [next; t2] 106 | else if t2 = next then [next; t1] 107 | else [t1; t2] 108 | | Int (t1, _), _ -> 109 | if t1 = next then [next] else [next; t1] 110 | | _, Int (t2, _) -> 111 | if t2 = next then [next] else [next; t2] 112 | | _, _ -> 113 | [next] 114 | 115 | let get_short_addr = function 116 | | Int (t, _) -> Some t, false 117 | | Lab str -> None, (String.sub str 0 6) = "nocjmp" 118 | | e -> None, false 119 | 120 | let add_edge cfg v_from v_to = 121 | (* reverse cfg *) 122 | Cfg.AST.add_edge cfg v_to v_from 123 | 124 | let add_exit_node blk st = 125 | match blk with 126 | | Some blk -> 127 | let cfg = add_edge st.cfg blk st.exit in {st with cfg=cfg} 128 | | None -> 129 | st 130 | 131 | let get_current_blk st stmt parent visited blkaddr = function 132 | | Some _ as blk -> st, blk, visited 133 | | None -> 134 | let cfg, vertex = Cfg.AST.create_vertex st.cfg [stmt] in 135 | let visited = BIM.add blkaddr vertex visited in 136 | let cfg = add_edge cfg parent vertex in 137 | {st with cfg=cfg}, Some vertex, visited 138 | 139 | let push_stack addr currblk addr_stack = 140 | Stack.push (addr, BatOption.get_exn currblk Not_found) addr_stack 141 | 142 | let cjmp st target is_fallthrough addr_stack currblk fallthrough = 143 | match target with 144 | | None -> 145 | if is_fallthrough then 146 | let () = push_stack fallthrough currblk addr_stack in st 147 | else 148 | add_exit_node currblk st 149 | | Some target -> 150 | let () = push_stack target currblk addr_stack in st 151 | 152 | let jmp st e currblk addr_stack = 153 | let addr, _nocjmp = get_short_addr e in 154 | let st = 155 | match addr with 156 | | None -> 157 | add_exit_node currblk st 158 | | Some addr -> 159 | let () = push_stack addr currblk addr_stack in 160 | st 161 | in 162 | st, None, true 163 | 164 | let call st currblk fallthrough addr_stack = 165 | let () = push_stack fallthrough currblk addr_stack in 166 | st, None, true 167 | 168 | let ret blk st = 169 | match blk with 170 | | Some blk -> 171 | let cfg = add_edge st.cfg blk st.ret in 172 | {st with cfg=cfg}, None, true 173 | | None -> 174 | st, None, true 175 | 176 | let build_from_stmt st currblk exited addr_stack addr fallthrough = function 177 | | Move (_,_,_) -> st, currblk, exited 178 | | Jmp (e,attrb) -> 179 | if is_call attrb then call st currblk fallthrough addr_stack 180 | else if is_ret attrb then ret currblk st 181 | else jmp st e currblk addr_stack 182 | | CJmp (_,e1,e2,_) -> 183 | let t1, f1 = get_short_addr e1 in 184 | let t2, f2 = get_short_addr e2 in 185 | let st = cjmp st t1 f1 addr_stack currblk fallthrough in 186 | let st = cjmp st t2 f2 addr_stack currblk fallthrough in 187 | st, currblk, true 188 | | Label (_,_) -> st, currblk, exited 189 | | Special (_,_,_) -> st, currblk, exited 190 | | Assert (_,_) -> st, currblk, exited 191 | | Halt (_,_) -> add_exit_node currblk st, currblk, true 192 | | s -> 193 | failwith ("unsupported statements encountered while building cfg" 194 | ^ (Pp.ast_stmt_to_string s)) 195 | 196 | let rec build_cfg st addr_stack addr parent visited = 197 | let prog, size = get_bap_block st.tid addr in 198 | let rec inner_loop st currblk exited addr fallthrough visited = function 199 | | stmt::tl -> 200 | let st, currblk, visited = 201 | get_current_blk st stmt parent visited addr currblk 202 | in 203 | let st, currblk, exited = 204 | build_from_stmt st currblk exited addr_stack addr fallthrough stmt 205 | in 206 | if exited then st, currblk, exited, visited 207 | else inner_loop st currblk exited addr fallthrough visited tl 208 | | [] -> 209 | st, currblk, exited, visited 210 | in 211 | let rec build_loop st currblk exited nextaddr visited = function 212 | | (stmts, inst_size)::tl -> 213 | let fallthrough = nextaddr +% inst_size in 214 | let st, currblk, exited, visited = 215 | inner_loop st currblk exited nextaddr fallthrough visited stmts 216 | in 217 | if exited then st, exited, visited 218 | else build_loop st currblk exited fallthrough visited tl 219 | | [] -> st, exited, visited 220 | in 221 | match prog with 222 | | [] -> st, visited 223 | | prog -> begin 224 | let st, is_fin, visited = 225 | build_loop st None false addr visited prog 226 | in 227 | if is_fin then 228 | st, visited 229 | else 230 | let nextaddr = addr +% size in 231 | build_cfg st addr_stack nextaddr parent visited 232 | end 233 | 234 | let rec resolve_loop st addr_stack visited = 235 | if Stack.is_empty addr_stack then 236 | st 237 | else 238 | let addr, parent = Stack.pop addr_stack in 239 | if BIM.mem addr visited then begin 240 | let vertex = BIM.find addr visited in 241 | let cfg = add_edge st.cfg parent vertex in 242 | resolve_loop {st with cfg=cfg} addr_stack visited 243 | end else begin 244 | let st, visited = 245 | build_cfg st addr_stack addr parent visited 246 | in 247 | resolve_loop st addr_stack visited 248 | end 249 | 250 | module Dom = Dominator.Make(Cfg.AST.G) 251 | 252 | let compute_idom = Dom.compute_idom 253 | 254 | let get_bap_stmt tid naddr = 255 | let maxbuf = 16 in 256 | let buf = get_mem tid naddr maxbuf in 257 | match get_bap_stmt_from_buf buf naddr with 258 | | Some (il, size) -> il, size 259 | | None -> failwith "failed to obtain bap stmt" 260 | 261 | let find_addr cfg pidom = 262 | let rec find_addr addr = function 263 | | Label (lbl,_)::_ -> State.label_address lbl 264 | | _::tl -> find_addr addr tl 265 | | [] -> addr 266 | in 267 | match find_addr None (Cfg.AST.get_stmts cfg pidom) with 268 | | None -> UnknownPdom 269 | | Some addr -> Pdom addr 270 | 271 | let get_postidoms (tid, (naddr: nativeint), target1, target2) = 272 | let _il, inssize = get_bap_stmt tid naddr in 273 | let baddr = biconst64 (get_clean_addr naddr) in 274 | (* list of potential jump addrs *) 275 | let addrs = get_next_addrs baddr inssize target1 target2 in 276 | let cfg = Cfg.AST.empty () in 277 | let cfg, entry = Cfg_ast.create_entry cfg in 278 | let cfg, exit = Cfg_ast.find_exit cfg in (* will create an exit node *) 279 | let cfg, ret = 280 | Cfg.AST.create_vertex cfg [Label (Type.Addr bi0, [Type.Asm "ret"])] 281 | in 282 | let cfg = add_edge cfg ret exit in 283 | let st = 284 | { 285 | tid=tid; 286 | cfg=cfg; 287 | entry=entry; 288 | exit=exit; 289 | ret=ret; 290 | } 291 | in 292 | let addrstack = Stack.create () in 293 | let () = List.iter (fun addr -> Stack.push (addr, entry) addrstack) addrs in 294 | let st = resolve_loop st addrstack BIM.empty in 295 | (* cfg_debugging st; *) 296 | let ret = 297 | try begin 298 | let pidom = (compute_idom st.cfg) st.exit st.entry in 299 | if pidom = st.exit then UnknownPdom 300 | else if pidom = st.ret then Return 301 | else find_addr st.cfg pidom 302 | end with Not_found -> 303 | UnknownPdom 304 | in 305 | ret 306 | 307 | let cfg_cache = BatCache.lru_cache ~gen:get_postidoms ~cap:997 308 | 309 | (* TODO : handle tid for threaded apps *) 310 | let get_postidoms tid addr target1 target2 = 311 | cfg_cache (tid, addr, target1, target2) 312 | 313 | -------------------------------------------------------------------------------- /src/analyzer/state.mli: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** analyzer state 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Dependency 37 | open Misc 38 | 39 | type t 40 | 41 | val get_state : unit -> t 42 | val set_state : t -> unit 43 | val bil_handle : LibBil.t 44 | 45 | val new_vector: t -> Libinput_type.input_vector -> t 46 | val new_option : t -> Options.t -> t 47 | 48 | val update_vdelta : t -> Var.t -> AbstrVal.t -> t 49 | val update_context : Context.t -> t 50 | val update_bblcount : t -> int -> int -> t 51 | val update_taintbbl : bool -> t -> t 52 | val cleanup_context : t -> t 53 | 54 | val introduce_arguments : int -> address_t -> int -> t -> t 55 | val introduce_files : t -> address_t -> int -> int -> nativeint -> string -> t 56 | val introduce_environment : t -> int32 -> address_t -> t 57 | 58 | val get_var_value : t -> Var.t -> Ast.exp * AbstrVal.t 59 | 60 | val set_pc : t -> address_t -> t 61 | val get_pc : t -> address_t 62 | val set_conc_mu : t -> address_t -> Ast.exp -> t 63 | val get_conc_mu : t -> address_t -> Type.typ -> Ast.exp 64 | val set_abstr_mu : t -> address_t -> AbstrVal.t -> int -> t 65 | val get_abstr_mu : t -> address_t -> Type.typ -> AbstrVal.t 66 | val set_delta : t -> Var.t -> Ast.exp -> t 67 | val get_delta : t -> Var.t -> Ast.exp 68 | val set_vdelta : t -> Var.t -> AbstrVal.t -> t 69 | val get_vdelta : t -> Var.t -> AbstrVal.t 70 | val update_gamma : t -> inputdep -> inputdep -> t 71 | val stash_gamma : t -> inputdep -> inputdep -> t 72 | val update_gamma_from_stashed : t -> t 73 | val clear_stash : t -> t 74 | val set_last_lbl : t -> Ast.stmt -> t 75 | val get_last_lbl : t -> string 76 | val is_debugging : t -> bool 77 | val set_debugging : bool -> t -> t 78 | val set_logdir : string -> t -> t 79 | val get_input_size : t -> int 80 | val get_idstack : t -> (nativeint * inputdep) Stack.t 81 | 82 | val dump_vars : t -> out_channel -> unit 83 | val dump_abstract_vars : t -> out_channel -> unit 84 | val dump_mem : t -> out_channel -> unit 85 | val dump_abstract_mem : t -> out_channel -> unit 86 | val dump_gamma : t -> out_channel -> unit 87 | val dump_stats : t -> out_channel -> int32 -> unit 88 | val dump_mem_info : t -> out_channel -> unit 89 | 90 | val get_nbytes_from_typ : Type.typ -> int 91 | 92 | val label_address : Type.label -> nativeint option 93 | 94 | val esp : Var.t 95 | 96 | -------------------------------------------------------------------------------- /src/analyzer/symfuzz.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** analyzer main 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Options 37 | open Misc 38 | open Dependency 39 | open Log_interface 40 | open Libinput_type 41 | open Libinput_value 42 | 43 | (** main analysis state *) 44 | type analysis_state = 45 | { 46 | id: int; 47 | input_queue: input_vector Queue.t; 48 | target: string; (* target binary name *) 49 | logdir: string; (* log directory *) 50 | sockname: string; 51 | } 52 | 53 | (** prepare execution environment for the input vector *) 54 | let prepare_env vector target = 55 | FileMap.iter (fun name file -> 56 | (* replace file contents *) 57 | let content = File.get_conc_value file in 58 | let f = open_out name in 59 | output_string f content; 60 | close_out f 61 | ) vector.files; 62 | vector 63 | 64 | let analysis options (ic,oc) st = 65 | (* step 1: run ibdi analysis *) 66 | let vector = Queue.pop st.input_queue in 67 | let vector = Symfuzz_protocol.push_vector oc vector in 68 | let vector = prepare_env vector st.target in 69 | let filenames = 70 | FileMap.fold (fun path _file names -> path::names) vector.files [] 71 | in 72 | logf "launching analysis"; 73 | let df = options.debug_flag in 74 | let bn = options.binname in 75 | Pin.execute vector st.logdir st.id st.sockname filenames df bn; 76 | (* step 2: obtain result from the analysis *) 77 | let _res = Symfuzz_protocol.pull_result ic oc in 78 | (* process the result *) 79 | st, vector 80 | 81 | (*******************************************************************) 82 | (* main symfuzz loop *) 83 | (*******************************************************************) 84 | let rec main_loop options ((ic,oc) as chan) st = 85 | let _st, _vector = analysis options chan st in 86 | (* TODO: run another analysis based on the result *) 87 | () 88 | 89 | let force_mkdir path perm = 90 | try Unix.mkdir path perm with _ -> () 91 | 92 | let force_symlink f t = 93 | let () = try Unix.unlink t with _ -> () in 94 | try Unix.symlink f t with _ -> () 95 | 96 | let init_logdir prefix = 97 | let lognum = 0 in 98 | let rec initialize lognum = 99 | let dirname = Printf.sprintf "%s-%d" prefix lognum in 100 | if Sys.file_exists dirname then initialize (lognum+1) 101 | else 102 | let () = force_mkdir dirname 0o777 in 103 | let () = force_symlink dirname (prefix^"-last") in 104 | dirname 105 | in 106 | initialize lognum 107 | 108 | let init_log options logdir = 109 | set_debug_flag (options.debug_flag); 110 | init_log (Filename.concat logdir "main.log") 111 | 112 | let child_proc sock main_to_child_in main_to_child_out = 113 | let () = Unix.close main_to_child_out in 114 | let intra_in, intra_out = Unix.socketpair Unix.PF_UNIX Unix.SOCK_STREAM 0 in 115 | let sock = Localsock.create_server sock in 116 | let t1 = Thread.create Comm.server_loop (main_to_child_in, intra_in) in 117 | let t2 = Thread.create Comm.client_accept_loop (sock, intra_out) in 118 | Thread.join t1; 119 | Thread.join t2; 120 | Unix.close intra_in; 121 | Unix.close intra_out 122 | 123 | let parent_proc options iv pid main_to_child_in main_to_child_out st = 124 | let () = Unix.close main_to_child_in in 125 | try begin 126 | let chan = Comm.fd_to_chans main_to_child_out in 127 | let () = Symfuzz_protocol.ping_check (fst chan) (snd chan) in 128 | let () = Queue.push iv st.input_queue in 129 | main_loop options chan st 130 | end with e -> 131 | Printf.eprintf "exception@parent: %s\n" (Printexc.to_string e); 132 | exit 1 133 | 134 | let check_binary path = 135 | if Sys.file_exists path then path 136 | else failwith (Printf.sprintf "invalid binary path: %s" path) 137 | 138 | (*****************************************************************************) 139 | (*****************************************************************************) 140 | (*****************************************************************************) 141 | 142 | let _ = 143 | let options = optparse () in 144 | let iv, binary = 145 | try get_input_vector () 146 | with Not_found -> error_exit "no input vector provided" 147 | in 148 | let bin = check_binary binary in 149 | let sock = options.socket_name in 150 | let logdir = init_logdir "symfuzzlog" in 151 | let () = init_log options logdir in 152 | let st = 153 | { 154 | id=0; 155 | input_queue=Queue.create (); 156 | target=bin; 157 | logdir=logdir; 158 | sockname=sock; 159 | } 160 | in 161 | let main_to_child_in, main_to_child_out = 162 | Unix.socketpair Unix.PF_UNIX Unix.SOCK_STREAM 0 163 | in 164 | let () = 165 | match Unix.fork () with 166 | | 0 -> child_proc sock main_to_child_in main_to_child_out 167 | | pid -> parent_proc options iv pid main_to_child_in main_to_child_out st 168 | in 169 | exit 0 170 | 171 | -------------------------------------------------------------------------------- /src/analyzer/symfuzz_protocol.ml: -------------------------------------------------------------------------------- 1 | open Protocol 2 | open Misc 3 | 4 | type protocol_t = 5 | | Ping of int 6 | | Pong of int 7 | | IVReq (* input vector request *) 8 | | IVResponse of Libinput_type.input_vector (* input vector response*) 9 | | OptionReq 10 | | OptionResponse of Options.t 11 | | Register of Libinput_type.input_vector 12 | | Result of int 13 | | ReqResult 14 | | Response 15 | | NoResponse 16 | 17 | module ProcessProtocol = ProtocolMake(struct 18 | 19 | type t = protocol_t 20 | 21 | let version = 1 22 | 23 | end) 24 | 25 | module ProcessCommunicate = Communicate (ProcessProtocol) 26 | 27 | let recv = ProcessCommunicate.recv 28 | let send = ProcessCommunicate.send 29 | 30 | let wait_for_ping ic oc = 31 | match recv ic with 32 | | Ping v -> 33 | assert (v = ProcessProtocol.version); 34 | send oc (Pong ProcessProtocol.version) 35 | | _ -> raise ProtocolError 36 | 37 | let ping_check ic oc = 38 | let () = send oc (Ping ProcessProtocol.version) in 39 | match recv ic with 40 | | Pong v -> assert (v = ProcessProtocol.version) 41 | | _ -> raise Not_found 42 | 43 | let client_prepare sock = 44 | let ic = Unix.in_channel_of_descr sock in 45 | let oc = Unix.out_channel_of_descr sock in 46 | let () = ping_check ic oc in 47 | ic, oc 48 | 49 | let push_vector oc vector = 50 | send oc (Register vector); 51 | vector 52 | 53 | let pull_result ic oc = 54 | send oc ReqResult; 55 | match recv ic with 56 | | Result r -> r 57 | | _ -> raise ProtocolError 58 | 59 | -------------------------------------------------------------------------------- /src/analyzer/symfuzz_protocol.mli: -------------------------------------------------------------------------------- 1 | open Protocol 2 | open Misc 3 | 4 | type protocol_t = 5 | | Ping of int 6 | | Pong of int 7 | | IVReq (* input vector request *) 8 | | IVResponse of Libinput_type.input_vector (* input vector response*) 9 | | OptionReq 10 | | OptionResponse of Options.t 11 | | Register of Libinput_type.input_vector 12 | | Result of int 13 | | ReqResult 14 | | Response 15 | | NoResponse 16 | 17 | val recv : in_channel -> protocol_t 18 | val send : out_channel -> protocol_t -> unit 19 | 20 | val wait_for_ping : in_channel -> out_channel -> unit 21 | val ping_check : in_channel -> out_channel -> unit 22 | val client_prepare : Unix.file_descr -> in_channel * out_channel 23 | 24 | val push_vector : 25 | out_channel 26 | -> Libinput_type.input_vector 27 | -> Libinput_type.input_vector 28 | 29 | val pull_result : 30 | in_channel 31 | -> out_channel 32 | -> int 33 | 34 | -------------------------------------------------------------------------------- /src/analyzer/syscall.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** system calls 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Misc 37 | 38 | type t = 39 | { 40 | file_descriptors : string IntMap.t; 41 | symfile_names : StringSet.t; 42 | } 43 | 44 | let empty = 45 | { 46 | file_descriptors=IntMap.empty; 47 | symfile_names=StringSet.empty; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/instrumentor/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | # 3 | # DO NOT EDIT THIS FILE! 4 | # 5 | ############################################################## 6 | 7 | override PIN_ROOT=../../pin 8 | 9 | # If the tool is built out of the kit, PIN_ROOT must be specified in the make invocation and point to the kit root. 10 | ifdef PIN_ROOT 11 | CONFIG_ROOT := $(PIN_ROOT)/source/tools/Config 12 | else 13 | CONFIG_ROOT := ../Config 14 | endif 15 | include $(CONFIG_ROOT)/makefile.config 16 | include makefile.rules 17 | include $(TOOLS_ROOT)/Config/makefile.default.rules 18 | 19 | ############################################################## 20 | # 21 | # DO NOT EDIT THIS FILE! 22 | # 23 | ############################################################## 24 | -------------------------------------------------------------------------------- /src/instrumentor/analysis_api.cpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: calling OCaml functions 3 | /// @file: analysis_api.cpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #include "analysis_api.hpp" 34 | #include "misc.hpp" 35 | 36 | #include 37 | #include 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | #include 43 | #include 44 | #include 45 | #include 46 | #ifdef __cplusplus 47 | } /* end of extern */ 48 | #endif 49 | 50 | void init_ocaml( char** argv ) 51 | { 52 | caml_startup( argv ); 53 | } 54 | 55 | void proc_start( const char* logdir, 56 | const uint32_t analysis_id, 57 | const char* sockname, 58 | bool debug_flag, 59 | const THREADID tid, 60 | char** argvp, 61 | int envc, 62 | char** envp ) 63 | { 64 | CAMLparam0(); 65 | CAMLlocalN( caml_args, 8 ); 66 | static value *proc_start_closure = NULL; 67 | 68 | if ( !proc_start_closure ) { 69 | proc_start_closure = caml_named_value( "proc_start" ); 70 | } 71 | 72 | caml_args[0] = caml_copy_string( logdir ); 73 | caml_args[1] = caml_copy_int32( analysis_id ); 74 | caml_args[2] = caml_copy_string( sockname ); 75 | caml_args[3] = Val_bool( debug_flag ); 76 | caml_args[4] = Val_int( tid ); 77 | caml_args[5] = caml_copy_nativeint( (long) argvp ); 78 | caml_args[6] = caml_copy_int32( envc ); 79 | caml_args[7] = caml_copy_nativeint( (long) envp ); 80 | 81 | caml_callbackN( *proc_start_closure, 8, caml_args ); 82 | 83 | CAMLreturn0; 84 | } 85 | 86 | void proc_end( unsigned int bbl_cnt ) 87 | { 88 | CAMLparam0(); 89 | 90 | value *proc_end_closure = caml_named_value( "proc_end" ); 91 | caml_callback( *proc_end_closure, caml_copy_int32( bbl_cnt ) ); 92 | 93 | CAMLreturn0; 94 | } 95 | 96 | int bbl_instrument( unsigned long addr, 97 | const bbl_content* content, 98 | const reg_context* context, 99 | const THREADID tid ) 100 | { 101 | CAMLparam0(); 102 | CAMLlocal1( ret ); 103 | CAMLlocalN( caml_args, 5 ); 104 | unsigned i, j; 105 | uint32_t size = (uint32_t) content->size; 106 | static value *bbl_instrument_closure = NULL; 107 | 108 | if ( !bbl_instrument_closure ) { 109 | bbl_instrument_closure = caml_named_value( "bbl_instrument" ); 110 | } 111 | 112 | caml_args[0] = caml_copy_nativeint( addr ); 113 | caml_args[1] = caml_copy_int32( size ); 114 | 115 | caml_args[2] = caml_alloc_string( size ); 116 | memcpy( (unsigned char*)String_val(caml_args[2]), content->content, size ); 117 | 118 | caml_args[3] = caml_alloc_tuple( 45 ); 119 | for ( i = 0; i < 20; ++i ) { 120 | Store_field( caml_args[3], i, caml_copy_nativeint( ((long*) &context->eax)[i] ) ); 121 | } 122 | for ( i = 20; i < 29; ++i ) { 123 | Store_field( caml_args[3], i, Val_bool( ((long*) &context->eax)[i] ) ); 124 | } 125 | for ( i = 29, j = 0; i < 45; ++i ) { 126 | Store_field( caml_args[3], i, caml_copy_int64( ((uint64_t*) &context->xmm0)[j++] ) ); 127 | Store_field( caml_args[3], i, caml_copy_int64( ((uint64_t*) &context->xmm0)[j++] ) ); 128 | } 129 | 130 | caml_args[4] = Val_int( tid ); 131 | 132 | ret = caml_callbackN( *bbl_instrument_closure, 5, caml_args ); 133 | 134 | CAMLreturnT( int, Int_val(ret) ); 135 | } 136 | 137 | void symbolic_read( ADDRINT addr, 138 | ADDRINT pos, 139 | ADDRINT ret, 140 | ADDRINT totalsize, 141 | const char* fname ) 142 | { 143 | CAMLparam0(); 144 | CAMLlocalN( caml_args, 5 ); 145 | static value *proc_symbolic_read = NULL; 146 | 147 | if ( !proc_symbolic_read ) { 148 | proc_symbolic_read = caml_named_value( "symbolic_read" ); 149 | } 150 | 151 | caml_args[0] = caml_copy_nativeint( (long) addr ); 152 | caml_args[1] = caml_copy_nativeint( (long) pos ); 153 | caml_args[2] = Val_int( (int) ret ); 154 | caml_args[3] = Val_int( (int) totalsize ); 155 | caml_args[4] = caml_copy_string( fname ); 156 | 157 | caml_callbackN( *proc_symbolic_read, 5, caml_args ); 158 | 159 | CAMLreturn0; 160 | } 161 | 162 | void handle_callret( const ADDRINT addr, const THREADID tid, UINT32 type ) 163 | { 164 | CAMLparam0(); 165 | CAMLlocal3( caml_addr, caml_tid, caml_type ); 166 | static value *proc_handle_callret = NULL; 167 | 168 | if ( !proc_handle_callret ) { 169 | proc_handle_callret = caml_named_value( "handle_callret" ); 170 | } 171 | 172 | caml_addr = caml_copy_nativeint( (long) addr ); 173 | caml_tid = Val_int( (int) tid ); 174 | caml_type = Val_int( (int) type ); 175 | 176 | caml_callback3( *proc_handle_callret, caml_addr, caml_tid, caml_type ); 177 | 178 | CAMLreturn0; 179 | } 180 | 181 | void handle_call( const ADDRINT addr, const THREADID tid ) 182 | { 183 | handle_callret( addr, tid, 0 ); 184 | } 185 | 186 | void handle_ret( const ADDRINT addr, const THREADID tid ) 187 | { 188 | handle_callret( addr, tid, 1 ); 189 | } 190 | 191 | bool check_regs_taint( UINT64 regs ) 192 | { 193 | CAMLparam0(); 194 | CAMLlocal2( used_regs, ret ); 195 | static value *proc_check_regs_taint = NULL; 196 | 197 | if ( !proc_check_regs_taint ) { 198 | proc_check_regs_taint = caml_named_value( "check_regs_taint" ); 199 | } 200 | 201 | used_regs = caml_copy_int64( regs ); 202 | 203 | ret = caml_callback( *proc_check_regs_taint, used_regs ); 204 | 205 | CAMLreturnT( bool, Bool_val( ret ) ); 206 | } 207 | 208 | bool check_mems_taint( memorylog_entry* memlog, unsigned int cnt ) 209 | { 210 | CAMLparam0(); 211 | CAMLlocal4( addrs, ret, v, tupl ); 212 | static value *proc_check_mems_taint = NULL; 213 | 214 | if ( !proc_check_mems_taint ) { 215 | proc_check_mems_taint = caml_named_value( "check_mems_taint" ); 216 | } 217 | 218 | addrs = Val_emptylist; 219 | for ( unsigned int i = 0; i < cnt; i ++ ) { 220 | tupl = caml_alloc_tuple( 2 ); 221 | Store_field( tupl, 0, caml_copy_nativeint( memlog[i].addr ) ); 222 | Store_field( tupl, 1, Val_int( memlog[i].size * 8 ) ); 223 | v = caml_alloc_small( 2, 0 ); 224 | Field( v, 0 ) = tupl; 225 | Field( v, 1 ) = addrs; 226 | addrs = v; 227 | } 228 | 229 | ret = caml_callback( *proc_check_mems_taint, addrs ); 230 | 231 | CAMLreturnT( bool, Bool_val( ret ) ); 232 | } 233 | 234 | ADDRINT check_postdom() 235 | { 236 | CAMLparam0(); 237 | CAMLlocal1( ret ); 238 | static value *proc_check_postdom = NULL; 239 | 240 | if ( !proc_check_postdom ) { 241 | proc_check_postdom = caml_named_value( "check_postdom" ); 242 | } 243 | 244 | ret = caml_callback( *proc_check_postdom, Val_unit ); 245 | 246 | CAMLreturnT( ADDRINT, Nativeint_val( ret ) ); 247 | } 248 | 249 | -------------------------------------------------------------------------------- /src/instrumentor/analysis_api.hpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: calling OCaml functions 3 | /// @file: analysis_api.hpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #pragma once 34 | 35 | #include 36 | #include "bbl_cache.hpp" 37 | #include "context.hpp" 38 | #include "tls.hpp" 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | void init_ocaml( char** argv ); 45 | 46 | /// 47 | void proc_start( const char* logdir, 48 | const uint32_t analysis_id, 49 | const char* sockname, 50 | bool debug_flag, 51 | const THREADID tid, 52 | char** argvp, 53 | int envc, 54 | char** envp ); 55 | 56 | void proc_end( unsigned int bblcnt ); 57 | 58 | int bbl_instrument( unsigned long addr, 59 | const bbl_content* content, 60 | const reg_context* context, 61 | const THREADID tid ); 62 | 63 | void symbolic_read( ADDRINT addr, 64 | ADDRINT pos, 65 | ADDRINT ret, 66 | ADDRINT totalsize, 67 | const char* fname ); 68 | 69 | void handle_ret( const ADDRINT retaddr, const THREADID tid ); 70 | void handle_call( const ADDRINT retaddr, const THREADID tid ); 71 | 72 | bool check_regs_taint( UINT64 regs ); 73 | bool check_mems_taint( memorylog_entry* memlog, unsigned int cnt ); 74 | 75 | ADDRINT check_postdom(); 76 | 77 | #ifdef __cplusplus 78 | } /* end of extern */ 79 | #endif 80 | 81 | -------------------------------------------------------------------------------- /src/instrumentor/bbl_cache.cpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: cache for bbl 3 | /// @file: bbl_cache.cpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | 34 | #include "bbl_cache.hpp" 35 | #include "misc.hpp" 36 | 37 | const bbl_content* bbl_content_get( unsigned char* buf, 38 | unsigned long buflen ) 39 | { 40 | static bbl_content content; 41 | 42 | content.size = buflen; 43 | content.content = buf; 44 | return &content; 45 | } 46 | 47 | -------------------------------------------------------------------------------- /src/instrumentor/bbl_cache.hpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: cache for bbl 3 | /// @file: bbl_cache.cpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #pragma once 34 | 35 | #include "pin.H" 36 | 37 | typedef struct bbl_content { 38 | unsigned long size; 39 | unsigned char* content; 40 | } bbl_content; 41 | 42 | const bbl_content* bbl_content_get( unsigned char* buf, unsigned long buflen ); 43 | 44 | -------------------------------------------------------------------------------- /src/instrumentor/callbacks.cpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: exposed callbacks for the analyzer 3 | /// @file: callbacks.cpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #include "callbacks.hpp" 34 | #include "logger.hpp" 35 | #include "misc.hpp" 36 | #include "memorylog.hpp" 37 | 38 | #include "pin.H" 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | #include "pinapi.h" 44 | #ifdef __cplusplus 45 | } /* end of extern */ 46 | #endif 47 | 48 | #include 49 | 50 | // prototypes 51 | byte_val cb_get_mem_byte( unsigned int tid, unsigned long addr ); 52 | char* cb_get_mem( unsigned int tid, unsigned long addr, unsigned int size ); 53 | char* cb_get_mem_string( unsigned int tid, unsigned long addr ); 54 | 55 | void init_callbacks() 56 | { 57 | get_mem_byte = cb_get_mem_byte; 58 | get_mem = cb_get_mem; 59 | get_mem_string = cb_get_mem_string; 60 | } 61 | 62 | // 63 | // callback implementations 64 | // 65 | 66 | byte_val cb_get_mem_byte( unsigned int tid, unsigned long addr ) 67 | { 68 | byte_val v = {0, 0}; 69 | VOID* ptr; 70 | size_t ret; 71 | 72 | ptr = get_log( tid, addr ); 73 | if ( ptr ) { 74 | ret = PIN_SafeCopy( &v.value, (VOID*) ptr, 1 ); 75 | } else { 76 | ret = PIN_SafeCopy( &v.value, (VOID*) addr, 1 ); 77 | } 78 | if ( ret == 1 ) v.valid = 1; 79 | else v.valid = 0; 80 | 81 | return v; 82 | } 83 | 84 | char* cb_get_mem( unsigned int tid, unsigned long addr, unsigned int size ) 85 | { 86 | char* buf = (char*) malloc( size ); 87 | if ( !buf ) error_exit( "not enough memory from cb_get_mem" ); 88 | 89 | VOID* ptr = get_log( tid, addr ); 90 | if ( !ptr ) ptr = (VOID*) addr; 91 | 92 | if ( PIN_SafeCopy( buf, ptr, size ) == size ) return buf; 93 | else return NULL; 94 | } 95 | 96 | bool zero_exists( const char* buf, unsigned long len, unsigned long* pos ) 97 | { 98 | register const char* s; 99 | register unsigned i = 0; 100 | 101 | for ( s = buf; *s; ++s, ++i ) { 102 | if ( i >= len ) break; 103 | } 104 | 105 | *pos = i; 106 | return (len != i); 107 | } 108 | 109 | char* cb_get_mem_string( unsigned int tid, unsigned long addr ) 110 | { 111 | const unsigned long interval = 4; // fetch interval 112 | unsigned long size = interval; 113 | unsigned long ptr = 0; 114 | unsigned long pos = 0; 115 | char* buf = (char*) malloc( size ); 116 | if ( !buf ) error_exit( "not enough memory from cb_get_mem" ); 117 | 118 | do { 119 | VOID* srcaddr = get_log( tid, addr + ptr ); 120 | if ( !srcaddr ) srcaddr = (VOID*) (addr + ptr); 121 | 122 | if ( PIN_SafeCopy( buf + ptr, srcaddr, interval ) == interval ) { 123 | if ( zero_exists( buf + ptr, interval, &pos ) ) { 124 | *(buf + ptr + pos) = 0; 125 | break; 126 | } else { 127 | ptr += interval; 128 | size += interval; 129 | buf = (char*) realloc( buf, size ); 130 | } 131 | } else { 132 | error_exit( "invalid memory access from get_mem_string" ); 133 | } 134 | } while ( true ); 135 | 136 | return buf; 137 | } 138 | 139 | -------------------------------------------------------------------------------- /src/instrumentor/callbacks.hpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: exposed callbacks for the analyzer 3 | /// @file: callbacks.hpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #pragma once 34 | 35 | void init_callbacks(); 36 | 37 | -------------------------------------------------------------------------------- /src/instrumentor/context.cpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: program context for the instrumentor 3 | /// @file: context.cpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #include "context.hpp" 34 | #include "logger.hpp" 35 | #include "analysis_api.hpp" 36 | 37 | #include 38 | 39 | void store_xmm_value( UINT64* low, UINT64* high, REG reg, const CONTEXT *ctxt ) 40 | { 41 | UINT64 val[4]; 42 | PIN_GetContextRegval( ctxt, reg, reinterpret_cast(&val) ); 43 | *low = val[0]; 44 | *high = val[1]; 45 | } 46 | 47 | void get_reg_context( reg_context* dst_ctxt, 48 | const CONTEXT *ctxt, 49 | const ADDRINT eip ) 50 | { 51 | long eflags; 52 | 53 | dst_ctxt->eax = PIN_GetContextReg( ctxt, REG_EAX ); 54 | dst_ctxt->ebx = PIN_GetContextReg( ctxt, REG_EBX ); 55 | dst_ctxt->ecx = PIN_GetContextReg( ctxt, REG_ECX ); 56 | dst_ctxt->edx = PIN_GetContextReg( ctxt, REG_EDX ); 57 | dst_ctxt->edi = PIN_GetContextReg( ctxt, REG_EDI ); 58 | dst_ctxt->esi = PIN_GetContextReg( ctxt, REG_ESI ); 59 | dst_ctxt->ebp = PIN_GetContextReg( ctxt, REG_EBP ); 60 | dst_ctxt->esp = PIN_GetContextReg( ctxt, REG_ESP ); 61 | dst_ctxt->eip = eip; 62 | 63 | eflags = dst_ctxt->eflags = PIN_GetContextReg( ctxt, REG_EFLAGS ); 64 | 65 | dst_ctxt->ldtr = PIN_GetContextReg( ctxt, REG_LDTR ); 66 | dst_ctxt->gdtr = 0; 67 | dst_ctxt->cs = PIN_GetContextReg( ctxt, REG_SEG_CS ); 68 | dst_ctxt->ds = PIN_GetContextReg( ctxt, REG_SEG_DS ); 69 | dst_ctxt->es = PIN_GetContextReg( ctxt, REG_SEG_ES ); 70 | dst_ctxt->fs = PIN_GetContextReg( ctxt, REG_SEG_FS ); 71 | dst_ctxt->gs = PIN_GetContextReg( ctxt, REG_SEG_GS ); 72 | dst_ctxt->ss = PIN_GetContextReg( ctxt, REG_SEG_SS ); 73 | dst_ctxt->fs_base = PIN_GetContextReg( ctxt, REG_SEG_FS_BASE ); 74 | dst_ctxt->gs_base = PIN_GetContextReg( ctxt, REG_SEG_GS_BASE ); 75 | 76 | dst_ctxt->cf = eflags & 0x1; 77 | dst_ctxt->pf = eflags & 0x4; 78 | dst_ctxt->af = eflags & 0x10; 79 | dst_ctxt->zf = eflags & 0x40; 80 | dst_ctxt->sf = eflags & 0x80; 81 | dst_ctxt->df = eflags & 0x400; 82 | dst_ctxt->of = eflags & 0x800; 83 | dst_ctxt->acf = eflags & 0x40000; 84 | dst_ctxt->idf = eflags & 0x200000; 85 | 86 | store_xmm_value( &dst_ctxt->xmm0.low, 87 | &dst_ctxt->xmm0.high, REG_XMM0, ctxt ); 88 | store_xmm_value( &dst_ctxt->xmm1.low, 89 | &dst_ctxt->xmm1.high, REG_XMM1, ctxt ); 90 | store_xmm_value( &dst_ctxt->xmm2.low, 91 | &dst_ctxt->xmm2.high, REG_XMM2, ctxt ); 92 | store_xmm_value( &dst_ctxt->xmm3.low, 93 | &dst_ctxt->xmm3.high, REG_XMM3, ctxt ); 94 | store_xmm_value( &dst_ctxt->xmm4.low, 95 | &dst_ctxt->xmm4.high, REG_XMM4, ctxt ); 96 | store_xmm_value( &dst_ctxt->xmm5.low, 97 | &dst_ctxt->xmm5.high, REG_XMM5, ctxt ); 98 | store_xmm_value( &dst_ctxt->xmm6.low, 99 | &dst_ctxt->xmm6.high, REG_XMM6, ctxt ); 100 | store_xmm_value( &dst_ctxt->xmm7.low, 101 | &dst_ctxt->xmm7.high, REG_XMM7, ctxt ); 102 | 103 | // out << std::hex 104 | // << "BBL: " << eip << "\n---CTXT---\n" 105 | // << "EAX:" << dst_ctxt.eax << "; " 106 | // << "EBX:" << dst_ctxt.ebx << "; " 107 | // << "ECX:" << dst_ctxt.ecx << "; " 108 | // << "EDX:" << dst_ctxt.edx << ";\n" 109 | // << "EDI:" << dst_ctxt.edi << "; " 110 | // << "ESI:" << dst_ctxt.esi << "; " 111 | // << "EBP:" << dst_ctxt.ebp << "; " 112 | // << "ESP:" << dst_ctxt.esp << ";\n" 113 | // << "XMM0:" << dst_ctxt.xmm0.low << ";" << dst_ctxt.xmm0.high << endl << endl; 114 | 115 | return; 116 | } 117 | 118 | regset_t get_regset( const REG r ) 119 | { 120 | if ( r == REG_INVALID() ) return regset_empty; 121 | 122 | switch ( r ) 123 | { 124 | #if __x86_64__ 125 | case REG_RAX: 126 | #endif 127 | case REG_EAX: 128 | case REG_AX: 129 | case REG_AL: 130 | case REG_AH: 131 | return regset_eax; 132 | #if __x86_64__ 133 | case REG_RBX: 134 | #endif 135 | case REG_EBX: 136 | case REG_BX: 137 | case REG_BL: 138 | case REG_BH: 139 | return regset_ebx; 140 | #if __x86_64__ 141 | case REG_RCX: 142 | #endif 143 | case REG_ECX: 144 | case REG_CX: 145 | case REG_CL: 146 | case REG_CH: 147 | return regset_ecx; 148 | #if __x86_64__ 149 | case REG_RDX: 150 | #endif 151 | case REG_EDX: 152 | case REG_DX: 153 | case REG_DL: 154 | case REG_DH: 155 | return regset_edx; 156 | #if __x86_64__ 157 | case REG_RSI: 158 | #endif 159 | case REG_ESI: 160 | case REG_SI: 161 | return regset_esi; 162 | #if __x86_64__ 163 | case REG_RDI: 164 | #endif 165 | case REG_EDI: 166 | case REG_DI: 167 | return regset_edi; 168 | case REG_ESP: 169 | case REG_SP: 170 | return regset_esp; 171 | case REG_EBP: 172 | case REG_BP: 173 | return regset_ebp; 174 | case REG_EIP: 175 | return regset_eip; 176 | case REG_MM0: 177 | case REG_XMM0: 178 | return regset_xmm0; 179 | case REG_MM1: 180 | case REG_XMM1: 181 | return regset_xmm1; 182 | case REG_MM2: 183 | case REG_XMM2: 184 | return regset_xmm2; 185 | case REG_MM3: 186 | case REG_XMM3: 187 | return regset_xmm3; 188 | case REG_MM4: 189 | case REG_XMM4: 190 | return regset_xmm4; 191 | case REG_MM5: 192 | case REG_XMM5: 193 | return regset_xmm5; 194 | case REG_MM6: 195 | case REG_XMM6: 196 | return regset_xmm6; 197 | case REG_MM7: 198 | case REG_XMM7: 199 | return regset_xmm7; 200 | case REG_ST0: 201 | return regset_st0; 202 | case REG_ST1: 203 | return regset_st1; 204 | case REG_ST2: 205 | return regset_st2; 206 | case REG_ST3: 207 | return regset_st3; 208 | case REG_ST4: 209 | return regset_st4; 210 | case REG_ST5: 211 | return regset_st5; 212 | case REG_ST6: 213 | return regset_st6; 214 | case REG_ST7: 215 | return regset_st7; 216 | case REG_EFLAGS: 217 | return regset_eflags; 218 | case REG_SEG_CS: 219 | case REG_SEG_DS: 220 | case REG_SEG_ES: 221 | case REG_SEG_FS: 222 | case REG_SEG_GS: 223 | case REG_SEG_SS: 224 | return regset_empty; 225 | case REG_X87: 226 | // FIXME 227 | return regset_empty; 228 | default: 229 | out << "unknown register: " << REG_StringShort( r ).c_str() << endl; 230 | return regset_empty; 231 | } 232 | } 233 | 234 | bool any_reg_tainted( regset_t used_regs ) 235 | { 236 | return check_regs_taint( (UINT64) used_regs );; 237 | } 238 | 239 | -------------------------------------------------------------------------------- /src/instrumentor/context.hpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: program context for the instrumentor 3 | /// @file: context.hpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #pragma once 34 | 35 | #include "pin.H" 36 | 37 | typedef struct xmm_t { 38 | 39 | uint64_t low; 40 | uint64_t high; 41 | 42 | } xmm_t; 43 | 44 | typedef struct reg_context { 45 | 46 | long eax; 47 | long ebx; 48 | long ecx; 49 | long edx; 50 | long edi; 51 | long esi; 52 | long ebp; 53 | long esp; 54 | long eip; 55 | 56 | long eflags; 57 | 58 | long ldtr; 59 | long gdtr; 60 | long cs; 61 | long ds; 62 | long es; 63 | long fs; 64 | long gs; 65 | long ss; 66 | long fs_base; 67 | long gs_base; 68 | 69 | /* eflags */ 70 | long cf; 71 | long pf; 72 | long af; 73 | long zf; 74 | long sf; 75 | long df; 76 | long of; 77 | long acf; 78 | long idf; 79 | 80 | xmm_t xmm0; 81 | xmm_t xmm1; 82 | xmm_t xmm2; 83 | xmm_t xmm3; 84 | xmm_t xmm4; 85 | xmm_t xmm5; 86 | xmm_t xmm6; 87 | xmm_t xmm7; 88 | 89 | /* TODO: FP control register? */ 90 | 91 | } reg_context; 92 | 93 | void get_reg_context( reg_context* dst_ctxt, const CONTEXT *ctxt, const ADDRINT eip ); 94 | 95 | typedef UINT64 regset_t; 96 | 97 | #define regset_empty (0LL) 98 | 99 | #define regset_eax (1LL << 0) 100 | #define regset_ebx (1LL << 1) 101 | #define regset_ecx (1LL << 2) 102 | #define regset_edx (1LL << 3) 103 | #define regset_edi (1LL << 4) 104 | #define regset_esi (1LL << 5) 105 | #define regset_ebp (1LL << 6) 106 | #define regset_esp (1LL << 7) 107 | #define regset_eip (1LL << 8) 108 | #define regset_eflags (1LL << 9) 109 | #define regset_xmm0 (1LL << 10) 110 | #define regset_xmm1 (1LL << 11) 111 | #define regset_xmm2 (1LL << 12) 112 | #define regset_xmm3 (1LL << 13) 113 | #define regset_xmm4 (1LL << 14) 114 | #define regset_xmm5 (1LL << 15) 115 | #define regset_xmm6 (1LL << 16) 116 | #define regset_xmm7 (1LL << 17) 117 | #define regset_xmm8 (1LL << 18) 118 | #define regset_xmm9 (1LL << 19) 119 | #define regset_xmm10 (1LL << 20) 120 | #define regset_xmm11 (1LL << 21) 121 | #define regset_xmm12 (1LL << 22) 122 | #define regset_xmm13 (1LL << 23) 123 | #define regset_xmm14 (1LL << 24) 124 | #define regset_xmm15 (1LL << 25) 125 | #define regset_x87 (1LL << 26) 126 | #define regset_st0 (1LL << 27) 127 | #define regset_st1 (1LL << 28) 128 | #define regset_st2 (1LL << 29) 129 | #define regset_st3 (1LL << 30) 130 | #define regset_st4 (1LL << 31) 131 | #define regset_st5 (1LL << 32) 132 | #define regset_st6 (1LL << 33) 133 | #define regset_st7 (1LL << 34) 134 | 135 | regset_t get_regset( const REG r ); 136 | 137 | bool any_reg_tainted( regset_t used_regs ); 138 | 139 | -------------------------------------------------------------------------------- /src/instrumentor/logger.cpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: log file generation 3 | /// @file: logger.cpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #include "logger.hpp" 34 | 35 | std::ofstream out; 36 | 37 | void open_log_new( const char* path ) 38 | { 39 | out.open( path, std::ios::binary | std::ios::trunc | std::ios::out ); 40 | } 41 | 42 | void open_log_append( const char* path ) 43 | { 44 | out.open( path, std::ios::binary | std::ios::app | std::ios::out ); 45 | } 46 | 47 | void close_log() 48 | { 49 | out.close(); 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/instrumentor/logger.hpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: log file generation 3 | /// @file: logger.hpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #pragma once 34 | 35 | #include 36 | #include 37 | 38 | extern std::ofstream out; 39 | 40 | void open_log_new( const char* path ); 41 | void open_log_append( const char* path ); 42 | void close_log(); 43 | 44 | -------------------------------------------------------------------------------- /src/instrumentor/makefile.rules: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | # 3 | # This file includes all the test targets as well as all the 4 | # non-default build rules and test recipes. 5 | # 6 | ############################################################## 7 | 8 | 9 | ############################################################## 10 | # 11 | # Test targets 12 | # 13 | ############################################################## 14 | 15 | ###### Place all generic definitions here ###### 16 | 17 | # This defines tests which run tools of the same name. This is simply for convenience to avoid 18 | # defining the test name twice (once in TOOL_ROOTS and again in TEST_ROOTS). 19 | # Tests defined here should not be defined in TOOL_ROOTS and TEST_ROOTS. 20 | TEST_TOOL_ROOTS := symfuzz 21 | 22 | # This defines the tests to be run that were not already defined in TEST_TOOL_ROOTS. 23 | TEST_ROOTS := 24 | 25 | # This defines a list of tests that should run in the "short" sanity. Tests in this list must also 26 | # appear either in the TEST_TOOL_ROOTS or the TEST_ROOTS list. 27 | # If the entire directory should be tested in sanity, assign TEST_TOOL_ROOTS and TEST_ROOTS to the 28 | # SANITY_SUBSET variable in the tests section below (see example in makefile.rules.tmpl). 29 | SANITY_SUBSET := 30 | 31 | # This defines the tools which will be run during the the tests, and were not already defined in 32 | # TEST_TOOL_ROOTS. 33 | TOOL_ROOTS := 34 | 35 | # This defines the static analysis tools which will be run during the the tests. They should not 36 | # be defined in TEST_TOOL_ROOTS. If a test with the same name exists, it should be defined in 37 | # TEST_ROOTS. 38 | # Note: Static analysis tools are in fact executables linked with the Pin Static Analysis Library. 39 | # This library provides a subset of the Pin APIs which allows the tool to perform static analysis 40 | # of an application or dll. Pin itself is not used when this tool runs. 41 | SA_TOOL_ROOTS := 42 | 43 | # This defines all the applications that will be run during the tests. 44 | APP_ROOTS := 45 | 46 | # This defines any additional object files that need to be compiled. 47 | OBJECT_ROOTS := 48 | 49 | # This defines any additional dlls (shared objects), other than the pintools, that need to be compiled. 50 | DLL_ROOTS := 51 | 52 | # This defines any static libraries (archives), that need to be built. 53 | LIB_ROOTS := 54 | 55 | 56 | ############################################################## 57 | # 58 | # Test recipes 59 | # 60 | ############################################################## 61 | 62 | # This section contains recipes for tests other than the default. 63 | # See makefile.default.rules for the default test rules. 64 | # All tests in this section should adhere to the naming convention: .test 65 | 66 | 67 | ############################################################## 68 | # 69 | # Build rules 70 | # 71 | ############################################################## 72 | 73 | # This section contains the build rules for all binaries that have special build rules. 74 | # See makefile.default.rules for the default build rules. 75 | 76 | OCAMLPATH = $(shell ocamlfind printconf stdlib) 77 | TOOLS := $(TEST_TOOL_ROOTS:%=$(OBJDIR)%$(PINTOOL_SUFFIX)) $(TOOL_ROOTS:%=$(OBJDIR)%$(PINTOOL_SUFFIX)) 78 | SRCS := $(wildcard *.cpp) 79 | OBJS := $(SRCS:%.cpp=$(OBJDIR)%.o) 80 | CAMLIDL_FLAG := -I$(OCAMLPATH) 81 | LIBANALYSIS_PATH := ../_build 82 | LIBANALYSIS_FLAG := -Wl,--no-undefined -L$(OCAMLPATH) -L$(LIBANALYSIS_PATH) -lanalysis -lunix -lasmrun_pic 83 | ANALYSIS_API := $(OBJDIR)analysis_api$(OBJ_SUFFIX) 84 | DBG=-g 85 | 86 | $(OBJDIR)%$(OBJ_SUFFIX): %.cpp 87 | $(CXX) $(TOOL_CXXFLAGS) $(DBG) $(COMP_OBJ)$@ $< 88 | 89 | $(OBJDIR)$(TEST_TOOL_ROOTS)$(OBJ_SUFFIX): main.cpp 90 | $(CXX) $(TOOL_CXXFLAGS) $(DBG) $(COMP_OBJ)$@ $< 91 | 92 | $(ANALYSIS_API): analysis_api.cpp analysis_api.hpp 93 | $(CXX) $(TOOL_CXXFLAGS) $(DBG) $(CAMLIDL_FLAG) $(COMP_OBJ)$@ $< 94 | 95 | $(OBJDIR)callbacks.o: callbacks.cpp callbacks.hpp 96 | $(CXX) $(TOOL_CXXFLAGS) -I../pinapi $(CAMLIDL_FLAG) $(DBG) $(COMP_OBJ)$@ $< 97 | 98 | $(TOOLS): $(OBJDIR)$(TEST_TOOL_ROOTS)$(OBJ_SUFFIX) $(OBJS) $(ANALYSIS_API) 99 | $(LINKER) $(TOOL_LDFLAGS) $(DBG) $(LINK_EXE)$@ $(OBJS) $(LIBANALYSIS_FLAG) $(TOOL_LPATHS) $(TOOL_LIBS) && \ 100 | mkdir -p ../_build/instrumentor 2> /dev/null; cp $@ ../_build/instrumentor 101 | 102 | # vim: set syntax=make softtabstop=0 tw=0 softtabstop=0 noexpandtab: 103 | -------------------------------------------------------------------------------- /src/instrumentor/memorylog.cpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: log memory accesses 3 | /// @file: memorylog.cpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #include "memorylog.hpp" 34 | #include "tls.hpp" 35 | #include 36 | #include 37 | 38 | void push_log( memorylog_entry* memlogs, 39 | UINT32* pLogcnt, 40 | ADDRINT addr, 41 | UINT32 size, 42 | bool storePrev ) 43 | { 44 | memlogs[*pLogcnt].addr = addr; 45 | 46 | if ( storePrev ) 47 | assert( PIN_SafeCopy( &memlogs[*pLogcnt].val[0], 48 | (const void*) addr, 49 | size ) == size ); 50 | else {} 51 | 52 | memlogs[*pLogcnt].size = (UINT16) size; 53 | 54 | *pLogcnt += 1; 55 | assert( *pLogcnt < MAX_ENTRY ); 56 | } 57 | 58 | void init_memlogs( memorylog_entry** ptr ) 59 | { 60 | *ptr = new memorylog_entry [MAX_ENTRY]; 61 | assert( *ptr != NULL ); 62 | } 63 | 64 | void* get_log( THREADID tid, ADDRINT addr ) 65 | { 66 | tls_info* tdata = 67 | static_cast( PIN_GetThreadData( g_tls_key, tid ) ); 68 | 69 | for ( UINT32 i = 0; i < tdata->wmemlog_cnt; i ++ ) { 70 | if ( tdata->wmemlogs[i].addr == addr ) 71 | return tdata->wmemlogs[i].val; 72 | else if ( tdata->wmemlogs[i].addr < addr 73 | && addr < (tdata->wmemlogs[i].addr + tdata->wmemlogs[i].size) ) 74 | return tdata->wmemlogs[i].val; 75 | } 76 | 77 | return NULL; 78 | } 79 | 80 | -------------------------------------------------------------------------------- /src/instrumentor/memorylog.hpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: log memory accesses 3 | /// @file: memorylog.hpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #pragma once 34 | 35 | #include "pin.H" 36 | 37 | #define MAX_ENTRY 10000 38 | 39 | #define READ_BIT (0x1) 40 | #define WRITE_BIT (0x10) 41 | 42 | 43 | typedef struct memorylog_entry { 44 | 45 | ADDRINT addr; 46 | UINT8 val[32]; // 32 byte memory (YMM) 47 | UINT16 size; 48 | 49 | } memorylog_entry; 50 | 51 | extern memorylog_entry g_memlogs[MAX_ENTRY]; 52 | 53 | void push_log( memorylog_entry* memlogs, 54 | UINT32* pLogcnt, 55 | ADDRINT addr, 56 | UINT32 size, 57 | bool storePrev ); 58 | 59 | void init_memlogs( memorylog_entry** ptr ); 60 | 61 | void* get_log( THREADID tid, ADDRINT addr ); 62 | 63 | -------------------------------------------------------------------------------- /src/instrumentor/misc.cpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: misc 3 | /// @file: misc.cpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | static char timebuf[64] = {0,}; 43 | 44 | void not_null( const void* ptr ) 45 | { 46 | assert( ptr && "pointer must not be NULL" ); 47 | } 48 | 49 | const char* timestamp() 50 | { 51 | struct timeval tv; 52 | struct tm *tm; 53 | 54 | gettimeofday( &tv, NULL ); 55 | if ( (tm = localtime(&tv.tv_sec)) != NULL ) { 56 | strftime( timebuf, sizeof(timebuf), "[%Y-%m-%d %H:%M:%S]", tm ); 57 | } 58 | 59 | return timebuf; 60 | } 61 | 62 | void error_exit( const char* msg ) 63 | { 64 | fprintf( stderr, "fatal error: %s\n", msg ); 65 | exit( -1 ); 66 | } 67 | 68 | bool file_exists( const char* path ) 69 | { 70 | return access( path, F_OK ) != -1; 71 | } 72 | 73 | -------------------------------------------------------------------------------- /src/instrumentor/misc.hpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: misc 3 | /// @file: misc.hpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | void not_null( const void* ptr ); 34 | const char* timestamp(); 35 | void error_exit( const char* msg ); 36 | bool file_exists( const char* path ); 37 | 38 | -------------------------------------------------------------------------------- /src/instrumentor/tls.cpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: tls 3 | /// @file: tls.cpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #include "tls.hpp" 34 | 35 | TLS_KEY g_tls_key; 36 | 37 | -------------------------------------------------------------------------------- /src/instrumentor/tls.hpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: tls 3 | /// @file: tls.hpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #pragma once 34 | 35 | #include "pin.H" 36 | #include "memorylog.hpp" 37 | #include "context.hpp" 38 | 39 | typedef struct tls_info { 40 | int syscall_num; 41 | long arg0; 42 | long arg1; 43 | long arg2; 44 | long arg3; 45 | long arg4; 46 | memorylog_entry* wmemlogs; 47 | UINT32 wmemlog_cnt; 48 | memorylog_entry* rmemlogs; 49 | UINT32 rmemlog_cnt; 50 | reg_context* bbl_ctxt; 51 | ADDRINT next_pdom_to_hit; 52 | UINT32 pdom_hit; 53 | } tls_info; 54 | 55 | extern TLS_KEY g_tls_key; 56 | 57 | -------------------------------------------------------------------------------- /src/libanalysis.clib: -------------------------------------------------------------------------------- 1 | analyzer/protocol.cmx 2 | analyzer/localsock.cmx 3 | analyzer/symfuzz_protocol.cmx 4 | analyzer/printer.cmx 5 | analyzer/misc.cmx 6 | analyzer/bapmisc.cmx 7 | analyzer/options.cmx 8 | analyzer/dependency.cmx 9 | analyzer/log_analysis.cmx 10 | analyzer/memory.cmx 11 | analyzer/eArray.cmx 12 | analyzer/state.cmx 13 | analyzer/context.cmx 14 | analyzer/rcfg.cmx 15 | analyzer/interpretation.cmx 16 | analyzer/pinapi_stubs.o 17 | analyzer/analysis.cmx 18 | pinapi/pinapi.o 19 | -------------------------------------------------------------------------------- /src/myocamlbuild.ml: -------------------------------------------------------------------------------- 1 | (* SymFuzz *) 2 | 3 | (** myocamlbuild 4 | 5 | @author Sang Kil Cha 6 | @since 2014-03-19 7 | 8 | *) 9 | 10 | (* 11 | Copyright (c) 2014, Sang Kil Cha 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are met: 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the nor the 22 | names of its contributors may be used to endorse or promote products 23 | derived from this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | *) 35 | 36 | open Ocamlbuild_plugin 37 | open Ocamlbuild_pack 38 | 39 | let run_and_read = Ocamlbuild_pack.My_unix.run_and_read 40 | 41 | let split s ch = 42 | let x = ref [] in 43 | let rec go s = 44 | let pos = String.index s ch in 45 | x := (String.before s pos)::!x; 46 | go (String.after s (pos + 1)) 47 | in 48 | try 49 | go s 50 | with Not_found -> !x 51 | 52 | let split_nl s = split s '\n' 53 | 54 | let before_space s = 55 | try String.before s (String.index s ' ') 56 | with Not_found -> s 57 | 58 | (* this lists all supported packages *) 59 | let find_packages () = 60 | List.map before_space (split_nl & run_and_read "ocamlfind list") 61 | 62 | (* ocamlfind command *) 63 | let ocamlfind x = S[A"ocamlfind"; x] 64 | 65 | (* camlidl command *) 66 | let camlidl = S([A"camlidl"]) 67 | 68 | let getline_from_cmd cmd = 69 | let ch = Unix.open_process_in cmd in 70 | let line = input_line ch in 71 | ignore (Unix.close_process_in ch); 72 | line 73 | 74 | (* ocaml path *) 75 | let ocamlpath = getline_from_cmd "ocamlfind printconf path" 76 | let camlidlpath = getline_from_cmd "ocamlfind query camlidl" 77 | 78 | (* read clib file and make P *) 79 | let read_clib file = 80 | let chan = open_in file in 81 | let specs = ref [] in 82 | try 83 | while true do specs := P(input_line chan) :: !specs done; [] 84 | with End_of_file -> 85 | close_in chan; List.rev !specs 86 | 87 | let _ = dispatch begin function 88 | | Before_options -> 89 | 90 | (* override default commands by ocamlfind ones *) 91 | Options.ocamlc := ocamlfind & A"ocamlc"; 92 | Options.ocamlopt := ocamlfind & A"ocamlopt"; 93 | Options.ocamldep := ocamlfind & A"ocamldep"; 94 | Options.ocamldoc := ocamlfind & A"ocamldoc"; 95 | Options.ocamlmktop := ocamlfind & A"ocamlmktop"; 96 | 97 | (* packages taggings *) 98 | tag_any 99 | ["pkg_str"; 100 | "pkg_unix"; 101 | "pkg_batteries"; 102 | "pkg_threads"; 103 | "pkg_yojson"; 104 | "pkg_camlidl"; 105 | "pkg_libbil"; 106 | "pkg_libinput"; 107 | ]; 108 | 109 | tag_file "analyzer/pinapi_stubs.c" ["stubs"]; 110 | 111 | | After_rules -> 112 | 113 | flag ["ocaml"; "link"; "program"] & A"-linkpkg"; 114 | 115 | (* For each ocamlfind package one inject the -package option when 116 | * compiling, computing dependencies, generating documentation and 117 | * linking. *) 118 | List.iter begin fun pkg -> 119 | flag ["ocaml"; "compile"; "pkg_"^pkg] & S[A"-package"; A pkg]; 120 | flag ["ocaml"; "ocamldep"; "pkg_"^pkg] & S[A"-package"; A pkg]; 121 | flag ["ocaml"; "doc"; "pkg_"^pkg] & S[A"-package"; A pkg]; 122 | flag ["ocaml"; "link"; "pkg_"^pkg] & S[A"-package"; A pkg]; 123 | flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S[A"-package"; A pkg]; 124 | end (find_packages ()); 125 | 126 | (* The default "thread" tag is not compatible with ocamlfind. 127 | Indeed, the default rules add the "threads.cma" or "threads.cmxa" 128 | options when using this tag. When using the "-linkpkg" option with 129 | ocamlfind, this module will then be added twice on the command line. 130 | 131 | To solve this, one approach is to add the "-thread" option when using 132 | the "threads" package using the previous plugin. 133 | *) 134 | flag ["ocaml"; "pkg_threads"; "compile"] (S[A "-thread"]); 135 | flag ["ocaml"; "pkg_threads"; "link"] (S[A "-thread"]); 136 | flag ["ocaml"; "pkg_threads"; "infer_interface"] (S[A "-thread"]); 137 | 138 | (* debugging and optimization *) 139 | flag ["ocaml"; "compile"] (S[A"-g"]); 140 | flag ["ocaml"; "link"] (S[A"-g"]); 141 | flag ["ocaml"; "compile"; "native"] (S[A"-inline";A"10"]); 142 | 143 | (* c stub generated from camlidl *) 144 | flag ["c"; "compile"; "stubs"] 145 | (S[A"-ccopt";A("-I"^camlidlpath);]); 146 | 147 | flag ["cpp"; "compile"; "stubs"] 148 | (S[A("-I"^ocamlpath^"/ocaml");A("-I"^camlidlpath);]); 149 | 150 | flag ["c"; "compile"; "file:analyzer/pinapi_stubs.c"] 151 | (S[A"-ccopt"; A"-I../pinapi"]); 152 | 153 | flag ["ocaml"; "link"; "native"] 154 | (S[ 155 | A"-inline"; A"10"; 156 | A"-cclib"; A"-L."; 157 | A"-cclib"; A"-lboost_system"; 158 | A"-cclib"; A"-lboost_filesystem"; 159 | A"-cclib"; A"-lcamlidl"; 160 | A"-cclib"; A"-lstdc++"; 161 | ]); 162 | 163 | flag ["ocamlmklib"; "c"] (S[A"-L."]); 164 | 165 | (* camlidl rules starts here *) 166 | rule "camlidl" 167 | ~prods:["%.mli"; "%.ml"; "%_stubs.c"] 168 | ~deps:["%.idl"] 169 | begin fun env _build -> 170 | let idl = env "%.idl" in 171 | let tags = tags_of_pathname idl ++ "compile" ++ "camlidl" in 172 | let cmd = Cmd( S[camlidl; T tags; P idl] ) in 173 | Seq [cmd] 174 | end; 175 | 176 | (* define c++ ruels here *) 177 | rule "cpp" 178 | ~prods:["%.o";] 179 | ~deps:["%.cpp"] 180 | begin fun env _build -> 181 | let file = env "%.cpp" in 182 | let target = env "%.o" in 183 | let tags = tags_of_pathname file ++ "compile" ++ "cpp" in 184 | let cmd = Cmd( S[A"g++"; A"-g"; A"-c"; A"-O3"; 185 | A("-I../"^Pathname.dirname file); 186 | A("-I/usr/local/include"); 187 | A("-fPIC"); 188 | A"-o"; A target; T tags; P file] ) 189 | in 190 | Seq [cmd] 191 | end; 192 | 193 | (* specific rule for libanalysis *) 194 | rule "libanalysis" 195 | ~prods:["libanalysis.native";] 196 | ~deps:["analyzer/pinapi_stubs.o"; 197 | "analyzer/analysis.cmx"; 198 | "analyzer/rcfg.cmx"] 199 | begin fun env _build -> 200 | let file = env "libanalysis.so" in 201 | let tags = 202 | tags_of_pathname file ++ "ocaml" ++ "link" ++ "native" 203 | in 204 | let cmd = Cmd( S[!Options.ocamlopt; 205 | A"-linkpkg"; 206 | S(read_clib (env "../libanalysis.clib")); 207 | A"-output-obj"; 208 | A"-o"; A file; 209 | T tags;] ) 210 | in 211 | Seq [cmd] 212 | end 213 | 214 | | _ -> () 215 | end 216 | 217 | -------------------------------------------------------------------------------- /src/pinapi/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | # 3 | # DO NOT EDIT THIS FILE! 4 | # 5 | ############################################################## 6 | 7 | override PIN_ROOT=../../pin 8 | 9 | # If the tool is built out of the kit, PIN_ROOT must be specified in the make invocation and point to the kit root. 10 | ifdef PIN_ROOT 11 | CONFIG_ROOT := $(PIN_ROOT)/source/tools/Config 12 | else 13 | CONFIG_ROOT := ../Config 14 | endif 15 | include $(CONFIG_ROOT)/makefile.config 16 | include makefile.rules 17 | include $(TOOLS_ROOT)/Config/makefile.default.rules 18 | 19 | ############################################################## 20 | # 21 | # DO NOT EDIT THIS FILE! 22 | # 23 | ############################################################## 24 | -------------------------------------------------------------------------------- /src/pinapi/makefile.rules: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | # 3 | # This file includes all the test targets as well as all the 4 | # non-default build rules and test recipes. 5 | # 6 | ############################################################## 7 | 8 | 9 | ############################################################## 10 | # 11 | # Test targets 12 | # 13 | ############################################################## 14 | 15 | ###### Place all generic definitions here ###### 16 | 17 | # This defines tests which run tools of the same name. This is simply for convenience to avoid 18 | # defining the test name twice (once in TOOL_ROOTS and again in TEST_ROOTS). 19 | # Tests defined here should not be defined in TOOL_ROOTS and TEST_ROOTS. 20 | TEST_TOOL_ROOTS := pinapi 21 | 22 | # This defines the tests to be run that were not already defined in TEST_TOOL_ROOTS. 23 | TEST_ROOTS := 24 | 25 | # This defines a list of tests that should run in the "short" sanity. Tests in this list must also 26 | # appear either in the TEST_TOOL_ROOTS or the TEST_ROOTS list. 27 | # If the entire directory should be tested in sanity, assign TEST_TOOL_ROOTS and TEST_ROOTS to the 28 | # SANITY_SUBSET variable in the tests section below (see example in makefile.rules.tmpl). 29 | SANITY_SUBSET := 30 | 31 | # This defines the tools which will be run during the the tests, and were not already defined in 32 | # TEST_TOOL_ROOTS. 33 | TOOL_ROOTS := 34 | 35 | # This defines the static analysis tools which will be run during the the tests. They should not 36 | # be defined in TEST_TOOL_ROOTS. If a test with the same name exists, it should be defined in 37 | # TEST_ROOTS. 38 | # Note: Static analysis tools are in fact executables linked with the Pin Static Analysis Library. 39 | # This library provides a subset of the Pin APIs which allows the tool to perform static analysis 40 | # of an application or dll. Pin itself is not used when this tool runs. 41 | SA_TOOL_ROOTS := 42 | 43 | # This defines all the applications that will be run during the tests. 44 | APP_ROOTS := 45 | 46 | # This defines any additional object files that need to be compiled. 47 | OBJECT_ROOTS := 48 | 49 | # This defines any additional dlls (shared objects), other than the pintools, that need to be compiled. 50 | DLL_ROOTS := 51 | 52 | # This defines any static libraries (archives), that need to be built. 53 | LIB_ROOTS := 54 | 55 | 56 | ############################################################## 57 | # 58 | # Test recipes 59 | # 60 | ############################################################## 61 | 62 | # This section contains recipes for tests other than the default. 63 | # See makefile.default.rules for the default test rules. 64 | # All tests in this section should adhere to the naming convention: .test 65 | 66 | 67 | ############################################################## 68 | # 69 | # Build rules 70 | # 71 | ############################################################## 72 | 73 | # This section contains the build rules for all binaries that have special build rules. 74 | # See makefile.default.rules for the default build rules. 75 | 76 | OCAMLPATH = $(shell ocamlfind printconf stdlib) 77 | TOOLS := $(TEST_TOOL_ROOTS:%=$(OBJDIR)%$(PINTOOL_SUFFIX)) $(TOOL_ROOTS:%=$(OBJDIR)%$(PINTOOL_SUFFIX)) 78 | SRCS := $(wildcard *.cpp) 79 | OBJS := $(SRCS:%.cpp=$(OBJDIR)%.o) 80 | CAMLIDL_FLAG := -I$(OCAMLPATH) 81 | LIBPINAPI_FLAGS := -Wl,--no-undefined -L$(OCAMLPATH) -lunix -lasmrun_pic 82 | LIBPINAPI := $(OBJDIR)/libpinapi.so.1 83 | LIBPINAPI_DIR := ../_build/pinapi/ 84 | LIBPINAPI_PATH := $(LIBPINAPI_DIR)pinapi.o 85 | LIBPINAPI_VERSION := 1 86 | DBG=-g 87 | 88 | $(LIBPINAPI): $(OBJDIR)pinapi.o 89 | $(CXX) -shared -Wl,-soname,libpinapi.so.$(LIBPINAPI_VERSION) $(CAMLIDL_FLAG) -o $@ $< 90 | 91 | $(LIBPINAPI_PATH): $(LIBPINAPI) 92 | mkdir -p $(LIBPINAPI_DIR) 2> /dev/null 93 | cp $(OBJDIR)pinapi.o $(LIBPINAPI_PATH) 94 | 95 | $(TOOLS): $(LIBPINAPI_PATH) 96 | $(LINKER) $(TOOL_LDFLAGS) $(LIBPINAPI_FLAGS) $(DBG) $(LINK_EXE)$@ $(OBJS) $(TOOL_LPATHS) $(TOOL_LIBS) 97 | 98 | # vim: set syntax=make softtabstop=0 tw=0 softtabstop=0 noexpandtab: 99 | -------------------------------------------------------------------------------- /src/pinapi/pinapi.cpp: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: placeholder for Pin APIs 3 | /// @file: pinapi.cpp 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #include "pin.H" 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | #include "pinapi.h" 39 | #ifdef __cplusplus 40 | } /* end of extern */ 41 | #endif 42 | 43 | byte_val (*get_mem_byte)( unsigned int tid, unsigned long addr ) = NULL; 44 | char* (*get_mem)( unsigned int tid, unsigned long addr, unsigned int size ) = NULL; 45 | char* (*get_mem_string)( unsigned int tid, unsigned long addr ) = NULL; 46 | 47 | -------------------------------------------------------------------------------- /src/pinapi/pinapi.h: -------------------------------------------------------------------------------- 1 | /// SymFuzz 2 | /// @brief: placeholder for Pin APIs 3 | /// @file: pinapi.h 4 | /// @author: Sang Kil Cha 5 | /// @date: 2014/03/19 6 | 7 | /* 8 | Copyright (c) 2014, Sang Kil Cha 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | * Neither the name of the nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL SANG KIL CHA BE LIABLE FOR ANY 26 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | */ 32 | 33 | #pragma once 34 | 35 | #include 36 | 37 | typedef struct byte_val { 38 | char valid; // for indicating SEGFAULT 39 | char value; 40 | } byte_val; 41 | 42 | // global function table 43 | extern byte_val (*get_mem_byte)( unsigned int tid, unsigned long addr ); 44 | extern char* (*get_mem)( unsigned int tid, unsigned long addr, unsigned int size ); 45 | extern char* (*get_mem_string)( unsigned int tid, unsigned long addr ); 46 | 47 | --------------------------------------------------------------------------------