First instance of anything that works

This commit is contained in:
2025-04-24 21:31:48 -07:00
commit 4e3a7745d7
17 changed files with 864 additions and 0 deletions

File diff suppressed because one or more lines are too long

0
analyzer/dumps/data.dat Normal file
View File

BIN
analyzer/dumps/rdata.dat Normal file

Binary file not shown.

Binary file not shown.

BIN
analyzer/dumps/text.dat Normal file

Binary file not shown.

84
analyzer/main.py Normal file
View File

@ -0,0 +1,84 @@
import base64
from io import BytesIO
import json
import pefile
def main():
subject = pefile.PE("subjects\\main.exe")
def _single_or_none(x):
items = [i for i in x]
if len(items) == 0:
return None
assert len(items) == 1
return items[0]
def _dump(fname, section):
with open(fname, "wb") as f:
if section is not None:
if isinstance(section, bytes):
f.write(section)
else:
f.write(section.get_data())
for i in subject.sections:
print(i)
text_section = _single_or_none(i for i in subject.sections if i.Name == b".text\0\0\0")
data_section = _single_or_none(i for i in subject.sections if i.Name == b".data\0\0\0")
rdata_section = _single_or_none(i for i in subject.sections if i.Name == b".rdata\0\0")
_dump("dumps\\text.dat", text_section)
_dump("dumps\\data.dat", data_section)
_dump("dumps\\rdata.dat", rdata_section)
relevant_sections = [section for section in (text_section, data_section, rdata_section) if section is not None]
if len(relevant_sections) == 0:
raise ValueError("no sections to plot")
min_address = min(i.VirtualAddress for i in relevant_sections)
max_address = max(_round_up_to_page(i.VirtualAddress + i.SizeOfRawData) for i in relevant_sections)
print(min_address, max_address)
buffer = bytearray(max_address - min_address)
for section in relevant_sections:
data = section.get_data() # TODO: De-pad the text section from 0xccs
start = section.VirtualAddress - min_address
buffer[start:start+len(data)] = data
buffer = bytes(buffer)
_dump("dumps\\starting_state.dat", buffer)
binary = {
"startingState": base64.b64encode(buffer).decode("utf8"),
"imports": [],
}
# find imports
# print(subject)
# print(dir(subject))
for entry in subject.DIRECTORY_ENTRY_IMPORT:
# print(entry.dll)
for imp in entry.imports:
# print(dir(imp))
import_address = imp.address - subject.OPTIONAL_HEADER.ImageBase - min_address
print(hex(import_address), imp.name)
binary["imports"].append({
"dll": entry.dll.decode("utf8"),
"symbol": imp.name.decode("utf8"),
"address": import_address,
})
entry_point_rva = subject.OPTIONAL_HEADER.AddressOfEntryPoint
binary["entryPoint"] = entry_point_rva - min_address
with open("binaries/main.json", "wt") as f:
f.write(json.dumps(binary, indent=4))
def _round_up_to_page(x: int):
# TODO: Is this the page size on x64? I think it is
return ((x + 0x1000 - 1) // 0x1000) * 0x1000
if __name__ == "__main__":
main()

17
analyzer/poetry.lock generated Normal file
View File

@ -0,0 +1,17 @@
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
[[package]]
name = "pefile"
version = "2024.8.26"
description = "Python PE parsing module"
optional = false
python-versions = ">=3.6.0"
files = [
{file = "pefile-2024.8.26-py3-none-any.whl", hash = "sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f"},
{file = "pefile-2024.8.26.tar.gz", hash = "sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632"},
]
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "6f28e4dc3bf3b09c57354693b75dc7975b70a7aac2ee7c83fc81b0058520d7f9"

15
analyzer/pyproject.toml Normal file
View File

@ -0,0 +1,15 @@
[tool.poetry]
name = "analyzer"
version = "0.1.0"
description = ""
authors = ["Nyeogmi <economicsbat@gmail.com>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.10"
pefile = "^2024.8.26"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

BIN
analyzer/subjects/main.exe Normal file

Binary file not shown.