96 lines
4.0 KiB
Python
96 lines
4.0 KiB
Python
import subprocess
|
|
import os
|
|
import shutil
|
|
import sys
|
|
import logging
|
|
|
|
logging.basicConfig(filename='analyzer.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
|
|
def decompile_pyc(pyc_file, source_dir):
|
|
try:
|
|
pycdc_process = subprocess.Popen(['resources\pycdc.exe', pyc_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
|
|
stdout, stderr = pycdc_process.communicate()
|
|
decoded_code = stdout.decode('utf-8')
|
|
pyc_filename = os.path.basename(pyc_file)
|
|
py_filename = pyc_filename[:-4] + '.py'
|
|
|
|
count = 2
|
|
while os.path.exists(os.path.join(source_dir, py_filename)):
|
|
py_filename = pyc_filename[:-4] + f'_{count}.py'
|
|
count += 1
|
|
|
|
py_filepath = os.path.join(source_dir, py_filename)
|
|
with open(py_filepath, 'w') as py_file:
|
|
py_file.write(decoded_code)
|
|
logging.info(f"Decompiled {pyc_filename}")
|
|
print(f"Decompiled {pyc_filename}")
|
|
except Exception as e:
|
|
logging.error(f"Error decompiling pyc: {e}")
|
|
print(f"Error decompiling pyc: {e}")
|
|
return
|
|
|
|
def main():
|
|
logging.info("Starting analysis.")
|
|
if len(sys.argv) != 2:
|
|
logging.error("Usage: python script.py FILE_TO_ANALYZE.exe")
|
|
print("Usage: python script.py FILE_TO_ANALYZE.exe")
|
|
sys.exit(1)
|
|
|
|
file_to_analyze = sys.argv[1]
|
|
extracted_dir = file_to_analyze + '_extracted'
|
|
source_dir = file_to_analyze + '_source'
|
|
entry_points_dir = os.path.join(source_dir, 'entry_points')
|
|
|
|
os.makedirs(source_dir, exist_ok=True)
|
|
os.makedirs(entry_points_dir, exist_ok=True)
|
|
|
|
try:
|
|
pycdc_process = subprocess.Popen(['python', 'resources\pyinstxtractor.py', file_to_analyze, '-w', extracted_dir], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
|
|
stdout, stderr = pycdc_process.communicate()
|
|
output_lines = stdout.decode('utf-8').splitlines()
|
|
|
|
entry_points = [line.split()[-1] for line in output_lines if 'Possible entry point' in line]
|
|
logging.info(f"Possible entry points: {entry_points}")
|
|
|
|
for root, dirs, files in os.walk(extracted_dir):
|
|
for file in files:
|
|
if file.endswith('.pyc'):
|
|
pyc_file = os.path.join(root, file)
|
|
pyc_filename = os.path.basename(pyc_file)
|
|
if pyc_filename in entry_points:
|
|
logging.info(f"Decompiling entry point: {pyc_filename}")
|
|
decompile_pyc(pyc_file, source_dir)
|
|
source_file = os.path.join(source_dir, pyc_filename[:-4] + '.py')
|
|
entry_point_dest = os.path.join(entry_points_dir, pyc_filename[:-4] + '.py')
|
|
shutil.move(source_file, entry_point_dest)
|
|
|
|
continue_with_others = input("Do you want to continue with decompiling other files? (y/n): ").strip().lower()
|
|
if continue_with_others != 'y':
|
|
logging.info("Decompilation of other files cancelled.")
|
|
print("Decompilation of other files cancelled.")
|
|
shutil.rmtree(extracted_dir)
|
|
logging.info("Analysis completed.")
|
|
print("Analysis completed.")
|
|
sys.exit(0)
|
|
|
|
for root, dirs, files in os.walk(extracted_dir):
|
|
for file in files:
|
|
if file.endswith('.pyc'):
|
|
pyc_file = os.path.join(root, file)
|
|
pyc_filename = os.path.basename(pyc_file)
|
|
if pyc_filename not in entry_points:
|
|
logging.info(f"Decompiling: {pyc_filename}")
|
|
decompile_pyc(pyc_file, source_dir)
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
logging.error(f"Error extracting bytecode: {e}")
|
|
print(f"Error extracting bytecode: {e}")
|
|
sys.exit(1)
|
|
|
|
shutil.rmtree(extracted_dir)
|
|
logging.info("Analysis completed.")
|
|
print("Analysis completed.")
|
|
|
|
if __name__ == '__main__':
|
|
main()
|