使用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
中的异常。我已经重新加载了同一个文件,但是作为原始二进制文件在一个很大的段中重新加载,并且该功能可以完美地运行。#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
评论
您在最后一行代码中缺少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吗?
同意,在修正拼写错误后,代码也可以正常工作。