Astral Wanderer
Astral Wanderer

Reputation: 35

Getting the Main functions code of a .NET executable using only Python

I have a c# .NET executable sample with the following structure (when opened in a disassembler, for example DnSpy) :

->executable_name
`->PE
`->Type References
`->References
`->{ } -
`->qCaVAPJGIk
    `-> OltkKtykOO
        `->Base Type and Interface
        `->OltkKtykOO(): void...
        `->GetProcAddress....
        `-> ...
        `-> ...
        `-> Main()

Is there any way I can read this .exe with python and somehow parse it and get the Main functions code?

I gave it a try with pefile and capstone modules but without luck. The only thing I managed was to extract embedded resources with the following code, but can't seem to be able to parse the functions of the program:

import pefile
import clr
clr.AddReference("System.Reflection")
clr.AddReference("System")
from System.IO import StreamReader
clr.AddReference("System.IO")
from System.Reflection import Assembly

def extract_embedded_resource(assembly_path, resource_name, output_file):
    try:
        # Load the assembly from the specified path
        assembly = Assembly.LoadFile(assembly_path)

        # Get all the embedded resources within the loaded assembly
        for resource in assembly.GetManifestResourceNames():
            if resource == resource_name:
                # Open the embedded resource stream
                resourceStream = assembly.GetManifestResourceStream(resource)

                if resourceStream is not None:
                    try:
                        # Read the content of the resource
                        streamReader = StreamReader(resourceStream)
                        content = streamReader.ReadToEnd()
                        

                        # Optionally, write the content to an output file
                        with open(output_file, "w") as f:
                            f.write(content)
                            print(f"Resource '{resource_name}' extracted to '{output_file}'")
                            return  # Exit function after extracting the resource
                    finally:
                        # Ensure the stream is closed
                        resourceStream.Close()

        # If resource is not found
        print(f"Resource '{resource_name}' not found in the assembly.")
    except Exception as e:
        print(f"Error extracting resource: {e}")

My try with the capstone did not manage to find anything related to main:

from capstone import *

def extract_main_function_code(pe_path):
    # Load the PE file
    pe = pefile.PE(pe_path)
    print(dir(pe))
    # Iterate over the PE sections
    for section in pe.sections:
        # Check if the section contains executable code
        if section.Characteristics & 0x20:
            # Extract the code from the section
            code_offset = section.VirtualAddress
            code_size = section.SizeOfRawData
            code_data = section.get_data(code_offset, code_size)

            # Initialize Capstone disassembler
            md = Cs(CS_ARCH_X86, CS_MODE_32 if pe.FILE_HEADER.Machine == 0x014c else CS_MODE_64)

            # Disassemble the code
            for insn in md.disasm(code_data, code_offset):
                # Check if the disassembled instruction is the start of the 'main' function
                if 'main' in insn.op_str:
                    # Print the disassembled instruction
                    print(f"Address: 0x{insn.address:08x} \t {insn.mnemonic} {insn.op_str}")

    # Close the PE file
    pe.close()

Upvotes: 0

Views: 31

Answers (0)

Related Questions