Python读取PE文件(exe/dll)中的时间戳
代码原文地址:
https://www.snip2code.com/Snippet/144008/Read-the-PE-Timestamp-from-a-Windows-Exe
https://gist.github.com/03152ba1a148d9475e81
直接上代码吧,引用过来以防链接失效:
1 #! /usr/bin/env python2.7 2 # 3 # Author: Pat Litke (C) 2014 4 # 5 # This code is free software: you can redistribute it and/or modify 6 # it under the terms of the GNU Affero General Public License as 7 # published by the Free Software Foundation, either version 3 of the 8 # License, or (at your option) any later version. 9 # 10 # This code is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # GNU General Public License for more details. 14 # 15 # You should have received a copy of the GNU Affero General Public License 16 # along with Baku. If not, see <http://www.gnu.org/licenses/>. 17 # 18 # Description: 19 # Quick and dirty module to read a binary file, look at the DOS header for the PE offset 20 # Seek to the PE offset, read the third DWORD in, unpack it, and return either EPOCH or GMTIMEs 21 # 22 # Returns 1 if the file doesn't havea a DOS header 23 # Returns 2 if file couldn't be read 24 # Returns the data in epoch or formatted otherwise 25 26 from struct import unpack 27 from binascii import hexlify 28 from time import gmtime, strftime 29 30 def getEpoch(filePath, epoch = True): 31 32 # Open the file in Binary mode 33 try: 34 handle = open(filePath, 'rb') 35 if hexlify(handle.read(2)) != hexlify(u'MZ'): 36 handle.close() 37 return 1 38 except: 39 return 2 40 41 # Get PE offset (@60, DWORD) from DOS header 42 # It's little-endian so we have to flip it 43 # We also need the HEX representation which is an INT value 44 handle.seek(60, 0) 45 offset = handle.read(4) 46 offset = hexlify(offset[::-1]) 47 offset = int(offset, 16) 48 49 # Seek to PE header and read second DWORD 50 handle.seek(offset+8, 0) 51 dword = handle.read(4) 52 handle.close() 53 t = unpack(">L", dword[::-1])[0] 54 55 if epoch: 56 return t 57 else: 58 return strftime('%Y-%m-%d %H:%M:%S', gmtime(float(t))) 59 60 61 62 def getUTC(filePath): 63 return getEpoch(filepath, False) 64 65 def getBoth(filePath): 66 return [getEpoch(filepath), getEpoch(filepath, False)]
如果想修改这个时间戳,按照上述规则,pack后写入即可,另外其中53行那句有些麻烦,其实这么写就可以了:t = unpack("<L", dword)[0] ,即按照小端直接解码即可。
更新:
更强大的修改PE文件时间戳的方式如下,而且支持PE文件与pdb一切修改,还可以顺道修改guid:
https://github.com/google/syzygy/tree/master/syzygy/zap_timestamp
这是谷歌syzygy工具链中的一个小公举(工具 O(∩_∩)O~)。
syzygy也是个好东西,可以改善软件的启动速度,体积较大的软件,本身启动已经没有什么优化空间时,可以考虑使用syzygy来提高加载速度