feat: 添加对python 3.11的反编译模块

This commit is contained in:
dqy
2024-05-31 20:33:47 +08:00
parent aeb4a33d98
commit df65fff2c7
3 changed files with 50 additions and 35 deletions

View File

@@ -38,11 +38,12 @@ def find_dangerous_functions(
} }
risk_patterns = patterns.get(file_extension, {}) risk_patterns = patterns.get(file_extension, {})
classified_results = {"high": [], "medium": [], "low": [], "none": []} classified_results = {"high": [], "medium": [], "low": [], "none": []}
for line_number, line in enumerate(file_content.split("\n"), start=1): if file_content is not None:
clean_line = remove_comments(line, file_extension) for line_number, line in enumerate(file_content.split("\n"), start=1):
if not clean_line: clean_line = remove_comments(line, file_extension)
continue if not clean_line:
for pattern, risk_level in risk_patterns.items(): continue
if re.search(pattern, clean_line): for pattern, risk_level in risk_patterns.items():
classified_results[risk_level].append((line_number, clean_line)) if re.search(pattern, clean_line):
classified_results[risk_level].append((line_number, clean_line))
return classified_results return classified_results

View File

@@ -1,4 +1,5 @@
import os import os
from pickle import FALSE
from typing import Dict, List, Tuple, Optional from typing import Dict, List, Tuple, Optional
from reportlab.lib.pagesizes import letter from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet from reportlab.lib.styles import getSampleStyleSheet
@@ -10,6 +11,8 @@ from .utils import *
import sys import sys
from colorama import init, Fore, Style from colorama import init, Fore, Style
PYCDC_FLAG = True
PYCDC_ADDR_FLAG = True
SUPPORTED_EXTENSIONS = {".py", ".js", ".cpp", ".pyc"} SUPPORTED_EXTENSIONS = {".py", ".js", ".cpp", ".pyc"}
OUTPUT_FORMATS = ["html", "md", "txt", "pdf"] OUTPUT_FORMATS = ["html", "md", "txt", "pdf"]
ORDERS = [ ORDERS = [
@@ -331,6 +334,13 @@ def checkModeAndDetect(mode: str, filePath: str, fileExtension: str, pycdc_addr:
if fileExtension == ".pyc": if fileExtension == ".pyc":
# 反汇编pyc文件 # 反汇编pyc文件
file_content = disassemble_pyc(filePath, pycdc_addr) file_content = disassemble_pyc(filePath, pycdc_addr)
if file_content == "none":
global PYCDC_FLAG
PYCDC_FLAG = False
return ""
elif file_content == "invalid":
global PYCDC_ADDR_FLAG
PYCDC_ADDR_FLAG = False
if mode == "regex": if mode == "regex":
return find_dangerous_functions(file_content, fileExtension) return find_dangerous_functions(file_content, fileExtension)
elif mode == "llm": elif mode == "llm":
@@ -360,26 +370,28 @@ def process_path(
file_results = checkModeAndDetect( file_results = checkModeAndDetect(
mode, file_path, file_extension, pycdc_addr mode, file_path, file_extension, pycdc_addr
) )
for key in file_results: if file_results != "":
if key != "none": # Exclude 'none' risk level for key in file_results:
results[key].extend( if key != "none": # Exclude 'none' risk level
[ results[key].extend(
(f"{file_path}: Line {line_num}", line) [
for line_num, line in file_results[key] (f"{file_path}: Line {line_num}", line)
] for line_num, line in file_results[key]
) ]
)
elif os.path.isfile(path): elif os.path.isfile(path):
file_extension = os.path.splitext(path)[1] file_extension = os.path.splitext(path)[1]
if file_extension in SUPPORTED_EXTENSIONS: if file_extension in SUPPORTED_EXTENSIONS:
file_results = checkModeAndDetect(mode, path, file_extension, pycdc_addr) file_results = checkModeAndDetect(mode, path, file_extension, pycdc_addr)
for key in file_results: if file_results != "":
if key != "none": # Exclude 'none' risk level for key in file_results:
results[key].extend( if key != "none": # Exclude 'none' risk level
[ results[key].extend(
(f"{path}: Line {line_num}", line) [
for line_num, line in file_results[key] (f"{path}: Line {line_num}", line)
] for line_num, line in file_results[key]
) ]
)
else: else:
print("Unsupported file type.") print("Unsupported file type.")
return return
@@ -420,6 +432,14 @@ def main():
output_file = args.output.rsplit(".", 1)[0] + ".txt" output_file = args.output.rsplit(".", 1)[0] + ".txt"
# 如果未指定输出文件,则输出到 stdout否则写入文件 # 如果未指定输出文件,则输出到 stdout否则写入文件
process_path(args.path, output_format, args.mode, args.pycdc, output_file) process_path(args.path, output_format, args.mode, args.pycdc, output_file)
if PYCDC_FLAG == False:
print(
"ERROR: Detected Python 3.11 or above .pyc files. You need to install pycdc and compile it yourself to obtain pycdc."
)
print("Repo: https://github.com/zrax/pycdc.git")
if PYCDC_ADDR_FLAG == False:
print("ERROR: The specified pycdc.exe path is not valid")
print("Please check your pycdc path.")
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -3,6 +3,7 @@ import uncompyle6
import io import io
import os import os
import subprocess import subprocess
from contextlib import redirect_stdout, redirect_stderr
def run_pycdc(exe_path: str, pyc_file: str) -> str: def run_pycdc(exe_path: str, pyc_file: str) -> str:
@@ -17,15 +18,12 @@ def run_pycdc(exe_path: str, pyc_file: str) -> str:
str: Output from pycdc.exe. str: Output from pycdc.exe.
""" """
if not os.path.isfile(exe_path): if not os.path.isfile(exe_path):
print(f"ERROR: The specified pycdc.exe path is not valid: {exe_path}") return "invalid"
print("Please check your pycdc path.")
exit(1)
command = f'"{exe_path}" "{pyc_file}"' command = f'"{exe_path}" "{pyc_file}"'
result = subprocess.run(command, capture_output=True, text=True, shell=True) result = subprocess.run(
command, capture_output=True, text=True, shell=True, encoding="utf-8"
if result.returncode != 0: )
raise Exception(f"Error running pycdc.exe: {result.stderr}")
return result.stdout return result.stdout
@@ -46,10 +44,6 @@ def disassemble_pyc(file_path: str, pycdc_addr=None) -> str:
return output.getvalue() return output.getvalue()
except Exception as e: except Exception as e:
if pycdc_addr is None: if pycdc_addr is None:
print( return "none"
"ERROR: For Python 3.11 and above, you need to install pycdc and compile it yourself to obtain pycdc.exe."
)
print("repo: https://github.com/zrax/pycdc.git")
exit(1)
else: else:
return run_pycdc(pycdc_addr, file_path) return run_pycdc(pycdc_addr, file_path)