Skip to content

Instantly share code, notes, and snippets.

@totekuh
Last active February 8, 2024 11:01
Show Gist options
  • Save totekuh/7318d2330be27a1037ef409fdf36bcdf to your computer and use it in GitHub Desktop.
Save totekuh/7318d2330be27a1037ef409fdf36bcdf to your computer and use it in GitHub Desktop.
A Python script for converting Relative Virtual Addresses (RVA) to file offsets within specific sections of Portable Executable (PE) files
#!/usr/bin/env python3
import os
import sys
import pefile
import argparse
def rva_to_offset(section,
rva: int):
if section.contains_rva(rva):
print(f"[*] Target RVA located in: {section.Name.decode().strip()}; "
f"virtual address: {hex(section.VirtualAddress)}; "
f"misc virtual size: {hex(section.Misc_VirtualSize)}; "
f"size of raw data: {hex(section.SizeOfRawData)}")
return section.get_offset_from_rva(rva)
def get_arguments():
parser = argparse.ArgumentParser(description='Convert RVA to file offset in a PE file.')
parser.add_argument('-f',
'--file',
dest="file",
required=True,
type=str,
help='Path to the PE file.')
parser.add_argument("-r",
'--rva',
dest="rva",
required=True,
type=lambda x: int(x, 0),
help='RVA to convert (e.g., "0x1D4B6").')
parser.add_argument("-sn",
'--section-name',
dest="section_name",
required=False,
type=str,
help='Optional. The name of the section to search through for the given --rva offset '
'(e.g., -sn ".data" or -sn ".text"). '
'If omitted, the script will look for matching RVA within all sections.')
return parser.parse_args()
def main():
options = get_arguments()
file = options.file
target_section_name = options.section_name
if not target_section_name:
print("[*] The target section name has not been provided, looking for the matching RVA across all sections")
if not os.path.exists(file):
print(f"[-] The PE file {file} doesn't exist")
sys.exit(1)
parsed_pe_file = pefile.PE(file)
for section in parsed_pe_file.sections:
section_name_decoded = section.Name.decode().strip()
if target_section_name and target_section_name not in section_name_decoded:
continue
offset = rva_to_offset(section=section,
rva=options.rva)
if offset:
print(f"[+] File offset ({section_name_decoded}): 0x{offset:x}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment