1*9a0e4156SSadaf Ebrahimi#!/usr/bin/python 2*9a0e4156SSadaf Ebrahimi 3*9a0e4156SSadaf Ebrahimi# Simple fuzzing tool by disassembling random code. By Nguyen Anh Quynh, 2014 4*9a0e4156SSadaf Ebrahimi# Syntax: 5*9a0e4156SSadaf Ebrahimi# ./suite/fuzz.py --> Fuzz all archs 6*9a0e4156SSadaf Ebrahimi# ./suite/fuzz.py x86 --> Fuzz all X86 (all 16bit, 32bit, 64bit) 7*9a0e4156SSadaf Ebrahimi# ./suite/fuzz.py x86-16 --> Fuzz X86-32 arch only 8*9a0e4156SSadaf Ebrahimi# ./suite/fuzz.py x86-32 --> Fuzz X86-32 arch only 9*9a0e4156SSadaf Ebrahimi# ./suite/fuzz.py x86-64 --> Fuzz X86-64 arch only 10*9a0e4156SSadaf Ebrahimi# ./suite/fuzz.py arm --> Fuzz all ARM (arm, thumb) 11*9a0e4156SSadaf Ebrahimi# ./suite/fuzz.py aarch64 --> Fuzz ARM-64 12*9a0e4156SSadaf Ebrahimi# ./suite/fuzz.py mips --> Fuzz all Mips (32bit, 64bit) 13*9a0e4156SSadaf Ebrahimi# ./suite/fuzz.py ppc --> Fuzz PPC 14*9a0e4156SSadaf Ebrahimi 15*9a0e4156SSadaf Ebrahimifrom capstone import * 16*9a0e4156SSadaf Ebrahimi 17*9a0e4156SSadaf Ebrahimifrom time import time 18*9a0e4156SSadaf Ebrahimifrom random import randint 19*9a0e4156SSadaf Ebrahimiimport sys 20*9a0e4156SSadaf Ebrahimi 21*9a0e4156SSadaf Ebrahimi 22*9a0e4156SSadaf Ebrahimi# file providing code to disassemble 23*9a0e4156SSadaf EbrahimiFILE = '/usr/bin/python' 24*9a0e4156SSadaf Ebrahimi 25*9a0e4156SSadaf EbrahimiTIMES = 64 26*9a0e4156SSadaf EbrahimiINTERVALS = (4, 5, 7, 9, 11, 13) 27*9a0e4156SSadaf Ebrahimi 28*9a0e4156SSadaf Ebrahimiall_tests = ( 29*9a0e4156SSadaf Ebrahimi (CS_ARCH_X86, CS_MODE_16, "X86-16bit (Intel syntax)", 0), 30*9a0e4156SSadaf Ebrahimi (CS_ARCH_X86, CS_MODE_16, "X86-16bit (ATT syntax)", CS_OPT_SYNTAX_ATT), 31*9a0e4156SSadaf Ebrahimi (CS_ARCH_X86, CS_MODE_32, "X86-32 (Intel syntax)", 0), 32*9a0e4156SSadaf Ebrahimi (CS_ARCH_X86, CS_MODE_32, "X86-32 (ATT syntax)", CS_OPT_SYNTAX_ATT), 33*9a0e4156SSadaf Ebrahimi (CS_ARCH_X86, CS_MODE_64, "X86-64 (Intel syntax)", 0), 34*9a0e4156SSadaf Ebrahimi (CS_ARCH_X86, CS_MODE_64, "X86-64 (ATT syntax)", CS_OPT_SYNTAX_ATT), 35*9a0e4156SSadaf Ebrahimi (CS_ARCH_ARM, CS_MODE_ARM, "ARM", 0), 36*9a0e4156SSadaf Ebrahimi (CS_ARCH_ARM, CS_MODE_THUMB, "THUMB (ARM)", 0), 37*9a0e4156SSadaf Ebrahimi (CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN, "MIPS-32 (Big-endian)", 0), 38*9a0e4156SSadaf Ebrahimi (CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_LITTLE_ENDIAN, "MIPS-64-EL (Little-endian)", 0), 39*9a0e4156SSadaf Ebrahimi (CS_ARCH_ARM64, CS_MODE_ARM, "ARM-64 (AArch64)", 0), 40*9a0e4156SSadaf Ebrahimi (CS_ARCH_PPC, CS_MODE_BIG_ENDIAN, "PPC", 0), 41*9a0e4156SSadaf Ebrahimi (CS_ARCH_PPC, CS_MODE_BIG_ENDIAN, "PPC, print register with number only", CS_OPT_SYNTAX_NOREGNAME), 42*9a0e4156SSadaf Ebrahimi (CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, "Sparc", 0), 43*9a0e4156SSadaf Ebrahimi (CS_ARCH_SYSZ, 0, "SystemZ", 0), 44*9a0e4156SSadaf Ebrahimi (CS_ARCH_XCORE, 0, "XCore", 0), 45*9a0e4156SSadaf Ebrahimi (CS_ARCH_M68K, 0, "M68K", 0), 46*9a0e4156SSadaf Ebrahimi ) 47*9a0e4156SSadaf Ebrahimi 48*9a0e4156SSadaf Ebrahimi 49*9a0e4156SSadaf Ebrahimi# for debugging 50*9a0e4156SSadaf Ebrahimidef to_hex(s): 51*9a0e4156SSadaf Ebrahimi return " ".join("0x" + "{0:x}".format(ord(c)).zfill(2) for c in s) # <-- Python 3 is OK 52*9a0e4156SSadaf Ebrahimi 53*9a0e4156SSadaf Ebrahimi 54*9a0e4156SSadaf Ebrahimi# read @size bytes from @f & return data. 55*9a0e4156SSadaf Ebrahimi# return None when there is not enough data 56*9a0e4156SSadaf Ebrahimidef get_code(f, size): 57*9a0e4156SSadaf Ebrahimi code = f.read(size) 58*9a0e4156SSadaf Ebrahimi if len(code) != size: # reached end-of-file? 59*9a0e4156SSadaf Ebrahimi # then reset file position to begin-of-file 60*9a0e4156SSadaf Ebrahimi f.seek(0) 61*9a0e4156SSadaf Ebrahimi return None 62*9a0e4156SSadaf Ebrahimi 63*9a0e4156SSadaf Ebrahimi return code 64*9a0e4156SSadaf Ebrahimi 65*9a0e4156SSadaf Ebrahimi 66*9a0e4156SSadaf Ebrahimidef cs(md, code): 67*9a0e4156SSadaf Ebrahimi insns = md.disasm(code, 0) 68*9a0e4156SSadaf Ebrahimi for i in insns: 69*9a0e4156SSadaf Ebrahimi if i.address == 0x100000: 70*9a0e4156SSadaf Ebrahimi print i 71*9a0e4156SSadaf Ebrahimi 72*9a0e4156SSadaf Ebrahimi 73*9a0e4156SSadaf Ebrahimidef cs_lite(md, code): 74*9a0e4156SSadaf Ebrahimi insns = md.disasm_lite(code, 0) 75*9a0e4156SSadaf Ebrahimi for (addr, size, mnem, ops) in insns: 76*9a0e4156SSadaf Ebrahimi if addr == 0x100000: 77*9a0e4156SSadaf Ebrahimi print i 78*9a0e4156SSadaf Ebrahimi 79*9a0e4156SSadaf Ebrahimi 80*9a0e4156SSadaf Ebrahimicfile = open(FILE) 81*9a0e4156SSadaf Ebrahimi 82*9a0e4156SSadaf Ebrahimifor (arch, mode, comment, syntax) in all_tests: 83*9a0e4156SSadaf Ebrahimi try: 84*9a0e4156SSadaf Ebrahimi request = sys.argv[1] 85*9a0e4156SSadaf Ebrahimi if not request in comment.lower(): 86*9a0e4156SSadaf Ebrahimi continue 87*9a0e4156SSadaf Ebrahimi except: 88*9a0e4156SSadaf Ebrahimi pass 89*9a0e4156SSadaf Ebrahimi 90*9a0e4156SSadaf Ebrahimi try: 91*9a0e4156SSadaf Ebrahimi md = Cs(arch, mode) 92*9a0e4156SSadaf Ebrahimi md.detail = True 93*9a0e4156SSadaf Ebrahimi 94*9a0e4156SSadaf Ebrahimi if syntax != 0: 95*9a0e4156SSadaf Ebrahimi md.syntax = syntax 96*9a0e4156SSadaf Ebrahimi 97*9a0e4156SSadaf Ebrahimi # test disasm() 98*9a0e4156SSadaf Ebrahimi print("\nFuzzing disasm() @platform: %s" %comment) 99*9a0e4156SSadaf Ebrahimi for ii in INTERVALS: 100*9a0e4156SSadaf Ebrahimi print("Interval: %u" %ii) 101*9a0e4156SSadaf Ebrahimi for j in xrange(1, TIMES): 102*9a0e4156SSadaf Ebrahimi while (True): 103*9a0e4156SSadaf Ebrahimi code = get_code(cfile, j * ii) 104*9a0e4156SSadaf Ebrahimi if code is None: 105*9a0e4156SSadaf Ebrahimi # EOF? break 106*9a0e4156SSadaf Ebrahimi break 107*9a0e4156SSadaf Ebrahimi #print to_hex(code) 108*9a0e4156SSadaf Ebrahimi cs(md, code) 109*9a0e4156SSadaf Ebrahimi 110*9a0e4156SSadaf Ebrahimi # test disasm_lite() 111*9a0e4156SSadaf Ebrahimi print("Fuzzing disasm_lite() @platform: %s" %comment) 112*9a0e4156SSadaf Ebrahimi for ii in INTERVALS: 113*9a0e4156SSadaf Ebrahimi print("Interval: %u" %ii) 114*9a0e4156SSadaf Ebrahimi for j in xrange(1, TIMES): 115*9a0e4156SSadaf Ebrahimi while (True): 116*9a0e4156SSadaf Ebrahimi code = get_code(cfile, j * ii) 117*9a0e4156SSadaf Ebrahimi if code is None: 118*9a0e4156SSadaf Ebrahimi # EOF? break 119*9a0e4156SSadaf Ebrahimi break 120*9a0e4156SSadaf Ebrahimi #print to_hex(code) 121*9a0e4156SSadaf Ebrahimi cs_lite(md, code) 122*9a0e4156SSadaf Ebrahimi 123*9a0e4156SSadaf Ebrahimi except CsError as e: 124*9a0e4156SSadaf Ebrahimi print("ERROR: %s" %e) 125