Что за зверь такой — Pinokio? Досконально разбираем его подкапотную

от автора

Не так давно я выпустил первую часть своей статьи, в которой поднял проблему отсутствия портативных установщиков репозиториев и показал разницу между Pinokio и своей разработкой PortableSource. Что ж, в этой части мы залезем под капот Pinokio и узнаем, что же он за зверь такой и в чем причина его лагов.

ЧАСТЬ 1. Публичный репозиторий на github — open‑source ли? Или это просто обман?

Казалось бы, репозиторий размещен на github, следовательно имеет открытый исходный код? Только вот… В данном случае это лишь отчасти правда. Посмотрим на основную страничку:

выглядит как самый обычный GUI на node.js. но не все так просто

выглядит как самый обычный GUI на node.js. но не все так просто

Привет Node.JS разработчики, если вы читаете! А если вы не шарите за ноду, то тут есть одна странность — где папка src? Она, по неведомой причине, отсутствует. Или все таки причина известна? Пожалуй, погрузимся в дебри package.json:

Весьма странное поведение — Манки-Патчи! (Улика №1)

{
«name»: «Pinokio»,
«private»: true,
«version»: «3.28.0»,
«homepage»: «https://pinokio.co»,
«description»: «pinokio»,
«main»: «main.js»,
«email»: «cocktailpeanuts@proton.me«,
«author»: «https://twitter.com/cocktailpeanut»,
«scripts»: {
«start»: «electron .»,
«pack»: «./node_modules/.bin/electron-builder —dir»,
«eject»: «hdiutil info | grep ‘/dev/disk’ | awk ‘{print 1}’ | xargs -I {} hdiutil detach {}{platform}»
},
«publish»: [
{
«provider»: «github»,
«owner»: «pinokiocomputer»,
«repo»: «pinokio»
}
],
«asarUnpack»: [
«node_modules/go-get-folder-size//*», «node_modules/7zip-bin//«, «node_modules/sweetalert2/**/«,
«node_modules/@homebridge//*» ], «nsis»: { «include»: «build/installer.nsh» }, «extraResources»: [ «./script/«,
{
«from»: «assets/icon_small.png»,
«to»: «assets/icon_small.png»
}
],
«protocols»: [
{
«name»: «pinokio»,
«schemes»: [
«pinokio»
]
}
],
«mac»: {
«category»: «utility»,
«target»: [
{
«target»: «default»,
«arch»: [
«x64»,
«arm64»
]
}
],
«hardenedRuntime»: true
},
«linux»: {
«maintainer»: «Cocktail Peanut «,
«target»: [
{
«target»: «deb»,
«arch»: [
«x64»,
«arm64»
]
},
{
«target»: «rpm»,
«arch»: [
«x64»,
«arm64»
]
},
{
«target»: «AppImage»,
«arch»: [
«x64»,
«arm64»
]
}
]
},
«win»: {
«artifactName»: «Pinokio-Installer.${ext}»,
«target»: [
{
«target»: «nsis»,
«arch»: [
«x64»
]
}
]
}
},
«license»: «MIT»,
«dependencies»: {
«electron-progressbar»: «^2.2.1»,
«electron-store»: «^8.1.0»,
«electron-updater»: «^6.6.2»,
«electron-window-state»: «^5.0.3»,
«pinokiod»: «^3.28.0»
},
«devDependencies»: {
«@electron/rebuild»: «3.2.10»,
«electron»: «^23.1.2»,
«electron-builder»: «^26.0.18»,
«electron-builder-notarize»: «^1.5.2»
}
}

Увидели странности? И я увидел: какие-то мутные манки-патчи, почта на протон домене и непонятный пакет pinokiod в зависимостях. Не странно ли? Зачем автор использует патчинг, демон с закрытым кодом и, собственно, анонимную почту? Эти 3 зацепки показывают, что код из-за внешних модулей нестабилен, само ядро закрыто, а автор хочет остаться анонимным.

Ну окей, пройдем дальше и рассмотрим main.js:

const Pinokiod = require("pinokiod") const config = require('./config') const pinokiod = new Pinokiod(config) let mode = pinokiod.kernel.store.get("mode") || "full" //iprocess.env.PINOKIO_MODE = process.env.PINOKIO_MODE || 'desktop'; if (mode === 'minimal') {   require('./minimal'); } else {   require('./full'); }

