aboutsummaryrefslogtreecommitdiffstats
path: root/capstone/suite/fuzz/fuzz_disasm.c
diff options
context:
space:
mode:
Diffstat (limited to 'capstone/suite/fuzz/fuzz_disasm.c')
-rw-r--r--capstone/suite/fuzz/fuzz_disasm.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/capstone/suite/fuzz/fuzz_disasm.c b/capstone/suite/fuzz/fuzz_disasm.c
new file mode 100644
index 000000000..0dd7ef72d
--- /dev/null
+++ b/capstone/suite/fuzz/fuzz_disasm.c
@@ -0,0 +1,99 @@
+// the following must precede stdio (woo, thanks msft)
+#if defined(_MSC_VER) && _MSC_VER < 1900
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include <capstone/capstone.h>
+
+#include "platform.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
+
+
+static FILE *outfile = NULL;
+
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ csh handle;
+ cs_insn *all_insn;
+ cs_detail *detail;
+ cs_err err;
+ unsigned int i;
+
+ if (Size < 1) {
+ // 1 byte for arch choice
+ return 0;
+ } else if (Size > 0x1000) {
+ //limit input to 4kb
+ Size = 0x1000;
+ }
+
+ if (outfile == NULL) {
+ // we compute the output
+ outfile = fopen("/dev/null", "w");
+ if (outfile == NULL) {
+ return 0;
+ }
+ }
+
+ i = get_platform_entry((uint8_t)Data[0]);
+
+ err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
+ if (err) {
+ return 0;
+ }
+
+ cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
+ if (Data[0]&0x80) {
+ //hack
+ cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
+ }
+
+ uint64_t address = 0x1000;
+ size_t count = cs_disasm(handle, Data+1, Size-1, address, 0, &all_insn);
+
+ if (count) {
+ size_t j;
+ unsigned int n;
+
+ for (j = 0; j < count; j++) {
+ cs_insn *i = &(all_insn[j]);
+ fprintf(outfile, "0x%"PRIx64":\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n",
+ i->address, i->mnemonic, i->op_str,
+ i->id, cs_insn_name(handle, i->id));
+
+ detail = i->detail;
+
+ if (detail->regs_read_count > 0) {
+ fprintf(outfile, "\tImplicit registers read: ");
+ for (n = 0; n < detail->regs_read_count; n++) {
+ fprintf(outfile, "%s ", cs_reg_name(handle, detail->regs_read[n]));
+ }
+ }
+
+ if (detail->regs_write_count > 0) {
+ fprintf(outfile, "\tImplicit registers modified: ");
+ for (n = 0; n < detail->regs_write_count; n++) {
+ fprintf(outfile, "%s ", cs_reg_name(handle, detail->regs_write[n]));
+ }
+ }
+
+ if (detail->groups_count > 0) {
+ fprintf(outfile, "\tThis instruction belongs to groups: ");
+ for (n = 0; n < detail->groups_count; n++) {
+ fprintf(outfile, "%s ", cs_group_name(handle, detail->groups[n]));
+ }
+ }
+ }
+
+ fprintf(outfile, "0x%"PRIx64":\n", all_insn[j-1].address + all_insn[j-1].size);
+ cs_free(all_insn, count);
+ }
+
+ cs_close(&handle);
+
+ return 0;
+}