
Набор инструментов для реверс-инжиниринга и фаззинга приложений на основе Protobuf
# pbtk - Обратная разработка Protobuf приложений
**[Protobuf](https://developers.google.com/protocol-buffers/) — это формат сериализации**, разработанный Google и используемый во всё большем числе Android, веб, настольных и других приложений. Он включает **язык для описания структур данных**, который затем компилируется в код или другую структуру в зависимости от целевой реализации.
pbtk (*Protobuf toolkit*) — это полноценный набор скриптов, доступных через единый графический интерфейс, предоставляющий две основные возможности:
- **Извлечение структур Protobuf из программ**, преобразование их обратно в читаемые *.proto* файлы, с поддержкой различных реализаций:
- Все основные среды выполнения Java (base, Lite, Nano, Micro, J2ME), с полной поддержкой Proguard, *(2026: всё ещё хорошо работает, но в основном со старыми APK)*
- Бинарные файлы, содержащие встроенные метаданные отражения (обычно C++, иногда Java и большинство других привязок), *(2026: всё ещё хорошо работает)*
- Веб-приложения, использующие среду выполнения JsProtoUrl. *(2026: нуждается в обновлении)*
- **Редактирование, повторная отправка и фаззинг данных**, отправляемых на сетевые конечные точки Protobuf, через удобный графический интерфейс, позволяющий в реальном времени редактировать поля сообщения Protobuf и просматривать результат.
<img src="https://assets.kitploit.com/production/public/readmes/3051/860b9306c2be49d204ad562b8bf0abdb831e9f1c9852edda265734fe26be1a2b.png" alt="The pbtk editor GUI">
## Установка
PBTK требует Python ≥ 3.5, PySide 6, Python-Protobuf 3 и несколько исполняемых программ (chromium, jad, dex2jar...) для запуска скриптов извлечения.
Пользователи Ubuntu могут установить его с помощью `snap`:
```
$ sudo snap install pbtk
$ pbtk
```
Пользователи Archlinux могут установить напрямую через [пакет](https://aur.archlinux.org/packages/pbtk-git/):
```
$ yay -S pbtk-git
$ pbtk
```
На большинстве других дистрибутивов лучше запускать напрямую:
```tcl
# For Ubuntu/Debian testing derivates:
$ sudo apt install python3-pip git openjdk-8-jre python3-qtpy-pyside6
# Then, using UV:
$ sudo snap install --classic astral-uv
$ uv tool install pbtk
$ pbtk
# Or using pipx:
$ sudo apt install pipx
$ pipx install pbtk
$ pbtk
```
Windows также поддерживается (с теми же требуемыми модулями). После запуска графического интерфейса он предупредит вас о том, чего не хватает, в зависимости от того, что вы пытаетесь сделать.
## Использование командной строки (установка через менеджер пакетов)
Графический интерфейс можно запустить через основной скрипт:
pbtk
Следующие скрипты также можно использовать отдельно, без GUI:
pbtk-jar-extract [-h] input_file [output_dir]
pbtk-from-binary [-h] input_file [output_dir]
pbtk-web-extract [-h] input_url [output_dir] # Needs update to work as of 2026
При установке через `snap` точные команды отличаются:
pbtk.jar-extract [-h] input_file [output_dir]
pbtk.from-binary [-h] input_file [output_dir]
pbtk.web-extract [-h] input_url [output_dir]
## Использование командной строки (локальная установка)
Графический интерфейс можно запустить через основной скрипт:
```bash
uv sync # Download dependencies to the .venv folder
source .venv/bin/activate # Put the local scripts in $PATH for the current shell session
uv tool install -e . # Put the local scripts in $PATH all time
pbtk
```
Следующие скрипты также можно использовать отдельно, без GUI:
pbtk-jar-extract [-h] input_file [output_dir]
pbtk-from-binary [-h] input_file [output_dir]
pbtk-web-extract [-h] input_url [output_dir] # Needs update to work as of 2026
## Типичный рабочий процесс
Предположим, вы занимаетесь обратной разработкой Android-приложения. Вы немного изучили приложение с помощью любимого декомпилятора и поняли, что оно передаёт Protobuf в качестве POST-данных по HTTPS обычным способом.
Вы открываете PBTK, и вас встречают с осмысленным приветствием:

Первый шаг — получить ваши .protos в текстовом формате. Если вы работаете с Android-приложением, просто перетащите APK и подождите — магия произойдет! (если только это не совсем экзотическая реализация)

После этого вы переходите в `~/.pbtk/protos/<имя вашего APK>` (либо через командную строку, либо через кнопку внизу экрана приветствия, чтобы открыть файловый менеджер — как вам удобнее). Все .protos приложения действительно здесь.
Вернувшись в декомпилятор, вы наткнулись на класс, который конструирует данные, отправляемые на интересующую вас HTTPS-конечную точку. Он сериализует сообщение Protobuf, вызывая класс, состоящий из сгенерированного кода.

Этот последний класс должен иметь точное соответствие в вашей директории .protos (т.е. `com.foo.bar.a.b` будет соответствовать `com/foo/bar/a/b.proto`). В любом случае, поиск по его имени позволит вам сослаться на него.
Отлично: следующий шаг — перейти к **Шагу 2**, выбрать нужный входной .proto и заполнить информацию о вашей конечной точке.

Вы также можете предоставить образец необработанных данных Protobuf, которые были отправлены на эту конечную точку и перехвачены через mitmproxy или Wireshark, и вставить их в шестнадцатеричном формате.
**Шаг 3** — это весёлая часть: нажимать кнопки и смотреть, что происходит! У вас есть древовидное представление, отображающее каждое поле в структуре Protobuf (повторяющиеся поля помечены суффиксом "+", обязательные поля не имеют флажков).

Просто наведите курсор на поле, чтобы сфокусироваться. Если поле целочисленного типа, используйте колёсико мыши для увеличения/уменьшения. Информация о перечислении также появляется при наведении.
Вот и всё! Вы можете определить значение каждого поля с помощью этого. Если вы извлекли .protos из минифицированного кода, вы можете переименовывать поля в соответствии с тем, что, как вы заметили, они означают, щёлкнув по их именам.
Удачного реверсинга! 👌 🎉
## Локальное хранение данных
PBTK сохраняет извлечённую информацию .proto в `~/.pbtk/protos/` (или `%APPDATA%\pbtk\protos` на Windows).
Вы можете перемещать, копировать, переименовывать, редактировать или удалять данные из этой директории напрямую через обычный файловый менеджер и текстовый редактор — это предусмотренный способ, и он не повлияет на работу PBTK.
HTTP-конечные точки сохраняются в `~/.pbtk/endpoints/` в виде JSON-объектов. Эти объекты представляют собой массивы пар информации запроса/ответа, которые выглядят так:
```javascript
[{
"request": {
"transport": "pburl",
"proto": "www.google.com/VectorTown.proto",
"url": "https://www.google.com/VectorTown",
"pb_param": "pb",
"samples": [{
"pb": "!....",
"hl": "fr"
}]
},
"response": {
"format": "other"
}
}]
```
## Структура исходного кода
PBTK внутренне использует два типа подключаемых модулей: экстракторы и транспорты.
* **Экстрактор** поддерживает извлечение структур .proto из целевой реализации или платформы Protobuf.
Экстракторы определены в `src/pbtk/extractors/*.py`. Они определяются как метод с декоратором, например:
```python
@register_extractor(name = 'my_extractor',
desc = 'Extract Protobuf structures from Foobar code (*.foo, *.bar)',
depends={'binaries': ['foobar-decompiler']})
def my_extractor(path):
# Load contents of the `path` input file and do your stuff...
# Then, yield extracted .protos using a generator:
for i in do_your_extraction_work():
yield proto_name + '.proto', proto_contents
# Other kinds of information can be yield, such as endpoint information or progress to display.
```
* **Транспорт** поддерживает способ десериализации, повторной сериализации и отправки данных Protobuf по сети. Например, наиболее часто используемый транспорт — это необработанные POST-данные через HTTP.
Транспорты определены в `src/pbtk/utils/transports.py`. Они определяются как класс с декоратором, например:
```python
@register_transport(
name = 'my_transport',
desc = 'Protobuf as raw POST data',
ui_data_form = 'hex strings'
)
class MyTransport():
def __init__(self, pb_param, url):
self.url = url
def serialize_sample(self, sample):
# We got a sample of input data from the user.
# Verify that it is valid in the form described through "ui_data_form" parameter, fail with an exception or return False otherwise.
# Optionally modify this data prior to returning it.
bytes.fromhex(sample)
return sample
def load_sample(self, sample, pb_msg):
# Parse input data into the provided Protobuf object.
pb_msg.ParseFromString(bytes.fromhex(sample))
def perform_request(self, pb_data, tab_data):
# Perform a request using the provided URL and Protobuf object, and optionally other transport-specific side data.
return post(url, pb_data.SerializeToString(), headers=USER_AGENT)
```
## Будущие улучшения
Следующее может появиться в будущих версиях:
* Завершение автоматического фаззинга.
* Поддержка извлечения расширений из Java-кода.
* Поддержка среды выполнения JSPB (основной JavaScript).
* Если есть какая-либо другая платформа, которую вы хотели бы видеть поддерживаемой, просто создайте issue, и я посмотрю.
Я постарался сделать код максимально читаемым и с комментариями (за исключением частей, которые в основном говорят сами за себя, например, подключение сигналов GUI) для большинства модулей, чтобы вы могли внести свой вклад.
## Лицензирование
pbtk выпущен под лицензией [GNU GPL](https://www.gnu.org/licenses/gpl-3.0.html) (я, настоящим, и т.д.).
Нет формализованного правила для регистра букв в названии проекта, правило просто — следовать своему сердцу ❤