如何查找IDAPython中的所有开关跳转表


1

我在IDA 6.5上使用IDAPython,并试图获取DLL中的所有开关跳转表。主要是我感兴趣的跳转表被间接地跳了起来:

jmp  ds:off_65018790[ecx*4] ; switch jump 

基本上,我感兴趣的是:

  • 从哪里JMP发生
  • 可能位置列表中的地址,例如 - loc_65018723,loc_65018736 ...

我已经知道如何使用IDAPython所有JMP的地址,但我不知道这是否是一个JMP到一个跳转表,或只是一个规范al jmp。

在大多数情况下,IDA知道识别这些跳转表,那么是否有方法从API获取该信息?

非常感谢!

  0

不幸的是我没有安装IDA 6.5,但据我记得idaapi.get_switch_info_ex(ea)已经在那里。查看此函数的参考用法的最简单方法是在github上调用此函数来搜索python代码。 25 8月. 162016-08-25 09:12:21

  0

非常感谢!这正是我所需要的。如果您将其作为回答发布,我会将其标记为已回答:) 26 8月. 162016-08-26 11:42:43

1

决定添加一个小代码片段来展示如何遍历.text段,获取所有切换表位置并将跳转目标存储在字典中。

text_seg = idaapi.get_segm_by_name('.text') 
jump_table = dict() 

# iterate through all items within the segment 
for head_ea in idautils.Heads(text_seg.startEA, text_seg.endEA): 
    if idc.isCode(idc.GetFlags(head_ea)): 
     switch_info = idaapi.get_switch_info_ex(head_ea) 
     if (switch_info and switch_info.jumps != 0): 
      loc = switch_info.jumps 
      jump_table[loc] = list() 
      element_num = switch_info.get_jtable_size() 
      element_size = switch_info.get_jtable_element_size() 
      for num in range(0, element_num): 
       table_entry = loc+num*element_size 
       jump_table[loc].append(idc.GetManyBytes(table_entry), element_size) 
  0

'getnseg'收到一个段号,而'SegByName'返回一个段选择器,这些不一样。你的第一行是错误的。 09 9月. 162016-09-09 10:38:04

  0

此外,使用'idc.Dword'感觉不安全,并假定交换代码的确按OP描述的方式构建,但并非总是如此。 09 9月. 162016-09-09 10:48:11

  0

感谢Nirlzr,上面的代码片段来自我在ARM32二进制文件中使用的旧脚本,以便提取出跳转表以重写它们。我已经更新它来修复你指出的错误。 10 9月. 162016-09-10 09:32:06


0

安全地从某个EA得到的所有引用,有idc.XrefsFrom(ea, flags)。你会从某个EA(switch-case的分支/跳转指令)获得一个交叉引用的迭代器。开关盒很容易识别,因为它们总是具有两个以上的交叉引用目标。

根据thisflags参数是下列之一:

XREF_USER = 32
XREF_TAIL = 64
XREF_BASE = 128
XREF_MASK = 31
XREF_PASTEND = 256
XREF_ALL = 0
XREF_FAR = 1
XREF_DATA = 2

,你会从每一次迭代中得到的对象是ida_xref对象,露出下面的属性:

  1. frm - 交叉引用,执行在我们的例子跳跃代码的来源。
  2. to - 交叉引用的目标,根据我们的情况,将根据跳转表选择器执行的代码。
  3. iscode - 布尔型,True如果交叉引用是代码交叉引用,则在我们的示例中必须为True
  4. type - 其中一个可用的类型值,请参阅下文。您可以使用idautils.XrefTypeName(typecode)将您在此获得的整数转换为可读的字符串。
  5. user - 布尔值,如果此交叉引用是由用户创建的,而不是由IDA自动创建的,则为True。

有效交叉引用类型是,根据this

ref_types = {
0: 'Data_Unknown',
1: '的DATA_Offset',
2: 'Data_Write',
3: 'DATA_READ',
4: 'Data_Text',
5: 'Data_Informational',
16: 'Code_Far_Call',
17: 'Code_Near_Call',
18: 'Code_Far_Jump',
19: 'Code_Near_Jump',
20: 'Code_User',
21: 'Ordinary_Flow'
}