mirror of
https://github.com/mtrojnar/osslsigncode.git
synced 2025-04-04 17:00:11 -05:00
140 lines
3.1 KiB
Python
140 lines
3.1 KiB
Python
#!/usr/bin/python
|
|
|
|
import struct
|
|
import sys
|
|
import hashlib
|
|
from pyasn1.type import univ
|
|
from pyasn1.codec.ber import encoder, decoder
|
|
|
|
f = open(sys.argv[1], 'rb')
|
|
filehdr = f.read(1024)
|
|
if filehdr[0:2] != 'MZ':
|
|
print "Not a DOS file."
|
|
sys.exit(0)
|
|
pepos = struct.unpack('<I', filehdr[60:64])[0]
|
|
if filehdr[pepos:pepos+4] != 'PE\0\0':
|
|
print "Not a PE file."
|
|
sys.exit(0)
|
|
pepos += 4
|
|
|
|
nsections = struct.unpack('<H', filehdr[pepos+2:pepos+4])[0]
|
|
print "#sections", nsections
|
|
|
|
magic = struct.unpack('<H', filehdr[pepos+20:pepos+22])[0]
|
|
pe32plus = 0
|
|
if magic == 0x20b:
|
|
pe32plus = 1
|
|
elif magic == 0x10b:
|
|
pe32plus = 0
|
|
else:
|
|
print "Unknown magic", magic
|
|
sys.exit(0)
|
|
|
|
sectoralign = struct.unpack('<I', filehdr[pepos+52:pepos+56])[0]
|
|
print "Sector alignment", sectoralign
|
|
|
|
pos = pepos + 112 + pe32plus*16
|
|
nrvas = struct.unpack('<I', filehdr[pos:pos+4])[0]
|
|
print "#rvas", nrvas
|
|
|
|
pos += 4
|
|
tpos = pos
|
|
rvas = []
|
|
for i in range(0, nrvas):
|
|
(p1,p2) = struct.unpack('<II', filehdr[pos:pos+8])
|
|
rvas.append((p1,p2))
|
|
pos += 8
|
|
|
|
sections = []
|
|
for i in range(0, nsections):
|
|
(vsize,vaddr,rsize,raddr) = struct.unpack('<IIII', filehdr[pos+8:pos+24])
|
|
pos += 40
|
|
sections.append((vsize,vaddr,rsize,raddr))
|
|
|
|
hdrend = pos
|
|
print "End of headers", pos
|
|
print rvas
|
|
print sections
|
|
|
|
sigpos,siglen = rvas[4]
|
|
if sigpos == 0:
|
|
print "No signature found"
|
|
sys.exit(0)
|
|
|
|
f.seek(sigpos)
|
|
sigblob = f.read(siglen)
|
|
cid_page_hash = "\xa6\xb5\x86\xd5\xb4\xa1\x24\x66\xae\x05\xa2\x17\xda\x8e\x60\xd6"
|
|
oid_ph_v1 = "\x06\x01\x04\x01\x82\x37\x02\x03\x01"
|
|
oid_ph_v2 = "\x06\x01\x04\x01\x82\x37\x02\x03\x02"
|
|
p = sigblob.find(cid_page_hash)
|
|
if p == -1:
|
|
print "No page hash present"
|
|
sys.exit(0)
|
|
|
|
p += len(cid_page_hash)
|
|
sha1 = True
|
|
i = sigblob.find(oid_ph_v1)
|
|
if i == -1:
|
|
i = sigblob.find(oid_ph_v2)
|
|
if i == -1:
|
|
print "No page hash found"
|
|
sys.exit(0)
|
|
sha1 = False
|
|
p = i + len(oid_ph_v1)
|
|
|
|
blob = str(decoder.decode(sigblob[p:])[0].getComponentByPosition(0))
|
|
ph = []
|
|
i = 0
|
|
hashlen = 20
|
|
if not sha1:
|
|
hashlen = 24
|
|
while i < len(blob):
|
|
offset = struct.unpack('<I', blob[i:i+4])[0]
|
|
i += 4
|
|
data = blob[i:i+hashlen]
|
|
ph.append((offset,data.encode("hex")))
|
|
i += hashlen
|
|
|
|
if sha1:
|
|
md = hashlib.sha1()
|
|
else:
|
|
md = hashlib.sha256()
|
|
b = filehdr[0:pepos+84]
|
|
b += filehdr[pepos+88:tpos+4*8]
|
|
b += filehdr[tpos+5*8:1024]
|
|
b += '\0'*(4096-1024)
|
|
md.update(b)
|
|
digest = md.hexdigest()
|
|
|
|
print ""
|
|
print "Checking page hash..."
|
|
print ""
|
|
|
|
nph = [(0,digest)]
|
|
lastpos = 0
|
|
pagesize = sectoralign # ???
|
|
for vs,vo,rs,ro in sections:
|
|
l = 0
|
|
while l < rs:
|
|
f.seek(ro+l)
|
|
howmuch = pagesize
|
|
if rs - l < pagesize:
|
|
howmuch = rs - l
|
|
b = f.read(howmuch)
|
|
if howmuch < pagesize:
|
|
b = b + '\0' * (pagesize - (rs - l))
|
|
if sha1:
|
|
d = hashlib.sha1(b).hexdigest()
|
|
else:
|
|
d = hashlib.sha256(b).hexdigest()
|
|
nph.append((ro+l, d))
|
|
l += pagesize
|
|
lastpos = ro + rs
|
|
|
|
nph.append((lastpos,'0'*(2*hashlen)))
|
|
for i in range(0,len(nph)):
|
|
x=ph[i]
|
|
y=nph[i]
|
|
if x[0] != y[0] or x[1] != y[1]:
|
|
print "Not matching:", x, "!=", y
|