Compare commits

..

No commits in common. "a7f5828f96c5724401a85a3ed4b9849f20da42c7" and "9a07551a22ec8fc5687f6190f74c5612e0de3f7d" have entirely different histories.

23 changed files with 22 additions and 19 deletions

3
compiler/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"python.analysis.typeCheckingMode": "standard"
}

View File

@ -1,7 +1,9 @@
import base64
from dataclasses import dataclass from dataclasses import dataclass
from io import BytesIO from io import BytesIO
import json
from typing import Generator from typing import Generator
from pefile import PE, Structure import pefile
@dataclass @dataclass
class Import: class Import:
@ -34,40 +36,38 @@ def _single[T](ts: Generator[T]) -> T:
raise ValueError(f"expected 1, got {len(items)}") raise ValueError(f"expected 1, got {len(items)}")
def _create_binary(subject: PE) -> Binary: def _create_binary(subject: pefile.PE) -> Binary:
optional_header = subject.OPTIONAL_HEADER optional_header = subject.OPTIONAL_HEADER
assert isinstance(optional_header, Structure) assert isinstance(optional_header, pefile.Structure)
text_section: Structure = _single(i for i in subject.sections if i.Name == b".text\0\0\0") text_section = _single(i for i in subject.sections if i.Name == b".text\0\0\0")
data_section: Structure | None = _single_or_none(i for i in subject.sections if i.Name == b".data\0\0\0") data_section = _single_or_none(i for i in subject.sections if i.Name == b".data\0\0\0")
rdata_section: Structure | None = _single_or_none(i for i in subject.sections if i.Name == b".rdata\0\0") rdata_section = _single_or_none(i for i in subject.sections if i.Name == b".rdata\0\0")
relevant_sections: list[Structure] = [section for section in (text_section, data_section, rdata_section) if section is not None] relevant_sections = [section for section in (text_section, data_section, rdata_section) if section is not None]
if len(relevant_sections) == 0: if len(relevant_sections) == 0:
raise ValueError("no sections to plot") raise ValueError("no sections to plot")
min_address = min(getattr(i, "VirtualAddress") for i in relevant_sections) min_address = min(i.VirtualAddress for i in relevant_sections)
max_address = max(getattr(i, "VirtualAddress") + getattr(i, "SizeOfRawData") for i in relevant_sections) max_address = max(i.VirtualAddress + i.SizeOfRawData for i in relevant_sections)
buffer = bytearray(max_address - min_address) buffer = bytearray(max_address - min_address)
for section in relevant_sections: for section in relevant_sections:
data = getattr(section, "get_data")() data = section.get_data()
start = getattr(section, "VirtualAddress") - min_address start = section.VirtualAddress - min_address
buffer[start:start+len(data)] = data buffer[start:start+len(data)] = data
starting_state = bytes(buffer) starting_state = bytes(buffer)
entry_point_rva = getattr(optional_header, "AddressOfEntryPoint") entry_point_rva = getattr(optional_header, "AddressOfEntryPoint")
entry_point = entry_point_rva - min_address entry_point = (entry_point_rva - min_address)
imports: list[Import] = [] imports: list[Import] = []
for entry in getattr(subject, "DIRECTORY_ENTRY_IMPORT"): for entry in getattr(subject, "DIRECTORY_ENTRY_IMPORT"):
entry: Structure library: bytes = entry.dll
library: bytes = getattr(entry, "dll")
procedures: list[tuple[bytes, int]] = [] procedures: list[tuple[bytes, int]] = []
for imp in getattr(entry, "imports"): for imp in entry.imports:
imp: Structure import_address_rva = imp.address - getattr(optional_header, "ImageBase")
import_address_rva = getattr(imp, "address") - getattr(optional_header, "ImageBase")
import_address = import_address_rva - min_address import_address = import_address_rva - min_address
procedures.append((getattr(imp, "name"), import_address)) procedures.append((imp.name, import_address))
imports.append(Import(library, procedures)) imports.append(Import(library, procedures))
@ -151,7 +151,7 @@ def _encode_binary(binary: Binary) -> bytes:
return out.getbuffer() return out.getbuffer()
def main(): def main():
subject = PE("subjects\\main.exe") subject = pefile.PE("subjects\\main.exe")
binary = _create_binary(subject) binary = _create_binary(subject)
code = _encode_binary(binary) code = _encode_binary(binary)