# IDAPython CTREE ## Important links * [Hex-Rays Decompiler Primer](http://www.hexblog.com/?p=107) * [hexrays.hpp](https://www.hex-rays.com/products/decompiler/manual/sdk/hexrays_8hpp_source.shtml) ## Description The CTREE is built from the optimized microcode (maturity at `CMAT_FINAL`), it represents an AST-like tree with C statements and expressions. It can be printed as C code. ## Play with decompiled function ### Decompile a function ```python ea = idaapi.here() cfunc = idaapi.decompile(ea) ``` ### Get decompiled function from pseudocode widget ```python w = idaapi.get_current_widget() # if widget type is pseudocode if idaapi.get_widget_type(w) == idaapi.BWN_PSEUDOCODE: vu = idaapi.get_widget_vdui(w) cfunc = vu.cfunc ``` ### Refresh pseudocode in widget ```python vu.refresh_ctext() ``` ### Get local variables ```python lvars = cfunc.get_lvars() ``` ### Get calling convention ```python tinfo = idaapi.tinfo_t() cfunc.get_func_type(tinfo) funcdata = idaapi.func_type_data_t() tinfo.get_func_details(funcdata) cc = funcdata.cc # can be one of CM_CC_* -> examples: CM_CC_CDECL, CM_CC_STDCALL, CM_CC_FASTCALL ``` ### Get arguments ```python for i in cfunc.argidx: tinfo = lvars[i].type() ``` ### Manipulate types of local variables ```python tinfo = lvars[0].type() if tinfo.is_funcptr(): number_of_args = tinfo.get_nargs() rettype = tinfo.get_rettype() for i in number_of_args: tinfo_arg = tinfo.get_nth_arg(i) ``` ## Exploring the CTREE ### Create a CTREE visitor ```python import idaapi class my_super_visitor(idaapi.ctree_visitor_t): def __init__(self): idaapi.ctree_visitor_t.__init__(self, idaapi.CV_FAST) # CV_FAST does not keep parents nodes in CTREE def visit_insn(self, i): return 0 def visit_expr(self, e): if e.op != idaapi.cot_asg: return 0 return 0 cfunc = idaapi.decompile(idc.here()) v = my_super_visitor() v.apply_to(cfunc.body, None) ``` ### Type of expressions and statements ```c enum ctype_t { cot_empty = 0, cot_comma = 1, ///< x, y cot_asg = 2, ///< x = y cot_asgbor = 3, ///< x |= y cot_asgxor = 4, ///< x ^= y cot_asgband = 5, ///< x &= y cot_asgadd = 6, ///< x += y cot_asgsub = 7, ///< x -= y cot_asgmul = 8, ///< x *= y cot_asgsshr = 9, ///< x >>= y signed cot_asgushr = 10, ///< x >>= y unsigned cot_asgshl = 11, ///< x <<= y cot_asgsdiv = 12, ///< x /= y signed cot_asgudiv = 13, ///< x /= y unsigned cot_asgsmod = 14, ///< x %= y signed cot_asgumod = 15, ///< x %= y unsigned cot_tern = 16, ///< x ? y : z cot_lor = 17, ///< x || y cot_land = 18, ///< x && y cot_bor = 19, ///< x | y cot_xor = 20, ///< x ^ y cot_band = 21, ///< x & y cot_eq = 22, ///< x == y int or fpu (see EXFL_FPOP) cot_ne = 23, ///< x != y int or fpu (see EXFL_FPOP) cot_sge = 24, ///< x >= y signed or fpu (see EXFL_FPOP) cot_uge = 25, ///< x >= y unsigned cot_sle = 26, ///< x <= y signed or fpu (see EXFL_FPOP) cot_ule = 27, ///< x <= y unsigned cot_sgt = 28, ///< x > y signed or fpu (see EXFL_FPOP) cot_ugt = 29, ///< x > y unsigned cot_slt = 30, ///< x < y signed or fpu (see EXFL_FPOP) cot_ult = 31, ///< x < y unsigned cot_sshr = 32, ///< x >> y signed cot_ushr = 33, ///< x >> y unsigned cot_shl = 34, ///< x << y cot_add = 35, ///< x + y cot_sub = 36, ///< x - y cot_mul = 37, ///< x * y cot_sdiv = 38, ///< x / y signed cot_udiv = 39, ///< x / y unsigned cot_smod = 40, ///< x % y signed cot_umod = 41, ///< x % y unsigned cot_fadd = 42, ///< x + y fp cot_fsub = 43, ///< x - y fp cot_fmul = 44, ///< x * y fp cot_fdiv = 45, ///< x / y fp cot_fneg = 46, ///< -x fp cot_neg = 47, ///< -x cot_cast = 48, ///< (type)x cot_lnot = 49, ///< !x cot_bnot = 50, ///< ~x cot_ptr = 51, ///< *x, access size in 'ptrsize' cot_ref = 52, ///< &x cot_postinc = 53, ///< x++ cot_postdec = 54, ///< x-- cot_preinc = 55, ///< ++x cot_predec = 56, ///< --x cot_call = 57, ///< x(...) cot_idx = 58, ///< x[y] cot_memref = 59, ///< x.m cot_memptr = 60, ///< x->m, access size in 'ptrsize' cot_num = 61, ///< n cot_fnum = 62, ///< fpc cot_str = 63, ///< string constant cot_obj = 64, ///< obj_ea cot_var = 65, ///< v cot_insn = 66, ///< instruction in expression, internal representation only cot_sizeof = 67, ///< sizeof(x) cot_helper = 68, ///< arbitrary name cot_type = 69, ///< arbitrary type cot_last = cot_type, cit_empty = 70, ///< instruction types start here cit_block = 71, ///< block-statement: { ... } cit_expr = 72, ///< expression-statement: expr; cit_if = 73, ///< if-statement cit_for = 74, ///< for-statement cit_while = 75, ///< while-statement cit_do = 76, ///< do-statement cit_switch = 77, ///< switch-statement cit_break = 78, ///< break-statement cit_continue = 79, ///< continue-statement cit_return = 80, ///< return-statement cit_goto = 81, ///< goto-statement cit_asm = 82, ///< asm-statement cit_end }; ```