Merge pull request 'yinao' (#7) from dev-yinao into main

dev-zhumingji
phq7r92sf 9 months ago
commit a4d5328a11

@ -0,0 +1,6 @@
{
"files.associations": {
"stdio.h": "c",
"alloc-inl.h": "c"
}
}

@ -70,9 +70,8 @@ static u8 be_quiet, /* Quiet mode (no stderr output) */
static u32 inst_ratio = 100, /* Instrumentation probability (%) */ static u32 inst_ratio = 100, /* Instrumentation probability (%) */
as_par_cnt = 1; /* Number of params to 'as' */ as_par_cnt = 1; /* Number of params to 'as' */
/* If we don't find --32 or --64 in the command line, default to /* 如果命令行中没有找到 --32 或 --64 参数,则默认对编译该工具时使用的模式进行插桩。
instrumentation for whichever mode we were compiled with. This is not 使 */
perfect, but should do the trick for almost all use cases. */
#ifdef WORD_SIZE_64 #ifdef WORD_SIZE_64
@ -89,9 +88,8 @@ static u8 use_64bit = 0;
#endif /* ^WORD_SIZE_64 */ #endif /* ^WORD_SIZE_64 */
/* Examine and modify parameters to pass to 'as'. Note that the file name /* 检查并修改传递给 'as' 的参数。注意 GCC 总是将文件名作为最后一个参数传递给 'as'
is always the last parameter passed by GCC, so we exploit this property */
to keep the code simple. */
static void edit_params(int argc, char** argv) { static void edit_params(int argc, char** argv) {
@ -102,17 +100,14 @@ static void edit_params(int argc, char** argv) {
u8 use_clang_as = 0; u8 use_clang_as = 0;
/* On MacOS X, the Xcode cctool 'as' driver is a bit stale and does not work /* 在 MacOS X 上Xcode cctool 'as' 驱动程序有点过时,无法处理由用户自己编译的较新版本的 clang
with the code generated by newer versions of clang that are hand-built 线http://goo.gl/HBWDtn.
by the user. See the thread here: http://goo.gl/HBWDtn.
To work around this, when using clang and running without AFL_AS 使 clang AFL_AS 'clang -c' 'as -q'
specified, we will actually call 'clang -c' instead of 'as -q' to .
compile the assembly file.
The tools aren't cmdline-compatible, but at least for now, we can
seemingly get away with this by making only very minor tweaks. Thanks Nico Weber */
to Nico Weber for the idea. */
if (clang_mode && !afl_as) { if (clang_mode && !afl_as) {
@ -126,9 +121,8 @@ static void edit_params(int argc, char** argv) {
#endif /* __APPLE__ */ #endif /* __APPLE__ */
/* Although this is not documented, GCC also uses TEMP and TMP when TMPDIR /* 虽然这在文档中没有提及,但 GCC 实际上也使用 TEMP 和 TMP当 TMPDIR 未设置时)。
is not set. We need to check these non-standard variables to properly pass_thru */
handle the pass_thru logic later on. */
if (!tmp_dir) tmp_dir = getenv("TEMP"); if (!tmp_dir) tmp_dir = getenv("TEMP");
if (!tmp_dir) tmp_dir = getenv("TMP"); if (!tmp_dir) tmp_dir = getenv("TMP");
@ -147,7 +141,7 @@ static void edit_params(int argc, char** argv) {
#ifdef __APPLE__ #ifdef __APPLE__
/* The Apple case is a bit different... */ /* MacOS X 的情况有点不同... */
if (!strcmp(argv[i], "-arch") && i + 1 < argc) { if (!strcmp(argv[i], "-arch") && i + 1 < argc) {
@ -157,8 +151,7 @@ static void edit_params(int argc, char** argv) {
} }
/* Strip options that set the preference for a particular upstream /* 移除 Xcode 中设置特定上游汇编器的选项 */
assembler in Xcode. */
if (clang_mode && (!strcmp(argv[i], "-q") || !strcmp(argv[i], "-Q"))) if (clang_mode && (!strcmp(argv[i], "-q") || !strcmp(argv[i], "-Q")))
continue; continue;
@ -171,8 +164,7 @@ static void edit_params(int argc, char** argv) {
#ifdef __APPLE__ #ifdef __APPLE__
/* When calling clang as the upstream assembler, append -c -x assembler /* 当调用 clang 作为上游汇编器时,追加 -c -x assembler 选项并希望一切顺利。 */
and hope for the best. */
if (use_clang_as) { if (use_clang_as) {
@ -199,10 +191,8 @@ static void edit_params(int argc, char** argv) {
} else { } else {
/* Check if this looks like a standard invocation as a part of an attempt /* 检查是否为标准调用,作为编译程序的一部分,而不是使用 gcc 对一个独立的 .s 文件进行编译。
to compile a program, rather than using gcc on an ad-hoc .s file in NSS */
a format we may not understand. This works around an issue compiling
NSS. */
if (strncmp(input_file, tmp_dir, strlen(tmp_dir)) && if (strncmp(input_file, tmp_dir, strlen(tmp_dir)) &&
strncmp(input_file, "/var/tmp/", 9) && strncmp(input_file, "/var/tmp/", 9) &&
@ -221,8 +211,7 @@ wrap_things_up:
} }
/* Process input file, generate modified_file. Insert instrumentation in all /* 处理输入文件并生成 modified_file。在所有适当的位置插入插桩代码。 */
the appropriate places. */
static void add_instrumentation(void) { static void add_instrumentation(void) {
@ -259,10 +248,8 @@ static void add_instrumentation(void) {
while (fgets(line, MAX_LINE, inf)) { while (fgets(line, MAX_LINE, inf)) {
/* In some cases, we want to defer writing the instrumentation trampoline /* 在某些情况下,我们希望在所有标签、宏、注释等之后再插入插桩跳板代码。
until after all the labels, macros, comments, etc. If we're in this */
mode, and if the line starts with a tab followed by a character, dump
the trampoline now. */
if (!pass_thru && !skip_intel && !skip_app && !skip_csect && instr_ok && if (!pass_thru && !skip_intel && !skip_app && !skip_csect && instr_ok &&
instrument_next && line[0] == '\t' && isalpha(line[1])) { instrument_next && line[0] == '\t' && isalpha(line[1])) {
@ -275,21 +262,19 @@ static void add_instrumentation(void) {
} }
/* Output the actual line, call it a day in pass-thru mode. */ /* 输出实际的行,在 pass-thru 模式下结束操作。 */
fputs(line, outf); fputs(line, outf);
if (pass_thru) continue; if (pass_thru) continue;
/* All right, this is where the actual fun begins. For one, we only want to /* 现在开始真正的插桩操作。首先,我们只希望插桩 .text 部分。
instrument the .text section. So, let's keep track of that in processed instr_ok */
files - and let's set instr_ok accordingly. */
if (line[0] == '\t' && line[1] == '.') { if (line[0] == '\t' && line[1] == '.') {
/* OpenBSD puts jump tables directly inline with the code, which is /* OpenBSD 在代码中直接放置跳转表,这稍微有点麻烦。
a bit annoying. They use a specific format of p2align directives 使 p2align 使 */
around them, so we use that as a signal. */
if (!clang_mode && instr_ok && !strncmp(line + 2, "p2align ", 8) && if (!clang_mode && instr_ok && !strncmp(line + 2, "p2align ", 8) &&
isdigit(line[10]) && line[11] == '\n') skip_next_label = 1; isdigit(line[10]) && line[11] == '\n') skip_next_label = 1;
@ -312,9 +297,8 @@ static void add_instrumentation(void) {
} }
/* Detect off-flavor assembly (rare, happens in gdb). When this is /* 检测非常规汇编(罕见,例如在 gdb 中)。当遇到这种汇编时,我们设置 skip_csect
encountered, we set skip_csect until the opposite directive is */
seen, and we do not instrument. */
if (strstr(line, ".code")) { if (strstr(line, ".code")) {
@ -323,13 +307,7 @@ static void add_instrumentation(void) {
} }
/* Detect syntax changes, as could happen with hand-written assembly. /* 检测并跳过手写汇编块__asm__同样不进行插桩。 */
Skip Intel blocks, resume instrumentation when back to AT&T. */
if (strstr(line, ".intel_syntax")) skip_intel = 1;
if (strstr(line, ".att_syntax")) skip_intel = 0;
/* Detect and skip ad-hoc __asm__ blocks, likewise skipping them. */
if (line[0] == '#' || line[1] == '#') { if (line[0] == '#' || line[1] == '#') {
@ -338,36 +316,30 @@ static void add_instrumentation(void) {
} }
/* If we're in the right mood for instrumenting, check for function /* 如果我们处于插桩模式,检查函数名或条件标签。这里逻辑有些复杂,但基本目标是捕获:
names or conditional labels. This is a bit messy, but in essence,
we want to catch:
^main: - function entry point (always instrumented) ^main: -
^.L0: - GCC branch label ^.L0: - GCC
^.LBB0_0: - clang branch label (but only in clang mode) ^.LBB0_0: - clang clang
^\tjnz foo - conditional branches ^\tjnz foo -
...but not: ...
^# BB#0: - clang comments ^# BB#0: - clang
^ # BB#0: - ditto ^ # BB#0: -
^.Ltmp0: - clang non-branch labels ^.Ltmp0: - clang
^.LC0 - GCC non-branch labels ^.LC0 - GCC
^.LBB0_0: - ditto (when in GCC mode) ^.LBB0_0: - GCC
^\tjmp foo - non-conditional jumps ^\tjmp foo -
Additionally, clang and GCC on MacOS X follow a different convention
with no leading dots on labels, hence the weird maze of #ifdefs
later on.
MacOS X clang GCC 使
*/ */
if (skip_intel || skip_app || skip_csect || !instr_ok || if (skip_intel || skip_app || skip_csect || !instr_ok ||
line[0] == '#' || line[0] == ' ') continue; line[0] == '#' || line[0] == ' ') continue;
/* Conditional branch instruction (jnz, etc). We append the instrumentation /* 条件分支指令jnz 等)。我们会在分支之后插入插桩(以插桩不执行路径),
right after the branch (to instrument the not-taken path) and at the */
branch destination label (handled later on). */
if (line[0] == '\t') { if (line[0] == '\t') {
@ -384,13 +356,11 @@ static void add_instrumentation(void) {
} }
/* Label of some sort. This may be a branch destination, but we need to /* 某类标签。这可能是分支目标,但我们需要小心处理不同的格式约定。 */
tread carefully and account for several different formatting
conventions. */
#ifdef __APPLE__ #ifdef __APPLE__
/* Apple: L<whatever><digit>: */ /* MacOS X: L<whatever><digit>: */
if ((colon_pos = strstr(line, ":"))) { if ((colon_pos = strstr(line, ":"))) {
@ -398,7 +368,7 @@ static void add_instrumentation(void) {
#else #else
/* Everybody else: .L<whatever>: */ /* 其他人:.L<whatever>: */
if (strstr(line, ":")) { if (strstr(line, ":")) {
@ -406,34 +376,29 @@ static void add_instrumentation(void) {
#endif /* __APPLE__ */ #endif /* __APPLE__ */
/* .L0: or LBB0_0: style jump destination */ /* .L0: 或 LBB0_0: 风格的分支目标 */
#ifdef __APPLE__ #ifdef __APPLE__
/* Apple: L<num> / LBB<num> */ /* MacOS X: L<num> / LBB<num> */
if ((isdigit(line[1]) || (clang_mode && !strncmp(line, "LBB", 3))) if ((isdigit(line[1]) || (clang_mode && !strncmp(line, "LBB", 3)))
&& R(100) < inst_ratio) { && R(100) < inst_ratio) {
#else #else
/* Apple: .L<num> / .LBB<num> */ /* MacOS X: .L<num> / .LBB<num> */
if ((isdigit(line[2]) || (clang_mode && !strncmp(line + 1, "LBB", 3))) if ((isdigit(line[2]) || (clang_mode && !strncmp(line + 1, "LBB", 3)))
&& R(100) < inst_ratio) { && R(100) < inst_ratio) {
#endif /* __APPLE__ */ #endif /* __APPLE__ */
/* An optimization is possible here by adding the code only if the /* 在仅需要在标签被引用时(非调用/跳转上下文)才添加代码的情况下可以进行优化。
label is mentioned in the code in contexts other than call / jmp. 使 stdin 10%
That said, this complicates the code by requiring two-pass
processing (messy with stdin), and results in a speed gain
typically under 10%, because compilers are generally pretty good
about not generating spurious intra-function jumps.
We use deferred output chiefly to avoid disrupting 使 MacOS X .Lfunc_begin0 */
.Lfunc_begin0-style exception handling calculations (a problem on
MacOS X). */
if (!skip_next_label) instrument_next = 1; else skip_next_label = 0; if (!skip_next_label) instrument_next = 1; else skip_next_label = 0;
@ -441,7 +406,7 @@ static void add_instrumentation(void) {
} else { } else {
/* Function label (always instrumented, deferred mode). */ /* 函数标签(总是插桩,延迟模式)。 */
instrument_next = 1; instrument_next = 1;
@ -472,7 +437,7 @@ static void add_instrumentation(void) {
} }
/* Main entry point */ /* 程序主入口点 */
int main(int argc, char** argv) { int main(int argc, char** argv) {
@ -527,9 +492,8 @@ int main(int argc, char** argv) {
setenv(AS_LOOP_ENV_VAR, "1", 1); setenv(AS_LOOP_ENV_VAR, "1", 1);
/* When compiling with ASAN, we don't have a particularly elegant way to skip /* 使用 ASAN 时,我们没有特别优雅的方法来跳过 ASAN 特定的分支。
ASAN-specific branches. But we can probabilistically compensate for ... */
that... */
if (getenv("AFL_USE_ASAN") || getenv("AFL_USE_MSAN")) { if (getenv("AFL_USE_ASAN") || getenv("AFL_USE_MSAN")) {
sanitizer = 1; sanitizer = 1;
@ -554,4 +518,3 @@ int main(int argc, char** argv) {
exit(WEXITSTATUS(status)); exit(WEXITSTATUS(status));
} }

Loading…
Cancel
Save