77 lines
2.0 KiB
Python
77 lines
2.0 KiB
Python
|
|
||
|
import dataclasses
|
||
|
from datetime import datetime
|
||
|
from pathlib import Path
|
||
|
import re
|
||
|
|
||
|
from pyhidra import __version__
|
||
|
|
||
|
|
||
|
MINIMUM_GHIDRA_VERSION = "10.3"
|
||
|
_APPLICATION_PATTERN = re.compile(r"^application\.(\S+?)=(.*)$")
|
||
|
|
||
|
|
||
|
@dataclasses.dataclass(frozen=True)
|
||
|
class ApplicationInfo:
|
||
|
"""
|
||
|
Ghidra Application Properties
|
||
|
"""
|
||
|
name: str
|
||
|
version: str
|
||
|
release_name: str
|
||
|
revision_ghidra: str = ""
|
||
|
build_date: str = ""
|
||
|
build_date_short: str = ""
|
||
|
layout_version: str = ""
|
||
|
gradle_min: str = ""
|
||
|
java_min: str = ""
|
||
|
java_max: str = ""
|
||
|
java_compiler: str = ""
|
||
|
gradle_max: str = ""
|
||
|
|
||
|
@classmethod
|
||
|
def from_file(cls, file: Path):
|
||
|
"""
|
||
|
Parses Ghidra's application.properties file from the provided path
|
||
|
"""
|
||
|
valid_fields = {f.name for f in dataclasses.fields(cls)}
|
||
|
kwargs = dict()
|
||
|
for line in file.read_text(encoding="utf8").splitlines():
|
||
|
match = _APPLICATION_PATTERN.match(line)
|
||
|
if not match:
|
||
|
continue
|
||
|
attr = match.group(1).replace('.', '_').replace('-', '_')
|
||
|
value = match.group(2)
|
||
|
if attr in valid_fields:
|
||
|
kwargs[attr] = value
|
||
|
return cls(**kwargs)
|
||
|
|
||
|
|
||
|
@dataclasses.dataclass
|
||
|
class ExtensionDetails:
|
||
|
"""
|
||
|
Python side ExtensionDetails
|
||
|
"""
|
||
|
name: str
|
||
|
description: str
|
||
|
author: str
|
||
|
createdOn: str = dataclasses.field(default_factory=lambda: str(datetime.now()))
|
||
|
version: str = None
|
||
|
plugin_version: str = "0.0.1"
|
||
|
|
||
|
@classmethod
|
||
|
def from_file(cls, ext_path: Path):
|
||
|
valid_fields = {f.name for f in dataclasses.fields(cls)}
|
||
|
def cast(key, value):
|
||
|
return cls.__annotations__[key](value)
|
||
|
lines = ext_path.read_text().splitlines()
|
||
|
kwargs = {
|
||
|
key: cast(key, value)
|
||
|
for key, value in map(lambda l: l.split("="), lines)
|
||
|
if key in valid_fields
|
||
|
}
|
||
|
return cls(**kwargs)
|
||
|
|
||
|
def __repr__(self):
|
||
|
return "\n".join(f"{key}={value}" for key, value in dataclasses.asdict(self).items())
|