OneShell

I fight for a brighter tomorrow

0%

IDAPython-段粒度

简单说明了IDA的反汇编输出窗口内容、如何使用IDAPython对单条指令进行简单分析。后续的笔记将先分别从段(segment)、函数(function)、块(block)、指令(instruction)多个粒度,对IDAPython经常使用到的数据结构和函数API进行说明,然后再到分析必不可少的交叉引用(cross-references)和数据搜索(searching for code or data)。

segment的基本操作

如下是对段(segments)进行一些基本的操作。idautils.Segments()会返回一个迭代器,可以使用循环遍历当前文件的所有段对象。对于每一个段对象可以使用idc.get_segm_name获取段名、idc.get_segm_start获取段起始地址、idc.get_segm_end获取段的结束地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import idautils
for seg in idautils.Segments():
print(idc.get_segm_name(seg), idc.get_segm_start(seg), idc.get_segm_end(seg))

'''
LOAD 4194304 4194568
REGINFO 4194568 4194592
LOAD 4194592 4216248
.init 4216248 4216384
.text 4216384 4649072
.MIPS.stubs 4649072 4651008
.fini 4651008 4651096
LOAD 4651096 4651104
......
'''

在实际的代码中,有时候需要对当前地址ea所在的段进行分析。idc.get_segm_start(ea)idc.get_segm_end(ea)分别可以获取到地址ea所在的段的起始地址和结束地址;idc.get_next_seg(ea)可以获取到ea所在段的下一个段起始地址,然后没有找到对应的寻找上一个段起始地址的API。使用idc.get_segm_name(ea)则可以获取到当前地址ea所在段的段名。如下:

1
2
3
4
5
6
7
8
9
10
11
Python>ea = idc.here()
Python>idc.get_segm_start(ea)
0x400120
Python>idc.get_segm_end(ea)
0x46f8f8
Python>idc.get_next_seg(ea)
0x46f8f8
Python>idc.get_segm_name(ea)
'.text'
Python>idc.get_segm_name(0x46f8f8)
'.fini'

同样的,也可以根据段名来获取到段相关属性:idc.get_segm_by_sel(idc.selector_by_name(str_SectionName))。需要首先使用idc.selector_by_name(str_SectionName)获取到段名为str_SectionName的段选择器(selector),然后使用idc.get_segm_by_sel()来获取到段的起始地址。如下:

1
2
3
Python>str_SectionName = ".text"
Python>idc.get_segm_by_sel(idc.selector_by_name(str_SectionName))
0x400120

idc模块中常用的段操作函数

api 作用
get_segm_attr(segea, attr) 根据段中的地址segea获取段的attr属性
get_segm_start(ea) 获取段起始地址
get_segm_end(ea) 获取段结束地址
get_segm_name(ea) 获取段名

包含更多段操作的模块:ida_segment

idc模块中对段的操作实际上是对ida_segment模块中函数的封装,在ida_segment模块中还有更多段的数据结构和方法,例如:

  • 新增段:add_segm
  • 删除段:del_segm
  • 根据段名获取段:get_segm_by_name
  • 根据当前地址获取段名:get_segm_name
  • 设置段名:set_segm_name
  • 设置段的起始地址:set_segm_startset_segm_end
  • ……

参考链接