Как сделать сигнатуру ida

Обновлено: 05.07.2024

У меня есть более 40 различных файлов сигнатур IDA (помимо встроенных), и иногда я не хочу перебирать проблемы с проверкой того, какие подписи могут быть релевантными для данной цели. Вместо этого я просто хочу применить все подписи, по одному, и пусть IDA скажет мне, какие из них имели наибольшее количество матчей в цели. Выполнение этого вручную очень утомительно, потому что

  1. IDA позволяет применять только 1 подпись в каждой операции применения.
  2. Порядок подачи подписей влияет на количество совпадений, которые генерирует данная сигнатура. Например, когда применяется sig A, это может означать, что sig B пропускает некоторые совпадения, которые A соответствовало перед ним.

Я предполагаю, что плагин/скрипт сделает что-то вроде этого: примените sig A к целевой базе данных, подсчитайте совпадения, затем удалите приложение sig A и примените B, подсчитайте совпадения, затем удалите приложение и примените C и т. Д.

У кого-нибудь еще не было этой идеи? Я не смог найти плагин или скрипт, который делает это, и я бы предпочел не писать свой собственный, если он уже существует.

Если вы говорите о подписях IDA FLIRT, к сожалению, рано или поздно вы, вероятно, столкнетесь с их ограничениями и, или, разочаруетесь в результатах, если хотите высокой точности.

Как видите, он соответствует только первым 32 байтам функций. И тогда он использует CRC16, поэтому есть вероятность столкновения.

Самая большая проблема с FLIRT заключается в том, что это довольно неоднозначно.
Он склонен к ложным матчам. И, или, если первые 32 байта согласованной функции не изменились, но тогда остальное все равно будет соответствовать. Это часто бывает хорошо, но тогда поведение непредсказуемо. Кроме того, в системе IDA нет ничего более минимального пользовательского интерфейса. Было бы неплохо, например, если бы IDA отслеживал и показывал вам список того, что соответствовало, а что не соответствовало, если вы этого хотели. Хотя, предположительно, в 6.4 они переработали и обновили настройку, чтобы, возможно, ее улучшили.

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

Я создал свою собственную систему подписи, которая просматривает каждую функцию целевой сигнатуры источника и копирует все ненулевые байты (IE пропускает байты смещения из команд JMP, MOV, CALL и т. Д.) И делает 64-битный хэш всего вещь. Я сохраняю уникальные пользовательские функции и пропускаю маленькие (ниже точки отсечки счетчика байтов). Нет смысла экономить избыточные подписи.

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

Я тестирую IDA с помощью некоторого простого кода, чтобы узнать, как его использовать, и я зацикливаюсь, потому что он не декомпилирует должным образом статическую функцию в пространстве имен:

функция объявлена ​​следующим образом:

эта функция заканчивается этой сигнатурой: ?transcode@pvrtex@@YA_NAAVCPVRTexture@1@TPixelType@1@W4EPVRTVariableType@@W4EPVRTColourSpace@@W4ECompressorQuality@1@_N@Z . Онлайновый demangler создает правильную подпись С++. Когда я загружаю свой исполняемый файл в IDA, он также показывает эту же подпись функции, однако, когда я пытаюсь декомпилировать эту функцию, IDA неправильно обрабатывает эту функцию, как если бы это была какая-то функция-член класса pvrtex и внутри всего кода заканчивался какой-то случайный беспорядок

bool __cdecl pvrtex::transcode(pvrtex *__hidden this, struct pvrtex::CPVRTexture *, union pvrtex::PixelType, enum EPVRTVariableType, enum EPVRTColourSpace, enum pvrtex::ECompressorQuality, bool) .


Я давно увлекаюсь реверс-инжинирингом. Сначала это было просто хобби, затем стало работой (и при этом хобби никуда не делось). Только на работе «всё серьёзно«, а дома — это баловство в виде обратной разработки игр под ретро-приставки: Sega Mega Drive / Genesis , PS1 , AmigaOS . Задача обычно стоит следующая: понять как работает игра, если есть сжатие победить его, понять как строится уровень, как размещаются враги на уровне и т.д.

За то время, которое прошло с момента, как я начал этим заниматься, мною было написано несколько удобных и полезных инструментов для тех, кто хотел реверсить игры на Сегу, Соньку, и другие платформы.

Мне удалось разреверсить один очень крутой shoot’em-up: Thunder Force 3 (а именно благодаря этой игре я и познакомился с Идой). Я написал редактор уровней, разреверсил игру до исходников на ассемблере, и всё это попутно создавая и улучшая инструмент, который в последствии и облегчал данную работу — плагин-отладчик сеговских ромов для IDA, который я назвал просто — Gensida (т.к. в основе лежал один очень популярный эмулятор этой платформы GENS, а точнее его модификация).


