Как сделать сигнатуру ida
У меня есть более 40 различных файлов сигнатур IDA (помимо встроенных), и иногда я не хочу перебирать проблемы с проверкой того, какие подписи могут быть релевантными для данной цели. Вместо этого я просто хочу применить все подписи, по одному, и пусть IDA скажет мне, какие из них имели наибольшее количество матчей в цели. Выполнение этого вручную очень утомительно, потому что
- IDA позволяет применять только 1 подпись в каждой операции применения.
- Порядок подачи подписей влияет на количество совпадений, которые генерирует данная сигнатура. Например, когда применяется 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 реализации с нуля.
К тому же, получившийся протокол легко масштабируется под другие методы и структуры и легко переносим.
Office
- Создавать SIG файлы 🔑
- ✅ Подписывать файлы SIG
- Проверять файлы SIG 🔥
- Просматривать содержимое файлы SIG
✅ После прочтение этой статьи у вас больше не будет вопросов как работать с форматом SIG 🔑 а если даже и возникнут, пишите мне на почту или оставляйте свои комментарии. 🔥
Данную статья я решил написать, после того как мне на почту от читателей поступил вопрос:
У меня возникла проблема с подписанием документа электронной подписью. Подскажите, пожалуйста, что можно сделать. Ситуация такая. Мне необходимо подписать pdf документ (в данном случае копию приказа) электронной подписью руководителя. Подписанный документ должен быть обязательно в формате .sig
- как подписать pdf документ ЭЦП кто не читал, советую ознакомиться.🔥🔥🔥
- 🔔🔔 как создать тестовый сертификат
Сейчас же мы рассмотрим подпись документа не просто c использованием ЭЦП, а что бы на выходе у нас получился файл формата SIG, как это сделать сейчас вы узнаете!
Что такое *.SIG файл?
Если вы задались вопрос, а что же за такой формат SIG? который нас гос службы обязывают сдать документы, то ответ на этот вопрос очень простой:
Файл формата SIG — имеет расширенное название Signature (что в переводе означает Подпись) уже отсюда можно сделать вывод, что данный файл имеет все основание называться официальным подписанным документом.
Итог: файл sig — это формат документа подписанный электронно цифровой подписью (ЭЦП)
Какие бывают подписи формата SIG
✅ У данного формата ЭЦП есть два варианта исполнения:
- 🔑 Отсоединенная ЭЦП
- 🔑 Присоединенная ЭЦП
Главное отличие этих подписей состоит в том:
Отсоединенная подпись ЭЦП в формате sig
✅ самое главное отличие этого формата в том, что когда вы подписываете отсоединенной подписью у вас документ остается того же формата и размера, а вот после подписания с ним будет идти отдельный файл формата sig 🔑 который будет считаться самой подписью.
на рисунке видно документ Документ Microsoft Word.docx и рядом с ним идет документ Документ Microsoft Word.docx.sig который считается его подписью
Тоесть когда вы подписываете отсоединенной подписью человек на другой стороне может без специальных программ открыть ваш файл и его прочитать (если вы подписывали документ PDF 🔥 то его откроют стандартной программой Adobe PDF и могут смотреть и так же с документами word и другими ) но вот если вы внесете в исходный документ какие то данные, то второй файл который идет с ним (отсоединенный) в формате sig уже будет не актуальный.
Поэтому отсоединенная копия очень удобный вариант подписи для второй стороны.
Присоединенная подпись ЭЦП в формате sig
Этот формат файла любимый у тендерных площадок и госпорталов когда вам нужно приложить каждый документ в формате SIG 🔑 (не отсоединенная) этот формат получается на выходе после подписания какого ли до документа. Когда вы подписываете документ у него изменяется:
- ✅ формат с pdf, word, xlsx меняется на .SIG
- изменяется размер документа потому как к нему добавляется в конец файла код с подписью
на рисунке видно документ Документ Microsoft Word.docx с размеров в 13кб, а под ним документ Документ Microsoft Word.docx.sig который и является уже документом с присоединенной подписью, что свидетельствует размер документа в 20кб
Для просмотра этого документа на другой стороне должна стоять программа которая может открыть этот документ и просмотреть его содержимое, т.е. тот же КриптоАРМ
Читайте также: