diff --git a/afl_transforms/tools/zafl/zafl.cpp b/afl_transforms/tools/zafl/zafl.cpp index 6387225b28e1c821831d8db6faa4052e499d676b..48e1db5eee2c218e13c66c2a80be7490bfe362d4 100644 --- a/afl_transforms/tools/zafl/zafl.cpp +++ b/afl_transforms/tools/zafl/zafl.cpp @@ -50,6 +50,7 @@ Zafl_t::Zafl_t(libIRDB::pqxxDB_t &p_dbinterface, libIRDB::FileIR_t *p_variantIR, m_exitpoints(p_exitPoints), m_use_stars(p_use_stars), m_autozafl(p_autozafl), + m_bb_graph_optimize(false), m_verbose(p_verbose) { auto ed=ElfDependencies_t(getFileIR()); @@ -74,6 +75,7 @@ Zafl_t::Zafl_t(libIRDB::pqxxDB_t &p_dbinterface, libIRDB::FileIR_t *p_variantIR, m_blacklist.insert("register_tm_clones"); m_blacklist.insert("deregister_tm_clones"); m_blacklist.insert("frame_dummy"); + m_blacklist.insert("__do_global_ctors_aux"); m_blacklist.insert("__do_global_dtors_aux"); m_blacklist.insert("__libc_csu_init"); m_blacklist.insert("__libc_csu_fini"); @@ -82,6 +84,11 @@ Zafl_t::Zafl_t(libIRDB::pqxxDB_t &p_dbinterface, libIRDB::FileIR_t *p_variantIR, m_num_temp_reg_saved = 0; m_num_tracemap_reg_saved = 0; m_num_previd_reg_saved = 0; + m_num_bb_zero_predecessors = 0; + m_num_bb_zero_successors = 0; + m_num_bb_single_predecessors = 0; + m_num_bb_single_successors = 0; + m_num_bb_skipped = 0; } static void create_got_reloc(FileIR_t* fir, pair<DataScoop_t*,int> wrt, Instruction_t* i) @@ -639,7 +646,9 @@ void Zafl_t::insertExitPoints() bool Zafl_t::isBlacklisted(const Function_t *p_func) const { - return (p_func->GetName()[0] == '.' || m_blacklist.find(p_func->GetName())!=m_blacklist.end()); + return (p_func->GetName()[0] == '.' || + p_func->GetName().find("@plt") != string::npos || + m_blacklist.find(p_func->GetName())!=m_blacklist.end()); } bool Zafl_t::isWhitelisted(const Function_t *p_func) const @@ -695,6 +704,7 @@ int Zafl_t::execute() }; auto bb_id = -1; + auto num_bb = 0; // for all functions // for all basic blocks @@ -716,20 +726,27 @@ int Zafl_t::execute() } cout << endl; + + ControlFlowGraph_t cfg(f); + auto num_bb_instrumented_this_function = 0; + const auto num_blocks = cfg.GetBlocks().size(); + num_bb += num_blocks; + if (leafAnnotation) cout << "Processing leaf function: "; else cout << "Processing function: "; - cout << f->GetName() << endl; + cout << f->GetName(); + cout << " " << num_blocks << " basic blocks" << endl; - auto current = num_bb_instrumented; - ControlFlowGraph_t cfg(f); for (auto bb : cfg.GetBlocks()) { assert(bb->GetInstructions().size() > 0); bb_id++; + cout << "basic block id#" << bb_id << " has " << bb->GetInstructions().size() << " instructions" << endl; + // if whitelist specified, only allow instrumentation for functions/addresses in whitelist if (m_whitelist.size() > 0) { if (!isWhitelisted(bb->GetInstructions()[0])) @@ -739,6 +756,7 @@ int Zafl_t::execute() if (isBlacklisted(bb->GetInstructions()[0])) continue; + // debugging support if (getenv("ZAFL_LIMIT_BEGIN")) { @@ -753,14 +771,31 @@ int Zafl_t::execute() continue; } - cout << "Instrumenting basic block #" << dec << bb_id << endl; - afl_instrument_bb(bb->GetInstructions()[0], leafAnnotation); + if (bb->GetPredecessors().size() == 0) + m_num_bb_zero_predecessors++; + if (bb->GetPredecessors().size() == 1) + m_num_bb_single_predecessors++; + if (bb->GetSuccessors().size() == 0) + m_num_bb_zero_successors++; + + if (bb->GetSuccessors().size() == 1) + { + m_num_bb_single_successors++; + if (m_bb_graph_optimize) + { + m_num_bb_skipped++; + continue; + } + } - num_bb_instrumented++; + cout << "Instrumenting basic block #" << dec << bb_id << " preds: " << bb->GetPredecessors().size() << " succs: " << bb->GetSuccessors().size() << endl; + num_bb_instrumented_this_function++; + afl_instrument_bb(bb->GetInstructions()[0], leafAnnotation); } + num_bb_instrumented += num_bb_instrumented_this_function; if (f) { - cout << "Function " << f->GetName() << " has " << dec << num_bb_instrumented - current << " basic blocks instrumented" << endl; + cout << "Function " << f->GetName() << " : " << dec << num_bb_instrumented_this_function << "/" << cfg.GetBlocks().size() << " basic blocks instrumented." << endl; } }); @@ -777,6 +812,12 @@ int Zafl_t::execute() cout << "#ATTRIBUTE num_temp_reg_saved=" << m_num_temp_reg_saved << endl; cout << "#ATTRIBUTE num_tracemap_reg_saved=" << m_num_tracemap_reg_saved << endl; cout << "#ATTRIBUTE num_previd_reg_saved=" << m_num_previd_reg_saved << endl; + cout << "#ATTRIBUTE num_bb=" << dec << num_bb << endl; + cout << "#ATTRIBUTE num_bb_zero_predecessors=" << dec << m_num_bb_zero_predecessors << endl; + cout << "#ATTRIBUTE num_bb_zero_successors=" << dec << m_num_bb_zero_successors << endl; + cout << "#ATTRIBUTE num_bb_single_predecessors=" << dec << m_num_bb_single_predecessors << endl; + cout << "#ATTRIBUTE num_bb_single_successors=" << dec << m_num_bb_single_successors << endl; + cout << "#ATTRIBUTE num_bb_skipped=" << dec << m_num_bb_skipped << endl; return 1; } diff --git a/afl_transforms/tools/zafl/zafl.hpp b/afl_transforms/tools/zafl/zafl.hpp index 5e4f41d3948ffddb7fe6d1a5d79a7e688b640eff..831bbf968531ea004d51c582e09fdb3c523ec651 100644 --- a/afl_transforms/tools/zafl/zafl.hpp +++ b/afl_transforms/tools/zafl/zafl.hpp @@ -1,6 +1,7 @@ #ifndef _LIBTRANSFORM_ZAFL_H #define _LIBTRANSFORM_ZAFL_H + #include <libIRDB-core.hpp> #include <stars.h> #include "transform.hpp" @@ -20,6 +21,7 @@ public: int execute(); void setWhitelist(const string&); void setBlacklist(const string&); + void setBasicBlockOptimization(bool p_bb_graph_optimize) {m_bb_graph_optimize=p_bb_graph_optimize;} private: void afl_instrument_bb(Instruction_t *inst, const bool p_hasLeafAnnotation); @@ -42,6 +44,7 @@ private: set<string> m_exitpoints; bool m_use_stars; bool m_autozafl; + bool m_bb_graph_optimize; bool m_verbose; std::pair<DataScoop_t*,int> m_trace_map; // afl shared memory trace map @@ -56,6 +59,11 @@ private: unsigned m_num_temp_reg_saved; unsigned m_num_tracemap_reg_saved; unsigned m_num_previd_reg_saved; + unsigned m_num_bb_zero_predecessors;; + unsigned m_num_bb_single_predecessors; + unsigned m_num_bb_zero_successors; + unsigned m_num_bb_single_successors; + unsigned m_num_bb_skipped; }; } diff --git a/afl_transforms/tools/zafl/zafl_driver.cpp b/afl_transforms/tools/zafl/zafl_driver.cpp index 4693b49d199c0bfd683b38643752c22de63ac8b0..8f42585117c70ac39f9afa292a69eaeeeaa9a9ad 100644 --- a/afl_transforms/tools/zafl/zafl_driver.cpp +++ b/afl_transforms/tools/zafl/zafl_driver.cpp @@ -41,8 +41,10 @@ static void usage(char* name) cerr<<"\t[--stars|-s] Enable STARS optimizations "<<endl; cerr<<"\t[--entrypoint|-e {<funcName>|<hex_address>}] Specify where to insert fork server (defaults to main if found)"<<endl; cerr<<"\t[--exitpoint|-E {<funcName>|<hex_address>}] Specify where to insert exit"<<endl; - cerr<<"\t[--whitelist|-w whitelistFile] Specify list of functions to instrument"<<endl; - cerr<<"\t[--blacklist|-b blacklistFile] Specify list of functions to omit"<<endl; + cerr<<"\t[--whitelist|-w whitelistFile] Specify list of functions/addresses to instrument"<<endl; + cerr<<"\t[--blacklist|-b blacklistFile] Specify list of functions/addresses to omit"<<endl; + cerr<<"\t[--enable-bb-graph-optimization|-g] Elide instrumentation if basic block has 1 successor"<<endl; + cerr<<"\t[--disable-bb-graph-optimization|-G] Elide instrumentation if basic block has 1 successor"<<endl; cerr<<"\t[--autozafl|-a] Auto-initialize fork server (incompatible with --entrypoint)"<<endl; } @@ -62,6 +64,7 @@ int main(int argc, char **argv) auto autozafl=false; auto whitelistFile=string(); auto blacklistFile=string(); + auto bb_graph_optimize=false; set<string> exitpoints; srand(getpid()+time(NULL)); @@ -77,9 +80,11 @@ int main(int argc, char **argv) {"whitelist", required_argument, 0, 'w'}, {"blacklist", required_argument, 0, 'b'}, {"autozafl", no_argument, 0, 'a'}, + {"enable-bb-graph-optimization", no_argument, 0, 'g'}, + {"disable-bb-graph-optimization", no_argument, 0, 'G'}, {0,0,0,0} }; - const char* short_opts="e:E:w:sv?ha"; + const char* short_opts="e:E:w:sv?hagG"; while(true) { @@ -116,6 +121,12 @@ int main(int argc, char **argv) case 'a': autozafl=true; break; + case 'g': + bb_graph_optimize=true;; + break; + case 'G': + bb_graph_optimize=false; + break; default: break; } @@ -156,6 +167,7 @@ int main(int argc, char **argv) zafl_transform.setWhitelist(whitelistFile); if (blacklistFile.size()>0) zafl_transform.setBlacklist(blacklistFile); + zafl_transform.setBasicBlockOptimization(bb_graph_optimize); int success=zafl_transform.execute();