Без эмулятора с отладкой тоже можно создать такой плагин, но для этого придётся писать отладочный функционал с нуля, что не всегда хочется делать.

Тем не менее, овладев некоторыми знаниями и умениями, и переборов желание не ввязываться в такой ужасный код (эмулятора), я смог написать и Snesida — отладчик SNES ромов для под IDA. И, я считаю, что теперь то уж настал тот момент, когда я готов рассказать о том, как создать более-менее полноценный отладчик для этого ревёрсерского инструмента.

Для того, чтобы создать свой плагин-отладчик под Иду, нам потребуется:

Думаю, список достаточно простой и понятный. Если чего-то из этого у вас нет, то плагин не получится, увы.

Прежде чем начать, советую ознакомиться со статьёй « Плагин

Собственно, как вы уже, должно быть, поняли, отладчик для Иды это тоже плагин, а значит он должен ей как-то идентифицироваться. Поэтому пишем следующий код:

Здесь мы описываем наш плагин, инициализируем структуру dbg , т.к. мы отладчик, и указываем, что работаем мы только с платформой PLFM_65C816 (в моём случае). Более подробно в статье про отладчик для Сеги.

Следом идёт ida_plugin.h . Тут всё просто — константы для cpp-файла плагина:

Код самого отладчика

Собственно, пока у нас в голове только идея отладчика, и мы ей горим, всё что мы можем пока написать, это базовый код, который будем постепенно дополнять. Начиная с этой части, если сравнивать с предыдущей статьёй, появились значительные изменения в коде и концепции в написании отладчика, поэтому читаем внимательно:

В ida_registers.h мы просто перечисляем список регистров для удоства обращений к ним в коде, а в ida_debmod.h описан формат eventlist_t , который мы будем использовать для хранения событий, с которыми будет работать IDA.

Подготовка завершена

Теперь, когда код шаблона у нас имеется, стоит понять, что мы будем делать дальше. А дальше нам нужно соорудить модель, по которой между IDA и эмулятором будет происходить общение. Для этого нужно держать в голове следующее:

Исходя из перечисленного понимаем, что понадобятся два канала, т.к. каждому может захотеться "пообщаться" в любой момент, асинхронно:

Учитывая это, можно, опять же, пойти по стопам предыдущей статьи про сеговский отладчик, а можно захотеть использовать "модные и современные" технологии для реализации RPC и сериализации любых данных. Мой выбор пал в сторону Thrift , т.к. с ним работать гораздо удобнее, и он практически не требует дополнительной подготовки (как, например, доклеивание RPC в protobuf, но тут, скорее, на любителя). Единственная сложность, это компиляция сего зверя, но, я оставлю это за рамками данной статьи.

Thrift — пишем прототип RPC

Давайте ещё раз посмотрим на те 4 пункта, которые я описал выше, и которые мы всё ещё держим в голове, откроем блокнот, и напишем что-то вроде этого:

Как видим, в Thrift нету ничего сложного. Здесь мы описали сервис IdaClient , которым будет пользоваться эмулятор, и обработчик которого будет располагаться в IDA. Все эти методы помечены ключевым словом oneway , т.к., по сути, нам не нужно дожидаться их выполнения, и в принципе ожидать, что их обработают.

start_event() будет сообщать Иде о том, что ром выбрал и его эмуляция началась.

add_visited() — метод, с помощью которого мы будем сообщать в Иду о том коде, который был выполнен эмулятором. Это полезно при отладке как раз таки ретро-платформ, т.к. в ромах для них код часто перемежается с данными. Если таковой функции в выбранном вами эмуляторе нет, её можно также пропустить и в протоколе.

pause_event() — этим методом мы будем сообщать Иде о том, что произошла пауза эмуляции по какой-либо причине: будь то брейкпоинт, завершился шаг при StepInto или StepOver или какой-то другой причине. В качестве нагрузки данный метод будет также передавать адрес, где именно произошла остановка.

stop_event() — думаю, тут всё понятно. Эмуляция завершилась, например, по причине завершения процесса эмуляции.

С этим разобрались, теперь часть посложнее — отладочный RPC:

Здесь у нас описана серверная часть, которая будет крутиться в эмуляторе, и к которой Ида время от времени будет приставать. Давайте разберём её более детально:

