├── README.txt └── colorpc.py /README.txt: -------------------------------------------------------------------------------- 1 | colorpc 2 | deroko of ARTeam 3 | 4 | Old script to color all pc redirections in IDA for intel/arm/aarch64. 5 | -------------------------------------------------------------------------------- /colorpc.py: -------------------------------------------------------------------------------- 1 | # colorpc.py - deroko of ARTeam 2 | # 3 | # prev name was coloreipred.py but now, since it supports arm/aarch64, 4 | # name is changed to colorpc.py 5 | # 6 | # IDA Script to color all PC redirection inside of selected procedure 7 | # Colors are as follows: 8 | # blue - call instructions 9 | # yellow - jcc/jmp instructions 10 | # red - ret instruction 11 | # green - call/jmp [mem/reg] 12 | # 13 | # It binds to key "i", and that can be changed at the bottom of 14 | # the script 15 | # 16 | # Added support for arm/aarch64 17 | # 18 | # deroko of ARTeam 19 | import idaapi 20 | import idc 21 | import colorsys 22 | 23 | #stop insts 24 | stop_list = [ 25 | idaapi.NN_retn, 26 | idaapi.NN_retf, 27 | idaapi.NN_retnq, 28 | idaapi.NN_retfq, 29 | 30 | ]; 31 | 32 | stop_list_arm = [ 33 | idaapi.ARM_ret 34 | ]; 35 | 36 | #list of jcc instructions 37 | jcc_list = [ 38 | idaapi.NN_ja, 39 | idaapi.NN_jae, 40 | idaapi.NN_jb, 41 | idaapi.NN_jbe, 42 | idaapi.NN_jc, 43 | idaapi.NN_je, 44 | idaapi.NN_jg, 45 | idaapi.NN_jge, 46 | idaapi.NN_jl, 47 | idaapi.NN_jle, 48 | idaapi.NN_jna, 49 | idaapi.NN_jnae, 50 | idaapi.NN_jnb, 51 | idaapi.NN_jnbe, 52 | idaapi.NN_jnc, 53 | idaapi.NN_jne, 54 | idaapi.NN_jng, 55 | idaapi.NN_jnge, 56 | idaapi.NN_jnl, 57 | idaapi.NN_jnle, 58 | idaapi.NN_jno, 59 | idaapi.NN_jnp, 60 | idaapi.NN_jns, 61 | idaapi.NN_jnz, 62 | idaapi.NN_jo, 63 | idaapi.NN_jp, 64 | idaapi.NN_jpe, 65 | idaapi.NN_jpo, 66 | idaapi.NN_js, 67 | idaapi.NN_jz, 68 | idaapi.NN_jcxz, 69 | idaapi.NN_jecxz, 70 | idaapi.NN_jrcxz, 71 | idaapi.NN_jmp, 72 | idaapi.NN_jmpni, 73 | idaapi.NN_jmpshort, 74 | idaapi.NN_loop, 75 | idaapi.NN_loopq, 76 | idaapi.NN_loope, 77 | idaapi.NN_loopqe, 78 | idaapi.NN_loopne, 79 | idaapi.NN_loopqne 80 | ]; 81 | 82 | jcc_list_arm = [ 83 | idaapi.ARM_b, 84 | idaapi.ARM_bx, 85 | idaapi.ARM_bxj, 86 | 87 | ]; 88 | 89 | call_list = [ 90 | idaapi.NN_call, 91 | idaapi.NN_callfi, 92 | idaapi.NN_callni, 93 | ]; 94 | 95 | call_list_arm = [ 96 | idaapi.ARM_bl, 97 | idaapi.ARM_blx1, 98 | idaapi.ARM_blx2, 99 | ]; 100 | 101 | def get_yellow(): 102 | r = 0xFF/255.0; 103 | g = 0xFF/255.0; 104 | b = 0x00/255.0; 105 | 106 | (h,s,v) = colorsys.rgb_to_hsv(r,g,b); 107 | s -= 0.6; 108 | (r,g,b) = colorsys.hsv_to_rgb(h,s,v); 109 | ida_color = (int(b*255) << 16) + (int(g*255)<<8) + int(r*255); 110 | return ida_color; 111 | 112 | def get_blue(): 113 | r = 0x00/255.0; 114 | g = 0x00/255.0; 115 | b = 0xff/255.0; 116 | 117 | (h,s,v) = colorsys.rgb_to_hsv(r,g,b); 118 | s -= 0.7; 119 | (r,g,b) = colorsys.hsv_to_rgb(h,s,v); 120 | #it's BGR 121 | ida_color = (int(b*255) << 16) + (int(g*255)<<8) + int(r*255); 122 | return ida_color; 123 | 124 | def get_green(): 125 | r = 0x00/255.0; 126 | g = 0xff/255.0; 127 | b = 0x00/255.0; 128 | 129 | (h,s,v) = colorsys.rgb_to_hsv(r,g,b); 130 | s -= 0.7; 131 | (r,g,b) = colorsys.hsv_to_rgb(h,s,v); 132 | #it's BGR 133 | ida_color = (int(b*255) << 16) + (int(g*255)<<8) + int(r*255); 134 | return ida_color; 135 | 136 | def get_red(): 137 | r = 0xff/255.0; 138 | g = 0x00/255.0; 139 | b = 0x00/255.0; 140 | 141 | (h,s,v) = colorsys.rgb_to_hsv(r,g,b); 142 | s -= 0.7; 143 | (r,g,b) = colorsys.hsv_to_rgb(h,s,v); 144 | #it's BGR 145 | ida_color = (int(b*255) << 16) + (int(g*255)<<8) + int(r*255); 146 | return ida_color; 147 | 148 | def get_proc_name(): 149 | info = idaapi.get_inf_structure(); 150 | return info.get_proc_name(); 151 | 152 | def get_call_list(): 153 | proc_name = get_proc_name(); 154 | if "metapc" in proc_name: 155 | return call_list; 156 | if "ARM" in proc_name: 157 | return call_list_arm; 158 | return None; 159 | 160 | def get_jcc_list(): 161 | proc_name = get_proc_name(); 162 | if "metapc" in proc_name: 163 | return jcc_list; 164 | if "ARM" in proc_name: 165 | return jcc_list_arm; 166 | return None; 167 | 168 | def get_stop_list(): 169 | proc_name = get_proc_name(); 170 | if "metapc" in proc_name: 171 | return stop_list; 172 | if "ARM" in proc_name: 173 | return stop_list_arm; 174 | return None; 175 | 176 | def inst_is_jcc(pc): 177 | i = idaapi.cmd.itype; 178 | lst = get_jcc_list(); 179 | for x in lst: 180 | if x == i: return True; 181 | return False; 182 | def inst_is_call(pc): 183 | i = idaapi.cmd.itype; 184 | lst = get_call_list(); 185 | for x in lst: 186 | if x == i: return True; 187 | return False; 188 | 189 | #for ARM this has to be processed in different manner... 190 | #we look for ldm/pop where pc is altered, and bx with lr 191 | def inst_is_ret(pc): 192 | i = idaapi.cmd.itype; 193 | lst = get_stop_list(); 194 | for x in lst: 195 | if x == i: return True; 196 | if "ARM" in get_proc_name(): 197 | #ok instead of understanding all specflags and vals for ARM in cmd.Operands 198 | #I'll use ins mnemonic... 199 | mne = idc.GetDisasm(pc); 200 | if idaapi.cmd.itype == idaapi.ARM_pop: 201 | if "PC" in mne: return True; 202 | #for x in idaapi.cmd.Operands: 203 | # print "%d %d %d" % (x.type, x.dtyp, x.specval); 204 | if idaapi.cmd.itype == idaapi.ARM_bx: 205 | if "LR" in mne: return True; 206 | if idaapi.cmd.itype == idaapi.ARM_ldm: 207 | if "PC" in mne: return True; 208 | return False; 209 | 210 | def is_indirect(pc): 211 | op = idaapi.cmd.Operands[0]; 212 | if not op: 213 | return False; 214 | if op.type in [idaapi.o_mem, idaapi.o_displ, idaapi.o_reg, idaapi.o_phrase]: 215 | return True; 216 | return False; 217 | 218 | def main(): 219 | eip = idaapi.get_screen_ea(); 220 | function = idaapi.func_item_iterator_t(); 221 | function.set(idaapi.get_func(eip)); 222 | 223 | b_ok = function.first(); 224 | while b_ok: 225 | pc = function.current(); 226 | inslen = idaapi.decode_insn(function.current()); 227 | if inslen == 0: 228 | b_ok = function.next_code(); 229 | continue; 230 | if inst_is_call(pc): 231 | color = get_blue(); 232 | if is_indirect(pc): 233 | color = get_green(); 234 | idc.SetColor(pc, CIC_ITEM, color); 235 | elif inst_is_ret(pc): 236 | color = get_red(); 237 | idc.SetColor(pc, CIC_ITEM, color); 238 | elif inst_is_jcc(pc): 239 | color = get_yellow(); 240 | if is_indirect(pc): 241 | color = get_green(); 242 | idc.SetColor(pc, CIC_ITEM, color); 243 | b_ok = function.next_code(); 244 | 245 | if __name__ == "__main__": 246 | idaapi.CompileLine('static color_key() { RunPythonStatement("main()"); }') 247 | # Add the hotkey 248 | AddHotkey("i", 'color_key'); 249 | 250 | 251 | --------------------------------------------------------------------------------