Упс, а где вызов src, где точка входа, как у нормальных open-source приложений? А ее нет, есть лишь безликий pinokiod — демон с закрытым кодом, о наличии которого я сказал чуть раньше. Наталкивает на весьма страшные мысли, что автор недобросовестный человек, и по какой-то неведомой причине хочет скрыть свои наработки… Или, быть может, на то есть рациональная причина?

Часть 2. Лезем демону под капот и рассматриваем под микроскопом его внутренности.

Не будем лить воду и перейдем к самому сладкому — реверс-инжинирингу, который будет весьма простым и быстрым, ведь автор построил крепость, но забыл защитить ее обфускацией кода. Но для начала, немного официальности:
Для начала — важный момент: наши действия полностью легальны. Проект использует лицензию MIT о чем указано 113 строке packages.json, а также свой файл LICENSE, который является перековеркой MIT:

Copyright 2023 Pinokio

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the «Software»), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED «AS IS», WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Итак, для начала нам надо установить парочку инструментов, благодаря которым мы сможем провести реверс, это Node.JS и самый обычный 7-zip. После быстренькой установки следуем инструкции:

Сначала, мы скачиваем вот этот релиз (если автор его не удалит, после выхода данной статьи в свет). Либо файл отсюда. Мы берем на препарацию Pinokio-3.9.0-win32.zip. Давайте сравним хеши, чтобы быть уверенными, что я вас не обманываю?
Вот копия страницы. Вот хэш этого архива:
sha256:322d5ce9e3d22c98b62fb67cf7ca79aad46882242c5339d4073affb5fa5148f1

Убедимся, что версия с интернет архива имеет такой же хэш. Вот так:

Get-FileHash Pinokio-3.9.0-win32.zip -Algorithm SHA256 | Format-List

Теперь просто распакуем архив и обнаружим «чудо»:

видим сетап, который и нужен нам

видим сетап, который и нужен нам

Не стоит кликать по нему два раза, ведь мы пришли не за этим. Просто следуйте инструкции ниже, которая покажет, как вытащить сердце — app.asar

необходимо перейти в $PLUGINSDIR

необходимо перейти в $PLUGINSDIR
нам нужен именно app-64.7z, забираем этот архив

нам нужен именно app-64.7z, забираем этот архив

Все, сетап больше нам не нужен и не интересен, ведь мы сняли этот первый слой луковой шелухи, теперь разархивируем архив и увидим вот такое наполнение папки:

архив нам больше не нужен. избавляемся от него.

архив нам больше не нужен. избавляемся от него.

Перейдем в папку resources и увидим заветный файл app.asar, ради которого эта операция и затевалась:

именно он нам и нужен!

именно он нам и нужен!

Немного усмирим коней и внесем ясность. Что же это за штука такая, app.asar? А это доказательство того, что ВСЯ логика написана на Node.JS и Electron. Помните лаги, баги, тупые ошибки? Вот их и первопричина, на которую можно будет взглянуть лично через пару действий! Ведь мы прямо сейчас будем данное чудо ДЕкомпилировать в понятный JS код, который уже могут почитать все. А знающие — ознакомиться с ним. Для этого открываем cmd, я пользуюсь таким лайфхаком:

Установим необходимую библиотеку для декомпиляции сего чуда, для этого мы и ставили node.js:

npm install -g asar

И с его помощью извлечем сердце, app.asar:

asar extract app.asar ./extracted

Итак. Команда ничего не выведет, но появится новая папка с таким содержимым, которое уже читаемое и его можно проанализировать:

интересен ли нам main.js? абсолютно нет.

интересен ли нам main.js? абсолютно нет.

Наша главная цель — node_modules/pinokiod. Тот самый закрытый код, который внезапно стал открытым. С помощью наших легких усилий. Кстати, весьма интересные пакеты…

но они не так интересны, как сердце - pinokiod.

но они не так интересны, как сердце — pinokiod.

ВОТ ОНО. Вот, то самое «чудо», которое так успешно скрывал и берег автор, словно зеницу ока. Будучи близким к своей цели… Он сделал много ошибок: оставил свою личную почту в логах сборки, закрыл исходный код демона, надеясь, что никто никогда не доберется до его истины и не полезет изучать истину данной программы. Он, мягко говоря, сильно ошибался.

а вот и само чудо - pinokiod.

а вот и само чудо — pinokiod.

