Last active
February 8, 2024 11:01
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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