def is_cjump(inst): return (inst.itype in [idaapi.NN_jnbe, idaapi.NN_ja, idaapi.NN_jnb, idaapi.NN_jae, idaapi.NN_jb, idaapi.NN_jnae, idaapi.NN_jbe, idaapi.NN_jna, idaapi.NN_jg, idaapi.NN_jnle, idaapi.NN_jge, idaapi.NN_jnl, idaapi.NN_jl, idaapi.NN_jnge, idaapi.NN_jle, idaapi.NN_jng, idaapi.NN_je, idaapi.NN_jz, idaapi.NN_jne, idaapi.NN_jnz]) def constrain_values(ea,low,high,const): i = idaapi.get_current_instruction() if (i.itype in [idaapi.NN_jnbe, idaapi.NN_ja, idaapi.NN_jg, idaapi.NN_jnle]): return (const+1,high,low,const) if (i.itype in [idaapi.NN_jnb, idaapi.NN_jae, idaapi.NN_jge, idaapi.NN_jnl]): return (const,high,low,const-1) if (i.itype in [idaapi.NN_jb, idaapi.NN_jnae, idaapi.NN_jl, idaapi.NN_jnge]): return (low,const-1,const,high) if (i.itype in [idaapi.NN_jbe, idaapi.NN_jna, idaapi.NN_jle, idaapi.NN_jng]): return (low,const,const+1,high) if (i.itype in [idaapi.NN_je, idaapi.NN_jz]): return (const,const,low,high) if (i.itype in [idaapi.NN_jne, idaapi.NN_jnz]): return (low,high,const,const) def is_compare(inst, reg): return ((inst.itype == idaapi.NN_cmp) and (idaapi.get_instruction_operand(inst,0).reg == reg) and (idaapi.get_instruction_operand(inst,1).type == idaapi.o_imm)) def get_compared_int(inst): return idaapi.get_instruction_operand(inst,1).value def analyze_bswitch(dict, reg, ea, low, high, lastcomp): idaapi.ua_ana0(ea) inst = idaapi.get_current_instruction() if(is_compare(inst,reg)): lastcomp = get_compared_int(inst) ea = idaapi.next_head(ea, ea+15) idaapi.ua_ana0(ea) inst = idaapi.get_current_instruction() if(is_cjump(inst)): l1,h1,l2,h2 = constrain_values(ea,low,high,lastcomp) analyze_bswitch(dict, reg, CodeRefsFrom(ea,0)[0], l1, h1, lastcomp) analyze_bswitch(dict, reg, idaapi.next_head(ea, ea+15), l2, h2, lastcomp) else: if(ea not in dict): dict[ea] = [(low,high)] else: dict[ea].extend([(low,high)]) def analyze_bswitch_unsigned(dict, reg, ea): analyze_bswitch(dict, reg, ea, 0, 4294967295, 0) def analyze_bswitch_signed(dict, reg, ea): analyze_bswitch(dict, reg, ea, -2147483648, 2147483647, 0) def bswitch(dict, reg, ea, signed): if signed: analyze_bswitch_signed(dict, reg, ea) else: analyze_bswitch_unsigned(dict, reg, ea) # first zero signifies eax dict = {} bswitch(dict, 0, idaapi.get_screen_ea(), 0) maxkey = 0 maxlen = 0 def process(key, list): str = "case " isFirst = 1; for (a,b) in list: cstr = "" substr = "" if isFirst == 0: substr = ", " if(a == b): cstr = "0%lXh" % a else: cstr = "0%lXh-0%lXh" % (a,b) str = str + (substr + cstr) idaapi.set_cmt(key, str, 1) isFirst = 0 for key in dict.keys(): if(len(dict[key]) > maxlen): if(maxlen != 0): process(maxkey, dict[maxkey]) maxkey = key maxlen = len(dict[key]) else: process(key, dict[key]) idaapi.set_cmt(maxkey, "default", 1)