#c #c #clang #llvm #fuzzing
Вопрос:
Я хочу отследить пути выполнения программы для нескольких входов. Для генерации входных данных я в настоящее время использую фаззинг с управлением охватом-сначала я попробовал AFL, а теперь использую Libfuzzer. Чтобы записать пути выполнения, я посмотрел на XRay и SanitizerCoverage, которые, насколько я понял, используют инструментарий LLVM; последний используется внутри Libfuzzer для своих показателей покрытия.
Если я использую XRay с Libfuzzer, я получаю сообщения об ошибках из-за нескольких определений функций:
#include <xray/xray_log_interface.h>
extern "C" {
int LLVMFuzzerRunDriver(int *argc, char ***argv, int (*UserCb)(const uint8_t *Data, size_t Size));
};
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
return 0;
}
int main(int argc, char** argv) {
return LLVMFuzzerRunDriver(amp;argc, amp;argv, amp;LLVMFuzzerTestOneInput);
}
clang -13 -o test test.cpp -fxray-instrument -fxray-instruction-threshold=1 -fsanitize=fuzzer-no-link -L /usr/lib/clang/13.0.0/lib/linux/ -l clang_rt.fuzzer_no_main-x86_64
Если я использую Libfuzzer с обратным вызовом SanitizerCoverage:
#include <cstdlib>
#include <inttypes.h>
#include <sanitizer/coverage_interface.h>
extern "C" void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
if (!*guard) return;
return;
}
extern "C" {
int LLVMFuzzerRunDriver(int *argc, char ***argv, int (*UserCb)(const uint8_t *Data, size_t Size));
};
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
return 0;
}
int main(int argc, char** argv) {
return LLVMFuzzerRunDriver(amp;argc, amp;argv, amp;LLVMFuzzerTestOneInput);
}
$ clang -13 -o test2 test2.cpp -fsanitize=fuzzer-no-link -fsanitize-coverage=trace-pc-guard -L /usr/lib/clang/13.0.0/lib/linux/ -l clang_rt.fuzzer_no_main-x86_64
/usr/bin/ld: /usr/lib/clang/13.0.0/lib/linux//libclang_rt.fuzzer_no_main-x86_64.a(fuzzer_no_main.o): in function `__sanitizer_cov_trace_pc_guard':
(.text.__sanitizer_cov_trace_pc_guard 0x0): multiple definition of `__sanitizer_cov_trace_pc_guard'; /tmp/test2-047590.o:test2.cpp:(.text 0x0): first defined here
Можно ли совместить готовое размытие (для создания «интересных» входных данных) и трассировку пути выполнения, или мне придется прибегнуть к чему-то более сложному, например, написать свой собственный пропуск LLVM.
Комментарии:
1. Я не уверен, что понимаю вашу цель. С помощью AFL вы можете проверить все края, на которые он попадает, с помощью afl-showmap и использовать afl-cov для получения результата gcov. это то, чего ты хочешь?
2. Насколько я понял результаты покрытия afl, я не получаю отдельных следов для входных данных, т. Е. Я знаю, что функции foo (), bar() и baz() покрываются во время выполнения, но я не знаю, в каком порядке функции были выполнены, с помощью каких входных данных
3. ах, справедливо — это звучит дорого с точки зрения производительности. Возможно, вам захочется немного ознакомиться с AFLGo, который вычисляет функциональное расстояние до цели перед кампанией по размыванию.