1
0
mirror of synced 2024-11-24 14:30:11 +01:00
bemaniutils/bemani/utils/struct.py
2020-03-25 23:17:06 +00:00

78 lines
2.0 KiB
Python

import argparse
import pefile # type: ignore
import struct
def parse_struct(data: bytes, startaddr: str, endaddr: str, fmt: str) -> None:
pe = pefile.PE(data=data, fast_load=True)
start: int = int(startaddr, 16)
end: int = int(endaddr, 16)
def virtual_to_physical(offset: int) -> int:
for section in pe.sections:
start = section.VirtualAddress + pe.OPTIONAL_HEADER.ImageBase
end = start + section.SizeOfRawData
if offset >= start and offset < end:
return (offset - start) + section.PointerToRawData
raise Exception(f'Couldn\'t find raw offset for virtual offset 0x{offset:08x}')
if start >= pe.OPTIONAL_HEADER.ImageBase:
# Assume this is virtual
start = virtual_to_physical(start)
if end >= pe.OPTIONAL_HEADER.ImageBase:
# Assume this is virtual
end = virtual_to_physical(end)
size: int = struct.calcsize(fmt)
while start < end:
chunk = data[start:(start + size)]
start = start + size
print(list(struct.unpack(fmt, chunk)))
def main() -> None:
parser = argparse.ArgumentParser(description="A utility to print structs out of a DLL.")
parser.add_argument(
"--file",
help="DLL file to extract from.",
type=str,
default=None,
required=True,
)
parser.add_argument(
"--start",
help="Hex offset into the file we should start at.",
type=str,
default=None,
required=True,
)
parser.add_argument(
"--end",
help="Hex offset into the file we should go until.",
type=str,
default=None,
required=True,
)
parser.add_argument(
"--format",
help="Python struct format we should print using.",
type=str,
default=None,
required=True,
)
args = parser.parse_args()
fp = open(args.file, 'rb')
data = fp.read()
fp.close()
parse_struct(data, args.start, args.end, args.format)
if __name__ == '__main__':
main()