我正在尝试使用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对象的列表,没有任何问题:
据我了解,unicode()似乎不包含任何字符串,原因不明(或插件有问题,可能是特定版本的Python?),但是它们显示在GUI中。我就我做错了的事寻求建议,或者使用IDApython插件提取字符串的另一种方法。谢谢
更新
上面的代码在添加了注释中提到的缺少括号后才有效。但是,这只是帖子中的错字,而不是问题的根源。在其他典型的二进制文件中,StringItem可以正常工作。进一步的证明是通过使用find_strings还返回了idc.GetString(self.ea, self.length, self.type)。尚不清楚的是,为什么函数失败了,而GUI却成功找到了大多数字符串。
0x208E处的第一个字符串是垃圾Unicode字符串。 0x21B0处的字符串是由37个字符组成的实际ASCII字符串。由于披露/法律问题,我无法发布完整的字符串。请注意,当显示在十六进制编辑器中时,由于未知原因,ASCII视图的字节顺序将反转。整个固件的位数为16位。
NoneType
最后,请注意,功能get_ascii_contents2可以正常工作。我有以下代码,在0x21B0处使用时,将成功在数据段内创建一个字符串:
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'
...

至此,我认为固件的结构应归咎于(位组合,缺少位)符号和已过时但受支持的微处理器),但是我无法指出确切的问题。现在,由于我可以使用null来获取偏移量,然后对具有一定长度的字符串和手动审核“真实”字符串使用434F 5059 5249 4748 5420 A920 ... 4544 2000 0000 : OCYPIRHG T ¬ ... DE.
最后的注释
为了后代,我从未真正解决过问题,但是我可以确认基本二进制文件负责引发MakeStr中的异常。我已经重新加载了同一个文件,但是作为原始二进制文件在一个很大的段中重新加载,并且该功能可以完美地运行。

评论

您在最后一行代码中缺少a),固定版本为; print(“%x:len =%d type =%d index =%d->'%s'”%(v.ea,v.length,v.type,i,str(v)))使用此修复该脚本可以在我的机器上正常运行。这不是问题吗?

不幸的是,似乎缺少括号是由于错误的复制粘贴所致。我的代码实际上包含多余的括号。另外,我一直在尝试使用idc.GetString(self.ea,self.length,self.type)具有相同的结果。我怀疑二进制文件的格式是某种原因。我正在查看的固件不是众所周知的体系结构(不是Intel,ARM或MIPS ...)

这对我来说没有再现。您在使用最新的IDAPython吗?

同意,在修正拼写错误后,代码也可以正常工作。

#1 楼

这花了一些时间,但是看来您遇到了一个有趣的极端情况,脚本的原始作者没有考虑过。
    def __str__(self):
        return self._toseq(False)


导致idautils.py中的str(StringItem)出现;

    def _toseq(self, as_unicode):
        if self.is_2_bytes_encoding():
            conv = idaapi.ACFOPT_UTF16
            pyenc = "utf-16"
        elif self.is_4_bytes_encoding():
            conv = idaapi.ACFOPT_UTF8
            pyenc = "utf-8"
        else:
            conv = idaapi.ACFOPT_ASCII
            pyenc = 'ascii'
        strbytes = idaapi.get_ascii_contents2(self.ea, self.length, self.type, conv)
        return unicode(strbytes, pyenc, 'replace') if as_unicode else strbytes

我们看到,如果_toseq失败,此方法实际上可以返回get_ascii_contents2

if ( !get_ascii_contents2(ea, len, type, buf, len+1, &used_size, flags) )
{
  qfree(buf);
  Py_RETURN_NONE;
}


基本上,代码是可以的,但是如果NoneType,则应添加检查或异常处理返回带有get_ascii_contents2的值,因为有可能返回这种类型的值。您的输出;

208e: len=8 type=3 index=0->


评论


您的描述很可能正在发生,即get_ascii_contents2失败。 find_strings函数可在其他文件中使用,因此我怀疑原因是尽管使用GUI正确找到了字符串,但是固件中单词的排序方式仍然如此。我将在帖子中张贴一些十六进制单词的示例。

–感染包
2015年10月15日下午5:40