File: pagehash.py

package info (click to toggle)
osslsigncode 2.9-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,148 kB
  • sloc: ansic: 11,997; python: 939; sh: 74; makefile: 12
file content (139 lines) | stat: -rw-r--r-- 3,180 bytes parent folder | download | duplicates (7)
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
136
137
138
139
#!/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