Files
Investidor-V2/tools/portal-stability-dll-diagnosis.py
T
nala 287e991486
tests / ci (push) Waiting to run
oportunidades 7
2026-10-13 11:40:29 +02:00

55 lines
3.0 KiB
Python

"""Read PE imports/exports to explain the mod_php startup failure, without loading DLLs."""
from pathlib import Path
import struct, hashlib, json
ROOT=Path(__file__).resolve().parent.parent
PRIVATE=ROOT/'storage/app/private/investmoz-v2/portal-audit'
APACHE=Path('C:/laragon/bin/apache/httpd-2.4.54-win64-VS16/bin')
PHP=Path('C:/laragon/bin/php/php-8.5.11-Win32-vs17-x64')
class PE:
def __init__(self,file):
self.b=Path(file).read_bytes();header=struct.unpack_from('<I',self.b,0x3c)[0]
assert self.b[header:header+4]==b'PE\0\0'
n=struct.unpack_from('<H',self.b,header+6)[0];size=struct.unpack_from('<H',self.b,header+20)[0];opt=header+24
self.wide=struct.unpack_from('<H',self.b,opt)[0]==0x20b
self.dd=opt+(112 if self.wide else 96)
self.sections=[]
for i in range(n):
p=opt+size+40*i;vsize,va,rawsize,raw=struct.unpack_from('<IIII',self.b,p+8)
self.sections.append((va,max(vsize,rawsize),raw))
def off(self,rva):
for va,size,raw in self.sections:
if va<=rva<va+size:return raw+rva-va
return rva
def string(self,rva):
p=self.off(rva);return self.b[p:self.b.index(b'\0',p)].decode('ascii')
def imports(self):
rva=struct.unpack_from('<I',self.b,self.dd+8)[0];p=self.off(rva);result={}
while rva:
original,_,_,name,thunk=struct.unpack_from('<IIIII',self.b,p)
if not name:break
tp=self.off(original or thunk);names=[];width=8 if self.wide else 4
while True:
value=struct.unpack_from('<Q' if self.wide else '<I',self.b,tp)[0];tp+=width
if not value:break
if value & (1<<(width*8-1)):continue
names.append(self.string(value+2))
result[self.string(name).lower()]=names;p+=20
return result
def exports(self):
rva=struct.unpack_from('<I',self.b,self.dd)[0]
if not rva:return set()
p=self.off(rva);n=struct.unpack_from('<I',self.b,p+24)[0];names=struct.unpack_from('<I',self.b,p+32)[0]
return {self.string(struct.unpack_from('<I',self.b,self.off(names)+4*i)[0]) for i in range(n)}
imports=PE(PHP/'ext/php_curl.dll').imports();result=[]
for dll,names in imports.items():
old=APACHE/dll;expected=PHP/dll
if old.is_file() and expected.is_file():
missing=set(names)-PE(old).exports();missing_expected=set(names)-PE(expected).exports()
result.append({'dependency':dll,'apache_path':str(old),'php_path':str(expected),
'apache_sha256':hashlib.sha256(old.read_bytes()).hexdigest(),
'php_sha256':hashlib.sha256(expected.read_bytes()).hexdigest(),
'missing_required_exports_in_apache':sorted(missing),'missing_in_php':sorted(missing_expected)})
proof={'result':'diagnosed','dependencies':result,'active_files_changed':False}
(PRIVATE/'portal-stability-dll-diagnosis.json').write_text(json.dumps(proof,indent=2),encoding='utf-8')
print(json.dumps(proof))