/src/capstonenext/suite/fuzz/fuzz_disasm.c
Line | Count | Source (jump to first uncovered line) |
1 | | // the following must precede stdio (woo, thanks msft) |
2 | | #if defined(_MSC_VER) && _MSC_VER < 1900 |
3 | | #define _CRT_SECURE_NO_WARNINGS |
4 | | #endif |
5 | | |
6 | | #include <stdio.h> |
7 | | #include <stdlib.h> |
8 | | #include <inttypes.h> |
9 | | |
10 | | #include <capstone/capstone.h> |
11 | | |
12 | | #include "platform.h" |
13 | | |
14 | | int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); |
15 | | |
16 | | static FILE *outfile = NULL; |
17 | | |
18 | | int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) |
19 | 82.5k | { |
20 | 82.5k | csh handle; |
21 | 82.5k | cs_insn *all_insn; |
22 | 82.5k | cs_detail *detail; |
23 | 82.5k | cs_err err; |
24 | 82.5k | unsigned int i; |
25 | | |
26 | 82.5k | if (Size < 1) { |
27 | | // 1 byte for arch choice |
28 | 0 | return 0; |
29 | 82.5k | } else if (Size > 0x1000) { |
30 | | //limit input to 4kb |
31 | 0 | Size = 0x1000; |
32 | 0 | } |
33 | | |
34 | 82.5k | if (outfile == NULL) { |
35 | | // we compute the output |
36 | 2 | outfile = fopen("/dev/null", "w"); |
37 | 2 | if (outfile == NULL) { |
38 | 0 | return 0; |
39 | 0 | } |
40 | 2 | } |
41 | | |
42 | 82.5k | i = get_platform_entry((uint8_t)Data[0]); |
43 | | |
44 | 82.5k | err = cs_open(platforms[i].arch, platforms[i].mode, &handle); |
45 | 82.5k | if (err) { |
46 | 8 | return 0; |
47 | 8 | } |
48 | | |
49 | 82.5k | cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); |
50 | 82.5k | if (Data[0] & 0x80) { |
51 | | //hack |
52 | 23.0k | cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); |
53 | 23.0k | } |
54 | | |
55 | 82.5k | uint64_t address = 0x1000; |
56 | 82.5k | size_t count = |
57 | 82.5k | cs_disasm(handle, Data + 1, Size - 1, address, 0, &all_insn); |
58 | | |
59 | 82.5k | if (count) { |
60 | 80.6k | size_t j; |
61 | 80.6k | unsigned int n; |
62 | | |
63 | 4.33M | for (j = 0; j < count; j++) { |
64 | 4.25M | cs_insn *insn = &(all_insn[j]); |
65 | 4.25M | fprintf(outfile, |
66 | 4.25M | "0x%" PRIx64 |
67 | 4.25M | ":\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n", |
68 | 4.25M | insn->address, insn->mnemonic, insn->op_str, |
69 | 4.25M | insn->id, cs_insn_name(handle, insn->id)); |
70 | | |
71 | 4.25M | detail = insn->detail; |
72 | | |
73 | 4.25M | if (detail->regs_read_count > 0) { |
74 | 1.00M | fprintf(outfile, "\tImplicit registers read: "); |
75 | 2.56M | for (n = 0; n < detail->regs_read_count; n++) { |
76 | 1.56M | fprintf(outfile, "%s ", |
77 | 1.56M | cs_reg_name( |
78 | 1.56M | handle, |
79 | 1.56M | detail->regs_read[n])); |
80 | 1.56M | } |
81 | 1.00M | } |
82 | | |
83 | 4.25M | if (detail->regs_write_count > 0) { |
84 | 1.74M | fprintf(outfile, |
85 | 1.74M | "\tImplicit registers modified: "); |
86 | 3.85M | for (n = 0; n < detail->regs_write_count; n++) { |
87 | 2.10M | fprintf(outfile, "%s ", |
88 | 2.10M | cs_reg_name( |
89 | 2.10M | handle, |
90 | 2.10M | detail->regs_write[n])); |
91 | 2.10M | } |
92 | 1.74M | } |
93 | | |
94 | 4.25M | if (detail->groups_count > 0) { |
95 | 2.43M | fprintf(outfile, |
96 | 2.43M | "\tThis instruction belongs to groups: "); |
97 | 5.90M | for (n = 0; n < detail->groups_count; n++) { |
98 | 3.47M | fprintf(outfile, "%s ", |
99 | 3.47M | cs_group_name( |
100 | 3.47M | handle, |
101 | 3.47M | detail->groups[n])); |
102 | 3.47M | } |
103 | 2.43M | } |
104 | 4.25M | } |
105 | | |
106 | 80.6k | fprintf(outfile, "0x%" PRIx64 ":\n", |
107 | 80.6k | all_insn[j - 1].address + all_insn[j - 1].size); |
108 | 80.6k | cs_free(all_insn, count); |
109 | 80.6k | } |
110 | | |
111 | 82.5k | cs_close(&handle); |
112 | | |
113 | 82.5k | return 0; |
114 | 82.5k | } |