import json
import os
import requests
import websocket # pip install websocket-client
from urllib.parse import urlparse
# ---------- НАСТРОЙКИ ----------
CEF_DEBUG_URL = "http://127.0.0.1:9222"
OUTPUT_DIR = "cef_dump"
TIMEOUT = 10
# --------------------------------
def ensure_output_dir():
if not os.path.exists(OUTPUT_DIR):
os.makedirs(OUTPUT_DIR)
print(f"[+] Создана папка: {OUTPUT_DIR}")
def get_targets():
"""Получает список открытых вкладок/браузеров CEF."""
try:
resp = requests.get(f"{CEF_DEBUG_URL}/json", timeout=TIMEOUT)
resp.raise_for_status()
return resp.json()
except Exception as e:
print(f"[-] Не удалось получить список целей CEF: {e}")
return []
def send_ws_command(ws, method, params=None, msg_id=1):
"""Отправляет команду по WebSocket и возвращает ответ."""
if params is None:
params = {}
payload = {"id": msg_id, "method": method, "params": params}
ws.send(json.dumps(payload))
while True:
try:
raw = ws.recv()
data = json.loads(raw)
if data.get("id") == msg_id:
return data
except Exception as e:
print(f"[-] Ошибка чтения WebSocket: {e}")
return None
def dump_target(target):
"""Дамп одного браузера CEF."""
ws_url = target.get("webSocketDebuggerUrl")
if not ws_url:
print(f"[-] Пропуск цели без WebSocket URL: {target.get('url')}")
return
title = target.get("title", "unknown").replace("/", "_").replace("\\", "_")
url = target.get("url", "")
print(f"\n[+] Обработка: {title} — {url}")
try:
ws = websocket.create_connection(ws_url, timeout=TIMEOUT)
except Exception as e:
print(f"[-] Не удалось подключиться к {ws_url}: {e}")
return
try:
# Включаем необходимые домены
send_ws_command(ws, "Page.enable", msg_id=1)
send_ws_command(ws, "Runtime.enable", msg_id=2)
send_ws_command(ws, "Network.enable", msg_id=3)
# 1. Получаем HTML через Runtime.evaluate
eval_resp = send_ws_command(
ws,
"Runtime.evaluate",
{"expression": "document.documentElement.outerHTML", "returnByValue": True},
msg_id=10
)
html_content = ""
if eval_resp and "result" in eval_resp:
html_content = eval_resp["result"].get("result", {}).get("value", "")
# 2. Получаем дерево ресурсов
tree_resp = send_ws_command(ws, "Page.getResourceTree", msg_id=11)
resources = []
if tree_resp and "result" in tree_resp:
def collect_resources(node):
if "resources" in node:
resources.extend(node["resources"])
for child in node.get("children", []):
collect_resources(child)
collect_resources(tree_resp["result"].get("frameTree", {}))
# 3. Сохраняем HTML
safe_title = "".join(c for c in title if c.isalnum() or c in " ._-")[:50]
html_path = os.path.join(OUTPUT_DIR, f"{safe_title}.html")
with open(html_path, "w", encoding="utf-8") as f:
f.write(html_content)
print(f" [+] HTML сохранён: {html_path} ({len(html_content)} байт)")
# 4. Сохраняем ресурсы (CSS, JS, картинки и т.д.)
for res in resources:
res_url = res.get("url", "")
if not res_url or res_url.startswith("data:"):
continue
# Пропускаем сам HTML-документ (он уже сохранён)
if res_url == url:
continue
try:
content_resp = send_ws_command(
ws,
"Page.getResourceContent",
{"frameId": tree_resp["result"]["frameTree"]["frame"]["id"], "url": res_url},
msg_id=100 + len(resources)
)
if content_resp and "result" in content_resp:
content = content_resp["result"].get("content", "")
# Пытаемся определить расширение по MIME-типу или URL
parsed = urlparse(res_url)
filename = os.path.basename(parsed.path) or "resource"
ext = os.path.splitext(filename)[1]
if not ext:
mime = res.get("mimeType", "")
if "css" in mime:
ext = ".css"
elif "javascript" in mime:
ext = ".js"
elif "image" in mime:
ext = ".png" # упрощённо
res_name = f"{safe_title}_{len(resources)}{ext}"
res_path = os.path.join(OUTPUT_DIR, res_name)
with open(res_path, "w", encoding="utf-8", errors="ignore") as f:
f.write(content)
print(f" [+] Ресурс: {res_name} ({len(content)} байт)")
except Exception as e:
print(f" [-] Ошибка загрузки ресурса {res_url}: {e}")
finally:
ws.close()
def main():
ensure_output_dir()
targets = get_targets()
if not targets:
print("[-] Цели CEF не найдены. Убедитесь, что включён режим отладки (порт 9222).")
return
# Фильтруем только браузеры RAGE:MP (обычно URL начинается с package:// или http://localhost)
cef_targets = [
t for t in targets
if t.get("type") == "page" and (
"package://" in t.get("url", "") or
"localhost" in t.get("url", "") or
"rage" in t.get("url", "").lower()
)
]
if not cef_targets:
# Если фильтр не сработал, пробуем все страницы
cef_targets = [t for t in targets if t.get("type") == "page"]
print(f"[+] Найдено целей CEF: {len(cef_targets)}")
for target in cef_targets:
dump_target(target)
print("\n[+] Дамп завершён.")
if __name__ == "__main__":
main()
КрутоPython:import json import os import requests import websocket # pip install websocket-client from urllib.parse import urlparse # ---------- НАСТРОЙКИ ---------- CEF_DEBUG_URL = "http://127.0.0.1:9222" OUTPUT_DIR = "cef_dump" TIMEOUT = 10 # -------------------------------- def ensure_output_dir(): if not os.path.exists(OUTPUT_DIR): os.makedirs(OUTPUT_DIR) print(f"[+] Создана папка: {OUTPUT_DIR}") def get_targets(): """Получает список открытых вкладок/браузеров CEF.""" try: resp = requests.get(f"{CEF_DEBUG_URL}/json", timeout=TIMEOUT) resp.raise_for_status() return resp.json() except Exception as e: print(f"[-] Не удалось получить список целей CEF: {e}") return [] def send_ws_command(ws, method, params=None, msg_id=1): """Отправляет команду по WebSocket и возвращает ответ.""" if params is None: params = {} payload = {"id": msg_id, "method": method, "params": params} ws.send(json.dumps(payload)) while True: try: raw = ws.recv() data = json.loads(raw) if data.get("id") == msg_id: return data except Exception as e: print(f"[-] Ошибка чтения WebSocket: {e}") return None def dump_target(target): """Дамп одного браузера CEF.""" ws_url = target.get("webSocketDebuggerUrl") if not ws_url: print(f"[-] Пропуск цели без WebSocket URL: {target.get('url')}") return title = target.get("title", "unknown").replace("/", "_").replace("\\", "_") url = target.get("url", "") print(f"\n[+] Обработка: {title} — {url}") try: ws = websocket.create_connection(ws_url, timeout=TIMEOUT) except Exception as e: print(f"[-] Не удалось подключиться к {ws_url}: {e}") return try: # Включаем необходимые домены send_ws_command(ws, "Page.enable", msg_id=1) send_ws_command(ws, "Runtime.enable", msg_id=2) send_ws_command(ws, "Network.enable", msg_id=3) # 1. Получаем HTML через Runtime.evaluate eval_resp = send_ws_command( ws, "Runtime.evaluate", {"expression": "document.documentElement.outerHTML", "returnByValue": True}, msg_id=10 ) html_content = "" if eval_resp and "result" in eval_resp: html_content = eval_resp["result"].get("result", {}).get("value", "") # 2. Получаем дерево ресурсов tree_resp = send_ws_command(ws, "Page.getResourceTree", msg_id=11) resources = [] if tree_resp and "result" in tree_resp: def collect_resources(node): if "resources" in node: resources.extend(node["resources"]) for child in node.get("children", []): collect_resources(child) collect_resources(tree_resp["result"].get("frameTree", {})) # 3. Сохраняем HTML safe_title = "".join(c for c in title if c.isalnum() or c in " ._-")[:50] html_path = os.path.join(OUTPUT_DIR, f"{safe_title}.html") with open(html_path, "w", encoding="utf-8") as f: f.write(html_content) print(f" [+] HTML сохранён: {html_path} ({len(html_content)} байт)") # 4. Сохраняем ресурсы (CSS, JS, картинки и т.д.) for res in resources: res_url = res.get("url", "") if not res_url or res_url.startswith("data:"): continue # Пропускаем сам HTML-документ (он уже сохранён) if res_url == url: continue try: content_resp = send_ws_command( ws, "Page.getResourceContent", {"frameId": tree_resp["result"]["frameTree"]["frame"]["id"], "url": res_url}, msg_id=100 + len(resources) ) if content_resp and "result" in content_resp: content = content_resp["result"].get("content", "") # Пытаемся определить расширение по MIME-типу или URL parsed = urlparse(res_url) filename = os.path.basename(parsed.path) or "resource" ext = os.path.splitext(filename)[1] if not ext: mime = res.get("mimeType", "") if "css" in mime: ext = ".css" elif "javascript" in mime: ext = ".js" elif "image" in mime: ext = ".png" # упрощённо res_name = f"{safe_title}_{len(resources)}{ext}" res_path = os.path.join(OUTPUT_DIR, res_name) with open(res_path, "w", encoding="utf-8", errors="ignore") as f: f.write(content) print(f" [+] Ресурс: {res_name} ({len(content)} байт)") except Exception as e: print(f" [-] Ошибка загрузки ресурса {res_url}: {e}") finally: ws.close() def main(): ensure_output_dir() targets = get_targets() if not targets: print("[-] Цели CEF не найдены. Убедитесь, что включён режим отладки (порт 9222).") return # Фильтруем только браузеры RAGE:MP (обычно URL начинается с package:// или http://localhost) cef_targets = [ t for t in targets if t.get("type") == "page" and ( "package://" in t.get("url", "") or "localhost" in t.get("url", "") or "rage" in t.get("url", "").lower() ) ] if not cef_targets: # Если фильтр не сработал, пробуем все страницы cef_targets = [t for t in targets if t.get("type") == "page"] print(f"[+] Найдено целей CEF: {len(cef_targets)}") for target in cef_targets: dump_target(target) print("\n[+] Дамп завершён.") if __name__ == "__main__": main()
Посмотреть вложение 29350
Ну ты проверь его на работоспособность и результат от его работы и отпиши сюда
РаботаетНу ты проверь его на работоспособность и результат от его работы и отпиши сюда
ну смотри это был бессплатный дипсик, но если немного изменить промпт и закинуть в тот же опус 5.5, ну потратишь ты на 10 сек побольше но результат будет соответственно лучше, это не стоит 1кНу ты проверь его на работоспособность и результат от его работы и отпиши сюда
import json
import os
import requests
import websocket
import mimetypes
from urllib.parse import urlparse
from pathlib import Path
from typing import Optional, Dict, List, Any
import time
# ---------- НАСТРОЙКИ ----------
CEF_DEBUG_URL = "http://127.0.0.1:9222"
OUTPUT_DIR = "cef_dump"
TIMEOUT = 10
MAX_RETRIES = 3
RETRY_DELAY = 0.5
# --------------------------------
class CEFDumper:
def __init__(self, debug_url: str, output_dir: str):
self.debug_url = debug_url
self.output_dir = Path(output_dir)
self.output_dir.mkdir(exist_ok=True)
print(f"[+] Папка вывода: {self.output_dir.absolute()}")
def get_targets(self) -> List[Dict[str, Any]]:
"""Получает список открытых вкладок/браузеров CEF."""
try:
resp = requests.get(f"{self.debug_url}/json", timeout=TIMEOUT)
resp.raise_for_status()
return resp.json()
except requests.RequestException as e:
print(f"[-] Не удалось получить список целей CEF: {e}")
return []
def send_ws_command(self, ws, method: str, params: Optional[Dict] = None, msg_id: int = 1) -> Optional[Dict]:
"""Отправляет команду по WebSocket с повторными попытками."""
if params is None:
params = {}
payload = {"id": msg_id, "method": method, "params": params}
for attempt in range(MAX_RETRIES):
try:
ws.send(json.dumps(payload))
while True:
raw = ws.recv()
data = json.loads(raw)
if data.get("id") == msg_id:
# Проверяем на ошибки
if "error" in data:
print(f" [-] Ошибка команды {method}: {data['error']}")
return None
return data
except Exception as e:
if attempt < MAX_RETRIES - 1:
time.sleep(RETRY_DELAY)
continue
print(f" [-] Ошибка WebSocket ({method}): {e}")
return None
return None
def sanitize_filename(self, name: str, max_len: int = 100) -> str:
"""Очищает имя файла от недопустимых символов."""
safe = "".join(c if c.isalnum() or c in " ._-" else "_" for c in name)
return safe[:max_len].strip()
def get_file_extension(self, url: str, mime_type: str = "") -> str:
"""Определяет расширение файла по URL или MIME-типу."""
parsed = urlparse(url)
path = parsed.path
# Пытаемся получить расширение из пути
if "." in path:
ext = Path(path).suffix.lower()
if ext and len(ext) < 10:
return ext
# Определяем по MIME-типу
mime_map = {
"text/css": ".css",
"application/javascript": ".js",
"text/javascript": ".js",
"image/png": ".png",
"image/jpeg": ".jpg",
"image/gif": ".gif",
"image/svg+xml": ".svg",
"application/json": ".json",
"text/plain": ".txt",
"application/font-woff": ".woff",
"application/font-woff2": ".woff2",
}
for mime, ext in mime_map.items():
if mime in mime_type.lower():
return ext
# Fallback
return ".bin"
def dump_target(self, target: Dict[str, Any]) -> bool:
"""Дамп одного браузера CEF."""
ws_url = target.get("webSocketDebuggerUrl")
if not ws_url:
print(f"[-] Пропуск цели без WebSocket URL: {target.get('url')}")
return False
title = target.get("title", "unknown")
url = target.get("url", "")
print(f"\n[+] Обработка: {title[:60]}")
print(f" URL: {url[:80]}")
try:
ws = websocket.create_connection(ws_url, timeout=TIMEOUT)
except Exception as e:
print(f"[-] Не удалось подключиться: {e}")
return False
try:
# Включаем необходимые домены
self.send_ws_command(ws, "Page.enable", msg_id=1)
self.send_ws_command(ws, "Runtime.enable", msg_id=2)
self.send_ws_command(ws, "Network.enable", msg_id=3)
safe_title = self.sanitize_filename(title)
target_dir = self.output_dir / safe_title
target_dir.mkdir(exist_ok=True)
# 1. Получаем HTML
html_content = self._get_html(ws)
if html_content:
html_path = target_dir / "index.html"
html_path.write_text(html_content, encoding="utf-8")
print(f" [+] HTML: {len(html_content)} байт")
# 2. Получаем ресурсы
tree_resp = self.send_ws_command(ws, "Page.getResourceTree", msg_id=11)
if tree_resp and "result" in tree_resp:
resources = self._collect_resources(tree_resp["result"].get("frameTree", {}))
frame_id = tree_resp["result"]["frameTree"]["frame"]["id"]
self._download_resources(ws, resources, target_dir, frame_id, url)
return True
except Exception as e:
print(f"[-] Ошибка при обработке: {e}")
return False
finally:
try:
ws.close()
except:
pass
def _get_html(self, ws) -> str:
"""Получает HTML через Runtime.evaluate."""
resp = self.send_ws_command(
ws,
"Runtime.evaluate",
{
"expression": "document.documentElement.outerHTML",
"returnByValue": True
},
msg_id=10
)
if resp and "result" in resp:
return resp["result"].get("result", {}).get("value", "")
return ""
def _collect_resources(self, node: Dict) -> List[Dict]:
"""Рекурсивно собирает все ресурсы из дерева."""
resources = []
def traverse(n):
if "resources" in n:
resources.extend(n["resources"])
for child in n.get("children", []):
traverse(child)
traverse(node)
return resources
def _download_resources(self, ws, resources: List[Dict], target_dir: Path,
frame_id: str, main_url: str) -> None:
"""Загружает ресурсы с фильтрацией."""
downloaded = 0
skipped = 0
for idx, res in enumerate(resources):
res_url = res.get("url", "")
mime = res.get("mimeType", "")
# Пропускаем ненужные ресурсы
if not res_url or res_url.startswith("data:") or res_url == main_url:
skipped += 1
continue
try:
resp = self.send_ws_command(
ws,
"Page.getResourceContent",
{"frameId": frame_id, "url": res_url},
msg_id=100 + idx
)
if resp and "result" in resp:
content = resp["result"].get("content", "")
# Определяем имя файла
parsed = urlparse(res_url)
filename = os.path.basename(parsed.path)
if not filename:
filename = f"resource_{idx}"
base, _ = os.path.splitext(filename)
ext = self.get_file_extension(res_url, mime)
safe_name = self.sanitize_filename(base) + ext
res_path = target_dir / safe_name
# Сохраняем с правильной кодировкой
if "image" in mime or "font" in mime or res_url.endswith((".woff", ".woff2", ".ttf")):
# Бинарные данные (base64)
if content:
import base64
try:
binary_data = base64.b64decode(content)
res_path.write_bytes(binary_data)
except:
res_path.write_text(content, encoding="utf-8", errors="ignore")
else:
# Текстовые данные
res_path.write_text(content, encoding="utf-8", errors="ignore")
downloaded += 1
if downloaded % 10 == 0:
print(f" [+] Загружено ресурсов: {downloaded}")
except Exception as e:
print(f" [-] Ошибка {res_url[:50]}: {str(e)[:50]}")
print(f" [+] Всего загружено: {downloaded}, пропущено: {skipped}")
def main():
dumper = CEFDumper(CEF_DEBUG_URL, OUTPUT_DIR)
targets = dumper.get_targets()
if not targets:
print("[-] Цели CEF не найдены. Убедитесь, что включён режим отладки (порт 9222).")
return
# Фильтруем браузеры
cef_targets = [
t for t in targets
if t.get("type") == "page" and any(
keyword in t.get("url", "").lower()
for keyword in ["package://", "localhost", "rage", "127.0.0.1"]
)
]
if not cef_targets:
cef_targets = [t for t in targets if t.get("type") == "page"]
print(f"[+] Найдено целей: {len(cef_targets)}")
success = 0
for target in cef_targets:
if dumper.dump_target(target):
success += 1
print(f"\n[+] Завершено: {success}/{len(cef_targets)} успешно")
if __name__ == "__main__":
main()
| Улучшение | Описание |
|---|---|
| Класс CEFDumper | Структурированный код с методами вместо функций |
| Обработка ошибок | Проверка на ошибки в ответах, повторные попытки |
| Безопасность имён | Лучшая санитизация имён файлов |
| Бинарные ресурсы | Правильная загрузка изображений и шрифтов (base64) |
| Организация файлов | Отдельная папка для каждой страницы |
| Типизация | Добавлены type hints для лучшей читаемости |
| Логирование | Детальная информация о прогрессе |
| Фильтрация ресурсов | Умная фильтрация по MIME-типам |
| Расширения файлов | Точное определение расширений |
Напомню python инжектора в гташку нетуну смотри это был бессплатный дипсик, но если немного изменить промпт и закинуть в тот же опус 5.5, ну потратишь ты на 10 сек побольше но результат будет соответственно лучше, это не стоит 1к
не благадарите
Python:import json import os import requests import websocket import mimetypes from urllib.parse import urlparse from pathlib import Path from typing import Optional, Dict, List, Any import time # ---------- НАСТРОЙКИ ---------- CEF_DEBUG_URL = "http://127.0.0.1:9222" OUTPUT_DIR = "cef_dump" TIMEOUT = 10 MAX_RETRIES = 3 RETRY_DELAY = 0.5 # -------------------------------- class CEFDumper: def __init__(self, debug_url: str, output_dir: str): self.debug_url = debug_url self.output_dir = Path(output_dir) self.output_dir.mkdir(exist_ok=True) print(f"[+] Папка вывода: {self.output_dir.absolute()}") def get_targets(self) -> List[Dict[str, Any]]: """Получает список открытых вкладок/браузеров CEF.""" try: resp = requests.get(f"{self.debug_url}/json", timeout=TIMEOUT) resp.raise_for_status() return resp.json() except requests.RequestException as e: print(f"[-] Не удалось получить список целей CEF: {e}") return [] def send_ws_command(self, ws, method: str, params: Optional[Dict] = None, msg_id: int = 1) -> Optional[Dict]: """Отправляет команду по WebSocket с повторными попытками.""" if params is None: params = {} payload = {"id": msg_id, "method": method, "params": params} for attempt in range(MAX_RETRIES): try: ws.send(json.dumps(payload)) while True: raw = ws.recv() data = json.loads(raw) if data.get("id") == msg_id: # Проверяем на ошибки if "error" in data: print(f" [-] Ошибка команды {method}: {data['error']}") return None return data except Exception as e: if attempt < MAX_RETRIES - 1: time.sleep(RETRY_DELAY) continue print(f" [-] Ошибка WebSocket ({method}): {e}") return None return None def sanitize_filename(self, name: str, max_len: int = 100) -> str: """Очищает имя файла от недопустимых символов.""" safe = "".join(c if c.isalnum() or c in " ._-" else "_" for c in name) return safe[:max_len].strip() def get_file_extension(self, url: str, mime_type: str = "") -> str: """Определяет расширение файла по URL или MIME-типу.""" parsed = urlparse(url) path = parsed.path # Пытаемся получить расширение из пути if "." in path: ext = Path(path).suffix.lower() if ext and len(ext) < 10: return ext # Определяем по MIME-типу mime_map = { "text/css": ".css", "application/javascript": ".js", "text/javascript": ".js", "image/png": ".png", "image/jpeg": ".jpg", "image/gif": ".gif", "image/svg+xml": ".svg", "application/json": ".json", "text/plain": ".txt", "application/font-woff": ".woff", "application/font-woff2": ".woff2", } for mime, ext in mime_map.items(): if mime in mime_type.lower(): return ext # Fallback return ".bin" def dump_target(self, target: Dict[str, Any]) -> bool: """Дамп одного браузера CEF.""" ws_url = target.get("webSocketDebuggerUrl") if not ws_url: print(f"[-] Пропуск цели без WebSocket URL: {target.get('url')}") return False title = target.get("title", "unknown") url = target.get("url", "") print(f"\n[+] Обработка: {title[:60]}") print(f" URL: {url[:80]}") try: ws = websocket.create_connection(ws_url, timeout=TIMEOUT) except Exception as e: print(f"[-] Не удалось подключиться: {e}") return False try: # Включаем необходимые домены self.send_ws_command(ws, "Page.enable", msg_id=1) self.send_ws_command(ws, "Runtime.enable", msg_id=2) self.send_ws_command(ws, "Network.enable", msg_id=3) safe_title = self.sanitize_filename(title) target_dir = self.output_dir / safe_title target_dir.mkdir(exist_ok=True) # 1. Получаем HTML html_content = self._get_html(ws) if html_content: html_path = target_dir / "index.html" html_path.write_text(html_content, encoding="utf-8") print(f" [+] HTML: {len(html_content)} байт") # 2. Получаем ресурсы tree_resp = self.send_ws_command(ws, "Page.getResourceTree", msg_id=11) if tree_resp and "result" in tree_resp: resources = self._collect_resources(tree_resp["result"].get("frameTree", {})) frame_id = tree_resp["result"]["frameTree"]["frame"]["id"] self._download_resources(ws, resources, target_dir, frame_id, url) return True except Exception as e: print(f"[-] Ошибка при обработке: {e}") return False finally: try: ws.close() except: pass def _get_html(self, ws) -> str: """Получает HTML через Runtime.evaluate.""" resp = self.send_ws_command( ws, "Runtime.evaluate", { "expression": "document.documentElement.outerHTML", "returnByValue": True }, msg_id=10 ) if resp and "result" in resp: return resp["result"].get("result", {}).get("value", "") return "" def _collect_resources(self, node: Dict) -> List[Dict]: """Рекурсивно собирает все ресурсы из дерева.""" resources = [] def traverse(n): if "resources" in n: resources.extend(n["resources"]) for child in n.get("children", []): traverse(child) traverse(node) return resources def _download_resources(self, ws, resources: List[Dict], target_dir: Path, frame_id: str, main_url: str) -> None: """Загружает ресурсы с фильтрацией.""" downloaded = 0 skipped = 0 for idx, res in enumerate(resources): res_url = res.get("url", "") mime = res.get("mimeType", "") # Пропускаем ненужные ресурсы if not res_url or res_url.startswith("data:") or res_url == main_url: skipped += 1 continue try: resp = self.send_ws_command( ws, "Page.getResourceContent", {"frameId": frame_id, "url": res_url}, msg_id=100 + idx ) if resp and "result" in resp: content = resp["result"].get("content", "") # Определяем имя файла parsed = urlparse(res_url) filename = os.path.basename(parsed.path) if not filename: filename = f"resource_{idx}" base, _ = os.path.splitext(filename) ext = self.get_file_extension(res_url, mime) safe_name = self.sanitize_filename(base) + ext res_path = target_dir / safe_name # Сохраняем с правильной кодировкой if "image" in mime or "font" in mime or res_url.endswith((".woff", ".woff2", ".ttf")): # Бинарные данные (base64) if content: import base64 try: binary_data = base64.b64decode(content) res_path.write_bytes(binary_data) except: res_path.write_text(content, encoding="utf-8", errors="ignore") else: # Текстовые данные res_path.write_text(content, encoding="utf-8", errors="ignore") downloaded += 1 if downloaded % 10 == 0: print(f" [+] Загружено ресурсов: {downloaded}") except Exception as e: print(f" [-] Ошибка {res_url[:50]}: {str(e)[:50]}") print(f" [+] Всего загружено: {downloaded}, пропущено: {skipped}") def main(): dumper = CEFDumper(CEF_DEBUG_URL, OUTPUT_DIR) targets = dumper.get_targets() if not targets: print("[-] Цели CEF не найдены. Убедитесь, что включён режим отладки (порт 9222).") return # Фильтруем браузеры cef_targets = [ t for t in targets if t.get("type") == "page" and any( keyword in t.get("url", "").lower() for keyword in ["package://", "localhost", "rage", "127.0.0.1"] ) ] if not cef_targets: cef_targets = [t for t in targets if t.get("type") == "page"] print(f"[+] Найдено целей: {len(cef_targets)}") success = 0 for target in cef_targets: if dumper.dump_target(target): success += 1 print(f"\n[+] Завершено: {success}/{len(cef_targets)} успешно") if __name__ == "__main__": main()
Основные улучшения:
Улучшение Описание Класс CEFDumper Структурированный код с методами вместо функций Обработка ошибок Проверка на ошибки в ответах, повторные попытки Безопасность имён Лучшая санитизация имён файлов Бинарные ресурсы Правильная загрузка изображений и шрифтов (base64) Организация файлов Отдельная папка для каждой страницы Типизация Добавлены type hints для лучшей читаемости Логирование Детальная информация о прогрессе Фильтрация ресурсов Умная фильтрация по MIME-типам Расширения файлов Точное определение расширений
не вижу проблемНапомню python инжектора в гташку нету
И что он выкачал? Закинь скрин, или даже проще чем и как ты выкачал если это пайтон?Работает
я не использовал его в действии, так как нахожусь на работе, я тебе просто показал что через нейронку дампер можно сделать в пол пинка было бы желение и продавать то что ты продаёшь за 1к, ну я не как не поверю что это ты делал сам личноИ что он выкачал? Закинь скрин, или даже проще чем и как ты выкачал если это пайтон?
А если у меня обфусцированный код - он сольет все?Продам скрипт для дампа CEF любого сервера RAGE:MP, скрипт работает только через executor в VANISH(проверено) / 1337(не проверено), помогу с установкой если потребуется, отвечу на все вопросы в дискорде.
Связь Вась со мной(discord): atlantax3d
Цена скрипта: 1000руб