1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| import pefile,sys,re from io import StringIO
dumplinelength = 16
def CIC(expression): if callable(expression): return expression() else: return expression
def IFF(expression, valueTrue, valueFalse): if expression: return CIC(valueTrue) else: return CIC(valueFalse)
class cDump(): def __init__(self, data, prefix='', offset=0, dumplinelength=16): self.data = data self.prefix = prefix self.offset = offset self.dumplinelength = dumplinelength
# 输出指定位置的十六进制格式 def HexDump(self): oDumpStream = self.cDumpStream(self.prefix) hexDump = '' for i, b in enumerate(self.data): if i % self.dumplinelength == 0 and hexDump != '': oDumpStream.Addline(hexDump) hexDump = '' hexDump += IFF(hexDump == '', '', ' ') + '%02X' % self.C2IIP2(b) oDumpStream.Addline(hexDump) return oDumpStream.Content()
def CombineHexAscii(self, hexDump, asciiDump): if hexDump == '': return '' countSpaces = 3 * (self.dumplinelength - len(asciiDump)) if len(asciiDump) <= self.dumplinelength / 2: countSpaces += 1 return hexDump + ' ' + (' ' * countSpaces) + asciiDump
# 输出指定位置的十六进制格式以及ASCII字符串 def HexAsciiDump(self): oDumpStream = self.cDumpStream(self.prefix) hexDump = '' asciiDump = '' for i, b in enumerate(self.data): b = self.C2IIP2(b) if i % self.dumplinelength == 0: if hexDump != '': oDumpStream.Addline(self.CombineHexAscii(hexDump, asciiDump)) hexDump = '%08X:' % (i + self.offset) asciiDump = '' if i % self.dumplinelength == self.dumplinelength / 2: hexDump += ' ' hexDump += ' %02X' % b asciiDump += IFF(b >= 32 and b <= 128, chr(b), '.') oDumpStream.Addline(self.CombineHexAscii(hexDump, asciiDump)) return oDumpStream.Content()
class cDumpStream(): def __init__(self, prefix=''): self.oStringIO = StringIO() self.prefix = prefix
def Addline(self, line): if line != '': self.oStringIO.write(self.prefix + line + '\n')
def Content(self): return self.oStringIO.getvalue()
@staticmethod def C2IIP2(data): if sys.version_info[0] > 2: return data else: return ord(data)
# 只输出十六进制数据 def HexDump(data): return cDump(data, dumplinelength=dumplinelength).HexDump()
# 输出十六进制与ASCII字符串 def HexAsciiDump(data): return cDump(data, dumplinelength=dumplinelength).HexAsciiDump()
# 找到指定节并读取hex数据 def GetSectionHex(pe): ImageBase = pe.OPTIONAL_HEADER.ImageBase for item in pe.sections: # 判断是否是.text节 if str(item.Name.decode('UTF-8').strip(b'\x00'.decode())) == ".text": # print("虚拟地址: 0x%.8X 虚拟大小: 0x%.8X" %(item.VirtualAddress,item.Misc_VirtualSize)) VirtualAddress = item.VirtualAddress VirtualSize = item.Misc_VirtualSize ActualOffset = item.PointerToRawData StartVA = hex(ImageBase + VirtualAddress) StopVA = hex(ImageBase + VirtualAddress + VirtualSize) print("[+] 代码段起始地址: {} 结束: {} 实际偏移:{} 长度: {}".format(StartVA, StopVA, ActualOffset, VirtualSize)) # 获取到.text节区间内的数据 hex_code = pe.write()[ActualOffset: VirtualSize] return hex_code else: print("程序中不存在.text节") return 0 return 0
REGEX_STANDARD = '[\x09\x20-\x7E]'
def ExtractStringsASCII(data): regex = REGEX_STANDARD + '{%d,}' return re.findall(regex % 4, data)
def ExtractStringsUNICODE(data): regex = '((' + REGEX_STANDARD + '\x00){%d,})' return [foundunicodestring.replace('\x00', '') for foundunicodestring, dummy in re.findall(regex % 4, data)]
# 将传入Hex字符串以每16字符分割在一个列表内 def ExtractStrings(data): return ExtractStringsASCII(data) + ExtractStringsUNICODE(data)
if __name__ == "__main__": pe = pefile.PE("d://lyshark.exe") # 得到.text节内数据 ref = GetSectionHex(pe) # 转为十六进制格式 dump_hex = HexDump(ref) print(dump_hex) # 打包为每16字符一个列表 dump_list = ExtractStrings(dump_hex) print(dump_list)
|