节中包含事实上真正运行的代码,所以也是特征提取的一个重点。
1.节头信息
节头中需要提取特征的信息列举如下。
节的个数:
len(binary.sections)
长度为0的节的个数:
sum(1 for s in binary.sections if s.size == 0)
名称为空的节的个数:
sum(1 for s in binary.sections if s.name == "")
可读可执行的节的个数。可读可执行,在lief中表示为:
lief.PE.SECTION_CHARACTERISTICS.MEM_READ lief.PE.SECTION_CHARACTERISTICS.MEM_EXECUTE
统计可读可执行的节的个数的方法为:
sum(1 for s in binary.sections if s.has_characteristic(lief.PE.SECTION_CHARAC TERISTICS. MEM_READ) and s.has_characteristic(lief.PE.SECTION_CHARACTERISTICS.MEM_EXECUTE))
可写的节的个数:
sum(1 for s in binary.sections if s.has_characteristic( lief.PE.SECTION_CHARACTERISTICS.MEM_WRITE))
2.节大小
节的大小包括两部分:一个是节在物理文件中的大小,一个是节在内存中的大小。
section_sizes = [(s.name, len(s.content)) for s in binary.sections] section_vsize = [(s.name, s.virtual_size) for s in binary.sections]
然后使用FeatureHasher均转换成维度为50的向量:
FeatureHasher(50, input_type="pair", dtype=self.dtype).transform( [section_sizes]).toarray(), FeatureHasher(50, input_type="pair", dtype=self.dtype).transform( [section_entropy]).toarray(), FeatureHasher(50, input_type="pair", dtype=self.dtype).transform( [section_vsize]).toarray()
3.节的熵
统计节的熵:并使用FeatureHasher均转换成维度为50的向量:
section_entropy = [(s.name, s.entropy) for s in binary.sections] FeatureHasher(50, input_type="pair", dtype=self.dtype).transform( [section_entropy]).toarray()
4.节的入口点名称和属性
根据节的入口点(entry point),找到入口点的名称和属性。
entry = binary.section_from_offset(binary.entrypoint) if entry is not None: entry_name = [entry.name] entry_characteristics = [str(c) for c in entry.characteristics_lists] else: entry_name = [] entry_characteristics = []
将入口点的名称和属性使用FeatureHasher转换成维度为50的向量:
FeatureHasher(50, input_type="string", dtype=self.dtype).transform( [entry_name]).toarray() FeatureHasher(50, input_type="string", dtype=self.dtype).transform([entry_characteristics]).toarray()
将节的特征组成一个特征向量:
return np.concatenate([ np.atleast_2d(np.asarray(general, dtype=self.dtype)), FeatureHasher(50, input_type="pair", dtype=self.dtype).transform( [section_sizes]).toarray(), FeatureHasher(50, input_type="pair", dtype=self.dtype).transform( [section_entropy]).toarray(), FeatureHasher(50, input_type="pair", dtype=self.dtype).transform( [section_vsize]).toarray(), FeatureHasher(50, input_type="string", dtype=self.dtype).transform( [entry_name]).toarray(), FeatureHasher(50, input_type="string", dtype=self.dtype).transform([entry_characteristics]).toarray() ], axis=-1).flatten().astype(self.dtype)