|
| 1 | +import re |
| 2 | +import sys |
| 3 | +import os |
| 4 | +import subprocess |
| 5 | +import hcl2 |
| 6 | + |
| 7 | +class HackerCompiler: |
| 8 | + def __init__(self, config_path="Virus.hcl"): |
| 9 | + self.cache_dir = "cache" |
| 10 | + self.env_dir = os.path.join(self.cache_dir, "env") |
| 11 | + self.build_dir = os.path.join(self.cache_dir, "build") |
| 12 | + self.src_dir = os.path.join(self.build_dir, "src") |
| 13 | + |
| 14 | + # Ładowanie konfiguracji HCL |
| 15 | + self.config = self._load_config(config_path) |
| 16 | + |
| 17 | + # Bezpieczne pobieranie danych z listy HCL |
| 18 | + project_list = self.config.get('project', [{}]) |
| 19 | + project_cfg = project_list[0] if isinstance(project_list, list) else project_list |
| 20 | + self.project_name = project_cfg.get('name', 'virus_payload') |
| 21 | + |
| 22 | + build_list = self.config.get('build', [{}]) |
| 23 | + build_cfg = build_list[0] if isinstance(build_list, list) else build_list |
| 24 | + self.binary_name = build_cfg.get('binary_name', 'payload') |
| 25 | + |
| 26 | + def _load_config(self, path): |
| 27 | + if not os.path.exists(path): |
| 28 | + print(f"[-] OSTRZEŻENIE: Brak pliku {path}. Używam domyślnych ustawień.") |
| 29 | + return {} |
| 30 | + try: |
| 31 | + with open(path, 'r', encoding='utf-8') as f: |
| 32 | + return hcl2.load(f) |
| 33 | + except Exception as e: |
| 34 | + print(f"[-] BŁĄD PARSOWANIA HCL: {e}") |
| 35 | + return {} |
| 36 | + |
| 37 | + def setup_workspace(self): |
| 38 | + """Tworzy strukturę folderów cache""" |
| 39 | + for directory in [self.env_dir, self.src_dir]: |
| 40 | + if not os.path.exists(directory): |
| 41 | + os.makedirs(directory, exist_ok=True) |
| 42 | + print(f"[+] Workspace przygotowany w /{self.cache_dir}") |
| 43 | + |
| 44 | + def translate_hcs_to_python(self, hcs_path): |
| 45 | + """Konwertuje .hcs na czysty Python""" |
| 46 | + if not os.path.exists(hcs_path): |
| 47 | + raise FileNotFoundError(f"Plik źródłowy {hcs_path} nie istnieje.") |
| 48 | + |
| 49 | + with open(hcs_path, 'r', encoding='utf-8') as f: |
| 50 | + lines = f.readlines() |
| 51 | + |
| 52 | + processed_lines = [] |
| 53 | + indent_level = 0 |
| 54 | + |
| 55 | + for line in lines: |
| 56 | + raw_line = line.strip() |
| 57 | + raw_line = re.sub(r'@.*', '', raw_line).strip() # Komentarze |
| 58 | + |
| 59 | + if not raw_line: |
| 60 | + processed_lines.append("") |
| 61 | + continue |
| 62 | + |
| 63 | + # Importy <core:nazwa> |
| 64 | + raw_line = re.sub(r'(import\s+)?<core:([\w\.]+)>', r'import \2', raw_line) |
| 65 | + |
| 66 | + # Słowa kluczowe |
| 67 | + raw_line = raw_line.replace('--- automatic ---', '').replace('--- manual ---', '') |
| 68 | + |
| 69 | + if raw_line.startswith('func '): |
| 70 | + raw_line = raw_line.replace('func ', 'def ', 1) |
| 71 | + |
| 72 | + if raw_line.startswith('log '): |
| 73 | + content = raw_line[4:].strip() |
| 74 | + raw_line = f"print({content})" |
| 75 | + |
| 76 | + # Obsługa bloków [ ] |
| 77 | + if raw_line == ']': |
| 78 | + indent_level -= 1 |
| 79 | + continue |
| 80 | + |
| 81 | + current_indent = " " * max(0, indent_level) |
| 82 | + |
| 83 | + if raw_line.endswith('['): |
| 84 | + formatted_line = current_indent + raw_line[:-1].rstrip() + ":" |
| 85 | + processed_lines.append(formatted_line) |
| 86 | + indent_level += 1 |
| 87 | + else: |
| 88 | + formatted_line = current_indent + raw_line |
| 89 | + processed_lines.append(formatted_line) |
| 90 | + |
| 91 | + return "\n".join(processed_lines) |
| 92 | + |
| 93 | + def prepare_rust_project(self, python_code): |
| 94 | + """Tworzy projekt Rust z poprawnymi zależnościami PyO3""" |
| 95 | + py_out_path = os.path.join(self.build_dir, "logic.py") |
| 96 | + with open(py_out_path, "w", encoding='utf-8') as f: |
| 97 | + f.write(python_code) |
| 98 | + |
| 99 | + # Cargo.toml - Używamy sprawdzonych flag dla wersji 0.23 |
| 100 | + cargo_content = f""" |
| 101 | +[package] |
| 102 | +name = "{self.project_name}" |
| 103 | +version = "0.1.0" |
| 104 | +edition = "2021" |
| 105 | +
|
| 106 | +[dependencies] |
| 107 | +pyo3 = {{ version = "0.23.3", features = ["auto-initialize"] }} |
| 108 | +""" |
| 109 | + with open(os.path.join(self.build_dir, "Cargo.toml"), "w") as f: |
| 110 | + f.write(cargo_content) |
| 111 | + |
| 112 | + # src/main.rs - Nowoczesne API Bound |
| 113 | + rust_content = r""" |
| 114 | +use pyo3::prelude::*; |
| 115 | +
|
| 116 | +fn main() -> PyResult<()> { |
| 117 | + // Automatyczna inicjalizacja interpretera dzięki fladze auto-initialize |
| 118 | + Python::with_gil(|py| { |
| 119 | + let code = include_str!("../logic.py"); |
| 120 | + let res = py.run_bound(code, None, None); |
| 121 | +
|
| 122 | + if let Err(e) = res { |
| 123 | + eprintln!("Python Script Error: {:?}", e); |
| 124 | + } |
| 125 | + Ok(()) |
| 126 | + }) |
| 127 | +} |
| 128 | +""" |
| 129 | + with open(os.path.join(self.src_dir, "main.rs"), "w") as f: |
| 130 | + f.write(rust_content) |
| 131 | + |
| 132 | + def compile_binary(self): |
| 133 | + """Uruchamia kompilację Cargo""" |
| 134 | + print(f"[*] Kompilowanie projektu '{self.project_name}' do binarki...") |
| 135 | + try: |
| 136 | + # Używamy --release dla optymalizacji i mniejszego rozmiaru |
| 137 | + result = subprocess.run( |
| 138 | + ["cargo", "build", "--release"], |
| 139 | + cwd=self.build_dir |
| 140 | + ) |
| 141 | + if result.returncode == 0: |
| 142 | + target_path = os.path.join(self.build_dir, "target", "release", self.project_name) |
| 143 | + print("-" * 40) |
| 144 | + print(f"[+] KOMPILACJA ZAKOŃCZONA SUKCESEM!") |
| 145 | + print(f"[+] Lokalizacja: {target_path}") |
| 146 | + print("-" * 40) |
| 147 | + else: |
| 148 | + print("[-] Błąd kompilacji Cargo. Sprawdź logi powyżej.") |
| 149 | + except FileNotFoundError: |
| 150 | + print("[-] BŁĄD: Nie znaleziono Cargo. Zainstaluj Rust.") |
| 151 | + |
| 152 | + def run(self, hcs_filename): |
| 153 | + hcs_path = hcs_filename |
| 154 | + if not os.path.exists(hcs_path): |
| 155 | + hcs_path = os.path.join("cmd", hcs_filename) |
| 156 | + |
| 157 | + try: |
| 158 | + print(f"[*] Przetwarzanie: {hcs_path}") |
| 159 | + self.setup_workspace() |
| 160 | + |
| 161 | + py_code = self.translate_hcs_to_python(hcs_path) |
| 162 | + self.prepare_rust_project(py_code) |
| 163 | + self.compile_binary() |
| 164 | + |
| 165 | + except Exception as e: |
| 166 | + print(f"[-] KRYTYCZNY BŁĄD: {e}") |
| 167 | + |
| 168 | +if __name__ == "__main__": |
| 169 | + if len(sys.argv) > 1: |
| 170 | + compiler = HackerCompiler() |
| 171 | + compiler.run(sys.argv[1]) |
| 172 | + else: |
| 173 | + print("Sposób użycia: python3 main.py <plik.hcs>") |
1 | 174 |
|
0 commit comments