最近使用androguard来反编译apk sample并分析,发现了一些问题
有些apk sample的dex文件的文件头的link_size和link_off不是默认的0值,填充着非零值,如05和06,这个值正好落在了dex文件头的magic number和checksum字段中,应该是没有任何意义的。使用Androguard反编译该dex文件时候,总是通不过,会有异常抛出。
在dalvik官网上查了一下,说这两个字段暂时保留,并未用到,说是为了runtime implementations 来使用。在smali的讨论区上也有人说是填写这两个字段是用来防止被反编译的。
手工将link_size和link_off改为0,然后重新计算sha1和checksum,并对应修改该dex文件。然后重新用Androguard解析,仍然未通过。怀疑Androguard本身可能有问题。
跟踪异常,得到信息如下
Traceback (most recent call last):
ag = androguard.AndroguardS(sFileName)
File "./Androguard/androguard.py", line 447, in __init__
self.__orig_a = Androguard( [ filename ], raw )
File "./Androguard/androguard.py", line 239, in __init__
self._analyze()
File "./Androguard/androguard.py", line 258, in _analyze
bc = dvm.DalvikVMFormat( self.__orig_raw[ i ] )
File "./Androguard/core/bytecodes/dvm.py", line 3093, in __init__
self.map_list = MapList( self.CM, self.__header.get_value().map_off, self )
File "./Androguard/core/bytecodes/dvm.py", line 3051, in __init__
mi = MapItem( buff, self.CM )
File "./Androguard/core/bytecodes/dvm.py", line 2788, in __init__
self.item = CodeItem( general_format.size, buff, cm )
File "./Androguard/core/bytecodes/dvm.py", line 2745, in __init__
x = DalvikCode( buff, cm )
File "./Androguard/core/bytecodes/dvm.py", line 2662, in __init__
self._code = DCode( self.__CM, self.insns_size.get_value(), buff.read( self.insns_size.get_value() * ushort ) )
File "./Androguard/core/bytecodes/dvm.py", line 2546, in __init__
operands, special = self._analyze_mnemonic( op_value, DALVIK_OPCODES[ op_value ])
File "./Androguard/core/bytecodes/dvm.py", line 2571, in _analyze_mnemonic
r = self._extract_values(i)
File "./Androguard/core/bytecodes/dvm.py", line 2562, in _extract_values
return MAP_EXTRACT_VALUES[i]( self.__insn, self.__current_pos )
File "./Androguard/core/bytecodes/dvm.py", line 2336, in op_AA_OP
i16 = unpack("=H", insn[current_pos:current_pos+2])[0]
struct.error: unpack requires a string argument of length 2
其中 函数op_AA_OP如下:
def op_AA_OP(insn, current_pos) :
print insn
print len(insn)
print current_pos
i16 = unpack("=H", insn[current_pos:current_pos+2])[0]
return [2, [i16 & 0xff, (i16 >> 8) & 0xff]]
在 调用“op_AA_OP”这个函数中打印 “insn” 和“current_pos”的信息:
p
[ÑíJ
20
18
p
[ÑíJ
20
20
发现,当current_pos = 20 也就是 len(insn)=20时,仍然会进入“op_AA_OP”中,结果
insn[current_pos:current_pos+2]
会返回空list,[],这样会导致unpack函数抛异常。
这一段是在 Androguard解析dex文件的CodeItem时候,出现的问题。我扫描一些正常文件(data link section 的值为0的sample),都是通过的。推测,sample的作者,为了防止反编译,不仅仅只是修改了link_size和link_off这两个字段并重新生成sha1和checksum,这么简单。应该对Code也做有相应修改。如果病毒apk都采用这种方式防止反编译,相信目前很多杀软都会束手无策。
还是不太清楚为什么,继续学习中。