Давайте рассмотрим это по порядку. Тут весьма много интересного, ведь автор, зачем-то сделал и сервер и клиент в одной оболочке. Это весьма нелогично и непрактично, мешать в одном месте мед, мух и пчелы. Ведь это весьма сложно отлаживать, это порождает море багов в использовании и раздувает сборки до весьма больших размеров.

ну и франкештейн!

ну и франкештейн!

Я не буду углублятся в каждый файл, в каждую написанную функцию, ведь мы пришли не на конференцию по кибербезу, а почитать статью, не так ли? Но, если кому интересно узнать подноготную, то я выпущу третью часть разбора, где в деталях и в полных красках расскажу о этом «черном ящике», который благодаря нашим усилиям оказался прозрачной призмой. Но в рамках данной статьи, пожалуй, направим Claude 4 Sonnet проанализировать весь код.

Анализ кода (ОСТОРОЖНО: ШОК-КОНТЕНТ)

Общее описание: pinokiod — это Node.js демон/сервер для платформы Pinokio, представляющий собой комплексную систему управления AI-приложениями и автоматизации. Версия: 3.9.0.

📁 Архитектура проекта :

Корневые файлы:

  • index.js — точка входа, экспортирует server модуль

  • package.json — конфигурация npm с 40+ зависимостями

  • worker.js — воркер процесс для асинхронных файловых операций

🖥️ Server (server/):

  • index.js — основной сервер класс (Express.js)

  • socket.js — WebSocket сервер для real-time коммуникации

  • views/ — EJS шаблоны для веб-интерфейса

  • public/ — статические ресурсы (CSS, JS, xterm.js)

  • ⚙️ Kernel (kernel/) — Ядро системы:

    Основные модули:

    • index.js — главный класс Kernel

    • environment.js — управление переменными окружения

    • shell.js — управление терминальными сессиями

    • script.js — выполнение и управление скриптами

    API модули (kernel/api/):

    • index.js — центральный API роутер

    • shell/fs/process/gradio/cloudflare/ — специализированные API

    Bin модули (kernel/bin/):

    • index.js — базовый класс для установки инструментов

    • python.jsconda.jsgit.jscuda.js — установщики

🔄 Pipe (pipe/): Система для создания публичных эндпоинтов.

📜 Script (script/): Автономный запуск сервера.


🔧 Ключевые функции

  • Управление окружением: Автоматическая установка Python, Conda, Git, CUDA.

  • Терминальный интерфейс: Веб-терминал через xterm.js.

  • Веб-интерфейс: Файловый менеджер, редакторы кода.

  • Интеграции: Git, Gradio, Cloudflare, HuggingFace.

  • Безопасность: Аутентификация для публичных эндпоинтов.

  • Мониторинг: Сбор системной информации (GPU, CPU, память).


📊 Технологический стек

  • Backend: Node.js, Express.js

  • Frontend: EJS, xterm.js, WebSocket

  • Терминал: node-pty

  • Git: isomorphic-git

  • Прокси: http-proxy


Вердикт: Это полнофункциональная платформа для разработки, развертывания и управления AI-приложениями с веб-интерфейсом и автоматизацией инфраструктуры.

Тот, кто решил почитать об архитектуре — ты видишь этот ужас? Использование в одном флаконе клиента и сервера, куча сложной логики, работа лишь с помощью скриптов и манки-патчи. А задумывался ли ты, к чему это может привести? Быть может, тебя не пугают сливы данных и подобное. Но когда ты используешь такой софт, который написан с использованием ненадежных вещей, который имеет полностью закрытый код и использует скриптовую установку, то невольно может возникнуть мысль — а в безопасности ли мои данные? Или мои наработки? Что если автор вшил в свое детище стиллер, ратник или еще какую-нибудь пакость, о которой ты не подозреваешь?

Хватит терпеть такое отношение от «open-source» проекта, который лишь просто красив, а по факту медленный, баганый и лаганный, использует тяжеловесные пакетные менеджеры и творит странные финты. Я бы не использовал такое решение, ведь банально, это подрывает мою безопасность! И безопасность моих данных.

Итог прост — пинокио не так прост, как кажется на первый взгляд. И лучше сделать выбор в пользу полностью открытого, быстрого и дружелюбного софта. Такого как PortableSource, ведь он имеет кастомные фичи: создание виртуальных дисков (что решило проблему длинных путей), использование кастомного менеджера пакетов и окружений и он практически полностью написан на Rust — это гарантия быстроты и надежности, которой так не хватает пинокио.


ссылка на оригинал статьи https://habr.com/ru/articles/935644/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *