diff options
author | van Hauser <vh@thc.org> | 2024-07-01 08:57:38 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-01 08:57:38 +0200 |
commit | 53409530b369e560c7f6f37ead5a5db9e116efd0 (patch) | |
tree | 6449fa84e6b9e26849d298af881014b18f55dc0b | |
parent | 36db3428ab16156dd72196213d2a02a5eadaed11 (diff) | |
parent | 43014cd465eec8cc47eda041802001776dbb5dd5 (diff) | |
download | afl++-53409530b369e560c7f6f37ead5a5db9e116efd0.tar.gz |
Merge pull request #2141 from AFLplusplus/dev
push to stable
42 files changed, 7010 insertions, 156 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0042bf28..8b4dcb6d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,6 +34,7 @@ file in one the following folders: * [docs/](docs/) (this is where you can find most of our docs content) * [frida_mode/](frida_mode/) * [instrumentation/](instrumentation/) +* [nyx_mode/](nyx_mode/) * [qemu_mode/](qemu_mode/) * [unicorn_mode/](unicorn_mode/) diff --git a/GNUmakefile b/GNUmakefile index e79d3f83..9f862120 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -441,6 +441,14 @@ test_shm: @echo "[-] shmat seems not to be working, switching to mmap implementation" endif +ifeq "$(shell echo '$(HASH)include <zlib.h>@int main() {return 0; }' | tr @ '\n' | $(CC) $(CFLAGS) -Werror -x c - -lz -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + override SPECIAL_PERFORMANCE += -DHAVE_ZLIB + override LDFLAGS += -lz + $(info [+] ZLIB detected) +else + $(info [!] Warning: no ZLIB detected) +endif + .PHONY: test_python ifeq "$(PYTHON_OK)" "1" test_python: diff --git a/TODO.md b/TODO.md index b36269b4..81196339 100644 --- a/TODO.md +++ b/TODO.md @@ -2,7 +2,7 @@ ## Must - - fast restart of afl-fuzz if cmdline + target hash is the same + - ijon support? - check for null ptr for xml/curl/g_ string transform functions - hardened_usercopy=0 page_alloc.shuffle=0 - add value_profile but only enable after 15 minutes without finds diff --git a/custom_mutators/atnwalk/README.md b/custom_mutators/atnwalk/README.md index 730349a3..7dbe8ee5 100644 --- a/custom_mutators/atnwalk/README.md +++ b/custom_mutators/atnwalk/README.md @@ -13,7 +13,7 @@ Just type `make` to build `atnwalk.so`. **NOTE:** The commands below just demonstrate an example how running ATNwalk looks like and require a working [testbed](https://github.com/atnwalk/testbed) ```bash -# create the required a random seed first +# create the required random seed first mkdir -p ~/campaign/example/seeds cd ~/campaign/example/seeds head -c1 /dev/urandom | ~/atnwalk/build/javascript/bin/decode -wb > seed.decoded 2> seed.encoded diff --git a/custom_mutators/atnwalk/atnwalk.c b/custom_mutators/atnwalk/atnwalk.c index c3a2cd95..45ccc181 100644 --- a/custom_mutators/atnwalk/atnwalk.c +++ b/custom_mutators/atnwalk/atnwalk.c @@ -180,7 +180,8 @@ size_t fail_fatal(int fd_socket, uint8_t **out_buf) { if (fd_socket != -1) { close(fd_socket); } *out_buf = NULL; - return 0; + fprintf(stderr, "atnwalk.socket not found in current directory!\n"); + exit(-1); } diff --git a/custom_mutators/custom_send_tcp/Makefile b/custom_mutators/custom_send_tcp/Makefile new file mode 100644 index 00000000..8549ccad --- /dev/null +++ b/custom_mutators/custom_send_tcp/Makefile @@ -0,0 +1,7 @@ +all: custom_send_tcp.so + +custom_send_tcp.so: + $(CC) -Wno-unused-result -g -O3 -shared -fPIC -o custom_send_tcp.so -I../../include custom_send_tcp.c + +clean: + rm -f custom_send_tcp.so *.o *~ core diff --git a/custom_mutators/custom_send_tcp/README.md b/custom_mutators/custom_send_tcp/README.md new file mode 100644 index 00000000..7b4bb869 --- /dev/null +++ b/custom_mutators/custom_send_tcp/README.md @@ -0,0 +1,13 @@ +# Send testcases via TCP custom mutator + +This custom mutator sends the fuzzing testcases via TCP. + +`AFL_CUSTOM_MUTATOR_LATE_SEND` - MUST be set! +`CUSTOM_SEND_IP` - the IP address to send to (basically only 127.0.0.1 makes sense) +`CUSTOM_SEND_PORT` - the TCP port to send to +`CUSTOM_SEND_READ` - if the custom mutator should wait for a reply from the target + +Example: +``` +CUSTOM_SEND_IP=127.0.0.1 CUSTOM_SEND_PORT=8000 CUSTOM_SEND_READ=1 AFL_CUSTOM_MUTATOR_LATE_SEND=1 AFL_CUSTOM_MUTATOR_LIBRARY=custom_send_tcp.so ./afl-fuzz ... +``` diff --git a/custom_mutators/custom_send_tcp/custom_send_tcp.c b/custom_mutators/custom_send_tcp/custom_send_tcp.c new file mode 100644 index 00000000..53689ced --- /dev/null +++ b/custom_mutators/custom_send_tcp/custom_send_tcp.c @@ -0,0 +1,113 @@ +#include <time.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <arpa/inet.h> +#include <sys/select.h> + +#include "afl-fuzz.h" + +static int my_debug = 0; +static int my_read = 0; + +#define DEBUG(...) if (my_debug) printf(__VA_ARGS__) + +typedef struct tcp_send_mutator { + afl_state_t* afl; + struct sockaddr_in server_addr; +} tcp_send_mutator_t; + +void *afl_custom_init(afl_state_t* afl, uint32_t seed) { + const char* ip = getenv("CUSTOM_SEND_IP"); + const char* port = getenv("CUSTOM_SEND_PORT"); + + if (getenv("AFL_DEBUG")) my_debug = 1; + if (getenv("CUSTOM_SEND_READ")) my_read = 1; + + if (!ip || !port) { + fprintf(stderr, "You forgot to set CUSTOM_SEND_IP and/or CUSTOM_SEND_PORT\n"); + exit(1); + } + + tcp_send_mutator_t* mutator = calloc(1, sizeof(tcp_send_mutator_t)); + if (!mutator) { + fprintf(stderr, "Failed to allocate mutator struct\n"); + exit(1); + } + + mutator->afl = afl; + + bzero(&mutator->server_addr, sizeof(mutator->server_addr)); + mutator->server_addr.sin_family = AF_INET; + if (inet_pton(AF_INET, ip, &mutator->server_addr.sin_addr) <= 0) { + fprintf(stderr, "Could not convert target ip address!\n"); + exit(1); + } + mutator->server_addr.sin_port = htons(atoi(port)); + + printf("[+] Custom tcp send mutator setup ready to go!\n"); + + return mutator; +} + +int try_connect(tcp_send_mutator_t *mutator, int sock, int max_attempts) { + while (max_attempts > 0) { + if (connect(sock, (struct sockaddr*)&mutator->server_addr, sizeof(mutator->server_addr)) == 0) { + return 0; + } + + // Even with AFL_CUSTOM_LATE_SEND=1, there is a race between the + // application under test having started to listen for connections and + // afl_custom_fuzz_send being called. To address this race, we attempt + // to connect N times and sleep a short period of time in between + // connection attempts. + struct timespec t; + t.tv_sec = 0; + t.tv_nsec = 100; + nanosleep(&t, NULL); + --max_attempts; + } + return 1; +} + +void afl_custom_fuzz_send(tcp_send_mutator_t *mutator, uint8_t *buf, size_t buf_size) { + int sock = socket(AF_INET, SOCK_STREAM, 0); + + int written = 0; + if (sock >= 0 && try_connect(mutator, sock, 10000) == 0) { + DEBUG("connected, write()\n"); + written = write(sock, buf, buf_size); + } else { + DEBUG("socket() or connect() error: %d\n", errno); + } + + if (written < 0) { + DEBUG("write() error: %d\n", errno); + } else if (my_read) { + struct timeval timeout; + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + fd_set set; + FD_ZERO(&set); + FD_SET(sock, &set); + + int select_res = select(sock + 1, &set, NULL, NULL, &timeout); + if (select_res == -1) { + DEBUG("select() error: %d\n", errno); + } else if (select_res == 0) { + DEBUG("read() timeout!\n"); + } else { + uint8_t buf[64]; + (void)read(sock, buf, sizeof(buf)); + } + } + + close(sock); +} + +void afl_custom_deinit(tcp_send_mutator_t* mutator) { + free(mutator); +} diff --git a/custom_mutators/gramatron/json-c b/custom_mutators/gramatron/json-c -Subproject 11546bfd07a575c47416924cb98de3d33a4e642 +Subproject af8dd4a307e7b837f9fa2959549548ace4afe08 diff --git a/custom_mutators/grammar_mutator/GRAMMAR_VERSION b/custom_mutators/grammar_mutator/GRAMMAR_VERSION index 02119caf..eea76ba3 100644 --- a/custom_mutators/grammar_mutator/GRAMMAR_VERSION +++ b/custom_mutators/grammar_mutator/GRAMMAR_VERSION @@ -1 +1 @@ -95a6857 +05d8f53 diff --git a/custom_mutators/grammar_mutator/grammar_mutator b/custom_mutators/grammar_mutator/grammar_mutator -Subproject 95a685773e571620cb6e2788dbbdba333e1b9bf +Subproject 05d8f537f8d656f0754e7ad5dcc653c42cb4f8f diff --git a/custom_mutators/radamsa/libradamsa.c b/custom_mutators/radamsa/libradamsa.c index e6838752..1dcf91d8 100644 --- a/custom_mutators/radamsa/libradamsa.c +++ b/custom_mutators/radamsa/libradamsa.c @@ -3707,7 +3707,7 @@ typedef intptr_t wdiff; 1024 * 1024 * 8 /* static malloc'd heap size if used as a library */ #define FBITS 24 /* bits in fixnum, on the way to 24 and beyond */ #define FMAX \ - ((1 << FBITS) - 1) /* maximum fixnum (and most negative fixnum) \ + ((1U << FBITS) - 1) /* maximum fixnum (and most negative fixnum) \ */ #define MAXOBJ 0xffff /* max words in tuple including header */ #define MAXPAYL \ diff --git a/dictionaries/ruby.dict b/dictionaries/ruby.dict new file mode 100644 index 00000000..601b7363 --- /dev/null +++ b/dictionaries/ruby.dict @@ -0,0 +1,5713 @@ +! +!= +!~ +% +& +* +** ++ ++@ +- +-@ +/ +< +<< +<= +<=> +== +=== +=~ +> +>= +>> +APOP +ASCIIZ +AdditiveExpr +AndExpr +Array +BigDecimal +CSV +Call +CloseKey +Complex +CreateKey +CurrentContext +D +DEBUG +DEBUG= +DelegateClass +DeleteKey +DeleteValue +Digest +E +ESCDELAY +ESCDELAY= +EnumKey +EnumValue +EqualityExpr +Fail +FilterExpr +Float +FlushKey +FunctionCall +Hash +I +Integer +JSON +JobManager +LOG_MASK +LOG_UPTO +LocationPath +MultiplicativeExpr +NodeTest +OpenKey +OrExpr +PI +PathExpr +Pathname +PermaLink? +Predicate +PrimaryExpr +Proxy +QueryInfoKey +QueryValue +Raise +Rational +RelationalExpr +RelativeLocationPath +SP +SP_Z +SetValue +String +TABSIZE +TABSIZE= +URI +UnaryExpr +UnionExpr +Z +[] +[]= +^ +_PermaLink? +__callee__ +__dir__ +__drbref +__drburi +__evaluate__ +__exit__ +__getobj__ +__id__ +__method__ +__send__ +__setobj__ +__to_xpath_helper +__validate +_ac_arg_enable +_attrs +_check_ac_args +_dump +_getproperty +_httpdate +_id2ref +_invoke +_iso8601 +_jisx0301 +_load +_nodeType +_ns +_parse +_parse_date_if_needed +_prepare_run +_print +_racc_do_parse_c +_racc_do_parse_rb +_racc_do_reduce +_racc_evalact +_racc_init_sysvars +_racc_setup +_racc_yyparse_c +_racc_yyparse_rb +_report +_reverse +_rfc2822 +_rfc3339 +_rfc822 +_run_parallel +_run_suite +_run_suites +_set_default_values +_set_last_value +_setproperty +_setup_maker_element +_strptime +_tags +_to_string +_validate +_xmlschema +` +a +abbrev +abbreviate +abi +abort +abort_on_exception +abort_on_exception= +about +abs +abs2 +absolute +absolute? +absolute_name +absolute_path +ac_arg_disable +ac_arg_enable +ac_arg_with +accept +accept_blank_line +accept_block_quote +accept_charset +accept_charset= +accept_document +accept_encoding +accept_heading +accept_indented_paragraph +accept_language +accept_list_end +accept_list_item_end +accept_list_item_start +accept_list_start +accept_loop +accept_nonblock +accept_paragraph +accept_raw +accept_rule +accept_uri_http +accept_verbatim +access_log +acct +acos +acos! +acosh +acosh! +actions +activate +activate_dependencies +activated +activated? +active? +active_count +active_job? +active_jobs +active_jobs_exist? +active_process_controllers +add +add! +add? +add_alias +add_also_in +add_attribute +add_attributes +add_authenticator +add_bindir +add_bulk_threshold_option +add_c_enclosure +add_c_variables +add_cert +add_certid +add_certificate +add_chain_to +add_checksums +add_class +add_class_or_module +add_clear_sources_option +add_comment +add_common_option +add_constant +add_converter +add_crl +add_data +add_date +add_dependency +add_dependency_with_type +add_description +add_development_dependency +add_dictionary +add_element +add_entry +add_event_to_arry +add_extend +add_extends +add_extension +add_extension_modules +add_extra_args +add_field +add_file +add_file_digest +add_file_signed +add_file_simple +add_filter +add_footnote +add_found_dependencies +add_from +add_generator +add_handler +add_have_children_element +add_html +add_import +add_include +add_includes +add_install_update_options +add_introspection +add_key_option +add_label +add_line_numbers +add_listener +add_loader +add_local_remote_options +add_location +add_log_header +add_maker +add_method +add_method_documentation +add_method_list +add_module +add_module_alias +add_multicall +add_namespace +add_need_initialize_variable +add_nonce +add_observer +add_option +add_other_element +add_owners +add_padding +add_paragraph +add_parser_run_info +add_path +add_platform +add_platform_option +add_plural_form +add_prerelease_option +add_private_type +add_protocol +add_proxy_option +add_rakelib +add_recipient +add_require +add_response_handler +add_revoked +add_row +add_ruby_type +add_rubygems_trusted_certs +add_runtime_dependency +add_schedule +add_section +add_self_to_load_path +add_setup_hook +add_signer +add_source_option +add_spec +add_special +add_special_RDOCLINK +add_special_TIDYLINK +add_specific_extra_args +add_specs +add_status +add_tag +add_target +add_teardown_hook +add_text +add_text_tests +add_to +add_to_classes_or_modules +add_to_element_method +add_to_fetcher +add_token +add_token_listener +add_tokens +add_trace_func +add_unconverted_fields +add_update_sources_option +add_value +add_version_option +add_visitor_tests +add_word_pair +addch +addr +addr_mask +addr_port +address +addstr +adler +adler32 +adler32_combine +advise +afamily +after +after_setup +after_teardown +after_worker_down +after_worker_quit +ajd +alert +alert_error +alert_warning +algorithm +alias +alias_command +alias_extension +alias_map +alias_method +aliases +alien +align +alive? +all +all= +all? +all_classes +all_classes_and_modules +all_files +all_modules +all_names +all_spec_names +all_specs +all_symbols +all_waits +allocate +allow_addr? +allow_socket? +alt_name_or_x509_entry +alternate= +amjd +ancestors +ancestors_of +anchor +angle +annotate +any? +any_content +any_to_s +ap_name +api_endpoint +api_endpoints +api_key +api_keys +api_uri +apop? +app_script_text +append +append_data +append_features +application +application= +apply_offset +appname +approximate_recommendation +aref +aref_prefix +aref_to +arg +arg_names +arglists +args +arguments +argv +arity +array +array_attributes +as_href +as_json +as_string +ascend +ascii_compatible? +ascii_only? +asciicompat_encoding +asctime +asin +asin! +asinh +asinh! +ask +ask_for_password +ask_for_password_on_unix +ask_for_password_on_windows +ask_if_ok +ask_yes_no +asn1_flag +asn1_flag= +assemble_template +assert +assert_block +assert_contains_make_command +assert_empty +assert_equal +assert_headers_equal +assert_in_delta +assert_in_epsilon +assert_includes +assert_instance_of +assert_kind_of +assert_match +assert_nil +assert_no_match +assert_not_equal +assert_not_nil +assert_not_same +assert_not_send +assert_nothing_raised +assert_nothing_thrown +assert_operator +assert_output +assert_path_exists +assert_performance +assert_performance_constant +assert_performance_exponential +assert_performance_linear +assert_performance_power +assert_predicate +assert_raise +assert_raises +assert_respond_to +assert_same +assert_send +assert_silent +assert_throws +asset +asset_dirs +asset_rel_path +assign_names +assoc +at +at_exit +atan +atan! +atan2 +atan2! +atanh +atanh! +atime +atom_validate +attempt_rule +attlistdecl +attlistdecl? +attr +attr_accessor +attr_reader +attr_writer +attribute +attribute_manager +attribute_names +attribute_of +attributes +attributes= +attributes_of +attroff +attron +attrset +atype +audit +auth_capable? +auth_cram_md5 +auth_data= +auth_login +auth_method +auth_only +auth_plain +auth_tag +auth_tag= +auth_type +authenticate +authenticated? +author +author= +authors +authors= +auto_indent_mode +autoclose= +autoclose? +autoload +autoload? +autorequire +autorun +avail_in +avail_out +avail_out= +available_specs +available_tags +axe +b +back_trace_limit +backticks +backtrace +backtrace_filter +backtrace_locations +banner +base +base64 +base64_encode +base64digest +base64digest! +base_dir +base_label +base_name +base_uri +basename +basic +basic_auth +basic_encode +basic_quote_characters +basic_quote_characters= +basic_word_break_characters +basic_word_break_characters= +beep +before +before_running_rdoc +before_setup +before_teardown +begin +begin_adding +begin_transport +beginning_of_line? +begins? +begx +begy +bench +bench_exp +bench_linear +bench_performance_constant +bench_performance_exponential +bench_performance_linear +bench_range +benchmark +benchmark_suites +between? +bin_dir +bin_file +bin_for_find +bin_key +bin_path +binary +binary= +binary? +binary_mode +bind +bind_at_call +bind_function +binding +bindir +binmode +binmode= +binmode? +binread +binwrite +bit_set? +bitmap +bitmap_for +bkgd +bkgdset +blank_line +blinding_off! +blinding_on! +blksize +block +block_given? +block_length +block_output_synchronize +block_params +block_params= +block_scanf +blockdev? +blockquote +blocks +bm +bmbm +body +body= +body_exist? +body_permitted? +body_stream +body_stream= +bool +boolean +boolean_writer +both? +bottom +bound? +box +break +break? +break_on_newline +break_outmost_groups +break_points +breakable +breakables +broadcast +broadcast_list +bsearch +buf +buffer +bufferSize +bufferType +build +build2 +build_args +build_args= +build_eigenvectors +build_extensions +build_heading +build_index +build_indicies +build_info_dir +build_info_file +build_list +build_marshal_gemspecs +build_modern +build_modern_index +build_modern_indicies +build_paragraph +build_path_query +build_rake_in +build_verbatim +builtin_curves +bulk_threshold +bump +by_col +by_col! +by_col_or_row +by_col_or_row! +by_id +by_row +by_row! +bytes +bytes_read +bytesize +byteslice +c_class_variables +c_function +c_singleton_class_variables +ca_certs +ca_file +ca_path +cache +cache_dir +cache_file +cache_path +cache_update_path +cachesize= +calc_checksum +calc_indent +calculate +calculate_checksum +call +call2 +call2_async +call_async +call_hook +call_method +call_seq +callcc +caller +caller_locations +calls_super +calltype +calltype= +can_change_color? +can_parse +can_parse_by_name +cancel +canceled? +candidate +canonical +canonical_each +canonname +capabilities +capability +capable? +capable_auth_types +capable_cram_md5_auth? +capable_login_auth? +capable_plain_auth? +capable_starttls? +capitalize +capitalize! +caption +capture2 +capture2e +capture3 +capture_io +capture_subprocess_io +captures +cascade +casecmp +casefold? +cat +catch +cbreak +cbrt +cbrt! +cd +cdata +cdata? +cdatas +cdesc +cdiv +ceil +ceiling +center +cert +cert_chain +cert_path +cert_store +certid +certificate +certificates +certificates= +certificates_matching +certs +chain +chain= +challenge +challenge= +change_attribute +change_privilege +change_workspace +changed +changed? +changed_attribute_by_name +char_pos +character +character_limit +characters +chardev? +charpos +chars +charset +chdir +check +check_arity +check_auth_args +check_auth_continue +check_auth_method +check_auth_response +check_cert +check_chain +check_closed +check_continue +check_credentials_permissions +check_data +check_files +check_fragment +check_gems +check_generator +check_headers +check_host +check_insecure_method +check_inspect_key +check_key +check_modeline +check_modify +check_names +check_nonce +check_ns +check_opaque +check_password +check_path +check_port +check_private_key +check_query +check_registry +check_response +check_root +check_ruby_version +check_scheme +check_shift_log +check_signedness +check_sizeof +check_that_user_bin_dir_is_in_path +check_to +check_trust +check_typecode +check_until +check_user +check_userinfo +checkbox +checkbox_group +checksums +childNodes +child_name +children +chmod +chmod_R +chomp +chomp! +choose_from_list +chop +chop! +chown +chown_R +chr +chroot +chunk +chunked= +chunked? +cipher +cipher= +ciphers +ciphers= +civil +class +class_attributes +class_dir +class_document +class_eval +class_exec +class_file +class_method_list +class_methods +class_name +class_path +class_variable_defined? +class_variable_get +class_variable_set +class_variables +classes +classes_and_includes_and_extends_for +classes_and_modules +classes_hash +classes_or_modules +classify +clean_gems +clean_up +cleanpath +cleanup +clear +clear_actions +clear_comment +clear_comments +clear_default_specs +clear_exclude +clear_paths +clear_prerequisites +client_ca +client_cert +client_cert_cb +client_error? +client_thread +clobber_task_description +clobber_task_name +clone +close +close! +close_enabled? +close_on_empty_response +close_on_exec= +close_on_exec? +close_read +close_screen +close_write +closed? +closed_read? +closed_write? +clrtoeol +cmd +cmds +cmp +cmp_issuer +cmsg_is? +code +code_object +codepage +codepage= +codepoints +coerce +coerce_other +cofactor +col_sep +collapse +collect +collect! +collect2 +collect_attributes +collect_attrs +collect_concat +collect_first_comment +collect_method +collect_tasks +collect_tokens +color_content +color_pair +color_pairs +color_set +colors +cols +column +column_count +column_size +column_vector +column_vectors +columns +combination +comma_breakable +command +command= +command_names +command_processor +commands +comment +comment= +comment? +comment_location +comments +commercial +commit +common_options +compact +compact! +compact_specs +compare +compare_by_identity +compare_by_identity? +compare_file +compare_language +compare_stream +compatible? +compile +compile_error +compile_file +compile_option +compile_option= +complain +complete +complete_authentication +completer_quote_characters +completer_quote_characters= +completer_word_break_characters +completer_word_break_characters= +completion_append_character +completion_append_character= +completion_case_fold +completion_case_fold= +completion_proc +completion_proc= +component +component_ary +compress +compress_indicies +compute_key +concat +conf +config +config= +config_file +config_file_name +configuration +configuration= +configure_connection_for_https +configure_options +conflict +conflicting_dependencies +conflicts +conj +conjugate +connect +connect_address +connect_from +connect_internal +connect_nonblock +connect_to +connecting +connection_close? +connection_for +connection_keep_alive? +connections +consider_local? +consider_remote? +console +const_defined? +const_defined_in? +const_get +const_load +const_missing +const_set +const_warning +constant_aliases +constants +constants_hash +construct +consume +consume_rbuff +contains +contains_requirable_file? +content +content= +content_encoding +content_is_set? +content_length +content_length= +content_range +content_setup +content_type +content_type= +content_writer +contents +context +context= +contextAttributes +continue? +continue_entry_body +continue_timeout +continue_timeout= +continued_exception +conv +conv2value +conv_arg +convert +convert_attr_reader +convert_attrs +convert_fields +convert_flow +convert_html +convert_special +convert_specials +convert_string +convert_to_uri +converter= +converters +convertible_int +convpath +cooked +cooked! +cookie +cookies +copy +copy_entry +copy_file +copy_files +copy_internal +copy_nonce +copy_static +copy_stream +copy_string +coredump? +correct? +correct_for_windows_path +cos +cos! +cosh +cosh! +count +count_objects +count_observers +covector +cover? +coverage_level +coverage_level= +coverage_report +cp +cp_r +cpu +cram_md5_challenge +cram_md5_response +cram_secret +crc +crc32 +crc32_combine +crc_table +create +createCleanedTree +create_carried_function +create_carrier +create_cert +create_cert_email +create_cert_self_signed +create_document +create_entries +create_entry +create_ext +create_ext_from_array +create_ext_from_hash +create_ext_from_string +create_extension +create_from +create_guid +create_header +create_id +create_items +create_key +create_listeners +create_logfile +create_makefile +create_new_id +create_option_parser +create_rule +create_self_signed_cert +create_ssl_params +create_temp_function +create_tmpdir +create_value +created? +credentials +credentials_path +critical +critical= +critical? +crl +crl= +crls +crls= +crmode +cross_reference +crypt +css +cstime +csv_attr_reader +csv_integer_writer +csv_writer +ctime +ctrl_cmd +ctype +ctype= +current +current= +current_element +current_group +current_job +current_line +current_scope +current_section +current_server +curry +curs_set +curve_name +curx +cury +cut_off +cutime +cvs_url +cwd +cwday +cweek +cwyear +cycle +d +d_o_s +daemon +data +data= +data_type +datadir +date +date= +dateTime +date_writer +datetime_format +datetime_format= +day +day= +day_fraction +dclone +deafen +deal +debug +debug= +debug? +debug_level +debug_level= +debug_mode +debug_msg +debug_output= +debug_thread_info +decode +decode64 +decode_all +decode_content +decode_utf7 +decode_www_form +decode_www_form_component +decoded +decrypt +deep_clone +def_array_element +def_atom_persons +def_atom_text_construct +def_children_accessor +def_class +def_class_accessor +def_classed_element +def_classed_element_without_accessor +def_classed_elements +def_convert +def_corresponded_attr_reader +def_corresponded_attr_writer +def_csv_accessor +def_csv_element +def_delegator +def_delegators +def_e2message +def_element_class_accessor +def_elements_class_accessor +def_else_enc +def_erb_method +def_exception +def_extend_command +def_get_text_element +def_head_option +def_iconv_convert +def_inspector +def_instance_delegator +def_instance_delegators +def_method +def_module +def_notifier +def_option +def_other_element +def_other_element_without_accessor +def_post_proc +def_pre_proc +def_prog_mode +def_same_enc +def_single_delegator +def_single_delegators +def_system_command +def_tail_option +def_to_euc_jp_from_iso_2022_jp +def_to_euc_jp_from_shift_jis +def_to_euc_jp_from_utf_8 +def_to_iso_2022_jp_from_euc_jp +def_to_iso_8859_1_from_utf_8 +def_to_shift_jis_from_euc_jp +def_to_shift_jis_from_utf_8 +def_to_utf_8_from_euc_jp +def_to_utf_8_from_iso_8859_1 +def_to_utf_8_from_shift_jis +def_uconv_convert_if_can +def_yes_clean_other_accessor +def_yes_other_accessor +default +default= +default_acl +default_argc_limit +default_argv +default_bindir +default_cert_path +default_dir +default_event_sources +default_exec_format +default_executable +default_external +default_external= +default_gem? +default_id_conv +default_imap_port +default_imaps_port +default_internal +default_internal= +default_key_path +default_load_limit +default_ole_types +default_options +default_parser +default_parser= +default_path +default_pop3_port +default_pop3s_port +default_port +default_proc +default_proc= +default_record_separator +default_record_separator= +default_rubygems_dirs +default_safe_level +default_sources +default_specifications_dir +default_src_encoding +default_ssl_context +default_ssl_port +default_submission_port +default_system_path +default_system_path= +default_title= +default_tls_port +default_value +defaults +defaults_str +define +define_aliases +define_finalizer +define_head +define_method +define_module_function +define_singleton_method +define_tail +define_task +defined_class +defined_in? +definition +definition_lists +deflate +degree +del_jobs_status +del_status_line +delch +delegate +delete +delete! +delete? +delete_all +delete_at +delete_attribute +delete_element +delete_field +delete_if +delete_key +delete_legacy_args +delete_namespace +delete_observer +delete_observers +delete_passwd +delete_unless_alive +delete_value +delete_worker +deleted? +deleteln +denominator +dep +depend_rules +dependencies +dependencies_ok? +dependency +dependency_order +dependent_gems +dependent_specs +deprecate +depth +deq +dequote +desc +descend +descendant_or_self +description +description= +deserialize +dest_directory +dest_latest_specs_index +dest_prerelease_specs_index +dest_specs_index +destination_encoding +destination_encoding_name +det +det_e +detach +detached +detached= +detached? +detect +detect_encoding +detect_gemdeps +detect_implicit +determinant +determinant_bareiss +determinant_e +determine_time +dev +dev_major +dev_minor +development +development_dependencies +dfdxi +dh_compute_key +diagonal +diagonal? +diagonalize +died +diff +diff= +difference +digest +digest! +digest_algorithm +digest_length +digests +dir +dir_config +dir_stack +direct_ancestors +directory +directory? +dirname +dirs +dirs= +disable +disable_close +disable_default_gem_server +disable_ssl +disable_starttls +disable_tls +disasm +disassemble +disconnect +disconnected? +disconnecting +dispatch +dispid +display +display? +display_attributes +display_c_call +display_c_call? +display_class +display_error_message +display_method +display_name +display_names +display_page +display_page_list +display_prerequisites +display_process_id +display_process_id? +display_tasks_and_comments +display_thread_id +display_thread_id? +disposition +div +divide +divmod +dlload +dlopen +dlunwrap +dlwrap +dn +dn= +do_GET +do_HEAD +do_OPTIONS +do_POST +do_aliases +do_attrs +do_boot_defclass +do_classes +do_configuration +do_constants +do_define_class +do_define_class_under +do_define_module +do_define_module_under +do_finish +do_helo +do_includes +do_methods +do_missing +do_modules +do_not_reverse_lookup +do_not_reverse_lookup= +do_nothing +do_parse +do_reply +do_rpc +do_singleton_class +do_sort +do_start +do_struct_define_without_accessor +do_validate +do_validate= +do_write +doc +doc_dir +doc_root +doc_stats +doctor +doctype +doctype? +doctype_end +document +document_children +document_children= +document_order +document_self +document_self= +document_self_or_methods +document_to_str +documentation_page +documentation_search +documentation_source +documented? +domain +done +done? +done_adding +done_documenting +done_documenting= +done_installing +done_installing_hooks +dont_rename_initialize +dot_pat +dot_pat_str +double +double_fig +doupdate +downcase +downcase! +download +download_reporter +download_to_cache +downto +dowrite +drop +drop_while +dry_run +dsa_sign_asn1 +dsa_verify_asn1 +dst? +dummy? +dummy_makefile +dump +dump_call +dump_coder +dump_default_options +dump_ivars +dump_list +dump_response +dump_stream +dup +dynamic_width +dynamic_width_stty +dynamic_width_tput +e2mm_message +each +each2 +each_active_object +each_address +each_ancestor +each_attribute +each_byte +each_capitalized +each_capitalized_name +each_certificate +each_char +each_child +each_classmodule +each_codepoint +each_cons +each_const +each_constant +each_data +each_element +each_element_with_attribute +each_element_with_text +each_entry +each_extend +each_filename +each_header +each_include +each_index +each_installed_parser +each_installed_writer +each_key +each_line +each_localized_path +each_mail +each_method +each_name +each_name_of +each_object +each_option +each_pair +each_parent +each_prime +each_recursive +each_resource +each_response_header +each_section +each_slice +each_source +each_strongly_connected_component +each_strongly_connected_component_from +each_sublocale +each_value +each_with_index +each_with_object +each_with_something +echo +echo= +echo? +edit_path +egid +egid= +ehlo +eid +eigen +eigensystem +eigenvalue_matrix +eigenvalues +eigenvector_matrix +eigenvector_matrix_inv +eigenvectors +ele +element +element= +element_initialize_arguments? +element_name +elementdecl +elementdecl? +elements +elements_to_f +elements_to_i +elements_to_r +emacs_editing_mode +emacs_editing_mode? +email +email_to_name +emailbx +emit_coder +emphasis +empty +empty? +empty_content? +empty_marshal_checksum +empty_marshal_data +enable +enable_close +enable_config +enable_ssl +enable_starttls +enable_starttls_auto +enable_tls +enabled? +enc_key +enclose +enclosed? +enclosure_dependencies +encode +encode! +encode64 +encode_fallback +encode_multipart_form_data +encode_re +encode_str +encode_token +encode_utf7 +encode_with +encode_www_form +encode_www_form_component +encoded +encoding +encoding= +encoding_updated +encrypt +end +endElement +end_accepting +end_document +end_element +end_element? +end_mapping +end_prefix_mapping +end_seen? +end_sequence +end_stream +end_transport +end_with? +ended? +endgrent +endpwent +engines +england +enhance +enhance_with_matching_rule +enq +ensure_dependencies_met +ensure_dependency +ensure_gem_subdirectories +ensure_loadable_spec +ensure_required_ruby_version_met +ensure_required_rubygems_version_met +ensure_xml_content +entities +entity +entity? +entity_class +entity_expansion_count +entity_expansion_limit +entity_expansion_limit= +entity_expansion_text_limit +entity_expansion_text_limit= +entitydecl +entitydecl? +entries +entry_details +entry_versions +enum_for +env_shebang +env_table +environment +eod +eof +eof? +eos? +eql? +equal? +equality_relational_compare +erf +erfc +errno +error +error? +error_bytes +error_char +error_message +error_string +errors +errs +escape +escape8bit +escapeElement +escapeHTML +escape_element +escape_form +escape_html +escape_path +escape_re +escape_userpass +esmtp +esmtp? +euid +euid= +eval +eval_history +eval_history= +eval_input +evaluate +even? +event +event? +event_arg +event_interface +event_type +events +examine +exception +exception_class +exception_details +exchange +exclude +exclude_end? +exclusive +exec +exec_format +exec_if +executable +executable= +executable? +executable_real? +executables +executables= +execute +exist? +exists? +exit +exit! +exit_code +exit_value +exited? +exitstatus +exp +exp! +expand +expand_class +expand_environ +expand_hexstring +expand_name +expand_pair +expand_path +expand_ref_in +expand_tabs +expand_value +expanded_name +expect +expected +expire +expired? +expires +expires= +exponent +export +expr +expunge +ext +extend +extend_object +extend_table +extended +extends +extension +extension? +extension_build_error +extensions +extensions= +extern +external +external_aliases +external_encoding +external_id +extname +extra_args +extra_args= +extra_chain_cert +extra_rdoc_files +extra_rdoc_files= +extract +extract_call_seq +extract_comment +extract_files +extract_reference +facility +fail +failed +false +family +family_addrinfo +fast_generate +fastmode= +fatal +fatal? +fault +faultCode +faultString +fcntl +fdatasync +fdiv +feed +feed_info +feed_subtype +feed_type +feed_version +fetch +fetch_file +fetch_http +fetch_https +fetch_internal +fetch_path +fetch_server +fetch_size +fetch_spec +fetcher +fetcher= +fiddle? +field +field? +field_row? +field_size_limit +fields +file +file= +file? +file_create +file_dir +file_field +file_input? +file_list_string +file_name +file_output +file_path +file_stat +filename +filename_quote_characters +filename_quote_characters= +fileno +files +files= +files_hash +files_so_far +fill +fill_breakable +fill_rbuff +filter +filter= +filter_backtrace +filter_methods +final +finalize +find +find_alias_comment +find_all +find_all_by_name +find_all_satisfiers +find_all_template +find_ancestor_local_symbol +find_attr_comment +find_attribute +find_attribute_named +find_body +find_by_name +find_by_path +find_c_enclosure +find_class +find_class_comment +find_class_method_named +find_class_named +find_class_named_from +find_class_or_module +find_command +find_command_possibilities +find_const_comment +find_constant_named +find_data +find_enclosing_module_named +find_encoding +find_executable +find_external_alias +find_external_alias_named +find_file_named +find_files +find_files_for_gem +find_first_recursive +find_gem +find_gems_with_sources +find_header +find_home +find_in_cache +find_in_unresolved +find_in_unresolved_tree +find_inactive_by_path +find_include_file +find_index +find_instance_method_named +find_ivars +find_library +find_local_symbol +find_location +find_method +find_method_named +find_methods +find_modifiers +find_module_named +find_name +find_override_comment +find_pager_jruby +find_paths +find_proxy +find_rakefile_location +find_reverse_dependencies +find_runnable +find_spec +find_spec_by_name_and_version +find_store +find_symbol +find_symbol_module +find_system_command +find_text_page +find_type +find_unique +find_unresolved_default_spec +finger +finish +finish_page_dir +finish_resolve +finished +finished? +finite? +fips_mode= +first +first? +first_lineno +fit_error +fit_exponential +fit_linear +fit_power +fix +fix_basic_object_inheritance +fix_syck_default_key_in_requirements +fixed_encoding? +flags= +flash +flat_map +flatten +flatten! +flock +floor +flow +flunk +flush +flush_buffer +flush_left +flush_next_in +flush_next_out +flush_sessions +fnmatch +fnmatch? +following +following_node_of +footnotes +for +for_cache +for_current_gems +for_fd +for_files +for_matching_files +for_spec? +force +force_documentation +force_documentation= +force_encoding +force_output +force_quotes? +force_update +foreach +fork +form +form_data= +format +format= +format_date +format_datetime +format_executable +format_line_num +format_message +format_severity +format_text +format_time +format_trace_flags +formatted_program_filename +formatter +found +frac +fragment +fragment= +free +free= +freeze +frexp +friday? +friendly_path +from +from_hash +from_list +from_module +from_name +from_path +from_prime_division +from_specs +from_yaml +front +frozen? +fsync +ftype +fu_blksize +fu_default_blksize +fu_stream_blksize +fu_windows? +full_comment +full_gem_path +full_name +full_name= +full_old_name +full_spec +fully_documented? +fully_expanded_name +function +gamma +garbage_collect +gather_dependencies +gather_files +gcd +gcdlcm +gem +gem_dir +gem_file_list +gem_home +gem_original_require +gem_paths +gem_repository? +gem_spec +gemdirs +gems_dir +gems_to_install +gen_multicall +gen_relative_url +gen_sub_directories +gen_url +generate +generate_bin +generate_bin_script +generate_bin_symlink +generate_class +generate_class_files +generate_default_dirs +generate_event +generate_file_files +generate_index +generate_key +generate_key! +generate_line +generate_name +generate_page +generate_prime +generate_rdoc +generate_ri +generate_servlet_not_found +generate_servlet_root +generate_table_of_contents +generate_tag +generate_windows_script +generation_hook +generator +generator_descriptions +generator_for +generator_options +generic? +genspace +get +get2 +get_all_gem_names +get_all_gem_names_and_versions +get_attribute +get_attribute_ns +get_attributes +get_bool +get_byte +get_candidate_gems +get_class_or_module +get_class_specification +get_constant +get_constant_with_optional_parens +get_credentials +get_default_handler +get_definition +get_description +get_elements +get_fields +get_file_and_line_from_caller +get_first +get_gems_to_cleanup +get_group +get_hosts_path +get_included +get_initial_token +get_instance +get_key_string +get_line +get_listeners +get_metadata +get_methods +get_namespace +get_no_proxy_from_env +get_one_gem_name +get_one_optional_argument +get_option +get_passwd +get_path +get_platform_from_requirements +get_primary_gems +get_print +get_procs +get_proxy_from_env +get_renewer +get_resolv_info +get_response +get_screen_size +get_service_hook +get_sorted_module_list +get_svninfo +get_symbol_or_name +get_tagged_response +get_text +get_thread +get_tk +get_tk_until +get_tkread +get_valid_ip +get_value +get_version_from_requirements +getacl +getaddress +getaddress_orig +getaddresses +getaddrinfo +getbinaryfile +getbkgd +getbyte +getc +getch +getdir +getegid +geteuid +getgid +getgm +getgrent +getgrgid +getgrnam +gethostbyaddr +gethostbyname +gethostname +getlocal +getlogin +getmouse +getname +getnameinfo +getnames +getok +getopts +getpeereid +getpeername +getpgid +getpgrp +getpriority +getpty +getpwent +getpwnam +getpwuid +getquota +getquotaroot +getresource +getresources +getrlimit +gets +getservbyname +getservbyport +getservername +getsid +getsockname +getsockopt +getstr +getter +gettextfile +getuid +getutc +getwd +gid +gid= +github +glob +global_variables +gm +gmt? +gmt_offset +gmtime +gmtoff +grant_privilege +great_job +greeting +gregorian +gregorian? +gregorian_leap? +grep +group +group= +group_by +group_entries +group_queue +group_sub +groups +groups= +grpowned? +gsub +gsub! +guard_inspect_key +guess +guess_type +guess_type_if_need +guid +gunzip +gzip +gzip_to +h +handle +handle_arguments +handle_attr +handle_class_module +handle_constants +handle_directive +handle_ifdefs_in +handle_interrupt +handle_method +handle_options +handle_pipe +handle_rdoc_link +handle_singleton +handle_special_CROSSREF +handle_special_HARD_BREAK +handle_special_HYPERLINK +handle_special_RDOCLINK +handle_special_SUPPRESSED_CROSSREF +handle_special_TIDYLINK +handle_tab_width +handler +handler= +handlers +handles? +hard_break +hasChildNodes +hasOnlyOneChild +has_attributes? +has_chain? +has_colors? +has_elements? +has_expires? +has_key? +has_name? +has_next? +has_rdoc +has_rdoc= +has_rdoc? +has_text? +has_unit_tests? +has_value? +hash +hash? +hash_old +have_author? +have_children_elements +have_const +have_content? +have_framework +have_func +have_header +have_library +have_macro +have_option? +have_rakefile +have_rdoc_4_plus? +have_required_elements? +have_required_values? +have_run? +have_struct_member +have_type +have_var +have_xml_content? +head +head2 +header +header? +header_convert +header_converters +header_row? +headers +headers= +height= +helo +help +helpcontext +helpfile +helpstring +here? +hermitian? +hessenberg_to_real_schur +hex +hexdigest +hexdigest! +hexencode +hidden +hierarchical? +history_file +history_file= +hkey +hmac_md5 +home +home= +home_dir +home_workspace +homepage +hook +host +host= +hostname +hostname= +hour +hour= +href +href= +html +html_escape +html_list_name +html_name +html_tags +hton +http_date +http_default_port +http_error +http_header +http_header_extra +http_last_response +http_resp +http_url +http_version +http_write +httpd +httpdate +https? +https_default_port +hyperlink_all +hypot +i +i_suck_and_my_tests_are_order_dependent! +icon +icon= +iconv +id +id2name +ident +identical? +identity +idle +idle_done +idlok +if_current_indent_equal +if_modified_since +iflush +ignore +ignore_dependencies +ignore_eof +ignore_eof? +ignore_sigint +ignore_sigint? +ignore_unknown_element +ignore_unknown_element= +ignore_whitespace_nodes +ignored? +imag +image +image_button +image_height +image_size +image_size= +image_width +imaginary +img +implemented_ole_types +implicit +implicit_end +import +import_function +import_symbol +import_value +in6_addr +in_addr +in_background +in_files +in_namespace +in_path? +in_service? +in_transaction +in_transaction_wr +in_tt? +inactivate +inc +inch +include +include? +include_file +include_path +included +included_modules +includes +incompatible_argument_styles +incomplete_input? +increment_io +indent +indent_text +indentation +index +index_classes +index_in_parent +index_methods +index_pages +indices +indir +infinite? +infinite_length +infinity? +inflate +info +info? +inherit_convert_attr_reader +inherited +inherited_array_reader +inherited_base +inherited_hash_reader +inherited_reader +init +init_color +init_comments +init_converters +init_headers +init_pair +init_parsers +init_screen +init_separators +init_tags +init_with +init_with_ary +init_with_hash +initgroups +initial_start_RDF +initial_start_entry +initial_start_feed +initial_start_rss +initialize +initialize_copy +initialize_have_children_elements +initialize_http_header +initialize_methods_etc +initialize_pattern +initialize_query +initialize_regexp +initialize_tracer +initialize_variables +inject +inject_into_list +inline +inline_html? +inline_other? +inline_other_base64? +inline_other_text? +inline_other_xml? +inline_text? +inline_xhtml? +inner_product +ino +inplace_mode +inplace_mode= +input +input= +input? +ins +insch +insecure_method? +insert +insert_after +insert_before +insert_output +insert_text +insertln +inspect +inspect? +inspect_mode +inspect_mode= +inspect_sockaddr +inspect_value +install +install_accessor_base +install_acl +install_alias_method +install_class_name +install_date_element +install_default_gems +install_default_specs +install_dublin_core +install_element +install_executables +install_extend_commands +install_file +install_from_gemdeps +install_gem +install_gem_user +install_get_attribute +install_get_text_element +install_have_attribute_element +install_have_child_element +install_have_children_element +install_id_conv +install_image_favicon +install_image_item +install_indicies +install_into +install_lib +install_list +install_model +install_must_call_validator +install_ns +install_rdoc +install_siginfo_handler +install_specs +install_system_commands +install_taxo_topic +install_taxo_topics +install_text_element +install_update_defaults_str +installation_satisfies_dependency? +installed? +installed_docs +installed_gems +installed_specs +instance +instance_attributes +instance_delegate +instance_eval +instance_exec +instance_method +instance_method_list +instance_methods +instance_of? +instance_variable_defined? +instance_variable_get +instance_variable_set +instance_variables +instruction +instruction? +instructions +int +int_from_prime_division +integer +integer? +integer_writer +interactive +intern +internal_encoding +interrupt +intersection +inv +invalidate_memoized_attributes +inverse +invert +invert! +investigation +invkind +invoke +invoke_kind +invoke_service +invoke_service_command +invoke_task +invoke_thread +invoke_with_build_args +io +io? +ioctl +ioflush +ip +ip6_arpa +ip6_int +ip? +ip_address +ip_address_list +ip_pktinfo +ip_port +ip_unpack +ipv4? +ipv4_compat +ipv4_compat? +ipv4_loopback? +ipv4_mapped +ipv4_mapped? +ipv4_multicast? +ipv4_private? +ipv6? +ipv6_linklocal? +ipv6_loopback? +ipv6_mc_global? +ipv6_mc_linklocal? +ipv6_mc_nodelocal? +ipv6_mc_orglocal? +ipv6_mc_sitelocal? +ipv6_multicast? +ipv6_pktinfo +ipv6_pktinfo_addr +ipv6_pktinfo_ifindex +ipv6_sitelocal? +ipv6_to_ipv4 +ipv6_unique_local? +ipv6_unspecified? +ipv6_v4compat? +ipv6_v4mapped? +ipv6only! +irb +irb_abort +irb_at_exit +irb_context +irb_exit +irb_level +irb_load +irb_name +irb_path +irb_require +isEqual +is_a? +is_alias_for +is_version_1_2? +isatty +isdst +iseuc +isjis +iso8601 +issetugid +issjis +issuer +issuer= +issuer_certificate +issuer_certificate= +issuer_of +isutf8 +it +italy +item +items +iterator? +iv= +j +jacobian +jd +jisx0301 +jj +jobs +jobs_exist? +jobs_status +join +join_nowait +jruby? +json_creatable +json_creatable? +json_create +json_index +julian +julian? +julian_leap? +kconv +keep_alive +keep_alive? +keep_alive_timeout +keep_clean +keep_if +key +key= +key? +key_len= +key_path +keyname +keypad +keypad= +keys +keys_with_inspector +kill +kill_job +kind_of? +known_class? +known_classes +l +label +labels +lambda +lambda? +lang +last +lastBuildDate= +last_comment +last_description +last_error +last_error= +last_line +last_match +last_modified +last_request +last_response +last_response_code +last_update +last_update= +last_value +lastresp +latest_rubygems_version +latest_spec_for +latest_specs +latest_version? +latest_version_for +launch +launch_worker +lazy +lchmod +lchown +lcm +ld +ldexp +leap? +length +let +level +level= +level_notifier +level_notifier= +levenshtein_distance +lex +lgamma +lib_dirs_glob +lib_files +lib_path +library_name +libs +libyaml_version +license +license= +licenses +licenses= +limit +line +line_buffer +line_index +line_numbers +line_trace_all +line_trace_specify +line_width +lineno +lineno= +lines +linger +link +link_files +link_to +list +list_end_for +list_files_in_directory +list_index +list_item_from +list_item_start +list_known_classes +list_methods_matching +list_type +list_width +listen +listener +listener= +listeners +literalize +ljust +ln +ln_s +ln_sf +load +load_all +load_and_instantiate +load_api_keys +load_cache +load_call +load_cert +load_certificate +load_class +load_class_data +load_data +load_default_cert +load_default_key +load_default_options +load_defaults +load_documents +load_env_plugins +load_file +load_gemdeps +load_imports +load_key +load_method +load_methods_matching +load_mime_types +load_modules +load_options +load_page +load_path_insert_index +load_plugin_files +load_plugins +load_private_key +load_public_key +load_rakefile +load_rdoc +load_response +load_spec +load_specs +load_stream +load_variable_map +load_yaml +loaded_from +loaded_from= +loaded_specs +loader +loadpath +local +local? +local_address +local_host +local_name +local_name= +local_port +local_variables +locale +locale= +locale_charmap +localtime +location +location_of_caller +locations +lock +locked? +log +log! +log10 +log10! +log2 +log2! +log= +logger +logger= +logging +login +logo +logo= +logout +long +long_name +look_for_directives_in +lookup +lookup_in_scope +lookup_method +lookup_prerequisite +lookup_ring +lookup_ring_any +lookup_server +loop +lower +lower_triangular? +ls +lstat +lstrip +lstrip! +lsub +ludecomp +lup +lup_decomposition +lusolve +magnitude +mail +mailfrom +mails +main +main= +main_irb +main_loop +main_page +main_thread +main_type +major +major_version +make +make_affine! +make_command +make_compiler +make_destination_dirs +make_entry +make_expires +make_feed +make_link +make_message +make_my_diffs_pretty! +make_passwd +make_regexp +make_sources +make_start_tag +make_switch +make_symlink +make_temp_directories +make_thread_list +make_time +make_tuple +make_variable_map +make_xml_stylesheets +makedirs +maker +maker_target +makers +malloc +malloc_allocated_size +malloc_allocations +manage_owners +map +map! +map2 +map= +map_gems_to_specs +mark_version +markup +markup_code +marshal_dump +marshal_load +marshal_version +mask +mask! +mask= +mask_protected_sequences +match +match? +match_platform! +match_platform? +match_to +match_to_consume +matched +matched? +matched_size +matches? +matches_for_glob +matches_spec? +matching_specs +matching_word_pairs +math? +math_mode +math_mode= +max +max= +maxConnections +max_age +max_by +max_flag_count +max_flag_count= +max_size +maxgroups +maxgroups= +maxwidth +maxx +maxy +maybe_xml? +mday +mdtm +measure +media_subtype +member +member? +members +memberwise +merge +merge! +merge0 +merge_key +merge_options +merge_path +merged? +message +message_loop +meta +meta_vars +metadata +meth +method +methodCall +methodCall_document +methodName +methodResponse +methodResponse_document +method_added +method_defined? +method_document +method_file +method_id +method_list +method_missing +method_name +method_removed +method_type +method_undefined +methods +methods_by_type +methods_hash +methods_matching +mime_split +mime_type +min +min= +min_by +minimum +minmax +minmax_by +minor +minor_version +minute +minute= +missing_dependencies +mjd +mkcol +mkdir +mkdir_p +mkmf +mkpath +mktime +mktmpdir +mname +mode +models +modifiable +modifieer +modsort +module +module? +module_eval +module_exec +module_function +module_names +modules +modules_hash +modulo +mon +mon= +mon_check_owner +mon_enter +mon_enter_for_cond +mon_exit +mon_exit_for_cond +mon_initialize +mon_synchronize +mon_try_enter +monday? +month +month= +month_days +mount +mount_proc +mountpoint? +mouseinterval +mousemask +move +mri? +msg +msg2str +mtime +mtime= +mu_lock +mu_locked? +mu_pp +mu_pp_for_diff +mu_synchronize +mu_try_lock +mu_unlock +mul +mult +multicall +multicall2 +multicall2_async +multicall_async +multicall_fault +multipart? +multipart_form +multitask +must_C_version +must_be +must_be_close_to +must_be_empty +must_be_instance_of +must_be_kind_of +must_be_nil +must_be_same_as +must_be_silent +must_be_within_delta +must_be_within_epsilon +must_call_validators +must_equal +must_include +must_match +must_output +must_raise +must_respond_to +must_send +must_throw +mv +n_bytes +n_jobs +n_mails +name +name= +name_for_path +name_list +name_path +name_prefix +name_regexp +name_tuple +named_captures +names +namespace +namespace= +namespace_context +namespace_context= +namespace_of +namespace_uri +namespaces +namespaces= +namesplit +nan? +nary +native +nc +ndata +need_base64_encode? +need_initialize_variables +need_keeper? +need_parent? +need_source_encoding_update? +need_tar +need_tar_bz2 +need_tar_gz +need_zip +needed? +needs +nest +nesting +net_http +new +new2 +new3 +new_alias_name +new_comment +new_cond +new_default_spec +new_from_hash +new_from_uri +new_internet_message_io +new_name +new_ntoh +new_offset +new_ostruct_member +new_scope +new_seed +new_session +new_spec +new_start +new_test +new_toplevel +new_with +new_with_uri +new_with_value_if_need +newline +newobj +next +next! +next_current +next_day +next_element +next_month +next_sibling= +next_sibling_node +next_to +next_token +next_update +next_update= +next_values +next_wait +next_words_on_error +next_year +nil? +nkf +nl +nlink +nlsolve +nlst +nmake_found? +no_proxy? +nocbreak +nocrmode +nodeMustBe +nodeName +nodeType +nodeValue +node_type +nodelay= +nodoc +noecho +non_aliases +non_nil_attributes +non_options +none? +nonl +nonzero? +noop +noraw +norm +normal? +normalize +normalize! +normalize_comment +normalize_path +normalize_rss +normalize_searching_criteria +normalize_space +normalize_uri +normalize_yaml_input +normalized +normalized_file_list +not +not_after +not_after= +not_before +not_before= +not_found +not_need_to_call_setup_maker_variables +not_set_name +not_set_required_variables +notation +notationdecl +notationdecl? +notations +note +note_for +notes +notifiers +notify +notify? +notify_event +notify_observers +notwice +noutrefresh +now +nowrite +nowrite_flag +npn_protocol +npn_protocols +npn_select_cb +nread +ns_declarations +nsec +ntop +null +null? +num_files +num_waiting +number +numerator +obj +object +object_address_group +object_class +object_group +object_id +object_maker +oct +odd? +of +off +off_event +off_tags +offset +offset_vtbl +oflush +oid +oid= +ok? +ok_to_remove? +old_enc= +old_name +ole_activex_initialize +ole_classes +ole_free +ole_func_methods +ole_get_methods +ole_initialize +ole_method +ole_method_help +ole_methods +ole_obj_help +ole_put_methods +ole_query_interface +ole_reference_count +ole_respond_to? +ole_show_help +ole_type +ole_type_detail +ole_typelib +ole_types +ole_uninitialize +omit_headings_below +on +on_attr_charref +on_attr_charref_hex +on_attr_entityref +on_attr_value +on_attribute +on_cdata +on_chardata +on_charref +on_charref_hex +on_connect +on_curve? +on_default +on_entityref +on_error +on_etag +on_event +on_event_with_outargs +on_head +on_parallel_worker? +on_stag +on_stag_end +on_stag_end_empty +on_tags +on_tail +on_windows? +on_xmldecl_encoding +on_xmldecl_end +on_xmldecl_standalone +on_xmldecl_version +one? +ongoing_visibility= +only_signed +only_trusted +op_dir +opaque +opaque= +open +open! +open? +open_and_lock_file +open_logfile +open_message_stream +open_server +open_timeout +open_uri_or_path +open_uri_original_open +opendir +opened? +option_list +option_parser +optional? +options +options= +options_of +optname +ord +order +order! +ordering +ordering= +ordinal +orig_initialize +orig_name +orig_name= +original_dir +orthogonal? +os +os_code +other_elements +others_possible? +out +out_of_date? +out_of_line? +outdated +output +output= +output? +output_encoding +output_encoding= +output_flag_file +output_name +output_query_results +output_versions +outputdir +outs +owned? +owner +p +pack +pack_sockaddr_in +pack_sockaddr_un +package_dir +package_dir_path +package_files +package_name +packdw +packqw +padding= +page +page-ChangeLog +page-NEWS +page_dir +page_file +page_name +paging? +pair +pair_content +pair_number +para +paragraph +paragraph_limit +paragraphs +parallelize_me! +param +param_list +param_seq +parameters +params +params= +params_ok? +paranoid +parent +parent= +parent? +parent_file_name +parent_name +parse +parse! +parseMethodCall +parseMethodResponse +parse_alias +parse_arg +parse_args +parse_attr +parse_attr_accessor +parse_bind_options +parse_call_parameters +parse_class +parse_comment +parse_comment_tomdoc +parse_config +parse_config_lines +parse_constant +parse_content_type +parse_ctype +parse_dn +parse_dot_doc_file +parse_entries +parse_extend +parse_file +parse_files +parse_files_matching +parse_form_data +parse_header +parse_headers +parse_helper +parse_include +parse_int +parse_line +parse_make_command_line +parse_meta_attr +parse_meta_method +parse_method +parse_method_dummy +parse_method_or_yield_parameters +parse_method_parameters +parse_mode +parse_module +parse_name +parse_openssl +parse_pasv_ipv4_host +parse_pasv_ipv6_host +parse_pasv_port +parse_pi_content +parse_printf_format +parse_query +parse_qvalues +parse_range_header +parse_require +parse_rescue +parse_rfc2253 +parse_set_cookie +parse_set_cookies +parse_sig +parse_signature +parse_source +parse_statements +parse_stream +parse_struct_signature +parse_subtree +parse_symbol_arg +parse_symbol_in_arg +parse_task_string +parse_time +parse_top_level_statements +parse_types +parse_url +parse_visibility +parse_yield +parseable? +parser +parsers +partition +parts +pass +passed? +passive +passwd +password +password= +password_field +patch +path +path= +path_info +path_ok? +path_query +path_separator +path_warning +pathmap +pathmap_explode +pathmap_partial +pathmap_replace +paths +paths= +pattern +pbkdf2_hmac +pbkdf2_hmac_sha1 +peek +peek_read +peek_tk +peek_token +peek_values +peep +peer_cert +peer_cert_chain +peeraddr +peg_parse +pem_files_in +pending +pending_interrupt? +percent_doc +permanent_link= +permanent_link? +permutation +permutation? +permute +permute! +pfamily +phase +pi +pick_best! +pid +pipe +pipe? +pipeline +pipeline_r +pipeline_rw +pipeline_start +pipeline_w +pivots +pkcs5_keyivgen +plain +plain_html +platform +platform= +platforms +platforms= +plural_forms +point +point_conversion_form +point_conversion_form= +pointer +pointer= +polar +pop +pop_inspect_key +pop_token +pop_workspace +popd +popdir +popen +popen2 +popen2e +popen3 +popup_menu +port +port= +pos +pos= +position +positive_integer_writer +post +post2 +post_build +post_build_hooks +post_connection_check +post_form +post_install +post_install_hooks +post_install_message +post_match +post_process +post_processors +post_reset +post_reset_hooks +post_uninstall +post_uninstall_hooks +power +power! +pp +pp_hash +pp_object +ppid +ppx +pre_input_hook +pre_input_hook= +pre_install +pre_install_checks +pre_install_hooks +pre_match +pre_reset +pre_reset_hooks +pre_uninstall +pre_uninstall_hooks +preceding +preceding_node_of +precs +pred +predicate +predicate_to_string +preference +prefetch +prefix +prefix_of +prefixes +prepend +prepend_features +prepended +preprocess +prerelease +prerelease? +prerequisite_tasks +prerequisites +pretty +pretty_generate +pretty_inspect +pretty_name +pretty_new_name +pretty_old_name +pretty_print +pretty_print_cycle +pretty_print_inspect +pretty_print_instance_variables +prev_day +prev_month +prev_words_on_error +prev_year +previous= +previous_element +previous_period_end +previous_sibling= +previous_sibling_node +pride +primary +primary_server +prime? +prime_division +prime_fasttest? +primes +primes_so_far +primitive_convert +primitive_errinfo +print +print_alias +print_attribute +print_class +print_constant +print_dependencies +print_file +print_method +print_module +print_profile +print_rakefile_directory +print_usage +printf +printn +priority +priority= +private +private? +private_class_method +private_constant +private_decrypt +private_encrypt +private_instance_methods +private_key +private_key= +private_key? +private_method_defined? +private_methods +problem +proc +procdest +process +process_args +process_based_port +process_controller +process_directive +process_line +process_options +processingInstruction +processing_instruction +product +progid +progids +progname +program_name +progress +progress_reporter +proj_id +project +prompt +prompt_c +prompt_i +prompt_mode +prompt_mode= +prompt_n +prompt_s +prompting? +proper_subset? +proper_superset? +propfind +proppatch +protectable +protected +protected_instance_methods +protected_method_defined? +protected_methods +proto +protocol +provide +proxy +proxy2 +proxy2_async +proxy? +proxy_address +proxy_async +proxy_auth_get +proxy_basic_auth +proxy_class? +proxy_from_env +proxy_from_env? +proxy_pass +proxy_port +proxy_user +proxyaddr +proxyport +prune +psych_to_yaml +psych_yaml_as +ptr +ptr= +pubDate +pubDate= +pubid +public +public? +public_class_method +public_constant +public_decrypt +public_encrypt +public_instance_method +public_instance_methods +public_key +public_key= +public_key? +public_method +public_method_defined? +public_methods +public_send +puke +pull +pull_event +purpose= +push +push_inspect_key +push_workspace +pushd +pushdir +put +put_status +put_string +putback +putbinaryfile +putc +puts +puttextfile +pwd +qdval +qop +query +query= +query_string +quick +quick_gem +quick_spec +quiet +quiet= +quiet? +quit +quit_called +quit_workers +quo +quote +quote_char +quote_string +quoted +r +racc_accept +racc_e_pop +racc_next_state +racc_print_stacks +racc_print_states +racc_read_token +racc_reduce +racc_shift +racc_token2str +radio_button +radio_group +raise +raise_for_undefined_entity? +raise_if_conflicts +raised_exception +rake_check_options +rake_extension +rake_merge_option +rake_original_const_missing +rake_original_time_compare +rake_output_message +rake_require +rake_system +rakefile +rakefile_location +rand +random_bytes +random_iv +random_key +random_number +random_string +range +range= +range_length +rank +rank_e +rassoc +rationalize +raw +raw! +raw_cookie +raw_cookie2 +raw_data +raw_encoding +raw_header +raw_path +rb_files_in +rb_scan_args +rc +rc? +rcptto +rcptto_list +rdev +rdev_major +rdev_minor +rdoc +rdoc_dir +rdoc_files +rdoc_include +rdoc_installed? +rdoc_options +rdoc_options= +rdoc_target +rdoc_task_description +rdoc_task_name +rdoc_version +re_exchange +re_exchangeable? +re_sign +read +read_all +read_bin +read_binary +read_body +read_body_0 +read_cache +read_checksums +read_directive +read_documentation_modifiers +read_file +read_from_cmdline +read_i +read_multipart +read_nonblock +read_s +read_s_expand +read_smime +read_status_line +read_timeout +read_timeout= +read_type_class +read_with_substitution +readable? +readable_after_eof? +readable_real? +readagain_bytes +readbyte +readchar +readline +readlines +readlink +readpartial +ready +ready? +real +real? +real_file +real_load +realdirpath +realloc +really_verbose +realm +realpath +realtime +reason +reason_phrase +receive +receive_responses +received_nodoc +receiver +recipients +record_entity_expansion +record_location +record_response +record_separator +record_task_metadata +recover +rect +rectangular +recurse +recurse_proc +recv +recv_io +recv_nonblock +recv_response +recvfrom +recvfrom_nonblock +recvmsg +recvmsg_nonblock +redirect? +redirect_to_directory_uri +redirector +redisplay +reduce +reduce_to_hessenberg +reenable +ref +reference +references +refine +refresh +refresh_line +refute +refute_empty +refute_equal +refute_in_delta +refute_in_epsilon +refute_includes +refute_instance_of +refute_kind_of +refute_match +refute_nil +refute_operator +refute_path_exists +refute_predicate +refute_respond_to +refute_same +regexp +regist +regist_server +register +register_command +register_default_spec +register_empty +register_spec_type +register_uri +registered +registry +registry= +regular? +rehash +reject +reject! +relative? +relative_name +relative_path_from +release +reload +remainder +remote? +remote_address +remote_ip +remove +removeChild +removeWhitespacesAndComments +remove_all +remove_by_name +remove_cache_file +remove_callback +remove_callback_internal +remove_cdecl_callback +remove_class_variable +remove_coding_comment +remove_comment +remove_commented_out_lines +remove_const +remove_dir +remove_entry +remove_entry_secure +remove_executables +remove_file +remove_from_documentation? +remove_handler +remove_installed! +remove_instance_variable +remove_invisible +remove_method +remove_nodoc +remove_nodoc_children +remove_old_bin_files +remove_old_lib_files +remove_option +remove_owners +remove_private +remove_private_comment +remove_private_comments +remove_response_handler +remove_server +remove_siginfo_handler +remove_spec +remove_specs_unsatisfied_by +remove_stdcall_callback +remove_token_listener +remove_unparseable +remove_unresolved_default_spec +rename +render +render_template +renegotiation_cb +renew +reopen +reorganize +repair_command +repeated_combination +repeated_permutation +replace +replace! +replace_child +replace_with +replacement +replacement= +replicate +reply +reply_service +report +report_attributes +report_class_module +report_constants +report_methods +represent_map +represent_object +represent_scalar +represent_seq +req +request +request_body_permitted? +request_get +request_head +request_http_version +request_line +request_method +request_post +request_time +request_uri +requester +requests +require +require_path +require_path= +require_path_info? +require_paths +require_relative +required_attribute? +required_attributes +required_element? +required_prefix +required_ruby_version +required_ruby_version= +required_rubygems_version +required_rubygems_version= +required_uri +required_variable_names +required_variables_are_set? +requirement +requirements +requirements= +requirements_list +requires +rerdoc_task_description +rerdoc_task_name +res +reset +reset_nil_attributes_to_default +reset_prog_mode +resize +resizeterm +resolve +resolve_add +resolve_aliases +resolve_args +resolve_args_without_dependencies +resolve_class +resolve_current +resolve_for +resource +resource= +resources +respace +respond_to? +respond_to_missing? +response +response_body_permitted? +response_class +response_handlers +responses +rest +rest? +rest_size +restore +restsize +result +resume +retrbinary +retrlines +retry +return_format +return_headers? +return_type +return_type_detail +return_value +return_vtype +retval? +reverse +reverse! +reverse_each +revive +revive_hash +revoked +revoked= +rewind +rfc1123_date +rfc2822 +rfc3339 +rfc822 +ri_dir +ri_installed? +ri_paths +rid +rindex +rjust +rm +rm_f +rm_r +rm_rf +rmailbx +rmdir +rmtree +rname +root +root? +root_node +root_search +roots +rotate +rotate! +round +route_from +route_to +row +row_count +row_sep +row_size +row_vector +row_vectors +rows +rpartition +rsqrt +rss +rss_version +rstrip +rstrip! +rubinius? +ruby +ruby= +ruby? +ruby_code +ruby_engine +ruby_opts +ruby_opts_string +ruby_version +rubybin +rubyforge_project +rubygems_api_key +rubygems_api_key= +rubygems_api_request +rubygems_version +rule +run +run_code +run_config +run_once +run_test +run_tests +run_with_threads +runtime_dependencies +rw +safe_level +safe_ln +safe_unlink +same_attributes? +same_feed_type? +sample +sanitize +sanitize_path +sanitize_string +satisfied_by? +satisfies_requirement? +saturday? +save +save_cache +save_class +save_data +save_data_with_atomic_file_rename_strategy +save_data_with_fast_strategy +save_exception_mode +save_history +save_history= +save_limit +save_method +save_page +save_rounding_mode +say +scalar +scalar= +scan +scan_full +scan_make_command_lines +scan_until +scanf +scanner +scheme +scheme= +scheme_list +scope +scope= +scope_name +script_name +scrl +scroll +scrolling_list +scrollok +search +search_const +search_convpath +search_file +search_for_dependency +search_full +search_internal +search_record +search_servlet +search_string +searcher= +sec +sec= +sec_fraction +second +second= +second_fraction +section +section_contents +sections +secure +secure= +security_policy +see +seed +seed= +seek +seen +select +select! +select_tasks_to_show +select_trace_output +self +send +send_command +send_data +send_entity +send_gem +send_io +send_list_data +send_literal +send_mail +send_message +send_number_data +send_quoted_string +send_request +send_request_with_body +send_request_with_body_data +send_request_with_body_stream +send_string_data +send_symbol_data +send_time_data +sendcmd +sender +sendmail +sendmsg +sendmsg_nonblock +sent_size +separator +seplist +seq +seq= +sequence +serial +serial= +serve +server +server_cert +server_error? +server_name +servername_cb +service +session +session= +session_add +session_cache_mode +session_cache_mode= +session_cache_size +session_cache_size= +session_cache_stats +session_get_cb +session_id +session_id_context +session_new_cb +session_remove +session_remove_cb +session_reused? +set +set_arg_names +set_attributes +set_attrs +set_auth +set_backtrace +set_banner +set_callback +set_callback_internal +set_cdecl_callback +set_close_on_exec +set_component +set_content_type +set_ctypes +set_current_section +set_debug_output +set_default +set_default_handler +set_default_paths +set_default_values +set_dictionary +set_dn +set_element +set_encoding +set_eoutvar +set_error +set_extensions +set_filter +set_form +set_form_data +set_fragment +set_generator +set_get_line_procs +set_headers +set_host +set_last_thread +set_last_value +set_log +set_next_element +set_non_blocking +set_opaque +set_option +set_options +set_params +set_parent +set_parser +set_passwd +set_password +set_path +set_port +set_program_name +set_query +set_range +set_redirect +set_registry +set_scheme +set_scope +set_screen_size +set_service_hook +set_size +set_socket +set_stdcall_callback +set_summary_indent +set_summary_width +set_term_to_element +set_to +set_to_infinity! +set_trace +set_trace_func +set_typecode +set_user +set_userinfo +set_valid_ip +set_visibility_for +set_writer +set_xhtml_uri_as_default_uri +setacl +setbyte +setegid +seteuid +setgid +setgid? +setgrent +setpgid +setpgrp +setpos +setpriority +setproperty +setpwent +setquota +setregid +setresgid +setresuid +setreuid +setrgid +setrlimit +setruid +setscrreg +setsid +setsockopt +setter +setuid +setuid? +setup +setup_certificate +setup_elements +setup_generator +setup_image +setup_items +setup_maker +setup_maker_attributes +setup_maker_element +setup_maker_element_writer +setup_maker_elements +setup_next_element +setup_next_element_in_unknown_element +setup_options +setup_other_elements +setup_output_dir +setup_pager +setup_params +setup_scanner +setup_signer +setup_ssl_context +setup_textinput +setup_values +sev_threshold +sev_threshold= +sexp +sexp_raw +sfork +sh +sharing_detection +shebang +shell +shellescape +shelljoin +shellsplit +shellwords +shift +shift_log_age +shift_log_period +short +short_name +show_all +show_documentation +show_hash +show_help +show_lookup_failure +show_owners +show_rdoc_for_pattern +show_version +shuffle +shuffle! +shutdown +sid_available? +sigma +sign +sign_in +signal +signal_handle +signal_status +signaled? +signame +signature +signature_algorithm +signed_time +signed_value +signers +signing_key +signo +sin +sin! +single? +single_delegate +singleline_format +singleline_pp +singleton +singleton_class +singleton_classes +singleton_method_added +singleton_method_removed +singleton_method_undefined +singleton_methods +singular? +sinh +sinh! +site +site_dir +size +size= +size? +size_opt_params +size_params +sizeof +skip +skip_blanks? +skip_during +skip_for_variable +skip_lines +skip_method +skip_optional_do_after_expression +skip_tkspace +skip_tkspace_comment +skip_until +sleep +slice +slice! +slice_before +sn +snippet +soak_up_spaces +sock +sockaddr_in +sockaddr_un +socket? +socketpair +socktype +solve +sort +sort! +sort_by +sort_by! +sort_if_need +sort_internal +sort_obj +sort_options +sort_sections +sorted +sorted_requests +source +source_encoding +source_encoding_name +source_exception +source_file +source_for +source_location +source_ole_types +sources +sources= +spawn +spec +spec_authors +spec_dir +spec_dirs +spec_file +spec_for_dependency +spec_homepage +spec_license +spec_loaded_from +spec_name +spec_path +spec_platforms +spec_predecessors +spec_summary +spec_type +special +special_prefixes +special_prefixes= +specific? +specific_extra_args +specific_extra_args_hash +specification_version +specs +specs_in +split +split_all +split_header_value +split_into_flow +split_name +split_path +split_userinfo +sprintf +sqrt +sqrt! +square? +squeeze +squeeze! +srand +src +src_type +ssl? +ssl_ca_cert +ssl_params +ssl_socket +ssl_timeout +ssl_verify_mode +ssl_version +ssl_version= +sspi_auth +sspi_auth? +stand_alone? +standalone +standard_exception_handling +standard_rake_options +standend +standout +start +startElement +start_accepting +start_collecting_tokens +start_color +start_doc +start_document +start_element +start_element? +start_else_element +start_export +start_get_text_element +start_have_something_element +start_immediately +start_import +start_job +start_keeper +start_mapping +start_prefix_mapping +start_profile +start_sequence +start_server +start_service +start_stream +start_tls_session +start_watchdog +start_with? +started +started? +starting +starts_with +starttls +starttls? +starttls_always? +starttls_auto? +stat +state +static_path +stats +status +status= +status_line +status_message +status_string +status_type_char +stdinput +stdlog +stdout +stdout= +stdout_mutex +stdoutput +stdscr +step +sticky? +stime +stop +stop? +stop_doc +stop_profile +stop_service +stopped? +stopping +stopsig +storbinary +store +store= +store_for +store_internal +stores +storlines +stream= +stream_check +stream_end? +streaming? +stress +stress= +strftime +strict_decode64 +strict_encode64 +string +string= +string_length +string_value +strings +strip +strip! +strip_hashes +strip_newlines +strip_quotes +strip_stars +strong +strongly_connected_components +strptime +struct +style +su +sub +sub! +sub_ext +sub_type +subdomain_of? +subject +subject= +subject_certificate +subject_certificate= +subject_request +subject_request= +submit +subpad +subscribe +subsec +subset? +substring +substring_after +substring_before +subtract +subwin +succ +succ! +succeed +success? +suffix_pattern +suffixes +suggest_gems_from_name +sum +summarize +summary +summary= +summary_indent +summary_width +sunday? +super_each +superclass +superclass= +superclass_method +superset? +supply_default_content_type +supported? +suppressed? +suspend +suspend_context +suspend_input_method +suspend_name +suspend_workspace +swapcase +swapcase! +switch +switch_name +sym +symlink +symlink? +symlink_files +symmetric? +sync +sync= +sync_ex_count +sync_ex_locker +sync_exclusive? +sync_extend +sync_initialize +sync_inspect +sync_lock +sync_locked? +sync_mode +sync_point? +sync_sh_locker +sync_shared? +sync_synchronize +sync_try_lock +sync_try_lock_sub +sync_unlock +sync_upgrade_waiting +sync_waiting +synchronize +syncmode= +synthesize_file_task +sysaccept +syscall +sysclose +sysconfdir +sysopen +sysread +sysread_nonblock +sysseek +syssign +system +system_dir +system_path +system_path= +systmpdir +sysverify +syswrite +syswrite_nonblock +t +tab_width +table +table_of_contents +tag +tag_class +tag_directives +tag_end +tag_filter +tag_name +tag_name_with_prefix +tag_start +tagging +tagurize +taint +tainted? +take +take_while +tan +tan! +tanh +tanh! +tap +tar_bz2_file +tar_command +tar_dir_header +tar_file_header +tar_gz_file +target +task +task_defined? +tasks +tasks_in_scope +taxo_link +taxo_link= +tcp +tcp_server_loop +tcp_server_sockets +tcp_socket +teardown +tee +tell +telnetmode +telnetmode= +temp_dir +template +template_dir +template_dir_for +template_for +template_result +temporary_section +terminal +terminal_columns +terminal_width +terminate +terminate_interaction +terminate_job +terminated? +termsig +territory +test +test_accept_blank_line +test_accept_block_quote +test_accept_document +test_accept_heading +test_accept_heading_1 +test_accept_heading_2 +test_accept_heading_3 +test_accept_heading_4 +test_accept_heading_b +test_accept_heading_indent +test_accept_heading_suppressed_crossref +test_accept_list_end_bullet +test_accept_list_end_label +test_accept_list_end_lalpha +test_accept_list_end_note +test_accept_list_end_number +test_accept_list_end_ualpha +test_accept_list_item_end_bullet +test_accept_list_item_end_label +test_accept_list_item_end_lalpha +test_accept_list_item_end_note +test_accept_list_item_end_number +test_accept_list_item_end_ualpha +test_accept_list_item_start_bullet +test_accept_list_item_start_label +test_accept_list_item_start_lalpha +test_accept_list_item_start_note +test_accept_list_item_start_note_2 +test_accept_list_item_start_note_multi_description +test_accept_list_item_start_note_multi_label +test_accept_list_item_start_number +test_accept_list_item_start_ualpha +test_accept_list_start_bullet +test_accept_list_start_label +test_accept_list_start_lalpha +test_accept_list_start_note +test_accept_list_start_number +test_accept_list_start_ualpha +test_accept_paragraph +test_accept_paragraph_b +test_accept_paragraph_br +test_accept_paragraph_break +test_accept_paragraph_i +test_accept_paragraph_indent +test_accept_paragraph_plus +test_accept_paragraph_star +test_accept_paragraph_underscore +test_accept_paragraph_wrap +test_accept_raw +test_accept_rule +test_accept_rule_indent +test_accept_verbatim +test_accept_verbatim_big_indent +test_accept_verbatim_indent +test_attributes +test_end_accepting +test_file +test_file= +test_files +test_files= +test_list_nested +test_list_verbatim +test_order +test_start_accepting +text +text= +text? +text_field +text_type_writer +text_zero_one +textarea +textinput +texts +tgz_file +thread +thread_internal +thread_list +thread_list_all +thread_variable? +thread_variable_get +thread_variable_set +thread_variables +threads +throw +thursday? +time +time2wtime +time= +time_delta_string +time_format +timeout +timeout= +timeouts= +times +timestamp +title +title= +tls? +tlsconnect +tmp_dh_callback +tmpdir +to +to= +to_a +to_ary +to_atom +to_basic +to_bn +to_c +to_class_name +to_csv +to_d +to_date +to_datetime +to_der +to_digits +to_element_methods +to_enum +to_f +to_feed +to_feed_for_categories +to_h +to_hash +to_html +to_i +to_id +to_int +to_io +to_json +to_mailtext +to_name +to_obj +to_oct +to_p +to_path +to_pem +to_proc +to_ptr +to_r +to_range +to_rfc822text +to_rss +to_ruby +to_ruby_for_cache +to_run +to_s +to_set +to_sockaddr +to_spec +to_specs +to_str +to_string +to_sym +to_text +to_time +to_toc +to_uri +to_value +to_write_io +to_xml +to_yaml +to_yaml_properties +today +toeuc +tojis +token +token_listener +token_pos +token_stream +token_to_str +tokenize +tokens +tokens_to_s +tolocale +tomdoc? +top +top_level +top_level_tasks +top_level_test +toplevel_load +tosjis +total +total_bytes +total_in +total_out +total_time +touch +toutf16 +toutf32 +toutf8 +tr +tr! +tr_s +tr_s! +trace +trace_func +trace_on +trace_rule +trace_var +trackback_validate +transact +transaction +transfer +transform +translate +transport_request +transpose +trap +traverse +tree +tridiagonalize +true +truncate +truncate_output? +trust +trust= +trust_cert +trust_dir +trusted_certificates +try_activate +try_const +try_convert +try_lock +try_mon_enter +try_type +tsort +tsort_each +tsort_each_child +tsort_each_node +tt? +tt_sections +ttl +tty +tty? +tty_output= +tty_output? +tuesday? +tuples_for +tv_nsec +tv_sec +tv_usec +type +type2name +type= +type_params +typealias +typecode +typecode= +typekind +typelibs +types +u +udp +udp_server_loop +udp_server_loop_on +udp_server_recv +udp_server_sockets +ui +ui= +uid +uid= +uid_copy +uid_fetch +uid_search +uid_sort +uid_store +uid_thread +uidl +ultra_safe +umask +umount +unadvise +unalias_command +unbind +unbind_at_call +unconverted_fields? +undef_method +undef_system_command +undefine_finalizer +undoc_params +unescape +unescapeElement +unescapeHTML +unescape_element +unescape_form +unescape_html +unescape_value +unget +unget_tk +ungetbyte +ungetc +ungetch +ungetmouse +uninstall +uninstall_dep +uninstall_gem +uninstall_old_gemcutter +union +uniq +uniq! +unique_classes +unique_classes_and_modules +unique_id +unique_modules +unit +unitary? +unix +unix? +unix_path +unix_rights +unix_server_loop +unix_server_socket +unix_socket_abstract_name? +unknown +unlink +unlock +unmask_protected_sequences +unmatched_alias_lists +unmount +unnormalize +unnormalized +unpack +unpack_sockaddr_in +unpack_sockaddr_un +unpackdw +unpackqw +unparsed_uri +unregist +unregister_command +unresolved_deps +unscan +unshift +unsigned_value +unsubscribe +untaint +untrace_var +untrust +untrusted? +unused +unyank_gem +upcase +upcase! +update +update_aliases +update_cache? +update_checksum +update_content +update_display +update_extends +update_gem +update_gems +update_includes +update_index +update_output_dir +update_rubygems +update_sources +update_specs_index +update_status +updated +updated= +upgrade_to_class +upload +upload_files +upper +upper_bound +upper_bound= +upper_triangular? +upto +uptodate? +uri +uri_convert_attr_reader +uri_escaper +uri_option +uri_registered? +url_encode +urlsafe_base64 +urlsafe_decode64 +urlsafe_encode64 +usage +use_default_colors +use_loader +use_loader= +use_loader? +use_markup +use_paths +use_prefix +use_readline +use_readline= +use_readline? +use_registry +use_ssl= +use_ssl? +use_stdout +use_tracer +use_tracer= +use_tracer? +use_ui +usec +user +user= +user_agent +user_dir +user_home +userdb +userinfo +userinfo= +utc +utc? +utc_offset +util_build_gem +util_clear_gems +util_dir_entry +util_entry +util_gem +util_gzip +util_inst_bindir +util_installer +util_make_exec +util_make_gems +util_remove_gem +util_set_arch +util_setup_fake_fetcher +util_setup_gem +util_setup_spec_fetcher +util_spec +util_zip +utime +uuid +v +v_inv +v_nil +valid? +valid_civil? +valid_commercial? +valid_date? +valid_encoding? +valid_jd? +valid_ordinal? +valid_v6? +validate +validate_attribute +validate_data +validate_duplicate_links +validate_for_stream +validate_one_tag_name +validate_permissions +validate_sy_updatePeriod +validation_for_fit +value +value= +value? +values +values_at +variable_is_set? +variable_kind +variables +variables= +varkind +vartype +vc_windows? +ver +verb +verbose +verbose= +verbose? +verbose_capture_io +verbose_flag +verbosity +verify +verify_api_key +verify_callback +verify_callback= +verify_certificate_identity +verify_chain +verify_data +verify_depth +verify_files +verify_gem +verify_gem_file +verify_gem_home +verify_mode +verify_result +verify_root +verify_signatures +verify_signer +version +version= +version_1_2 +version_1_2? +versions +vi_editing_mode +vi_editing_mode? +viewer +virtual_host +visibility +visible? +visit +visit_Array +visit_BigDecimal +visit_Class +visit_Complex +visit_Date +visit_DateTime +visit_Exception +visit_FalseClass +visit_Float +visit_Hash +visit_Integer +visit_Module +visit_NilClass +visit_Object +visit_Psych_Nodes_Alias +visit_Psych_Nodes_Document +visit_Psych_Nodes_Mapping +visit_Psych_Nodes_Scalar +visit_Psych_Nodes_Sequence +visit_Psych_Nodes_Stream +visit_Psych_Omap +visit_Psych_Set +visit_Range +visit_Rational +visit_Regexp +visit_String +visit_Struct +visit_Symbol +visit_Time +visit_TrueClass +visit_array_subclass +voidcmd +w3cdtf +wait +wait2 +wait? +wait_all_jobs_execution +wait_for_child_process_to_exit +wait_for_continue +wait_readable +wait_to_finish_all_process_controllers +wait_until +wait_while +wait_writable +waitall +waitfor +waiting +waiting_job? +waiting_jobs +waiting_jobs_exist? +waitpid +waitpid2 +wakeup +warn +warn? +warning +wday +weakref_alive? +webcvs +wednesday? +weight +welcome +when_invoked +when_writing +which_to_update +whitespace +why_not_ok? +width +width= +win32_last_error +win32_last_error= +win_platform= +win_platform? +windows? +windows_stub_script +winsize +winsize= +with +with_config +with_defaults +with_index +with_object +with_response +with_verbose +wont_be +wont_be_close_to +wont_be_empty +wont_be_instance_of +wont_be_kind_of +wont_be_nil +wont_be_same_as +wont_be_within_delta +wont_be_within_epsilon +wont_equal +wont_include +wont_match +wont_respond_to +word_pair_map +wordy +workspace +workspace_home +workspaces +world_readable? +world_writable? +wrap +wrap_arg +wrap_args +wrap_result +wrappers +writable? +writable_real? +write +writeTo +write_bin +write_build_info_file +write_cache_file +write_cdata +write_comment +write_document +write_element +write_file +write_header +write_headers? +write_i +write_instruction +write_nonblock +write_options +write_s +write_service +write_smime +write_spec +write_style_sheet +write_text +write_with_substitution +writeencoding +writethis +written +wrong_type +wtime2time +xhtml +xhtml= +xlist +xml +xml= +xmlDecl +xml_content= +xml_decl +xml_getter +xml_setter +xml_stylesheet_pi +xml_stylesheets +xml_type? +xmldecl +xmldecl? +xmled_content +xmlschema +xmp +xpath +y +yaml +yaml_as +yaml_initialize +yaml_tag +yank_api_request +yank_gem +yday +year +year= +yes_clean_other_attr_reader +yes_clean_other_writer +yes_other_attr_reader +yes_other_writer +yield +yyaccept +yydebug +yydebug= +yyerrok +yyerror +yyparse +zero +zero? +zip +zip? +zip_command +zip_file +zlib_version +zone +zone_offset +zone_utc? +| +~ \ No newline at end of file diff --git a/docs/Changelog.md b/docs/Changelog.md index 1590b2df..d33d3121 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -4,11 +4,29 @@ release of the tool. See README.md for the general instruction manual. ### Version ++4.22a (dev) + - afl-fuzz: + - fastresume feature added. if you abort fuzzing and resume fuzzing + with `-i -` or `AFL_AUTORESUME=1` and the target binary has not changed + then a dump will be loaded and the calibration phase skipped. + to disable this feature set `AFL_NO_FASTRESUME=1` + zlib compression is used if zlib is found at compile time + - improved seed selection algorithm + - added `AFL_CUSTOM_MUTATOR_LATE_SEND=1` to call the custom send() + function after the target has been restarted. - frida_mode: - AFL_FRIDA_PERSISTENT_ADDR can now be be any reachable address not just a function entry - AFL_DEBUG is now the same as AFL_FRIDA_VERBOSE - AFL_FRIDA_DEBUG_MAPS now works as expected + - qemu_mode: + - new hooks supported (optional), see qemu_mode/hooking_bridge - thanks to + @CowBoy4mH3LL + - custom mutators: + - custom_send_tcp custom mutator added, thanks to @dergoegge + - afl-cc + - new runtime (!) variable: `AFL_OLD_FORKSERVER` to use the old vanilla + AFL type forkserver. Useful for symcc/symqemu/nautilus/etc. with + AFL_LLVM_INSTRUMENT=CLASSIC ### Version ++4.21c (release) diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index b7a7032f..3067ceab 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -198,6 +198,11 @@ def deinit(): # optional for Python This method can be used if you want to send data to the target yourself, e.g. via IPC. This replaces some usage of utils/afl_proxy but requires that you start the target with afl-fuzz. + + Setting `AFL_CUSTOM_MUTATOR_LATE_SEND` will call the afl_custom_fuzz_send() + function after the target has been restarted. (This is needed for e.g. TCP + services.) + Example: [custom_mutators/examples/custom_send.c](../custom_mutators/examples/custom_send.c) - `queue_new_entry` (optional): diff --git a/docs/env_variables.md b/docs/env_variables.md index 22e0ce0f..8c2d5848 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -331,7 +331,26 @@ mode. the target performs only a few loops, then this will give a small performance boost. -## 4) Settings for afl-fuzz +## 4) Runtime settings + +The following environment variables are for a compiled AFL++ target. + + - Setting `AFL_DUMP_MAP_SIZE` when executing the target directly will + dump the map size of the target and exit. + + - Setting `AFL_OLD_FORKSERVER` will use the old AFL vanilla forkserver. + This makes only sense when you + a) compile in a classic colliding coverage mode (e.g. + AFL_LLVM_INSTRUMENT=CLASSIC) or if the map size of the target is + below MAP_SIZE (65536 by default), AND + b) you want to use this compiled AFL++ target with a different tool + that expects vanilla AFL behaviour, e.g. symcc, symqemu, nautilus, etc. + You would use this option together with the target fuzzing application. + + - Setting `AFL_DISABLE_LLVM_INSTRUMENTATION` will disable collecting + instrumentation. (More of an internal option.) + +## 5) Settings for afl-fuzz The main fuzzer binary accepts several options that disable a couple of sanity checks or alter some of the more exotic semantics of the tool: @@ -368,6 +387,10 @@ checks or alter some of the more exotic semantics of the tool: XML or other highly flexible structured input. For details, see [custom_mutators.md](custom_mutators.md). + - Setting `AFL_CUSTOM_MUTATOR_LATE_SEND` will call the afl_custom_fuzz_send() + function after the target has been restarted. (This is needed for e.g. TCP + services.) + - Setting `AFL_CYCLE_SCHEDULES` will switch to a different schedule every time a cycle is finished. @@ -514,6 +537,8 @@ checks or alter some of the more exotic semantics of the tool: - `AFL_NO_SNAPSHOT` will advise afl-fuzz not to use the snapshot feature if the snapshot lkm is loaded. + - `AFL_NO_FASTRESUME` will not try to read or write a fast resume file. + - Setting `AFL_NO_UI` inhibits the UI altogether and just periodically prints some basic stats. This behavior is also automatically triggered when the output from afl-fuzz is redirected to a file or to a pipe. @@ -636,7 +661,7 @@ checks or alter some of the more exotic semantics of the tool: Note that will not be exact and with slow targets it can take seconds until there is a slice for the time test. -## 5) Settings for afl-qemu-trace +## 6) Settings for afl-qemu-trace The QEMU wrapper used to instrument binary-only code supports several settings: @@ -708,7 +733,7 @@ The QEMU wrapper used to instrument binary-only code supports several settings: crash is found. Setting `AFL_NO_CRASH_README` will prevent this. Useful when counting crashes based on a file count in that directory. -## 7) Settings for afl-frida-trace +## 8) Settings for afl-frida-trace The FRIDA wrapper used to instrument binary-only code supports many of the same options as `afl-qemu-trace`, but also has a number of additional advanced @@ -798,7 +823,7 @@ support. dump you must set a sufficient timeout (using `-t`) to avoid `afl-fuzz` killing the process whilst it is being dumped. -## 8) Settings for afl-cmin +## 9) Settings for afl-cmin The corpus minimization script offers very little customization: @@ -816,7 +841,7 @@ The corpus minimization script offers very little customization: - `AFL_PRINT_FILENAMES` prints each filename to stdout, as it gets processed. This can help when embedding `afl-cmin` or `afl-showmap` in other scripts. -## 9) Settings for afl-tmin +## 10) Settings for afl-tmin Virtually nothing to play with. Well, in QEMU mode (`-Q`), `AFL_PATH` will be searched for afl-qemu-trace. In addition to this, `TMPDIR` may be used if a @@ -827,12 +852,12 @@ to match when minimizing crashes. This will make minimization less useful, but may prevent the tool from "jumping" from one crashing condition to another in very buggy software. You probably want to combine it with the `-e` flag. -## 10) Settings for afl-analyze +## 11) Settings for afl-analyze You can set `AFL_ANALYZE_HEX` to get file offsets printed as hexadecimal instead of decimal. -## 11) Settings for libdislocator +## 12) Settings for libdislocator The library honors these environment variables: @@ -854,12 +879,12 @@ The library honors these environment variables: - `AFL_LD_VERBOSE` causes the library to output some diagnostic messages that may be useful for pinpointing the cause of any observed issues. -## 11) Settings for libtokencap +## 13) Settings for libtokencap This library accepts `AFL_TOKEN_FILE` to indicate the location to which the discovered tokens should be written. -## 12) Third-party variables set by afl-fuzz & other tools +## 14) Third-party variables set by afl-fuzz & other tools Several variables are not directly interpreted by afl-fuzz, but are set to optimal values if not already present in the environment: diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index e3e4e246..0f0e45d3 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -116,6 +116,10 @@ #include <TargetConditionals.h> #endif +#ifndef __has_builtin + #define __has_builtin(x) 0 +#endif + #undef LIST_FOREACH /* clashes with FreeBSD */ #include "list.h" #ifndef SIMPLE_FILES @@ -236,7 +240,6 @@ struct queue_entry { custom, /* Marker for custom mutators */ stats_mutated; /* stats: # of mutations performed */ - u8 *trace_mini; /* Trace bytes, if kept */ u32 tc_ref; /* Trace bytes ref count */ #ifdef INTROSPECTION @@ -246,13 +249,11 @@ struct queue_entry { double perf_score, /* performance score */ weight; - u8 *testcase_buf; /* The testcase buffer, if loaded. */ - - u8 *cmplog_colorinput; /* the result buf of colorization */ - struct tainted *taint; /* Taint information from CmpLog */ - - struct queue_entry *mother; /* queue entry this based on */ - + struct queue_entry *mother; /* queue entry this based on */ + u8 *trace_mini; /* Trace bytes, if kept */ + u8 *testcase_buf; /* The testcase buffer, if loaded. */ + u8 *cmplog_colorinput; /* the result buf of colorization */ + struct tainted *taint; /* Taint information from CmpLog */ struct skipdet_entry *skipdet_e; }; @@ -448,8 +449,9 @@ extern char *power_names[POWER_SCHEDULES_NUM]; typedef struct afl_env_vars { u8 afl_skip_cpufreq, afl_exit_when_done, afl_no_affinity, afl_skip_bin_check, - afl_dumb_forksrv, afl_import_first, afl_custom_mutator_only, afl_no_ui, - afl_force_ui, afl_i_dont_care_about_missing_crashes, afl_bench_just_one, + afl_dumb_forksrv, afl_import_first, afl_custom_mutator_only, + afl_custom_mutator_late_send, afl_no_ui, afl_force_ui, + afl_i_dont_care_about_missing_crashes, afl_bench_just_one, afl_bench_until_crash, afl_debug_child, afl_autoresume, afl_cal_fast, afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new, afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems, @@ -457,7 +459,7 @@ typedef struct afl_env_vars { afl_no_startup_calibration, afl_no_warn_instability, afl_post_process_keep_original, afl_crashing_seeds_as_new_crash, afl_final_sync, afl_ignore_seed_problems, afl_disable_redundant, - afl_sha1_filenames, afl_no_sync; + afl_sha1_filenames, afl_no_sync, afl_no_fastresume; u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload, diff --git a/include/envs.h b/include/envs.h index 45b080cb..3accbda0 100644 --- a/include/envs.h +++ b/include/envs.h @@ -24,23 +24,23 @@ static char *afl_environment_variables[] = { "AFL_DUMP_CYCLOMATIC_COMPLEXITY", "AFL_CMPLOG_MAX_LEN", "AFL_COMPCOV_LEVEL", "AFL_CRASH_EXITCODE", "AFL_CRASHING_SEEDS_AS_NEW_CRASH", "AFL_CUSTOM_MUTATOR_LIBRARY", "AFL_CUSTOM_MUTATOR_ONLY", - "AFL_CUSTOM_INFO_PROGRAM", "AFL_CUSTOM_INFO_PROGRAM_ARGV", - "AFL_CUSTOM_INFO_PROGRAM_INPUT", "AFL_CUSTOM_INFO_OUT", "AFL_CXX", - "AFL_CYCLE_SCHEDULES", "AFL_DEBUG", "AFL_DEBUG_CHILD", "AFL_DEBUG_GDB", - "AFL_DEBUG_UNICORN", "AFL_DISABLE_REDUNDANT", "AFL_NO_REDUNDANT", - "AFL_DISABLE_TRIM", "AFL_NO_TRIM", "AFL_DISABLE_LLVM_INSTRUMENTATION", - "AFL_DONT_OPTIMIZE", "AFL_DRIVER_STDERR_DUPLICATE_FILENAME", - "AFL_DUMB_FORKSRV", "AFL_EARLY_FORKSERVER", "AFL_ENTRYPOINT", - "AFL_EXIT_WHEN_DONE", "AFL_EXIT_ON_TIME", "AFL_EXIT_ON_SEED_ISSUES", - "AFL_FAST_CAL", "AFL_FINAL_SYNC", "AFL_FORCE_UI", "AFL_FRIDA_DEBUG_MAPS", + "AFL_CUSTOM_MUTATOR_LATE_SEND", "AFL_CUSTOM_INFO_PROGRAM", + "AFL_CUSTOM_INFO_PROGRAM_ARGV", "AFL_CUSTOM_INFO_PROGRAM_INPUT", + "AFL_CUSTOM_INFO_OUT", "AFL_CXX", "AFL_CYCLE_SCHEDULES", "AFL_DEBUG", + "AFL_DEBUG_CHILD", "AFL_DEBUG_GDB", "AFL_DEBUG_UNICORN", + "AFL_DISABLE_REDUNDANT", "AFL_NO_REDUNDANT", "AFL_DISABLE_TRIM", + "AFL_NO_TRIM", "AFL_DISABLE_LLVM_INSTRUMENTATION", "AFL_DONT_OPTIMIZE", + "AFL_DRIVER_STDERR_DUPLICATE_FILENAME", "AFL_DUMB_FORKSRV", + "AFL_EARLY_FORKSERVER", "AFL_ENTRYPOINT", "AFL_EXIT_WHEN_DONE", + "AFL_EXIT_ON_TIME", "AFL_EXIT_ON_SEED_ISSUES", "AFL_FAST_CAL", + "AFL_FINAL_SYNC", "AFL_FORCE_UI", "AFL_FRIDA_DEBUG_MAPS", "AFL_FRIDA_DRIVER_NO_HOOK", "AFL_FRIDA_EXCLUDE_RANGES", "AFL_FRIDA_INST_CACHE_SIZE", "AFL_FRIDA_INST_COVERAGE_ABSOLUTE", "AFL_FRIDA_INST_COVERAGE_FILE", "AFL_FRIDA_INST_DEBUG_FILE", "AFL_FRIDA_INST_INSN", "AFL_FRIDA_INST_JIT", "AFL_FRIDA_INST_NO_CACHE", "AFL_FRIDA_INST_NO_DYNAMIC_LOAD", "AFL_FRIDA_INST_NO_OPTIMIZE", "AFL_FRIDA_INST_NO_PREFETCH", "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH", - "AFL_FRIDA_INST_NO_SUPPRESS" - "AFL_FRIDA_INST_RANGES", + "AFL_FRIDA_INST_NO_SUPPRESS", "AFL_FRIDA_INST_RANGES", "AFL_FRIDA_INST_REGS_FILE", "AFL_FRIDA_INST_SEED", "AFL_FRIDA_INST_TRACE", "AFL_FRIDA_INST_TRACE_UNIQUE", "AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE", "AFL_FRIDA_JS_SCRIPT", "AFL_FRIDA_OUTPUT_STDOUT", "AFL_FRIDA_OUTPUT_STDERR", @@ -49,7 +49,7 @@ static char *afl_environment_variables[] = { "AFL_FRIDA_PERSISTENT_RET", "AFL_FRIDA_STALKER_ADJACENT_BLOCKS", "AFL_FRIDA_STALKER_IC_ENTRIES", "AFL_FRIDA_STALKER_NO_BACKPATCH", "AFL_FRIDA_STATS_FILE", "AFL_FRIDA_STATS_INTERVAL", "AFL_FRIDA_TRACEABLE", - "AFL_FRIDA_VERBOSE", + "AFL_FRIDA_VERBOSE", "AFL_OLD_FORKSERVER", "AFL_FUZZER_ARGS", // oss-fuzz "AFL_FUZZER_STATS_UPDATE_INTERVAL", "AFL_GDB", "AFL_GCC_ALLOWLIST", "AFL_GCC_DENYLIST", "AFL_GCC_BLOCKLIST", "AFL_GCC_INSTRUMENT_FILE", @@ -115,7 +115,8 @@ static char *afl_environment_variables[] = { "AFL_TRACE_PC", "AFL_USE_ASAN", "AFL_USE_MSAN", "AFL_USE_TRACE_PC", "AFL_USE_UBSAN", "AFL_USE_TSAN", "AFL_USE_CFISAN", "AFL_USE_LSAN", "AFL_WINE_PATH", "AFL_NO_SNAPSHOT", "AFL_EXPAND_HAVOC_NOW", "AFL_USE_FASAN", - "AFL_USE_QASAN", "AFL_PRINT_FILENAMES", "AFL_PIZZA_MODE", NULL + "AFL_USE_QASAN", "AFL_PRINT_FILENAMES", "AFL_PIZZA_MODE", + "AFL_NO_FASTRESUME", NULL }; diff --git a/include/forkserver.h b/include/forkserver.h index 593e34a2..6c649528 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -206,6 +206,15 @@ typedef struct afl_forkserver { s32 nyx_log_fd; #endif +#ifdef __AFL_CODE_COVERAGE + u8 *persistent_trace_bits; /* Persistent copy of bitmap */ +#endif + + void *custom_data_ptr; + u8 *custom_input; + u32 custom_input_len; + void (*late_send)(void *, const u8 *, size_t); + } afl_forkserver_t; typedef enum fsrv_run_result { diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index a09f28a9..63ea71c1 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -214,8 +214,12 @@ class ModuleSanitizerCoverageLTO void SetNoSanitizeMetadata(Instruction *I) { +#if LLVM_VERSION_MAJOR >= 19 + I->setNoSanitizeMetadata(); +#else I->setMetadata(I->getModule()->getMDKindID("nosanitize"), MDNode::get(*C, None)); +#endif } @@ -225,7 +229,7 @@ class ModuleSanitizerCoverageLTO FunctionCallee SanCovTracePCIndir; FunctionCallee SanCovTracePC /*, SanCovTracePCGuard*/; Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy, - *Int16Ty, *Int8Ty, *Int8PtrTy, *Int1Ty, *Int1PtrTy; + *Int16Ty, *Int8Ty, *Int8PtrTy, *Int1Ty, *Int1PtrTy, *PtrTy; Module *CurModule; std::string CurModuleUniqueId; Triple TargetTriple; @@ -416,6 +420,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule( Int16Ty = IRB.getInt16Ty(); Int8Ty = IRB.getInt8Ty(); Int1Ty = IRB.getInt1Ty(); + PtrTy = PointerType::getUnqual(*C); /* AFL++ START */ char *ptr; @@ -1350,7 +1355,7 @@ void ModuleSanitizerCoverageLTO::instrumentFunction( Function &F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) { if (F.empty()) return; - if (F.getName().find(".module_ctor") != std::string::npos) + if (F.getName().contains(".module_ctor")) return; // Should not instrument sanitizer init functions. #if LLVM_VERSION_MAJOR >= 18 if (F.getName().starts_with("__sanitizer_")) @@ -1372,6 +1377,10 @@ void ModuleSanitizerCoverageLTO::instrumentFunction( if (F.hasPersonalityFn() && isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) return; + if (F.hasFnAttribute(Attribute::NoSanitizeCoverage)) return; +#if LLVM_VERSION_MAJOR >= 19 + if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation)) return; +#endif // if (Allowlist && !Allowlist->inSection("coverage", "fun", F.getName())) // return; // if (Blocklist && Blocklist->inSection("coverage", "fun", F.getName())) @@ -2023,16 +2032,20 @@ GlobalVariable *ModuleSanitizerCoverageLTO::CreatePCArray( if (&F.getEntryBlock() == AllBlocks[i]) { - PCs.push_back((Constant *)IRB.CreatePointerCast(&F, IntptrPtrTy)); - PCs.push_back((Constant *)IRB.CreateIntToPtr( - ConstantInt::get(IntptrTy, 1), IntptrPtrTy)); + PCs.push_back((Constant *)IRB.CreatePointerCast(&F, PtrTy)); + PCs.push_back( + (Constant *)IRB.CreateIntToPtr(ConstantInt::get(IntptrTy, 1), PtrTy)); } else { PCs.push_back((Constant *)IRB.CreatePointerCast( - BlockAddress::get(AllBlocks[i]), IntptrPtrTy)); - PCs.push_back((Constant *)IRB.CreateIntToPtr( - ConstantInt::get(IntptrTy, 0), IntptrPtrTy)); + BlockAddress::get(AllBlocks[i]), PtrTy)); +#if LLVM_VERSION_MAJOR >= 16 + PCs.push_back(Constant::getNullValue(PtrTy)); +#else + PCs.push_back( + (Constant *)IRB.CreateIntToPtr(ConstantInt::get(IntptrTy, 0), PtrTy)); +#endif } diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index 01881f28..49fe904b 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -161,7 +161,9 @@ class ModuleSanitizerCoverageAFL void SetNoSanitizeMetadata(Instruction *I) { -#if LLVM_VERSION_MAJOR >= 16 +#if LLVM_VERSION_MAJOR >= 19 + I->setNoSanitizeMetadata(); +#elif LLVM_VERSION_MAJOR >= 16 I->setMetadata(LLVMContext::MD_nosanitize, MDNode::get(*C, std::nullopt)); #else I->setMetadata(I->getModule()->getMDKindID("nosanitize"), @@ -179,7 +181,7 @@ class ModuleSanitizerCoverageAFL FunctionCallee SanCovTraceSwitchFunction; GlobalVariable *SanCovLowestStack; Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy, - *Int16Ty, *Int8Ty, *Int8PtrTy, *Int1Ty, *Int1PtrTy; + *Int16Ty, *Int8Ty, *Int8PtrTy, *Int1Ty, *Int1PtrTy, *PtrTy; Module *CurModule; std::string CurModuleUniqueId; Triple TargetTriple; @@ -272,13 +274,19 @@ std::pair<Value *, Value *> ModuleSanitizerCoverageAFL::CreateSecStartEnd( if (!TargetTriple.isOSBinFormatCOFF()) return std::make_pair(SecStart, SecEnd); - // Account for the fact that on windows-msvc __start_* symbols actually - // point to a uint64_t before the start of the array. + // Account for the fact that on windows-msvc __start_* symbols actually + // point to a uint64_t before the start of the array. +#if LLVM_VERSION_MAJOR >= 19 + auto GEP = + IRB.CreatePtrAdd(SecStart, ConstantInt::get(IntptrTy, sizeof(uint64_t))); + return std::make_pair(GEP, SecEnd); +#else auto SecStartI8Ptr = IRB.CreatePointerCast(SecStart, Int8PtrTy); auto GEP = IRB.CreateGEP(Int8Ty, SecStartI8Ptr, ConstantInt::get(IntptrTy, sizeof(uint64_t))); return std::make_pair(IRB.CreatePointerCast(GEP, PointerType::getUnqual(Ty)), SecEnd); +#endif } @@ -370,6 +378,7 @@ bool ModuleSanitizerCoverageAFL::instrumentModule( Int16Ty = IRB.getInt16Ty(); Int8Ty = IRB.getInt8Ty(); Int1Ty = IRB.getInt1Ty(); + PtrTy = PointerType::getUnqual(*C); LLVMContext &Ctx = M.getContext(); AFLMapPtr = @@ -572,7 +581,8 @@ void ModuleSanitizerCoverageAFL::instrumentFunction( if (F.empty()) return; if (!isInInstrumentList(&F, FMNAME)) return; - if (F.getName().find(".module_ctor") != std::string::npos) + // if (F.getName().find(".module_ctor") != std::string::npos) + if (F.getName().contains(".module_ctor")) return; // Should not instrument sanitizer init functions. #if LLVM_VERSION_MAJOR >= 18 if (F.getName().starts_with("__sanitizer_")) @@ -595,6 +605,9 @@ void ModuleSanitizerCoverageAFL::instrumentFunction( isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) return; if (F.hasFnAttribute(Attribute::NoSanitizeCoverage)) return; +#if LLVM_VERSION_MAJOR >= 19 + if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation)) return; +#endif if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge) SplitAllCriticalEdges( F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests()); @@ -692,16 +705,16 @@ GlobalVariable *ModuleSanitizerCoverageAFL::CreatePCArray( if (&F.getEntryBlock() == AllBlocks[i]) { - PCs.push_back((Constant *)IRB.CreatePointerCast(&F, IntptrPtrTy)); - PCs.push_back((Constant *)IRB.CreateIntToPtr( - ConstantInt::get(IntptrTy, 1), IntptrPtrTy)); + PCs.push_back((Constant *)IRB.CreatePointerCast(&F, PtrTy)); + PCs.push_back( + (Constant *)IRB.CreateIntToPtr(ConstantInt::get(IntptrTy, 1), PtrTy)); } else { PCs.push_back((Constant *)IRB.CreatePointerCast( - BlockAddress::get(AllBlocks[i]), IntptrPtrTy)); + BlockAddress::get(AllBlocks[i]), PtrTy)); #if LLVM_VERSION_MAJOR >= 16 - PCs.push_back(Constant::getNullValue(IntptrPtrTy)); + PCs.push_back(Constant::getNullValue(PtrTy)); #else PCs.push_back((Constant *)IRB.CreateIntToPtr( ConstantInt::get(IntptrTy, 0), IntptrPtrTy)); @@ -711,10 +724,10 @@ GlobalVariable *ModuleSanitizerCoverageAFL::CreatePCArray( } - auto *PCArray = CreateFunctionLocalArrayInSection(N * 2, F, IntptrPtrTy, - SanCovPCsSectionName); + auto *PCArray = + CreateFunctionLocalArrayInSection(N * 2, F, PtrTy, SanCovPCsSectionName); PCArray->setInitializer( - ConstantArray::get(ArrayType::get(IntptrPtrTy, N * 2), PCs)); + ConstantArray::get(ArrayType::get(PtrTy, N * 2), PCs)); PCArray->setConstant(true); return PCArray; @@ -822,7 +835,12 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage( StringRef FuncName = Callee->getName(); if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue; +#if LLVM_VERSION_MAJOR >= 20 + // test canary + InstrumentationIRBuilder IRB(callInst); +#else IRBuilder<> IRB(callInst); +#endif if (!FunctionGuardArray) { diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index c08e6380..83aa9486 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -118,6 +118,7 @@ u32 __afl_map_size = MAP_SIZE; u32 __afl_dictionary_len; u64 __afl_map_addr; u32 __afl_first_final_loc; +u32 __afl_old_forkserver; #ifdef __AFL_CODE_COVERAGE typedef struct afl_module_info_t afl_module_info_t; @@ -616,7 +617,7 @@ static void __afl_map_shm(void) { fprintf(stderr, "DEBUG: (2) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " "__afl_area_ptr_dummy %p, __afl_map_addr 0x%llx, MAP_SIZE " - "%u, __afl_final_loc %u, __afl_map_size %u", + "%u, __afl_final_loc %u, __afl_map_size %u\n", id_str == NULL ? "<null>" : id_str, __afl_area_ptr, __afl_area_initial, __afl_area_ptr_dummy, __afl_map_addr, MAP_SIZE, __afl_final_loc, __afl_map_size); @@ -856,7 +857,7 @@ static void __afl_start_forkserver(void) { signal(SIGTERM, at_exit); u32 already_read_first = 0; - u32 was_killed; + u32 was_killed = 0; u32 version = 0x41464c00 + FS_NEW_VERSION_MAX; u32 tmp = version ^ 0xffffffff, status2, status = version; u8 *msg = (u8 *)&status; @@ -866,75 +867,95 @@ static void __afl_start_forkserver(void) { void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL); + if (getenv("AFL_OLD_FORKSERVER")) { + + __afl_old_forkserver = 1; + status = 0; + + if (__afl_final_loc && __afl_final_loc > MAP_SIZE) { + + fprintf(stderr, + "Warning: AFL_OLD_FORKSERVER is used with a target compiled with " + "non-colliding coverage instead of AFL_LLVM_INSTRUMENT=CLASSIC - " + "this target may crash!\n"); + + } + + } + /* Phone home and tell the parent that we're OK. If parent isn't there, assume we're not running in forkserver mode and just execute program. */ // return because possible non-forkserver usage if (write(FORKSRV_FD + 1, msg, 4) != 4) { return; } - if (read(FORKSRV_FD, reply, 4) != 4) { _exit(1); } - if (tmp != status2) { + if (!__afl_old_forkserver) { - write_error("wrong forkserver message from AFL++ tool"); - _exit(1); + if (read(FORKSRV_FD, reply, 4) != 4) { _exit(1); } + if (tmp != status2) { - } + write_error("wrong forkserver message from AFL++ tool"); + _exit(1); - // send the set/requested options to forkserver - status = FS_NEW_OPT_MAPSIZE; // we always send the map size - if (__afl_sharedmem_fuzzing) { status |= FS_NEW_OPT_SHDMEM_FUZZ; } - if (__afl_dictionary_len && __afl_dictionary) { + } - status |= FS_NEW_OPT_AUTODICT; + // send the set/requested options to forkserver + status = FS_NEW_OPT_MAPSIZE; // we always send the map size + if (__afl_sharedmem_fuzzing) { status |= FS_NEW_OPT_SHDMEM_FUZZ; } + if (__afl_dictionary_len && __afl_dictionary) { - } + status |= FS_NEW_OPT_AUTODICT; - if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } + } - // Now send the parameters for the set options, increasing by option number + if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } - // FS_NEW_OPT_MAPSIZE - we always send the map size - status = __afl_map_size; - if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } + // Now send the parameters for the set options, increasing by option number - // FS_NEW_OPT_SHDMEM_FUZZ - no data + // FS_NEW_OPT_MAPSIZE - we always send the map size + status = __afl_map_size; + if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } - // FS_NEW_OPT_AUTODICT - send autodictionary - if (__afl_dictionary_len && __afl_dictionary) { + // FS_NEW_OPT_SHDMEM_FUZZ - no data - // pass the dictionary through the forkserver FD - u32 len = __afl_dictionary_len, offset = 0; + // FS_NEW_OPT_AUTODICT - send autodictionary + if (__afl_dictionary_len && __afl_dictionary) { - if (write(FORKSRV_FD + 1, &len, 4) != 4) { + // pass the dictionary through the forkserver FD + u32 len = __afl_dictionary_len, offset = 0; - write(2, "Error: could not send dictionary len\n", - strlen("Error: could not send dictionary len\n")); - _exit(1); + if (write(FORKSRV_FD + 1, &len, 4) != 4) { - } + write(2, "Error: could not send dictionary len\n", + strlen("Error: could not send dictionary len\n")); + _exit(1); - while (len != 0) { + } - s32 ret; - ret = write(FORKSRV_FD + 1, __afl_dictionary + offset, len); + while (len != 0) { - if (ret < 1) { + s32 ret; + ret = write(FORKSRV_FD + 1, __afl_dictionary + offset, len); - write_error("could not send dictionary"); - _exit(1); + if (ret < 1) { - } + write_error("could not send dictionary"); + _exit(1); - len -= ret; - offset += ret; + } + + len -= ret; + offset += ret; + + } } - } + // send welcome message as final message + status = version; + if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } - // send welcome message as final message - status = version; - if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } + } // END forkserver handshake diff --git a/nyx_mode/README.md b/nyx_mode/README.md index 7a2a8e6c..a839c157 100644 --- a/nyx_mode/README.md +++ b/nyx_mode/README.md @@ -23,7 +23,7 @@ requires an Intel processor (6th generation onwards) and a special 5.10 kernel 2. Additionally, install the following packages: ```shell - apt-get install -y libgtk-3-dev pax-utils python3-msgpack python3-jinja2 + apt-get install -y libgtk-3-dev pax-utils python3-msgpack python3-jinja2 libcapstone-dev ``` 3. As Nyx is written in Rust, install the newest rust compiler (rust packages in @@ -33,7 +33,7 @@ requires an Intel processor (6th generation onwards) and a special 5.10 kernel curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` -4. Finally build Nyx mode: +4. Finally build Nyx mode (or use `make distrib` at the repo root to build all AFL++ modes): ```shell ./build_nyx_support.sh @@ -92,7 +92,7 @@ sudo modprobe -r kvm-intel sudo modprobe -r kvm sudo modprobe kvm enable_vmware_backdoor=y sudo modprobe kvm-intel -cat /sys/module/kvm/parameters/enable_vmware_backdoor | grep -q Y && echi OK || echo KVM module problem +cat /sys/module/kvm/parameters/enable_vmware_backdoor | grep -q Y && echo OK || echo KVM module problem ``` All the hard parts are done, fuzzing with Nyx mode is easy - just supply the @@ -186,7 +186,7 @@ make CC=afl-clang-fast CXX=afl-clang-fast++ LD=afl-clang-fast #### Nyx share directories -Nyx expects that the target is provided in a certain format. More specifically, the target is passed as a so-called „share directory“ to a Nyx-frontend implementation. The share directory contains the target as well as a folder containing all dependencies and other files that are copied over to the guest. But more importantly, this share directory also contains a bootstrap script (`fuzz.sh`if you are using `KVM-Nyx`otherwise `fuzz_no_pt.sh`) that is also executed right after launching the fuzzer. Both bootstrap scripts use several tools to communicate with the "outer world": +Nyx expects that the target is provided in a certain format. More specifically, the target is passed as a so-called „share directory“ to a Nyx-frontend implementation. The share directory contains the target as well as a folder containing all dependencies and other files that are copied over to the guest. But more importantly, this share directory also contains a bootstrap script (`fuzz.sh`if you are using `KVM-Nyx`otherwise `fuzz_no_pt.sh`) that is also executed right after launching the fuzzer. Either of these scripts can be edited to more fully prepare an environment for the target, like transferring configuration files to the target's filesystem. Both bootstrap scripts use several tools to communicate with the "outer world": - `hcat` - this tool copies a given string to the host - `hget` - this program requests a file from the host's share directory diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION index 296745f9..9a62db20 100644 --- a/qemu_mode/QEMUAFL_VERSION +++ b/qemu_mode/QEMUAFL_VERSION @@ -1 +1 @@ -a6f0632a65 +847b43acb1 diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh index 19336114..4dd4fad2 100755 --- a/qemu_mode/build_qemu_support.sh +++ b/qemu_mode/build_qemu_support.sh @@ -386,6 +386,19 @@ else make -C libqasan CC="$CROSS $CROSS_FLAGS" && echo "[+] libqasan ready" fi +#### Hooking support +if [ "$ENABLE_HOOKING" = "1" ];then + echo "[+] ENABLING HOOKING" + set -e + cd ./hooking_bridge || exit 255 + mkdir -p ./build + echo "[+] Hook compiler = $CROSS" + make CC="$CROSS $CROSS_FLAGS" GLIB_H="$GLIB_H" GLIB_CONFIG_H="$GLIB_CONFIG_H" + set +e + cd .. +fi +#### End of hooking support + echo "[+] All done for qemu_mode, enjoy!" exit 0 diff --git a/qemu_mode/hooking_bridge/Makefile b/qemu_mode/hooking_bridge/Makefile new file mode 100644 index 00000000..dcc6f12a --- /dev/null +++ b/qemu_mode/hooking_bridge/Makefile @@ -0,0 +1,18 @@ +.PHONY: clean + +all: plugin +SRC=./src +BLD=./build +INC=-I./inc -I../qemuafl/include -I$(GLIB_H) -I$(GLIB_CONFIG_H) +# CC=gcc + +$(BLD)/patching.o:$(SRC)/patching.c + $(CC) -c -fPIC $(INC) -o $(BLD)/patching.o $(SRC)/patching.c + +plugin:$(SRC)/main.c $(BLD)/patching.o + $(CC) -c -fPIC $(INC) -o $(BLD)/plugin.o $(SRC)/main.c + $(CC) -shared -o $(BLD)/plugin.so $(BLD)/plugin.o $(BLD)/patching.o + +clean: + rm -rf $(BLD)/*.o + rm -rf $(BLD)/*.so \ No newline at end of file diff --git a/qemu_mode/hooking_bridge/README.md b/qemu_mode/hooking_bridge/README.md new file mode 100644 index 00000000..ae8e62e4 --- /dev/null +++ b/qemu_mode/hooking_bridge/README.md @@ -0,0 +1,101 @@ +# Native hooking support into QEMUAFL +* The essential idea is to have inbuilt hooking support into QEMU, instead of relying on the more expensive options UNICORN and its children. +* This solution comprises a bridge (QEMU plugin) that connects your hooks (in a shared library (.so)) with the QEMU usermode ecosystem. +* Currently, LINUX only + +## Bridge compilation +Run build_qemu_support.sh as you do to compile qemuafl, additionally with three args namely: +* `ENABLE_HOOKING=1` to compile the bridge +* `GLIB_H` and `GLIB_CONFIG_H` point to headers `glib.h` and `glibconfig.h` to wherever they are installed on your system + +## Writting hooks +1. Create one or more hooking functions in a shared library, say `hook.so`. +2. Include `exports.h` in your hook build. You can find this header at `<your AFL++ path>/qemu_mode/hooking_bridge/inc`. +3. Shown below is an example which will use to walkthrough hook creation + ```C + struct ret* hook_000000400deadc08(){ + memset (buf, 0, 8); + scanf("%s",buf); + r_reg(RSI,(void *)&h_addr); + w_mem(h_addr,8, buf); + to_ret = (struct ret){0x400deadcab, 0}; + return &to_ret; + } + ``` + i. Hook functions must be named as `hook_<left padded hook location>`. Here, `<left padded hook location>` means `<hook location>` left padded with 0's to until the `(system word length)/4` number of hex characters, e.g. 16 on a 64 bit machine. The unpaded part of `<hook location>` is the absolute address where you want to place the hook. It is basically the file base address (which does not change in QEMU as of now) plus the instruction offset where the hooks is to be placed. The hook function must return a `struct ret *`, which is touched upon later. + + ii. Most likely you will need to access memory or registers in the hook. So we provide four functions + ```C + // Read memory (from address, num. bytes, destination buffer) -> returns 0 on success + int r_mem(unsigned long long addr, unsigned long long len, void *dest); + // Write memory (to address, num. bytes, source buffer) -> returns 0 on success + int w_mem(unsigned long long addr, unsigned long long len, void *src); + // Read register (identifier, destination buffer) -> returns number of bytes read + int r_reg(unsigned char reg, void *dest); + // Read register (identifier, source buffer) -> returns number of bytes written + int w_reg(unsigned char reg, char *src); + ``` + When operating on registers, the functions require a `reg` identifier. This is basically a number gdb uses to lookup a register and can be found under `<qemu(afl) path>/gdb-xml` in the architecture specific xml files. For the example case from above, `RSI` is 4 as obtained from `i386-64bit.xml`. + + iii. Once done with the processing, the hooks needs to return a `struct ret` type pointer, the struct format being + ```C + struct ret{ + unsigned long long addr; + char remove_bp; + }; + ``` + As we can see, there are two fields: first that indicates the address to return to and second that indicates whether the installed hook should be removed after the return. The second field becomes critical if the hook is within an ongoing loop and should be kept intact for future references. + + iv. Finally, mention the list of hooks in a `configure` function that we can call and install your hooks + ```C + struct conf config; + struct conf* configure(){ + config.IP_reg_num = 16; + config.entry_addr = 0x4000001000; + config.num_hooks = NUMHOOKS; //1,2,3... + hooks[0] = 0x400deadc08; + // hooks[1] = 0xcafecace + // .... + config.hooks = hooks; + + //Any other processing stuff you need done before fuzztime + + return &config; + } + ``` + The `configure` function must have the signature `struct conf* configure()` i.e. it must return a pointer to the `config` object. The format of the `config` object is + ```C + struct conf{ + unsigned char IP_reg_num; //found in <qemudir>/gdb-xml + unsigned long long entry_addr; //Main, init, or any entry point that is executed by QEMU prior to hooking targets + unsigned long long* hooks; //list of hooked addresses + unsigned long long num_hooks; // Number of hooks + }; + ``` + `IP_reg_num` here is the register number assigned under the architecture specific xml file under `<qemu(afl) path>/gdb-xml` to the instruction pointer. + +## Running with hooks +Set `QEMU_PLUGIN="file=<AFL download path>qemu_mode/hooking_bridge/build/plugin.so,arg=<your hook .so>"` before running AFL++ in QEMU mode. Note `<your hook .so>` is the absolute path to your hooks library. + +## Contributing +* If you want to enable debugging + * Compile with an additional `DEBUG=1` switch. + * Akin to QEMU's own documentation, set `QEMU_LOG=plugin QEMU_LOG_FILENAME=<your plugin log path>` before you run. + +## Current limitations +1. Cannot be used to debug (-g option) when using the bridge as it uses the gdbstub internally. This is not a problem if used with AFL++, so not such a big issue. +2. Cannot put a hook on the first block after `<entry point>`. Not typically a hookable location. +3. The current implementation can only function on Linux. We have tested on the following configuration + ```Bash + lsb_release -a + --------------- + Distributor ID: Ubuntu + Description: Ubuntu 22.04.3 LTS + Release: 22.04 + Codename: jammy + ``` + ```Bash + uname -a + ---------- + Linux someone 6.5.0-28-generic #29~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Apr 4 14:39:20 UTC 2 x86_64 x86_64 x86_64 GNU/Linux + ``` diff --git a/qemu_mode/hooking_bridge/inc/common.h b/qemu_mode/hooking_bridge/inc/common.h new file mode 100644 index 00000000..f2260977 --- /dev/null +++ b/qemu_mode/hooking_bridge/inc/common.h @@ -0,0 +1,11 @@ +#ifndef COMMON_H +#define COMMON_H + +#include <qemu/qemu-plugin.h> + +void patch_finish_cb(void *userdata); +void patch_block_trans_cb(struct qemu_plugin_tb *tb); +void patch_vpu_init_cb(unsigned int vcpu_index); +void patch_init(char *hook_library); + +#endif \ No newline at end of file diff --git a/qemu_mode/hooking_bridge/inc/exports.h b/qemu_mode/hooking_bridge/inc/exports.h new file mode 100644 index 00000000..186976f4 --- /dev/null +++ b/qemu_mode/hooking_bridge/inc/exports.h @@ -0,0 +1,29 @@ +#ifndef API_H +#define API_H + +//# EXPORTS +// Returns 0 on success +int r_mem(unsigned long long addr, unsigned long long len, void *dest); +// // Returns 0 on success +int w_mem(unsigned long long addr, unsigned long long len, void *src); +// Returns num of bytes read; +int r_reg(unsigned char reg, void *dest); +// // Returns num of bytes written +int w_reg(unsigned char reg, char *src); + + +//NOTE hook function must be named hook_<16 hex character at_addr> +//NOTE must define function `struct conf* configure()` +struct conf{ + unsigned char IP_reg_num; + unsigned long long entry_addr; + unsigned long long* hooks; + unsigned long long num_hooks; +}conf; + +struct ret{ + unsigned long long addr; + char remove_bp; +}; + +#endif \ No newline at end of file diff --git a/qemu_mode/hooking_bridge/src/main.c b/qemu_mode/hooking_bridge/src/main.c new file mode 100644 index 00000000..98e8da98 --- /dev/null +++ b/qemu_mode/hooking_bridge/src/main.c @@ -0,0 +1,36 @@ +#include <stdio.h> +#include <stdlib.h> +#include "common.h" + +QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; + +static void finish_cb(qemu_plugin_id_t id, void *userdata) { + + patch_finish_cb(userdata); + +} + +static void block_trans_cb(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) { + + patch_block_trans_cb(tb); + +} + +static void vpu_init_cb(qemu_plugin_id_t id, unsigned int vcpu_index) { + + patch_vpu_init_cb(vcpu_index); + +} + +QEMU_PLUGIN_EXPORT +int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info, int argc, + char **argv) { + + patch_init(argv[0]); + qemu_plugin_register_vcpu_init_cb(id, vpu_init_cb); + qemu_plugin_register_vcpu_tb_trans_cb(id, block_trans_cb); + qemu_plugin_register_atexit_cb(id, finish_cb, NULL); + return 0; + +} + diff --git a/qemu_mode/hooking_bridge/src/patching.c b/qemu_mode/hooking_bridge/src/patching.c new file mode 100644 index 00000000..123ad99d --- /dev/null +++ b/qemu_mode/hooking_bridge/src/patching.c @@ -0,0 +1,173 @@ +#include <stdlib.h> +#include <stdio.h> +#include <dlfcn.h> +#include <glib.h> +#include "common.h" +#include "exports.h" + +void *handle; +struct conf *config; +struct conf *(*configure)(); +GByteArray *out; +void *cpu; +char cbuf[100]; + +// region GDB Imports +#pragma region GDB Imports +void cpu_single_step(void *cpu, int enabled); +int get_sstep_flags(void); +void gdb_accept_init(int fd); +int gdb_breakpoint_insert(int type, unsigned long long addr, + unsigned long long len); +int gdb_breakpoint_remove(int type, unsigned long long addr, + unsigned long long len); +void *qemu_get_cpu(int index); +int target_memory_rw_debug(void *cpu, unsigned long long addr, void *ptr, + unsigned long long len, char is_write); +int gdb_read_register(void *cs, GByteArray *mem_buf, int n); +int gdb_write_register(void *cs, char *mem_buf, int n); +void gdb_set_cpu_pc(unsigned long long pc); +void gdb_continue(void); +#pragma endregion GDB Imports + +// region API +int r_mem(unsigned long long addr, unsigned long long len, void *dest) { + + return target_memory_rw_debug(cpu, addr, dest, len, 0); + +} + +int w_mem(unsigned long long addr, unsigned long long len, void *src) { + + return target_memory_rw_debug(cpu, addr, src, len, 1); + +} + +int r_reg(unsigned char reg, void *dest) { + + g_byte_array_steal(out, NULL); + int op = gdb_read_register(cpu, out, reg); + memcpy(dest, out->data, out->len); + return op; + +} + +int w_reg(unsigned char reg, char *src) { + + return gdb_write_register(cpu, src, reg); + +} + +// region Breakpoint handling +char single_stepped; +unsigned long long gen_addr; +struct ret *(*hook)(); +struct ret *returned; +// Defined and imported gdbstub.c +void set_signal_callback(void (*cb)(int)); +// Breakpoints are set here +void patch_block_trans_cb(struct qemu_plugin_tb *tb) { + + unsigned long long addr; + addr = qemu_plugin_tb_vaddr(tb); + + if (addr == config->entry_addr) { + + // NOTE This means we cannot put a BP in the first basic block + gdb_accept_init(-1); + for (int i = 0; i < config->num_hooks; i++) { + + gdb_breakpoint_insert(0, config->hooks[i], 1); + + } + + } + +} + +void handle_signal_callback(int sig) { + + if (single_stepped) { + + single_stepped = 0; + gdb_breakpoint_insert(0, gen_addr, 1); + cpu_single_step(cpu, 0); + gdb_continue(); + return; + + } + + r_reg(config->IP_reg_num, cbuf); + gen_addr = *(unsigned long long *)cbuf; + + sprintf(cbuf, "hook_%016llx", gen_addr); + // TODO maybe find a way to put the hook function pointers in the TCG data + // structure instead of this dlsym call + *(unsigned long long **)(&hook) = dlsym(handle, cbuf); + if (!hook) { + + exit(-1); + + } + + returned = hook(); + + if (returned->remove_bp || + (returned->addr == + gen_addr)) { //* force removal of bp in returning to the same address, + //otherwise hook will be called again + gdb_breakpoint_remove(0, gen_addr, 1); + + } + + if (returned->addr == gen_addr) { + + single_stepped = 1; + cpu_single_step(cpu, get_sstep_flags()); + + } else { + + //* no need to rexecute the IP instruction + gdb_set_cpu_pc(returned->addr); + + } + + gdb_continue(); + +} + +// region Constructor/Destructor +void patch_finish_cb(void *userdata) { + + g_byte_array_free(out, 1); + dlclose(handle); + +} + +void patch_vpu_init_cb(unsigned int vcpu_index) { + + cpu = qemu_get_cpu(vcpu_index); + +} + +void patch_init(char *hook_lib) { + + // TODO make OS agnostic, remove dlopen + handle = dlopen(hook_lib, RTLD_NOW); + if (!handle) { + + fprintf(stderr, "DLOPEN Error: %s\n", dlerror()); + exit(-1); + + } + + single_stepped = 0; + + *(void **)(&configure) = dlsym(handle, "configure"); + config = configure(); + + set_signal_callback(handle_signal_callback); + out = g_byte_array_new(); + +} + diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl -Subproject a6f0632a65e101e680dd72643a6128dd180dff7 +Subproject 847b43acb11530e775013dc24b54c6e27406179 diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 71d8570d..cec91f76 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -252,6 +252,10 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) { fsrv->uses_crash_exitcode = false; fsrv->uses_asan = false; +#ifdef __AFL_CODE_COVERAGE + fsrv->persistent_trace_bits = NULL; +#endif + fsrv->init_child_func = fsrv_exec_child; list_append(&fsrv_list, fsrv); @@ -278,12 +282,19 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->fsrv_kill_signal = from->fsrv_kill_signal; fsrv_to->debug = from->debug; +#ifdef __AFL_CODE_COVERAGE + fsrv_to->persistent_trace_bits = from->persistent_trace_bits; +#endif + // These are forkserver specific. fsrv_to->out_dir_fd = -1; fsrv_to->child_pid = -1; fsrv_to->use_fauxsrv = 0; fsrv_to->last_run_timed_out = 0; + fsrv_to->late_send = from->late_send; + fsrv_to->custom_data_ptr = from->custom_data_ptr; + fsrv_to->init_child_func = from->init_child_func; // Note: do not copy ->add_extra_func or ->persistent_record* @@ -1944,6 +1955,13 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, } + if (unlikely(fsrv->late_send)) { + + fsrv->late_send(fsrv->custom_data_ptr, fsrv->custom_input, + fsrv->custom_input_len); + + } + exec_ms = read_s32_timed(fsrv->fsrv_st_fd, &fsrv->child_status, timeout, stop_soon_p); diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 03bc5d6c..97ccd3d3 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -75,9 +75,13 @@ u32 count_bits(afl_state_t *afl, u8 *mem) { } +#if __has_builtin(__builtin_popcount) + ret += __builtin_popcount(v); +#else v -= ((v >> 1) & 0x55555555); v = (v & 0x33333333) + ((v >> 2) & 0x33333333); ret += (((v + (v >> 4)) & 0xF0F0F0F) * 0x01010101) >> 24; +#endif } @@ -459,7 +463,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (unlikely(fault == FSRV_RUN_TMOUT && afl->afl_env.afl_ignore_timeouts)) { - if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) { + if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { classify_counts(&afl->fsrv); u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); @@ -485,7 +489,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { /* Generating a hash on every input is super expensive. Bad idea and should only be used for special schedules */ - if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) { + if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { classify_counts(&afl->fsrv); classified = 1; diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 7310e49f..98de26dd 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1019,7 +1019,7 @@ void perform_dry_run(afl_state_t *afl) { } - if (!q->was_fuzzed) { + if (unlikely(!q->was_fuzzed)) { q->was_fuzzed = 1; afl->reinit_table = 1; diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index f4cb930d..999929a1 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -123,7 +123,7 @@ void create_alias_table(afl_state_t *afl) { double weight = 1.0; { // inline does result in a compile error with LTO, weird - if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) { + if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { u32 hits = afl->n_fuzz[q->n_fuzz_entry]; if (likely(hits)) { weight /= (log10(hits) + 1); } @@ -133,39 +133,127 @@ void create_alias_table(afl_state_t *afl) { if (likely(afl->schedule < RARE)) { double t = q->exec_us / avg_exec_us; + if (likely(t < 0.1)) { // nothing - } else if (likely(t <= 0.25)) + } else if (likely(t <= 0.25)) { + + weight *= 0.95; + + } else if (likely(t <= 0.5)) { + + // nothing + + } else if (likely(t <= 0.75)) { + + weight *= 1.05; + + } else if (likely(t <= 1.0)) { - weight *= 0.9; - else if (likely(t <= 0.5)) { + weight *= 1.1; + + } else if (likely(t < 1.25)) { + + weight *= 0.2; // WTF ??? makes no sense + + } else if (likely(t <= 1.5)) { // nothing - } else if (likely(t < 1.0)) + } else if (likely(t <= 2.0)) { + + weight *= 1.1; + + } else if (likely(t <= 2.5)) { + + } else if (likely(t <= 5.0)) { weight *= 1.15; - else if (unlikely(t > 2.5 && t < 5.0)) + + } else if (likely(t <= 20.0)) { + weight *= 1.1; - // else nothing + // else nothing + + } } double l = q->len / avg_len; - if (likely(l < 0.1)) - weight *= 0.75; - else if (likely(l < 0.25)) - weight *= 1.1; - else if (unlikely(l >= 10)) - weight *= 1.1; + if (likely(l < 0.1)) { + + weight *= 0.5; + + } else if (likely(l <= 0.5)) { + + // nothing + + } else if (likely(l <= 1.25)) { + + weight *= 1.05; + + } else if (likely(l <= 1.75)) { + + // nothing + + } else if (likely(l <= 2.0)) { + + weight *= 0.95; + + } else if (likely(l <= 5.0)) { + + // nothing + + } else if (likely(l <= 10.0)) { + + weight *= 1.05; + + } else { + + weight *= 1.15; + + } double bms = q->bitmap_size / avg_bitmap_size; - if (likely(bms < 0.5)) - weight *= (1.0 + ((bms - 0.5) / 2)); - else if (unlikely(bms > 1.33)) - weight *= 1.1; + if (likely(bms < 0.1)) { + + weight *= 0.01; + + } else if (likely(bms <= 0.25)) { + + weight *= 0.55; + + } else if (likely(bms <= 0.5)) { + + // nothing + + } else if (likely(bms <= 0.75)) { + + weight *= 1.2; + + } else if (likely(bms <= 1.25)) { + + weight *= 1.3; + + } else if (likely(bms <= 1.75)) { + + weight *= 1.25; + + } else if (likely(bms <= 2.0)) { + + // nothing + + } else if (likely(bms <= 2.5)) { + + weight *= 1.3; + + } else { + + weight *= 0.75; + + } if (unlikely(!q->was_fuzzed)) { weight *= 2.5; } if (unlikely(q->fs_redundant)) { weight *= 0.75; } @@ -401,7 +489,9 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) { } else { - if (unlink(fn)) { PFATAL("Unable to remove '%s'", fn); } + if (unlink(fn)) { /*PFATAL("Unable to remove '%s'", fn);*/ + + } } @@ -699,12 +789,11 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { void destroy_queue(afl_state_t *afl) { - u32 i; + u32 i; + struct queue_entry *q; for (i = 0; i < afl->queued_items; i++) { - struct queue_entry *q; - q = afl->queue_buf[i]; ck_free(q->fname); ck_free(q->trace_mini); @@ -740,7 +829,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 fav_factor; u64 fuzz_p2; - if (likely(afl->schedule >= FAST && afl->schedule < RARE)) { + if (unlikely(afl->schedule >= FAST && afl->schedule < RARE)) { fuzz_p2 = 0; // Skip the fuzz_p2 comparison @@ -776,7 +865,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 top_rated_fav_factor; u64 top_rated_fuzz_p2; - if (likely(afl->schedule >= FAST && afl->schedule < RARE)) { + if (unlikely(afl->schedule >= FAST && afl->schedule < RARE)) { top_rated_fuzz_p2 = 0; // Skip the fuzz_p2 comparison diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 6a0da6ab..2f244a1d 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -60,6 +60,27 @@ fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, u32 timeout) { fsrv_run_result_t res = afl_fsrv_run_target(fsrv, timeout, &afl->stop_soon); +#ifdef __AFL_CODE_COVERAGE + if (unlikely(!fsrv->persistent_trace_bits)) { + + // On the first run, we allocate the persistent map to collect coverage. + fsrv->persistent_trace_bits = (u8 *)malloc(fsrv->map_size); + memset(fsrv->persistent_trace_bits, 0, fsrv->map_size); + + } + + for (u32 i = 0; i < fsrv->map_size; ++i) { + + if (fsrv->persistent_trace_bits[i] != 255 && fsrv->trace_bits[i]) { + + fsrv->persistent_trace_bits[i]++; + + } + + } + +#endif + /* If post_run() function is defined in custom mutator, the function will be called each time after AFL++ executes the target program. */ @@ -173,7 +194,17 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { if (el->afl_custom_fuzz_send) { - el->afl_custom_fuzz_send(el->data, *mem, new_size); + if (!afl->afl_env.afl_custom_mutator_late_send) { + + el->afl_custom_fuzz_send(el->data, *mem, new_size); + + } else { + + afl->fsrv.custom_input = *mem; + afl->fsrv.custom_input_len = new_size; + + } + sent = 1; } diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index fbe6d32a..eead3e50 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -286,6 +286,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_no_sync = get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_NO_FASTRESUME", + + afl_environment_variable_len)) { + + afl->afl_env.afl_no_fastresume = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_CUSTOM_MUTATOR_ONLY", afl_environment_variable_len)) { @@ -293,6 +300,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_custom_mutator_only = get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_CUSTOM_MUTATOR_LATE_SEND", + + afl_environment_variable_len)) { + + afl->afl_env.afl_custom_mutator_late_send = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_CMPLOG_ONLY_NEW", afl_environment_variable_len)) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 3a71e158..a20c46d0 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -76,7 +76,13 @@ char *get_fuzzing_state(afl_state_t *afl) { void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { - u8 fn[PATH_MAX]; + u8 fn[PATH_MAX], fn2[PATH_MAX]; + + snprintf(fn2, PATH_MAX, "%s/target_hash", afl->out_dir); + FILE *f2 = create_ffile(fn2); + fprintf(f2, "%p\n", (void *)get_binary_hash(afl->fsrv.target_path)); + fclose(f2); + snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir); FILE *f = create_ffile(fn); u32 i; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index a7ddef6e..8a84d447 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -36,6 +36,67 @@ #include <sys/ipc.h> #include <sys/shm.h> #endif +#ifdef HAVE_ZLIB + + #define ck_gzread(fd, buf, len, fn) \ + do { \ + \ + s32 _len = (s32)(len); \ + s32 _res = gzread(fd, buf, _len); \ + if (_res != _len) RPFATAL(_res, "Short read from %s", fn); \ + \ + } while (0) + + #define ck_gzwrite(fd, buf, len, fn) \ + do { \ + \ + if (len <= 0) break; \ + s32 _written = 0, _off = 0, _len = (s32)(len); \ + \ + do { \ + \ + s32 _res = gzwrite(fd, (buf) + _off, _len); \ + if (_res != _len && (_res > 0 && _written + _res != _len)) { \ + \ + if (_res > 0) { \ + \ + _written += _res; \ + _len -= _res; \ + _off += _res; \ + \ + } else { \ + \ + RPFATAL(_res, "Short write to %s (%d of %d bytes)", fn, _res, \ + _len); \ + \ + } \ + \ + } else { \ + \ + break; \ + \ + } \ + \ + } while (1); \ + \ + \ + \ + } while (0) + + #include <zlib.h> + #define ZLIBOPEN gzopen + #define ZLIBREAD ck_gzread + #define NZLIBREAD gzread + #define ZLIBWRITE ck_gzwrite + #define ZLIBCLOSE gzclose + #define ZLIB_EXTRA "9" +#else + #define ZLIBOPEN open + #define NZLIBREAD read + #define ZLIBREAD ck_read + #define ZLIBWRITE ck_write + #define ZLIBCLOSE close +#endif #ifdef __APPLE__ #include <sys/qos.h> @@ -181,7 +242,7 @@ static void usage(u8 *argv0, int more_help) { "it.\n" " if using QEMU/FRIDA or the fuzzing target is " "compiled\n" - " for CmpLog then use '-c 0'. To disable Cmplog use '-c " + " for CmpLog then use '-c 0'. To disable CMPLOG use '-c " "-'.\n" " -l cmplog_opts - CmpLog configuration values (e.g. \"2ATR\"):\n" " 1=small files, 2=larger files (default), 3=all " @@ -335,6 +396,7 @@ static void usage(u8 *argv0, int more_help) { "AFL_STATSD_PORT: change default statsd port (default: 8125)\n" "AFL_STATSD_TAGS_FLAVOR: set statsd tags format (default: disable tags)\n" " suported formats: dogstatsd, librato, signalfx, influxdb\n" + "AFL_NO_FASTRESUME: do not read or write a fast resume file\n" "AFL_NO_SYNC: disables all syncing\n" "AFL_SYNC_TIME: sync time between fuzzing instances (in minutes)\n" "AFL_FINAL_SYNC: sync a final time when exiting (will delay the exit!)\n" @@ -960,7 +1022,11 @@ int main(int argc, char **argv_orig, char **envp) { } - if (afl->fsrv.mem_limit < 5) { FATAL("Dangerously low value of -m"); } + if (afl->fsrv.mem_limit && afl->fsrv.mem_limit < 5) { + + FATAL("Dangerously low value of -m"); + + } if (sizeof(rlim_t) == 4 && afl->fsrv.mem_limit > 2000) { @@ -1868,6 +1934,15 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Using Frida Address Sanitizer Mode"); + if (afl->fsrv.mem_limit) { + + WARNF( + "in the Frida Address Sanitizer Mode we disable all memory " + "limits"); + afl->fsrv.mem_limit = 0; + + } + fasan_check_afl_preload(afl_preload); setenv("ASAN_OPTIONS", "detect_leaks=false", 1); @@ -2067,6 +2142,31 @@ int main(int argc, char **argv_orig, char **envp) { } + if (afl->custom_mutators_count && afl->afl_env.afl_custom_mutator_late_send) { + + u32 count_send = 0; + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_fuzz_send) { + + if (count_send) { + + FATAL( + "You can only have one custom send() function if you are using " + "AFL_CUSTOM_MUTATOR_LATE_SEND!"); + + } + + afl->fsrv.late_send = el->afl_custom_fuzz_send; + afl->fsrv.custom_data_ptr = el->data; + count_send = 1; + + } + + }); + + } + if (afl->limit_time_sig > 0 && afl->custom_mutators_count) { if (afl->custom_only) { @@ -2101,13 +2201,92 @@ int main(int argc, char **argv_orig, char **envp) { } + setup_cmdline_file(afl, argv + optind); + check_binary(afl, argv[optind]); + + u64 prev_target_hash = 0; + s32 fast_resume = 0; + #ifdef HAVE_ZLIB + gzFile fr_fd = NULL; + #else + s32 fr_fd = -1; + #endif + + if (afl->in_place_resume && !afl->afl_env.afl_no_fastresume) { + + u8 fn[PATH_MAX], buf[32]; + snprintf(fn, PATH_MAX, "%s/target_hash", afl->out_dir); + s32 fd = open(fn, O_RDONLY); + if (fd >= 0) { + + if (read(fd, buf, 32) >= 16) { + + sscanf(buf, "%p", (void **)&prev_target_hash); + + } + + close(fd); + + } + + } + write_setup_file(afl, argc, argv); - setup_cmdline_file(afl, argv + optind); + if (afl->in_place_resume && !afl->afl_env.afl_no_fastresume) { + + u64 target_hash = get_binary_hash(afl->fsrv.target_path); + + if (!target_hash || prev_target_hash != target_hash) { + + ACTF("Target binary is different, cannot perform FAST RESUME!"); + + } else { + + u8 fn[PATH_MAX]; + snprintf(fn, PATH_MAX, "%s/fastresume.bin", afl->out_dir); + #ifdef HAVE_ZLIB + if ((fr_fd = ZLIBOPEN(fn, "rb")) != NULL) { + + #else + if ((fr_fd = open(fn, O_RDONLY)) >= 0) { + + #endif + + u8 ver_string[8]; + u64 *ver = (u64 *)ver_string; + u64 expect_ver = + afl->shm.cmplog_mode + (sizeof(struct queue_entry) << 1); + + if (NZLIBREAD(fr_fd, ver_string, sizeof(ver_string)) != + sizeof(ver_string)) + WARNF("Emtpy fastresume.bin, ignoring, cannot perform FAST RESUME"); + else if (expect_ver != *ver) + WARNF( + "Different AFL++ version or feature usage, cannot perform FAST " + "RESUME"); + else { + + OKF("Will perform FAST RESUME"); + fast_resume = 1; + + } + + } else { + + ACTF("fastresume.bin not found, cannot perform FAST RESUME!"); + + } + + // If the fast resume file is not valid we will be unable to start, so + // we remove the file but keep the file descriptor open. + unlink(fn); + + } + + } read_testcases(afl, NULL); - // read_foreign_testcases(afl, 1); for the moment dont do this - OKF("Loaded a total of %u seeds.", afl->queued_items); pivot_inputs(afl); @@ -2140,6 +2319,9 @@ int main(int argc, char **argv_orig, char **envp) { } + // read_foreign_testcases(afl, 1); for the moment dont do this + OKF("Loaded a total of %u seeds.", afl->queued_items); + /* If we don't have a file name chosen yet, use a safe default. */ if (!afl->fsrv.out_file) { @@ -2196,8 +2378,6 @@ int main(int argc, char **argv_orig, char **envp) { } - check_binary(afl, argv[optind]); - #ifdef AFL_PERSISTENT_RECORD if (unlikely(afl->fsrv.persistent_record)) { @@ -2416,7 +2596,7 @@ int main(int argc, char **argv_orig, char **envp) { } - OKF("Cmplog forkserver successfully started"); + OKF("CMPLOG forkserver successfully started"); } @@ -2454,29 +2634,102 @@ int main(int argc, char **argv_orig, char **envp) { dedup_extras(afl); if (afl->extras_cnt) { OKF("Loaded a total of %u extras.", afl->extras_cnt); } - // after we have the correct bitmap size we can read the bitmap -B option - // and set the virgin maps - if (afl->in_bitmap) { + if (unlikely(fast_resume)) { - read_bitmap(afl->in_bitmap, afl->virgin_bits, afl->fsrv.map_size); + u64 resume_start = get_cur_time_us(); + // if we get here then we should abort on errors + ZLIBREAD(fr_fd, afl->virgin_bits, afl->fsrv.map_size, "virgin_bits"); + ZLIBREAD(fr_fd, afl->virgin_tmout, afl->fsrv.map_size, "virgin_tmout"); + ZLIBREAD(fr_fd, afl->virgin_crash, afl->fsrv.map_size, "virgin_crash"); + ZLIBREAD(fr_fd, afl->var_bytes, afl->fsrv.map_size, "var_bytes"); - } else { + u8 res[1] = {0}; + u8 *o_start = (u8 *)&(afl->queue_buf[0]->colorized); + u8 *o_end = (u8 *)&(afl->queue_buf[0]->mother); + u32 r = 8 + afl->fsrv.map_size * 4; + u32 q_len = o_end - o_start; + u32 m_len = (afl->fsrv.map_size >> 3); + struct queue_entry *q; - memset(afl->virgin_bits, 255, map_size); + for (u32 i = 0; i < afl->queued_items; i++) { - } + q = afl->queue_buf[i]; + ZLIBREAD(fr_fd, (u8 *)&(q->colorized), q_len, "queue data"); + ZLIBREAD(fr_fd, res, 1, "check map"); + if (res[0]) { + + q->trace_mini = ck_alloc(m_len); + ZLIBREAD(fr_fd, q->trace_mini, m_len, "trace_mini"); + r += q_len + m_len + 1; + + } else { + + r += q_len + 1; + + } + + afl->total_bitmap_size += q->bitmap_size; + ++afl->total_bitmap_entries; + update_bitmap_score(afl, q); + + if (q->was_fuzzed) { --afl->pending_not_fuzzed; } - memset(afl->virgin_tmout, 255, map_size); - memset(afl->virgin_crash, 255, map_size); + if (q->disabled) { + + if (!q->was_fuzzed) { --afl->pending_not_fuzzed; } + --afl->active_items; + + } + + if (q->var_behavior) { ++afl->queued_variable; } + if (q->favored) { + + ++afl->queued_favored; + if (!q->was_fuzzed) { ++afl->pending_favored; } + + } + + } - if (likely(!afl->afl_env.afl_no_startup_calibration)) { + u8 buf[4]; + if (NZLIBREAD(fr_fd, buf, 3) > 0) { - perform_dry_run(afl); + FATAL("invalid trailing data in fastresume.bin"); + + } + + OKF("Successfully loaded fastresume.bin (%u bytes)!", r); + ZLIBCLOSE(fr_fd); + afl->reinit_table = 1; + update_calibration_time(afl, &resume_start); } else { - ACTF("skipping initial seed calibration due option override!"); - usleep(1000); + // after we have the correct bitmap size we can read the bitmap -B option + // and set the virgin maps + if (afl->in_bitmap) { + + read_bitmap(afl->in_bitmap, afl->virgin_bits, afl->fsrv.map_size); + + } else { + + memset(afl->virgin_bits, 255, map_size); + + } + + memset(afl->virgin_tmout, 255, map_size); + memset(afl->virgin_crash, 255, map_size); + + if (likely(!afl->afl_env.afl_no_startup_calibration)) { + + perform_dry_run(afl); + + } else { + + ACTF("Skipping initial seed calibration due option override!"); + usleep(1000); + + } } @@ -2984,6 +3237,28 @@ stop_fuzzing: write_bitmap(afl); save_auto(afl); + #ifdef __AFL_CODE_COVERAGE + if (afl->fsrv.persistent_trace_bits) { + + char cfn[4096]; + snprintf(cfn, sizeof(cfn), "%s/covmap.dump", afl->out_dir); + + FILE *cov_fd; + if ((cov_fd = fopen(cfn, "w")) == NULL) { + + PFATAL("could not create '%s'", cfn); + + } + + // Write the real map size, as the map size must exactly match the pointer + // map in length. + fwrite(afl->fsrv.persistent_trace_bits, 1, afl->fsrv.real_map_size, cov_fd); + fclose(cov_fd); + + } + + #endif + if (afl->pizza_is_served) { SAYF(CURSOR_SHOW cLRD "\n\n+++ Baking aborted %s +++\n" cRST, @@ -3067,6 +3342,72 @@ stop_fuzzing: fclose(afl->fsrv.det_plot_file); #endif + if (!afl->afl_env.afl_no_fastresume) { + + /* create fastresume.bin */ + u8 fr[PATH_MAX]; + snprintf(fr, PATH_MAX, "%s/fastresume.bin", afl->out_dir); + ACTF("Writing %s ...", fr); + #ifdef HAVE_ZLIB + if ((fr_fd = ZLIBOPEN(fr, "wb9")) != NULL) { + + #else + if ((fr_fd = open(fr, O_WRONLY | O_TRUNC | O_CREAT, DEFAULT_PERMISSION)) >= + #endif + + u8 ver_string[8]; + u32 w = 0; + u64 *ver = (u64 *)ver_string; + *ver = afl->shm.cmplog_mode + (sizeof(struct queue_entry) << 1); + + ZLIBWRITE(fr_fd, ver_string, sizeof(ver_string), "ver_string"); + ZLIBWRITE(fr_fd, afl->virgin_bits, afl->fsrv.map_size, "virgin_bits"); + ZLIBWRITE(fr_fd, afl->virgin_tmout, afl->fsrv.map_size, "virgin_tmout"); + ZLIBWRITE(fr_fd, afl->virgin_crash, afl->fsrv.map_size, "virgin_crash"); + ZLIBWRITE(fr_fd, afl->var_bytes, afl->fsrv.map_size, "var_bytes"); + w += sizeof(ver_string) + afl->fsrv.map_size * 4; + + u8 on[1] = {1}, off[1] = {0}; + u8 *o_start = (u8 *)&(afl->queue_buf[0]->colorized); + u8 *o_end = (u8 *)&(afl->queue_buf[0]->mother); + u32 q_len = o_end - o_start; + u32 m_len = (afl->fsrv.map_size >> 3); + struct queue_entry *q; + + afl->pending_not_fuzzed = afl->queued_items; + afl->active_items = afl->queued_items; + + for (u32 i = 0; i < afl->queued_items; i++) { + + q = afl->queue_buf[i]; + ZLIBWRITE(fr_fd, (u8 *)&(q->colorized), q_len, "queue data"); + if (!q->trace_mini) { + + ZLIBWRITE(fr_fd, off, 1, "no_mini"); + w += q_len + 1; + + } else { + + ZLIBWRITE(fr_fd, on, 1, "yes_mini"); + ZLIBWRITE(fr_fd, q->trace_mini, m_len, "trace_mini"); + w += q_len + m_len + 1; + + } + + } + + ZLIBCLOSE(fr_fd); + afl->var_byte_count = count_bytes(afl, afl->var_bytes); + OKF("Written fastresume.bin with %u bytes!", w); + + } else { + + WARNF("Could not create fastresume.bin"); + + } + + } + destroy_queue(afl); destroy_extras(afl); destroy_custom_mutators(afl); diff --git a/src/afl-performance.c b/src/afl-performance.c index e8ece6b5..b824fd35 100644 --- a/src/afl-performance.c +++ b/src/afl-performance.c @@ -99,11 +99,13 @@ inline u64 hash64(u8 *key, u32 len, u64 seed) { u64 get_binary_hash(u8 *fn) { + if (!fn) { return 0; } int fd = open(fn, O_RDONLY); if (fd < 0) { PFATAL("Unable to open '%s'", fn); } struct stat st; if (fstat(fd, &st) < 0) { PFATAL("Unable to fstat '%s'", fn); } u32 f_len = st.st_size; + if (!f_len) { return 0; } u8 *f_data = mmap(0, f_len, PROT_READ, MAP_PRIVATE, fd, 0); if (f_data == MAP_FAILED) { PFATAL("Unable to mmap file '%s'", fn); } close(fd); diff --git a/unicorn_mode/README.md b/unicorn_mode/README.md index ce87a2e9..69ccc476 100644 --- a/unicorn_mode/README.md +++ b/unicorn_mode/README.md @@ -144,7 +144,7 @@ The following examples exist at the time of writing: blocks - persistent: A C example using persistent mode for maximum speed, and resetting the target state between each iteration -- simple: A simple Python example +- python_simple: A simple Python example - speedtest/c: The C harness for an example target, used to compare C, Python, and Rust bindings and fix speed issues - speedtest/python: Fuzzing the same target in Python @@ -158,4 +158,4 @@ get shipped pre-built (plus their source). Especially take a look at the [speedtest documentation](./samples/speedtest/README.md) to see how the -languages compare. \ No newline at end of file +languages compare. |