/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 | 39.3k | { |
20 | 39.3k | csh handle; |
21 | 39.3k | cs_insn *all_insn; |
22 | 39.3k | cs_detail *detail; |
23 | 39.3k | cs_err err; |
24 | 39.3k | unsigned int i; |
25 | | |
26 | 39.3k | if (Size < 1) { |
27 | | // 1 byte for arch choice |
28 | 0 | return 0; |
29 | 39.3k | } else if (Size > 0x1000) { |
30 | | //limit input to 4kb |
31 | 0 | Size = 0x1000; |
32 | 0 | } |
33 | | |
34 | 39.3k | if (outfile == NULL) { |
35 | | // we compute the output |
36 | 1 | outfile = fopen("/dev/null", "w"); |
37 | 1 | if (outfile == NULL) { |
38 | 0 | return 0; |
39 | 0 | } |
40 | 1 | } |
41 | | |
42 | 39.3k | i = get_platform_entry((uint8_t)Data[0]); |
43 | | |
44 | 39.3k | err = cs_open(platforms[i].arch, platforms[i].mode, &handle); |
45 | 39.3k | if (err) { |
46 | 7 | return 0; |
47 | 7 | } |
48 | | |
49 | 39.3k | cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); |
50 | 39.3k | if (Data[0] & 0x80) { |
51 | | //hack |
52 | 10.4k | cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); |
53 | 10.4k | } |
54 | | |
55 | 39.3k | uint64_t address = 0x1000; |
56 | 39.3k | size_t count = |
57 | 39.3k | cs_disasm(handle, Data + 1, Size - 1, address, 0, &all_insn); |
58 | | |
59 | 39.3k | if (count) { |
60 | 38.3k | size_t j; |
61 | 38.3k | unsigned int n; |
62 | | |
63 | 2.09M | for (j = 0; j < count; j++) { |
64 | 2.05M | cs_insn *insn = &(all_insn[j]); |
65 | 2.05M | fprintf(outfile, |
66 | 2.05M | "0x%" PRIx64 |
67 | 2.05M | ":\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n", |
68 | 2.05M | insn->address, insn->mnemonic, insn->op_str, |
69 | 2.05M | insn->id, cs_insn_name(handle, insn->id)); |
70 | | |
71 | 2.05M | detail = insn->detail; |
72 | | |
73 | 2.05M | if (detail->regs_read_count > 0) { |
74 | 505k | fprintf(outfile, "\tImplicit registers read: "); |
75 | 1.26M | for (n = 0; n < detail->regs_read_count; n++) { |
76 | 761k | fprintf(outfile, "%s ", |
77 | 761k | cs_reg_name( |
78 | 761k | handle, |
79 | 761k | detail->regs_read[n])); |
80 | 761k | } |
81 | 505k | } |
82 | | |
83 | 2.05M | if (detail->regs_write_count > 0) { |
84 | 952k | fprintf(outfile, |
85 | 952k | "\tImplicit registers modified: "); |
86 | 2.07M | for (n = 0; n < detail->regs_write_count; n++) { |
87 | 1.11M | fprintf(outfile, "%s ", |
88 | 1.11M | cs_reg_name( |
89 | 1.11M | handle, |
90 | 1.11M | detail->regs_write[n])); |
91 | 1.11M | } |
92 | 952k | } |
93 | | |
94 | 2.05M | if (detail->groups_count > 0) { |
95 | 1.29M | fprintf(outfile, |
96 | 1.29M | "\tThis instruction belongs to groups: "); |
97 | 3.03M | for (n = 0; n < detail->groups_count; n++) { |
98 | 1.73M | fprintf(outfile, "%s ", |
99 | 1.73M | cs_group_name( |
100 | 1.73M | handle, |
101 | 1.73M | detail->groups[n])); |
102 | 1.73M | } |
103 | 1.29M | } |
104 | 2.05M | } |
105 | | |
106 | 38.3k | fprintf(outfile, "0x%" PRIx64 ":\n", |
107 | 38.3k | all_insn[j - 1].address + all_insn[j - 1].size); |
108 | 38.3k | cs_free(all_insn, count); |
109 | 38.3k | } |
110 | | |
111 | 39.3k | cs_close(&handle); |
112 | | |
113 | 39.3k | return 0; |
114 | 39.3k | } |