Эти методы мы будем использовать тогда, когда нам потребуется прочитать или записать один регистр. Использованный enum BsnesRegister выглядит так:

Фактически, это те регистры, значения которых мы хотим видеть во время отладки, у вас они могут быть другими.

Т.к. IDA сама никогда не запрашивает по одному регистру, а требует все сразу, напишем метод, который будет их все сразу и отдавать:

Здесь я завёл одну общую структуру под регистры, указав их размеры и указал её в качестве возвращаемого значения для метода get_cpu_regs() .

Теперь работа с памятью:

Здесь мы использовали встроенный в Thrift тип данных binary , и указали различные области памяти, которые могут быть прочитаны (взято из эмулятора).

Теперь пришла очередь брейкпоинтов:

Т.к. список областей памяти, которые можно читать, и на которые можно ставить брейкпоинты отличаются, заводим отдельный список DbgBptSource . Также указываем тип брейкпоинта BpType и адрес его начала/конца bstart / bend . Ещё нам может понадобиться включать брейкпоинт не сразу enabled .

С основными сложными частями протокола закончили, теперь можно описать более простые:

Метод pause() будет приостанавливать процесс отладки по запросу от IDA, resume() — продолжать.

start_emulation() — нужен для того, чтобы IDA могла сообщить эмулятору, что она начала процесс отладки, и ожидает от него какие-либо события. Фактически, используется в качестве синхронизации начала эмуляции между плагином-отладчиком и собственно эмулятором.

exit_emulation() — на случай, если мы захотим остановить отладку из IDA, а не из эмулятора.

step_into() и step_over() — пошаговая отладка.

От RPC-прототипа к реализации

На этом процесс написания RPC-прототипа завершён. Чтобы сгенерировать из него код для языка C++, качаем Thrift-компилятор , выполняем из командной строки следующее:

На выходе мы получим каталог gen-cpp , в котором нас будут ждать не только файлики, которые нужно будет компилировать вместе с проектом, но и шаблон кода каждого из сервисов — IdaClient и BsnesDebugger .


Добавляем сгенерированные файлы в студийный проект (кроме файлов *_server.skeleton.cpp ). Также необходимо слинковать наш проект плагина (и эмулятора) со скомпилированными статичными библиотеками thrift -а и libevent -а (мы будем использовать "nonblocking" вариант Thrift). У этих библиотек имеется CMake вариант сборки, который значительно упрощает процесс.

Код IdaClient хэндлера

Теперь давайте напишем шаблон кода, реализующий IdaClient -сервис:

В этом коде мы реагируем на события эмуляции и сообщаем о них Иде, добавляя эти события в список. Более подробно о них можно прочитать в той же статье про отладчик для Сеги. Код add_visited() пока оставляем пустым. О нём позже.

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

Осталось дополнить имеющийся шаблон ida_debug.cpp кодом для работы со Thrift. Вот что получилось:

Дабы не описывать весь этот код, здесь я опишу лишь типичный код для работы со Thrift со стороны IDA:

Т.е. мы просто оборачиваем код для работы с клиентом BsnesDebugger (серверную часть которого сейчас также напишем) в обработчик исключения и возвращаем либо ошибку, либо ОК.

Код BsnesDebugger хэндлера

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

Фактически, я взял код, который уже был во встроенном отладчике, и скопировал его в реализацию каждого из требуемых методов интерфейса BsnesDebugger .

Часть объектов и методов я не делал статичными, т.к. к ним нам нужно будет обращаться из других участков кода эмулятора. Эти методы и объекты представлены в следующем списке:

  • ::std::set visited; — сюда мы будем добавлять код, который выполнялся во время эмуляции, и который мы будем отправлять в Иду
  • void init_dbg_server() — будем запускать RPC-сервер не при запуске эмулятора, а при запуске эмуляции выбранного рома
  • void send_pause_event(bool is_step) — данный метод я использую не только для уведомления Иды о том, что эмуляция приостановлена, но и для отправки перед этим карты кода (codemap). Подробнее про параметр bool is_step и codemap я расскажу чуть позже

Теперь остаётся найти, где же эмулятору стоит сообщать о паузе, где начинается эмуляция, и где заполняется карта кода. Вот эти места:

Выполнение одной инструкции:

Открытие SNES рома:



Реакция на срабатывание брейкпоинта:


Хитрости применения codemap в Иде

Осталось рассказать о хитростях работы с функциями анализатора в IDA, и затем со спокойной (но переживающей "сомпилируется ли") душой нажать на Build Solution .

