我正在尝试使用 IDA Pro 6.5 和 IDA Python 自动反汇编固件映像。我想要实现的过程之一是定位字符串并在它们周围创建一个数据段。
使用 GUI,我这样做几乎没有问题。但是,在使用idautils.Strings()
API 调用时,我可以检索StringItem
对象列表,但无法使用str()
或访问实际的字符串数据unicode()
。下面是失败的函数,它取自IDA Python Google 代码存档:
def find_strings():
s = idautils.Strings(False)
s.setup(strtypes=Strings.STR_UNICODE | Strings.STR_C)
for i, v in enumerate(s):
if v is None:
print("Failed to retrieve string index %d" % i)
else:
print("%x: len=%d type=%d index=%d-> '%s'" % (v.ea, v.length, v.type, i, str(v)))
遇到IDA,报如下错误:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "<string>", line 8, in find_strings
TypeError: 'StringItem' object is not callable
当更换str(v)
与常变量aaa
的print
函数,我得到的名单StringItem
没有任何问题的对象:
Python>find_strings()
208e: len=8 type=3 index=0-> 'aaa'
21b0: len=55 type=0 index=1-> 'aaa'
229d: len=6 type=0 index=2-> 'aaa'
22c5: len=5 type=0 index=3-> 'aaa'
22d3: len=33 type=0 index=4-> 'aaa'
...
如果我尝试使用该unicode()
函数,则会出现以下错误:
Python>find_strings()
208e: len=8 type=3 index=0-> '
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "<string>", line 8, in find_strings
TypeError: coercing to Unicode: need string or buffer, NoneType found
根据我的理解,似乎由于StringItem
未知原因(或插件的问题,可能是 Python 的特定版本?)不包含任何字符串,但是它们显示在 GUI 中。
我正在寻求关于我做错了什么的建议,或者使用 IDApython 插件提取字符串的替代方法。谢谢
更新
添加注释中提到的缺少的括号后,上面的代码似乎有效。然而,这只是帖子中的一个错字,而不是问题的根源。在find_strings
其他典型的二进制文件的罚款。进一步的证明是,通过使用idc.GetString(self.ea, self.length, self.type)
还返回的NoneType
.
Diff 提到get_ascii_contents2
正在失败并因此返回null
,这很可能是原因。不清楚的是为什么该函数失败,而 GUI 成功定位了大部分字符串。
0x208E 处的第一个字符串是垃圾 Unicode 字符串。0x21B0 处的字符串是由 37 个字符组成的实际 ASCII 字符串。由于披露/法律问题,我无法发布完整的字符串。请注意,当在十六进制编辑器中显示时,ASCII 视图的字节顺序因未知原因而反转。整体固件的位数为 16 位。
434F 5059 5249 4748 5420 A920 ... 4544 2000 0000 : OCYPIRHG T ¬ ... DE.
最后,请注意该功能MakeStr
可以正常工作。我有以下代码,当在 0x21B0 处使用时,将成功在数据段内创建一个字符串:
def create_string(self, _startea, _endea, _segname=".const", _unicode=False):
if (SegStart(_startea) == idc.BADADDR):
self.create_data_segment(_startea, _endea, ".const")
else:
segtype = GetSegmentAttr(_startea, SEGATTR_TYPE)
if (segtype != IDAEngine.SEG_TYPE_DATA):
DelSeg(_startea, 0)
self.create_data_segment(_startea, _endea, _segname)
result = MakeStr(_startea, _endea)
if (result == IDAEngine.FAIL):
print "[-] Failed to create a string at 0x{:x} to 0x{:x}.".format(_startea, _endea)
在这一点上,我认为应该归咎于固件的结构(位组合、缺少符号和过时但受支持的微处理器),但是我无法确定确切的问题。现在,因为我可以find_strings()
用来检索偏移量,然后MakeStr
在具有一定长度的字符串上使用并手动审查“真实”字符串。
结语
对于后代,我从来没有真正解决过这个问题,但是我可以确认底层的二进制文件负责在get_ascii_contents2
. 我重新加载了同一个文件,但是作为一个大段中的原始二进制文件,该功能运行完美。