#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@author: JonKyle
"""
import sys
import os
from pe_file import PE32
import subprocess
import re

def hex_to_dec(hexString):
    return int(hexString, base=16)
    
def dump_file_to_console(peFile):
    
    print('\nPE HEADER FEATURE EXTRACTION:\n')
    print('FILENAME: ' + peFile.get_file_name+'\n')
    print('\nFileSize: '+ str(peFile.get_file_length())+' bytes')
    print('FileEntropy: ' + str(peFile.get_file_entropy()))
    print('CodeDataRatio: '+ str(peFile.get_code_data_ratio()))
    
    print('\n***FILE HEADER***\n')
    print('Machine: '+ peFile.get_machine())
    print('NumberOfSections: '+ str(peFile.get_number_of_sections()))
    print('TimeDateStamp: '+ peFile.get_time_date_stamp())
    print('PointerToSymbolTable: '+ peFile.get_pointer_to_symbol_table())
    print('NumberOfSymbols: '+ peFile.get_number_of_symbols())
    print('SizeOfOptionalHeader: '+ peFile.get_size_of_optional_header())
    print('Characteristics: '+ peFile.get_characteristics())

    print('\n***OPTIONAL HEADER STANDARD FIELDS***\n')
    print('Magic: '+ peFile.get_magic())
    print('MajorLinkerVersion: '+ peFile.get_major_linker_version())
    print('MinorLinkerVersion: '+ peFile.get_minor_linker_version())
    print('SizeOfCode: '+ peFile.get_size_of_code())
    print('SizeOfInitializedData: '+ peFile.get_size_of_initialized_data())
    print('SizeOfUninitializedData: '+ peFile.get_size_of_uninitialized_data())
    print('AddressOfEntryPoint: '+ peFile.get_address_of_entry_point())
    print('BaseOfCode: '+ peFile.get_base_of_code())
    print('BaseOfData: '+ peFile.get_base_of_data())

    print('\n***OPTIONAL HEADER WINDOWS SPECIFIC***\n')
    print('ImageBase: '+ peFile.get_image_base())
    print('SectionAlignment: '+ peFile.get_section_alignment())
    print('FileAlignment: '+ peFile.get_file_alignment())
    print('MajorOperatingSystemVersion: '+ peFile.get_major_operating_system_version())
    print('MinorOperatingSystemVersion: '+ peFile.get_minor_operating_system_version())
    print('MajorImageVersion: '+ peFile.get_major_image_version())
    print('MinorImageVersion: '+ peFile.get_minor_image_version())
    print('MajorSubsystemVersion: '+ peFile.get_major_subsystem_version())
    print('MinorSubsystemVersion: '+ peFile.get_minor_subsystem_version())
    print('Win32VersionValue: '+ peFile.get_win32_version_value())
    print('SizeOfImage: '+ peFile.get_size_of_image())
    print('SizeOfHeaders: '+ peFile.get_size_of_headers())
    print('CheckSum: '+ peFile.get_check_sum())
    print('Subsystem: '+ peFile.get_subsystem())
    print('DllCharacteristics: '+ peFile.get_dll_characteristics())
    print('SizeOfStackReserve: '+ peFile.get_size_of_stack_reserve())
    print('SizeOfStackCommit: '+ peFile.get_size_of_stack_commit())
    print('SizeOfHeapReserve: '+ peFile.get_size_of_heap_reserve())
    print('SizeOfHeapCommit: '+ peFile.get_size_of_heap_commit())
    print('LoaderFlags: '+ peFile.get_loader_flags())
    print('NumberOfRvaAndSizes: '+ peFile.get_number_of_rva_and_sizes())

    print('\n***OPTIONAL HEADER DATA DICTIONARIES***\n')
    print('ExportTableRVA: '+ peFile.get_export_table_rva())
    print('ExportTableSize: '+ peFile.get_export_table_size())
    print('ImportTableRVA: '+ str(peFile.get_import_table_rva()))
    print('ImportTableSize: '+ peFile.get_import_table_size())
    print('ResourceTableRVA: '+ peFile.get_resource_table_rva())
    print('ResourceTableSize: '+ peFile.get_resource_table_size())
    print('ExceptionTableRVA: '+ peFile.get_exception_table_rva())
    print('ExceptionTableSize: '+ peFile.get_exception_table_size())
    print('CertificateTableRVA: '+ peFile.get_certificate_table_rva())
    print('CertificateTableSize: '+ peFile.get_certificate_table_size())
    print('BaseRelocationTableRVA: '+ peFile.get_base_relocation_table_rva())
    print('BaseRelocationTableSize: '+ peFile.get_base_relocation_table_size())
    print('DebugRVA: '+ peFile.get_debug_rva())
    print('DebugSize: '+ peFile.get_debug_size())
    print('ArchitectureRVA: '+ peFile.get_architecture_rva())
    print('ArchitectureSize: '+ peFile.get_architecture_size())
    print('GlobalPtrRVA: '+ peFile.get_global_ptr_rva())
    print('GlobalPtrSize: '+ peFile.get_global_ptr_size())
    print('TLSTableRVA: '+ peFile.get_tls_table_rva())
    print('TLSTableSize: '+ peFile.get_tls_table_size())
    print('LoadConfigTableRVA: '+ peFile.get_load_config_table_rva())
    print('LoadConfigTableSize: '+ peFile.get_load_config_table_size())
    print('BoundImportRVA: '+ peFile.get_bound_import_rva())
    print('BoundImportSize: '+ peFile.get_bound_import_size())
    print('IATRVA: '+ peFile.get_iat_rva())
    print('IATSize: '+ peFile.get_iat_size())
    print('DelayImportDescriptorRVA: '+ peFile.get_delay_import_descriptor_rva())
    print('DelayImportDescriptorSize: '+ peFile.get_delay_import_descriptor_size())
    print('CLRRuntimeHeaderRVA: '+ peFile.get_clr_runtime_header_rva())
    print('CLRRuntimeHeaderSize: '+ peFile.get_clr_runtime_header_size())
    
    print('\n***SECTION HEADERS***\n')
    for index in range(peFile.get_number_of_sections()):
        print("\nSECTION "+ str(index))
        print('Section '+ str(index) + ' Name: '+ peFile.get_section_name(index))
        print('Section '+ str(index) + ' VirtualSize: '+ peFile.get_section_virtual_size(index))
        print('Section '+ str(index) + ' VirtualAddress: '+ peFile.get_section_virtual_address(index))
        print('Section '+ str(index) + ' SizeOfRawData: '+ peFile.get_section_size_of_raw_data(index))
        print('Section '+ str(index) + ' PointerToRawData: '+ peFile.get_section_pointer_to_raw_data(index))
        print('Section '+ str(index) + ' PointerToRelocations: '+ peFile.get_section_pointer_to_relocations(index))
        print('Section '+ str(index) + ' PointerToLinenumbers: '+ peFile.get_section_pointer_to_linenumbers(index))
        print('Section '+ str(index) + ' NumberOfRelocations: '+ peFile.get_section_number_of_relocations(index))
        print('Section '+ str(index) + ' NumberOfLinenumbers: '+ peFile.get_section_number_of_linenumbers(index))
        print('Section '+ str(index) + ' Characteristics: '+ peFile.get_section_characteristics(index))
        Offset = peFile.get_section_pointer_to_raw_data(index)
        Length = peFile.get_section_size_of_raw_data(index)
        print('Section '+ str(index) + ' Entropy: '+ str(peFile.calculate_entropy(hex_to_dec(Offset),hex_to_dec(Length))))
        print('Section '+ str(index) + ' Md5: '+ str(peFile.get_section_md5(index)))


    print('\n***IMPORTS***\n')  
    
    for import_name in peFile.get_imports():
        print('IMPORTING: ' + import_name)

if len(sys.argv) > 1:
    file = sys.argv[1]
    with open(file,"rb") as bufferedReader:
        peFile= PE32()
        peFile.File(bufferedReader,file, "")
        dump_file_to_console(peFile)
                