Оказалось, что просто так взять и в цикле выполнять функции, которые меняют IDB (файлы проектов в IDA) во время отладки нельзя — будет вылетать через раз, и доводить своим непостоянством до сумасшествия. Нужно делать по-умному, например, вот так:

Если вкратце, то суть в использовании метода execute_sync() и реализации своего варианта структуры exec_request_t и её колбэка int idaapi execute(void) . Это рекомендованный разработчиками способ.

Выводы и компиляция

Фактически, мы закончили писать свой собственный плагин-отладчик для IDA. Мне показалось, что как раз для реализации общения между Идой и эмулятором и создания отладчика Thrift подошёл как нельзя кстати. С минимальными усилиями мне удалось написать и серверную и клиентскую часть для обеих сущностей, не городя велосипеды в виде открытия сокетов по разному для разных платформ, и изобретения RPC реализации с нуля.

К тому же, получившийся протокол легко масштабируется под другие методы и структуры и легко переносим.

подписываем документы формата sig

Office

  1. Создавать SIG файлы 🔑
  2. ✅ Подписывать файлы SIG
  3. Проверять файлы SIG 🔥
  4. Просматривать содержимое файлы SIG

✅ После прочтение этой статьи у вас больше не будет вопросов как работать с форматом SIG 🔑 а если даже и возникнут, пишите мне на почту или оставляйте свои комментарии. 🔥

Данную статья я решил написать, после того как мне на почту от читателей поступил вопрос:

У меня возникла проблема с подписанием документа электронной подписью. Подскажите, пожалуйста, что можно сделать. Ситуация такая. Мне необходимо подписать pdf документ (в данном случае копию приказа) электронной подписью руководителя. Подписанный документ должен быть обязательно в формате .sig

  1. как подписать pdf документ ЭЦП кто не читал, советую ознакомиться.🔥🔥🔥
  2. 🔔🔔 как создать тестовый сертификат

Сейчас же мы рассмотрим подпись документа не просто c использованием ЭЦП, а что бы на выходе у нас получился файл формата SIG, как это сделать сейчас вы узнаете!

Что такое *.SIG файл?

Если вы задались вопрос, а что же за такой формат SIG? который нас гос службы обязывают сдать документы, то ответ на этот вопрос очень простой:

Файл формата SIG — имеет расширенное название Signature (что в переводе означает Подпись) уже отсюда можно сделать вывод, что данный файл имеет все основание называться официальным подписанным документом.

Итог: файл sig — это формат документа подписанный электронно цифровой подписью (ЭЦП)

Какие бывают подписи формата SIG

✅ У данного формата ЭЦП есть два варианта исполнения:

  1. 🔑 Отсоединенная ЭЦП
  2. 🔑 Присоединенная ЭЦП

Главное отличие этих подписей состоит в том:

Отсоединенная подпись ЭЦП в формате sig

Отсоединенная подпись ЭЦП в формате sig

✅ самое главное отличие этого формата в том, что когда вы подписываете отсоединенной подписью у вас документ остается того же формата и размера, а вот после подписания с ним будет идти отдельный файл формата sig 🔑 который будет считаться самой подписью.

на рисунке видно документ Документ Microsoft Word.docx и рядом с ним идет документ Документ Microsoft Word.docx.sig который считается его подписью

Тоесть когда вы подписываете отсоединенной подписью человек на другой стороне может без специальных программ открыть ваш файл и его прочитать (если вы подписывали документ PDF 🔥 то его откроют стандартной программой Adobe PDF и могут смотреть и так же с документами word и другими ) но вот если вы внесете в исходный документ какие то данные, то второй файл который идет с ним (отсоединенный) в формате sig уже будет не актуальный.

Поэтому отсоединенная копия очень удобный вариант подписи для второй стороны.

Присоединенная подпись ЭЦП в формате sig

Этот формат файла любимый у тендерных площадок и госпорталов когда вам нужно приложить каждый документ в формате SIG 🔑 (не отсоединенная) этот формат получается на выходе после подписания какого ли до документа. Когда вы подписываете документ у него изменяется:

  1. ✅ формат с pdf, word, xlsx меняется на .SIG
  2. изменяется размер документа потому как к нему добавляется в конец файла код с подписью

Присоединенная подпись ЭЦП в формате sig

на рисунке видно документ Документ Microsoft Word.docx с размеров в 13кб, а под ним документ Документ Microsoft Word.docx.sig который и является уже документом с присоединенной подписью, что свидетельствует размер документа в 20кб

Для просмотра этого документа на другой стороне должна стоять программа которая может открыть этот документ и просмотреть его содержимое, т.е. тот же КриптоАРМ

Читайте также: