This is a mobile optimized page that loads fast, if you want to load the real page, click this text.

Продам скрипт для дампа CEF любого сервера RAGE:MP

Ser

Участник портала
5 Июн 2024
111
13
55
18
Продам скрипт для дампа CEF любого сервера RAGE:MP, скрипт работает только через executor в VANISH(проверено) / 1337(не проверено), помогу с установкой если потребуется, отвечу на все вопросы в дискорде.

Связь Вась со мной(discord): atlantax3d
Цена скрипта: 1000руб
 
Реакции: nafanych!

fivepkost

Начинающий специалист
25 Мар 2023
443
45
85
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()

 
Реакции: Inoi

Ser

Участник портала
5 Июн 2024
111
13
55
18
Круто
 

fivepkost

Начинающий специалист
25 Мар 2023
443
45
85
ну смотри это был бессплатный дипсик, но если немного изменить промпт и закинуть в тот же опус 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-типам
Расширения файловТочное определение расширений
 

Ser

Участник портала
5 Июн 2024
111
13
55
18
Напомню python инжектора в гташку нету
 

fivepkost

Начинающий специалист
25 Мар 2023
443
45
85
я не использовал его в действии, так как нахожусь на работе, я тебе просто показал что через нейронку дампер можно сделать в пол пинка было бы желение и продавать то что ты продаёшь за 1к, ну я не как не поверю что это ты делал сам лично
 

fivepkost

Начинающий специалист
25 Мар 2023
443
45
85
я конечно не на что не намекаю но
 

Scripter228

Участник портала
26 Авг 2025
83
16
30
А если у меня обфусцированный код - он сольет все?
 

Similar threads