Skip to content

Instantly share code, notes, and snippets.

@utkonos
Last active November 30, 2022 15:12
Show Gist options
  • Save utkonos/86585b85a313a2e41d33471c22cc26c6 to your computer and use it in GitHub Desktop.
Save utkonos/86585b85a313a2e41d33471c22cc26c6 to your computer and use it in GitHub Desktop.
View RT_VERSION Resources in PE EXE
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "f948162c-7083-4959-a9f3-ca5680058269",
"metadata": {},
"outputs": [],
"source": [
"import hashlib\n",
"import pathlib\n",
"import subprocess\n",
"import tempfile"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dcee1abb-dfc6-4c0e-b0fa-38309cb0df53",
"metadata": {},
"outputs": [],
"source": [
"import pefile"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "310e45a9-cdfd-47b7-8232-895865782fe2",
"metadata": {},
"outputs": [],
"source": [
"target = pathlib.Path('example.exe')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8091302d-7ceb-4bb1-89d2-9bd12335918f",
"metadata": {},
"outputs": [],
"source": [
"target.exists()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "069134c4-00ec-4e33-83ab-3a75240b0e43",
"metadata": {},
"outputs": [],
"source": [
"process = subprocess.run(['hexf', target], capture_output=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "450a33c8-813d-4524-a8e8-56a1b3c452af",
"metadata": {},
"outputs": [],
"source": [
"process = subprocess.run(['010editor \"{}\"'.format(str(target))], capture_output=True, shell=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "71b6113a-3b88-4672-a7a6-2519da194abc",
"metadata": {},
"outputs": [],
"source": [
"pe = pefile.PE(target)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5ce7e833-f1d2-4970-9fb5-dc36fc87936b",
"metadata": {},
"outputs": [],
"source": [
"def get_sections(pe):\n",
" sections = list()\n",
" for section in pe.sections:\n",
" va = section.VirtualAddress\n",
" end = section.VirtualAddress + section.SizeOfRawData\n",
" ptrd = section.PointerToRawData\n",
" sections.append((va, end, ptrd, ))\n",
"\n",
" return sections"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b4a564d1-b787-4c28-985c-35d353b00863",
"metadata": {},
"outputs": [],
"source": [
"def find_section(rva, sections):\n",
" for entry in sections:\n",
" va, end, ptrd = entry\n",
" if rva > va and rva < end:\n",
"\n",
" return va, ptrd"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ba97c27e-a57b-4779-b97a-cf2b2bd070f9",
"metadata": {},
"outputs": [],
"source": [
"def get_resource_location(entry):\n",
" if hasattr(entry, 'data'):\n",
" rva = entry.data.struct.OffsetToData\n",
" size = entry.data.struct.Size\n",
"\n",
" return [(rva, size, )]\n",
"\n",
" elif hasattr(entry, 'directory'):\n",
" locations = list()\n",
" for sub in entry.directory.entries:\n",
" locations.extend(get_resource_data(sub))\n",
"\n",
" return locations"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8edd6457-34a8-4939-a2f8-97d7cc60b96e",
"metadata": {},
"outputs": [],
"source": [
"def get_data(target, location, section):\n",
" rva, size = location\n",
" va, ptrd = section\n",
" offset = rva - va + ptrd\n",
" with open(target, 'rb') as fh:\n",
" fh.seek(offset)\n",
" data = fh.read(size)\n",
"\n",
" return data, offset"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1044ef09-338b-4897-ac60-29e8b7276ae0",
"metadata": {},
"outputs": [],
"source": [
"def hexdump_data(data):\n",
" with tempfile.NamedTemporaryFile() as tf:\n",
" pathlib.Path(tf.name).write_bytes(data)\n",
" try:\n",
" process = subprocess.run(['hexdump', '-C', tf.name], capture_output=True)\n",
" except FileNotFoundError as e:\n",
" print(f'Error running hexdump command: {e}\\n')\n",
" return\n",
" print(process.stdout.decode())"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b7e092a7-1e8b-4ebd-832b-15c63aee3b26",
"metadata": {},
"outputs": [],
"source": [
"def dump_version_resources(pe, target):\n",
" sections = get_sections(pe)\n",
" first = True\n",
" for entry in pe.DIRECTORY_ENTRY_RESOURCE.entries:\n",
" if entry.id == 16:\n",
" locations = get_resource_location(entry)\n",
" for location in locations:\n",
" rva, size = location\n",
" section = find_section(rva, sections)\n",
" data, offset = get_data(target, location, section)\n",
" end = offset + size\n",
" print(f'Offset: {offset} {hex(offset)}, RVA: {rva} {hex(rva)}, Size: {size} {hex(size)}, End: {end} {hex(end)}\\n')\n",
" if first:\n",
" subprocess.run(['010editor {}'.format(f'-select:{offset}:{size}')], capture_output=True, shell=True)\n",
" first = False\n",
" sha256 = hashlib.sha256(data).hexdigest()\n",
" print(f'SHA256: {sha256}\\n')\n",
" hexdump_data(data)\n",
" hd = data.hex()\n",
" print('Hex:\\n\\n{}\\n'.format(hd))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "09036422-5e04-4975-9061-1610e192531d",
"metadata": {},
"outputs": [],
"source": [
"dump_version_resources(pe, target)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
@utkonos
Copy link
Author

utkonos commented Nov 27, 2022

For full effect, you must have 010editor and HexFiend installed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment