import subprocess
import json
import os
from typing import Dict, List, Union, Optional
from dataclasses import dataclass
from pathlib import Path
@dataclass
class DIEAnalysisOptions:
json_output: bool = True
deep_scan: bool = False
entropy: bool = False
verbose: bool = False
show_methods: bool = False
class DIEAnalyzer:
def __init__(self, die_path: str = r"D:\backup\tool\die_win64_portable_3.10_x64\diec.exe"):
self.die_path = Path(die_path)
if not self.die_path.exists():
raise FileNotFoundError(f"DIE NOT FOUND > {die_path}")
def _build_command(self, target_file: str, options: DIEAnalysisOptions) -> List[str]:
cmd = [str(self.die_path)]
if options.json_output:
cmd.append("--json")
if options.deep_scan:
cmd.append("--deepscan")
if options.entropy:
cmd.append("--entropy")
if options.verbose:
cmd.append("--verbose")
if options.show_methods:
cmd.append("--showmethods")
cmd.append(target_file)
return cmd
def _run_command(self, cmd: List[str]) -> str:
try:
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
return result.stdout.strip()
except subprocess.CalledProcessError as e:
raise RuntimeError(f"Error executing DIE: {e.stderr if e.stderr else str(e)}")
def analyze_file(self, file_path: str, options: Optional[DIEAnalysisOptions] = None) -> Dict:
if options is None:
options = DIEAnalysisOptions()
file_path = str(Path(file_path).resolve())
if not os.path.exists(file_path):
raise FileNotFoundError(f"Target file not found: {file_path}")
cmd = self._build_command(file_path, options)
result = self._run_command(cmd)
try:
return json.loads(result)
except json.JSONDecodeError:
if options.show_methods:
# Parse methods output format
methods = []
for line in result.split('\n'):
if line.strip() and not line.startswith('Methods:'):
methods.append(line.strip())
return {"methods": methods}
raise ValueError(f"Failed to parse DIE output as JSON: {result}")
def get_special_info(self, file_path: str, method: str) -> Dict:
file_path = str(Path(file_path).resolve())
if not os.path.exists(file_path):
raise FileNotFoundError(f"Target file not found: {file_path}")
cmd = [str(self.die_path), "--special", method, "--json", file_path]
result = self._run_command(cmd)
try:
return json.loads(result)
except json.JSONDecodeError:
raise ValueError(f"Failed to parse DIE output as JSON: {result}")
def list_methods(self, file_path: str) -> List[str]:
options = DIEAnalysisOptions(show_methods=True, json_output=False)
result = self.analyze_file(file_path, options)
return result.get("methods", [])
def get_entropy_analysis(self, file_path: str) -> Dict:
options = DIEAnalysisOptions(entropy=True, deep_scan=True)
return self.analyze_file(file_path, options)
def get_full_analysis(self, file_path: str) -> Dict:
options = DIEAnalysisOptions(
deep_scan=True,
entropy=True,
verbose=True
)
return self.analyze_file(file_path, options)
def print_analysis_result(result: Union[Dict, List], title: str = "Analysis Result"):
print(f"\n=== {title} ===")
if isinstance(result, dict):
print(json.dumps(result, indent=2))
else:
for item in result:
print(item)
print("=" * (len(title) + 8))
def main():
try:
analyzer = DIEAnalyzer()
file_path = "requirements.txt"
result = analyzer.get_full_analysis(file_path)
print_analysis_result(result, "Full Analysis")
methods = analyzer.list_methods(file_path)
if methods:
print_analysis_result(methods, "Available Methods")
entropy_result = analyzer.get_entropy_analysis(file_path)
print_analysis_result(entropy_result, "Entropy Analysis")
for method in methods:
try:
special_info = analyzer.get_special_info(file_path, method)
print_analysis_result(special_info, f"Special Info - {method}")
except Exception as e:
print(f"\nError getting {method} info: {str(e)}")
except Exception as e:
print(f"Error: {str(e)}")
return 1
return 0
if __name__ == "__main__":
exit(main())