reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
79
our-skills/re-roast-2026/SKILL.md
Normal file
79
our-skills/re-roast-2026/SKILL.md
Normal file
@@ -0,0 +1,79 @@
|
||||
---
|
||||
name: re-roast-2026
|
||||
description: "Use when roasting/verifying a reverse-engineering guide, post, or list of RE tools; fact-checking stars/tool counts; link liveness sweep; cutting hyperbole; splitting content into Telegram messages (4096 limit); or when building/evaluating any 2026 RE stack content: IDA/Ghidra/Binary Ninja, Qiling, OGhidra, AI-RE pipeline, IDA licensing. Triggers: прожарка, реверс, реверсинг, RE, reverse engineering, бинарь, дизассемблер, декомпилятор, проверь ссылки, гайд по реверсу, проверить факты в посте."
|
||||
---
|
||||
|
||||
# Что делает
|
||||
|
||||
Прожарка RE-контента: факт-чек против первоисточников, свип живости ссылок, срезка гипербол, разбивка под Telegram. Второй контур — канонный верифицированный стек реверс-инжиниринга 2026 (проверен 26.09.2026, 102/102 ссылки живы).
|
||||
|
||||
## When to use
|
||||
|
||||
- Прожарка/разбор чужого гайда по реверсу перед репостом в канал
|
||||
- Факт-чек цифр (звёзды GitHub, число тулов, доменов, статей) и названий репо/книг
|
||||
- Свип живости ссылок в MD (102+ ссылок)
|
||||
- Составление нового RE-материала на проверенном стеке
|
||||
- Оценка инструмента: лицензия и цена (бесплатно/ограниченно/платно)
|
||||
|
||||
## When NOT to use
|
||||
|
||||
- Сам разбор бинарника, malware, crackme (это другие скиллы: reverse-engineering, malware-analysis)
|
||||
- Общая редактура текста без RE-темы
|
||||
- Если не нужно ничего проверять — только писать свежий контент без фактов
|
||||
|
||||
## Workflow (прожарка RE-гайда)
|
||||
|
||||
1. **Триаж ссылок**: извлечь все URL из текста, прогнать `scripts/linkcheck.py`. 403/405 = бот-волл (сайт жив), не мёртвый. 404/сетевая ошибка = кандидат на удаление/замену.
|
||||
2. **Цифры**: каждое число — против первоисточника (GitHub API/search, README репо). Звёзды, число тулов в описании, число статей/доменов. Несколько источников, если неоднозначно.
|
||||
3. **Названия**: репо и книги сверять дословно; репо могло переехать (PMAT-course → PMAT-labs).
|
||||
4. **Лицензии и цены**: пометить каждое ограничение. IDA Pro / Binary Ninja — платные, фраза «всё бесплатное» при них ложь; de4py = CC BY-NC; disrobe = платно для компаний.
|
||||
5. **Гиперболы**: срезать «инструменты бесполезны», «свободно читаешь», «лучший способ», «от запуска до ответа», «~20 новых 0-day» (тавтология).
|
||||
6. **Техническая точность**: Qiling исполняет в эмуляции → «без запуска на живой системе»; OGhidra поддерживает и облачные API (приватность только в локальном режиме); промпт-инъекция в бинарнике = «встраивает команды в строки», не «учится разговаривать».
|
||||
7. **Атрибуция**: при репосте сохранять автора («[REDACTED] ([REDACTED])»), убирать промо-футеры автора (боты/платные ссылки).
|
||||
8. **Разбивка**: сообщения ≤ 4096 символов, каждое самодостаточно, маркеры `===MSG N/4===`.
|
||||
9. **Лицензия IDA**: при упоминании IDA Pro добавить раздел про легальные пути (IDA Free, Ghidra, студенческая Hex-Rays) — иначе аудитория идёт за кейгенами и тянет малварь.
|
||||
|
||||
## Success criteria
|
||||
|
||||
- Все ссылки проверены: 0 DEAD, BOTWALL задокументирован
|
||||
- Каждая цифра текста сходится с первоисточником (с датой проверки)
|
||||
- Каждое языковое/лицензионное утверждение без гипербол
|
||||
- Все блоки ≤ 4096 символов
|
||||
- Под-пост готов, если пользователь просил («под пост» = сообщение-компаньон, в канал не отправлять)
|
||||
|
||||
## Failure modes
|
||||
|
||||
- **Сервер режет HEAD** → GET fallback в linkcheck; 403 Cloudflare/Anubis = живой, не ошибка
|
||||
- **Цифры устарели между проверками** → писать дату проверки рядом с цифрой
|
||||
- **Репозиторий переехал** → искать новый owner/название (labs/archive суффиксы), не удалять секцию вслепую
|
||||
- **Ссылка отдаёт 200 на сайте, но бот-волл браузеру** → не удалять, пометить «жив, отдаёт 403 ботам»
|
||||
|
||||
## Gotchas (проверено 26.09.2026)
|
||||
|
||||
| Факт | Значение |
|
||||
|---|---|
|
||||
| binary-ninja-headless-mcp | 181 тул (не 180) |
|
||||
| firefox-reverse | 857 звёзд (не 855) |
|
||||
| shannon | 48к звёзд (не 47к) |
|
||||
| Anthropic-Cybersecurity-Skills | 34 домена (не 29) |
|
||||
| open-reverselab | 180+ статей (не 194) |
|
||||
| PMAT | репо PMAT-labs (не PMAT-course) |
|
||||
| Книга Нарвахи | «Введение в реверсинг с нуля, используя IDA PRO» (перевод на gitbook yutewiyof) |
|
||||
| Qiling | исполняет код в эмуляции — «без запуска на живой системе», не «без запуска» |
|
||||
| OGhidra | LLM через Ollama или облачные API; приватность только в локальном режиме |
|
||||
| de4py | CC BY-NC (некоммерческая) |
|
||||
| disrobe | платно для компаний |
|
||||
| Промпт-инъекция в строках бинарника | arxiv 2605.30667 — встраивает команды в строки |
|
||||
| Гиперболы интро | «свободно читаешь» → «читаешь»; godbolt «лучший способ» — снять |
|
||||
| IDA лицензия | .hexlic офлайн, JSON+подпись, ключ в бинаре; keygen с приватным ключом публично не подтверждён; пропатченная сборка = вектор малвари |
|
||||
|
||||
## Available scripts
|
||||
|
||||
- `scripts/linkcheck.py` — свип живости ссылок из MD. Запуск из корня скилла: `python scripts/linkcheck.py <file.md> [--workers N] [--timeout S]`. Stdlib only, exit 0 всегда (отчёт в stdout, формат `CHECK <status> <url>`).
|
||||
|
||||
## References
|
||||
|
||||
- Канон v4.1: `C:/Users/User/tmp/rev-guide-v4.md` (4 сообщения, 3854/3679/3875/1934 симв.)
|
||||
- Под-пост: `C:/Users/User/tmp/rev-guide-v4-subpost.md` (1363 симв.)
|
||||
- Автор оригинала: [REDACTED] (https://[REDACTED])
|
||||
- Воркфлоу владельца: посты в TG ботом НЕ отправлять, инфу выдавать в чат; «под пост» = сообщение-компаньон
|
||||
94
our-skills/re-roast-2026/scripts/linkcheck.py
Normal file
94
our-skills/re-roast-2026/scripts/linkcheck.py
Normal file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Link liveness sweep for Markdown files (stdlib only).
|
||||
|
||||
Usage:
|
||||
python linkcheck.py <file.md> [<file2.md> ...] [--workers N] [--timeout S]
|
||||
|
||||
Checks every http(s) URL found in the markdown files.
|
||||
- 403/405 are reported as BOTWALL (bot wall — site is alive, not dead)
|
||||
- Other HTTP errors are reported with their code
|
||||
- Network errors/timeouts are reported as DEAD
|
||||
|
||||
Output line format: CHECK <status> <url>
|
||||
Exit code is always 0; the report is the output. Diagnostics go to stderr.
|
||||
"""
|
||||
import argparse
|
||||
import concurrent.futures
|
||||
import re
|
||||
import ssl
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
URL_RE = re.compile(r"https?://[^\s()<>{}|\"'`]+")
|
||||
UA = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
|
||||
"(KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36")
|
||||
|
||||
|
||||
def probe(url, method, timeout, ctx):
|
||||
req = urllib.request.Request(url, headers={"User-Agent": UA}, method=method)
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=timeout, context=ctx) as resp:
|
||||
return resp.status
|
||||
except urllib.error.HTTPError as e:
|
||||
return e.code
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def check(url, timeout):
|
||||
url = url.rstrip(".,;:!?)]}")
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
for method in ("HEAD", "GET"):
|
||||
status = probe(url, method, timeout, ctx)
|
||||
if status is not None and status != 999:
|
||||
if status in (403, 405):
|
||||
return f"CHECK BOTWALL {status} {url}"
|
||||
if status < 400:
|
||||
return f"CHECK {status} {url}"
|
||||
# 4xx/5xx from HEAD could be server refusing HEAD; try GET first
|
||||
if method == "GET":
|
||||
return f"CHECK {status} {url}"
|
||||
continue
|
||||
if method == "GET":
|
||||
break
|
||||
return f"CHECK DEAD {url}"
|
||||
|
||||
|
||||
def collect_urls(files):
|
||||
urls, seen = [], set()
|
||||
for path in files:
|
||||
try:
|
||||
text = open(path, encoding="utf-8").read()
|
||||
except OSError as e:
|
||||
print(f"ERR cannot read {path}: {e}", file=sys.stderr)
|
||||
continue
|
||||
for u in URL_RE.findall(text):
|
||||
if u not in seen:
|
||||
seen.add(u)
|
||||
urls.append(u)
|
||||
return urls
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description="Link liveness sweep for Markdown files.")
|
||||
ap.add_argument("files", nargs="+", metavar="file.md")
|
||||
ap.add_argument("--workers", type=int, default=24, help="parallel workers (default: 24)")
|
||||
ap.add_argument("--timeout", type=float, default=15.0, help="per-request timeout in s (default: 15)")
|
||||
args = ap.parse_args()
|
||||
|
||||
urls = collect_urls(args.files)
|
||||
if not urls:
|
||||
print("CHECK NONE (no URLs found)")
|
||||
return 0
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=args.workers) as pool:
|
||||
for result in pool.map(lambda u: check(u, args.timeout), urls):
|
||||
print(result)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user