eXTracted INternals

eXTracted INternals
 
ФорумФорум  ЧаВоЧаВо  ПоискПоиск  РегистрацияРегистрация  ПользователиПользователи  ГруппыГруппы  Вход  

Поделиться | 
 

 IDA Pro: процессорный модуль

Предыдущая тема Следующая тема Перейти вниз 
АвторСообщение
erithion



Количество сообщений : 25
Дата регистрации : 2006-09-18

СообщениеТема: IDA Pro: процессорный модуль   Пн 6 Ноя - 11:11

IDA Pro: процессорный модуль


Всем, кто имеет даже небольшой опыт работы с IDA Pro, безусловно, известны как плюсы, так и минусы этого дизассемблера. Кто-то об этом только слышал, а кто-то сталкивался лично и имеет собственный уникальный опыт борьбы с некоторыми “надоедливыми достоинствами” IDA. И уж точно всем известна плачевная ситуация по сопутствующей документации.
Столкнувшись в свое время с необходимостью разработки процессорного модуля, мне некоторое время пришлось восполнять подобные пробелы. Иногда было достаточно порыться в заголовочных файлах, почитать комментарии, но иногда доходило и до отладки IDA ею же самой. Smile И тот, кто хоть раз вел разработку под IDA Pro знает, что такое случается, иногда даже чаще чем хотелось бы.
Любой квалифицированный разработчик программного обеспечения имеет представление об этапах технологического процесса разработки. И каждому знакомо ощущение, когда недостает информации для старта. И читая комментарии, я обнаружил, что несмотря на их обилие в SDK, порой они совершенно не дают информации о самом процессе, не приводят к видению общей картины, а соответственно и не позволяют непосредственно приступить к реализации задуманного. Как это всегда бывает у исследователей, разработка подобных инструментов – частая и необходимая, но все же побочная ветвь в достижении необходимого результата и трата большого количества времени на решение подобных задач порой является непозволительной роскошью.
В свое время меня очень удивляло, что в работах подобного рода по прошествии некоторого времени очень часты случаи “амнезии”. Судя по опыту это является нормой для такой области как реверсивная инженерия и исследование программного кода, ввиду невероятно большого количества поступающей информации, которую приходится анализировать каждый день. И так из года в год. Wink
Данный материал ориентирован прежде всего на специалистов, часто использующих IDA Pro в своей проф. деятельности. Он предназначен для того, чтобы максимально помочь в быстром старте и дальнейшей успешной разработке процессорного модуля. По этой причине я не стану повторять информацию, которая доступна в виде комментариев к SDK, а буду останавливаться на общем, указаниях, что и где искать, и на тех деталях, которые в SDK не отображены.
Итак, пока я не забыл, а вы читаете и следовательно чувствуете себя готовым – будем разбираться как сделать для IDA Pro свой собственный процессорный модуль.


Последний раз редактировалось: (Пн 6 Ноя - 11:30), всего редактировалось 1 раз(а)
Вернуться к началу Перейти вниз
Посмотреть профиль
erithion



Количество сообщений : 25
Дата регистрации : 2006-09-18

СообщениеТема: Re: IDA Pro: процессорный модуль   Пн 6 Ноя - 11:11

Что же это такое?


Вполне справедливый вопрос, который может возникнуть в голове даже самого опытного пользователя IDA Pro.
Процессорный модуль, или как принято его именовать в SDK – IDP, это “плагин” для IDA Pro специального назначения. Почему специального? Потому что подобных назначений у IDA не одно.
Например, существуют модули-загрузчики, отвечающие за то, как именно файл должен быть загружен в IDA. Именно они понимают такие форматы как COFF, OMF, PE, ELF, EPOC, Palm Pilot и мн. другие.
Существуют модули-отладчики, которые соответственно занимаются отладкой.
В то же время, существуют процессорные модули, которые занимаются процессом дизассемблирования и анализа бинарного кода. Находятся они в папке procs. Процессорный модуль, кроме дизассемблирования, занимается построением зависимостей, добавлением перекрестных ссылок, анализом и созданием функций, выводом на экран. Иными словами, весь код, который виден на экране IDA производится и отображается IDP.
Вернуться к началу Перейти вниз
Посмотреть профиль
erithion



Количество сообщений : 25
Дата регистрации : 2006-09-18

СообщениеТема: Re: IDA Pro: процессорный модуль   Пн 6 Ноя - 11:14

Создание проекта нового процессорного модуля.


Чтобы непосредственно приступить к разработке процессорного модуля, лучше всего клонировать какой-либо из существующих проектов IDP из SDK. Они находятся в папке \IDA SDK\module. Но не спешите удалять оттуда абсолютно все. Лучше всего закомментируйте, оставив временно пустые заглушки.
Подобная манипуляция позволит автоматически соблюсти принятые соглашения для проекта IDP. Более подробно их можно отыскать в текстовых файлах в корневой папке SDK. Например, соглашения для разработки с использованием MS VC находятся в файле install_visual.txt.
Обратите особое внимание на использование утилиты mkidp.exe, что находится в \IDA SDK\bin\mkidp.exe. В моем случае в Post Build Event для MS VS 2003 прописана строка
IDA\bin\mkidp.exe "$(OutDir)\mcore.w32" "Motorola:M*Core"
Здесь вторым параметром командной строки служит “DLL-description” формата processor:procname1:procname2:…:procnameN, о чем сказано в install_visual.txt. Эта строка станет частью PE-Header’а указанного первым параметром имени IDP. И следует заранее отметить, что части указанной строки должны в точности совпадать со значениями пары полей, что будут указаны для переменной типа processor_t. О некоторых элементах этой структуры речь пойдет ниже, а пока для моего случая в полях
processor_t::psnames указана строка “Motorola”
processor_t::plnames содержит указатель на массив из одной строки “M*Core”
Игнорирование соглашений для mkidp.exe может привести к тому, что IDA может просто не “признать” ваш IDP или не дать возможности выбрать его текущим (это произойдет в случае упомянутого несовпадения строк).
Поскольку на данном этапе процессорный модуль пока еще ничего не умеет, то осталось только добиться того, чтобы успешно собранный IDP можно было выбрать при открытии файла. В окне “Load a new file”, в выпадающем списке “Processor type” должна появиться указанная для mkidp.exe строка. Выбрав ее, нажав кнопку Set (после чего она должна стать disabled), а затем Ok, файл должен быть загружен.
Вернуться к началу Перейти вниз
Посмотреть профиль
erithion



Количество сообщений : 25
Дата регистрации : 2006-09-18

СообщениеТема: Re: IDA Pro: процессорный модуль   Пн 6 Ноя - 11:15

Начало - структура IDP.


Каждый IDP описывает один процессор или семейство процессоров. Вспомните Intel x86, ARM, Motorola или PowerPC. По этой причине для связи с ядром IDA процессорный модуль обязан “выставить” на экспорт символ LPH, имеющий тип processor_t. Данная структура скажет ядру о том, что позволено делать с процессорным модулем. Свое знакомство удобнее начать именно с этой структуры в idp.hpp. И пока это происходит, немного комментариев.
Беглый взгляд на содержимое processor_t говорит нам, что модуль может:
• Иметь в своем арсенале более одного ассемблера благодаря полю assemblers типа asm_t** (idp.hpp), .
• Получать уведомления о событиях GUI, чтобы иметь возможность произвести коррекцию производимых по умолчанию действий.
• Иметь заданный набор регистров и несколько способов задания этого набора.
• Иметь заранее заданный набор инструкций, который, как и регистры необходимо определить.
• Функцию для установки опций IDP.
• Функции формирования документа, чтобы создать его header/footer.
• Функции формирования сегментов для создания их начала/конца.
• Функции анализа/эмуляции/генерации.
• Функцию для чисел с плавающей точкой.
• Функции для работы со стековым фреймом и стековыми переменными.
• Функцию для определения switch инструкций.
А также множество других полей. Многие из них могут и не потребоваться. Тем более, что для довольно большого количества полей чаще всего вполне подходит старое содержимое, что досталось в наследство от проекта-оригинала. Это либо 0, либо такие элементы, которые вероятнее всего не будут подлежать замене или будут немного модифицированы.
Таким образом, можно начать, например, с установки флагов и строк, функций генерации документа/сегментов, задания набора регистров. Поэкспериментировать и остановиться тогда, когда результат будет удовлетворительным. Большую помощь в этом процессе окажет “подглядывание” за реализацией одного из старых процессорных модулей. Поэтому на данном этапе все довольно очевидно и не вызывает никаких трудностей.
Вернуться к началу Перейти вниз
Посмотреть профиль
erithion



Количество сообщений : 25
Дата регистрации : 2006-09-18

СообщениеТема: Re: IDA Pro: процессорный модуль   Пн 6 Ноя - 11:16

Сведения о процессе дизассемблирования кода в IDA Pro.


Структура processor_t содержит, на мой взгляд, три наиболее важных поля, вокруг которых и будет сосредоточена вся дальнейшая работа. Это поля
processor_t::u_ana – определяет стадию анализа
processor_t::u_emu – определяет стадию эмуляции
processor_t::u_out – определяет стадию вывода
Поскольку результат, который виден в качестве кода на экране дизассемблера, всегда опирается именно на них, то с их появлением вполне справедливо говорить о ключевых понятиях IDP IDA Pro. А именно, говоря о результате дизассемблирования в привычном его понимании для IDA Pro, в качестве самого процесса прежде всего следует представлять себе некий цикл вызовов приведенных функций. У каждой из них свой четко сформулированный набор обязанностей, ровно как и четко определенное время вызова. Что же касается порядка вызова, то эмуляция всегда предшествует выводу. А анализ всегда будет предшествовать двум другим стадиям.
И прежде чем непосредственно перейти к описанию упомянутых стадий, необходимо сделать некоторые отступления.
Вернуться к началу Перейти вниз
Посмотреть профиль
erithion



Количество сообщений : 25
Дата регистрации : 2006-09-18

СообщениеТема: Re: IDA Pro: процессорный модуль   Пн 6 Ноя - 11:18

База IDA Pro.


Всем известно, что IDA сохраняет информацию в свою базу.
С точки зрения разработчика IDP, база является:
1. Виртуальными массивами 32 битных флагов, которые хранят информацию о каждом байте дизассемблируемого файла. А именно, что собственно этот байт описывает – код, данные, хвост некоего элемента, unexplored; дополнительно также подтверждает есть ли у него какие-либо общие характеристики – имя, комментарий, references; локальные характеристики: для данных типа code – свойства инструкций/операндов, размеры и типы – для данных типа data. Подробнее об этом в bytes.hpp.
2. Графом, вершинами которого являются элементы типа netnode, а ребрами – netlink. В вершинах графа сохраняется вся информация, имеющая переменную длину. Это такая информация, как комментарии или имена. Подробнее в nalt.hpp и netnode.hpp.
Но тем не менее, радостная новость – непосредственно, т.е. на столь низком уровне работать с базой в пределах IDP нет необходимости. Все используемые для IDP API функции работают с базой самостоятельно. Правда над API функцией никогда не указывается, изменяет ли она базу. Хотя чаще всего это все же заметно и необходимости “препарировать” ядро нет. Подобное может быть замечено разными способами:
• Если взять в качестве примера добавление reference’ов – это построение связей между элементами в базе. Изменение в данном случае очевидно. И если, вопреки запрету, все же поставить добавление ref’а на стадии analysis, то можно невероятно удивиться насколько много их может появиться на экране, это если конечно экран вообще будет виден. 
• Также конвертирование unexplored байт в нечто осмысленное приводит к сохранению информации как минимум о типе и размерах созданного элемента с неким стартовым адресом, будь-то код или данные. Здесь изменения также очевидны.


Последний раз редактировалось: (Пн 6 Ноя - 11:21), всего редактировалось 1 раз(а)
Вернуться к началу Перейти вниз
Посмотреть профиль
erithion



Количество сообщений : 25
Дата регистрации : 2006-09-18

СообщениеТема: Re: IDA Pro: процессорный модуль   Пн 6 Ноя - 11:20

Задание набора инструкций.


Полагаю уже стало понятно какие поля структуры processor_t необходимо определить в этом случае. Осталось лишь упомянуть где это используется.
Задание массива инструкций в соответствующее поле структуры processor_t служит одной цели, чтобы некоторые API функции знали где они находятся.
Так делается на этапе вывода на экран, когда текущий номер инструкции служит порядковым номером для заданного массива и ядро может вывести мнемонику инструкции на экран самостоятельно.
Одна инструкция описывается структурой instruct_t (idp.hpp) – всего лишь два поля: мнемоника и флаги. Помимо мнемоники для каждой инструкции желательно определить ее набор флагов, т.к. это окажет существенную помощь в дальнейшем.
Например, во время работы упомянутых стадий может понадобиться узнать “тип” инструкции – передает ли она управление на процедуру или метку, использует/изменяет ли один из своих операндов. Для этих целей можно воспользоваться API функцией ::InstrIsSet, которая как раз этим и занимается или поискать альтернативный вариант в bytes.hpp.
Вернуться к началу Перейти вниз
Посмотреть профиль
erithion



Количество сообщений : 25
Дата регистрации : 2006-09-18

СообщениеТема: Re: IDA Pro: процессорный модуль   Пн 6 Ноя - 11:22

Несколько слов об ассемблере.


Это действительно несколько слов, т.к. в каждом конкретном случае ассемблер будет свой.
Структура asm_t находится в idp.hpp. Предназначена для того, чтобы иметь возможность настроить как именно все на экране будет выглядеть: directives, keywords, delimiters, вид функций и пр. На первый взгляд, может показаться, что большая часть ассемблеров во многом сходны с точки зрения asm_t, учитывая тот факт, что компании сегодня любят перестраивать GNU ассемблер для своих нужд. В этом случае, выражаясь словами персонажа Л.Кэрролла, если все равно, куда хочешь попасть, тогда все равно куда и идти. Поэтому до поры можно оставить тот, что был в оригинале. А позже уже будет очевидней, что нужно изменить.
Вернуться к началу Перейти вниз
Посмотреть профиль
erithion



Количество сообщений : 25
Дата регистрации : 2006-09-18

СообщениеТема: Re: IDA Pro: процессорный модуль   Пн 6 Ноя - 11:23

Стадия 1: Analysis


Стадия анализа случается всякий раз, когда возникает надобность в конвертировании последовательности байт в инструкции. А причиной этому может служить множество факторов. Это может быть
• требование пользователя <P> или <C>;
• “всплывающая” подсказка на ref’е с кодом;
• показ/пролистывание любой части открытого файла, уже содержащей код;
• вызов программным путем с использованием таких API функций как, например, ::ua_ana0 или ::reanalyze_area(), которые где-то в IDP вставил разработчик;
В любом случае, должен отметить, что это случается очень часто. Это есть следствием того, что в каждый конкретный момент времени IDA хранит только одну распознанную инструкцию. Для нужд вывода на экран, например, ядру легче всего прогнать стадию анализа для всех инструкций видимой части экрана вновь, чем сделать что-либо иное, в чем нет явной надобности. Именно по причине очень частых вызовов в комментариях к сигнатуре функции processor_t::u_ana сказано, что функция не должна изменять базу сама или пользоваться API, которые это делают.
Круг ее обязанностей сводится к тому, что за один вызов должна быть выбрана и распознана одна единственная инструкция. Результат распознавания должен быть сохранен в глобальную переменную cmd типа insn_t. И переменная и ее тип находятся в ua.hpp. Эта переменная предназначена для хранения всей необходимой информации о текущей инструкции, включая ее адрес и операнды.
В целом структура insn_t удовлетворит любые потребности. И поскольку ответственность за семантическую нагрузку на ее содержимое несет разработчик IDP, то на него же возлагается и ответственность за распознавание содержимого на более поздних стадиях. В редких случаях соглашения оговариваются. Это, например, касается типа операнда op_t::type, который во многих API функциях распознается автоматически.
Таким образом глобальную переменную cmd можно воспринимать как входной/выходной параметр функции: на входе у разработчика есть корректные текущие адреса, такие как cmd.ea, cmd.ip, cmd.cs. На выходе остальное должно быть дополнено информацией о распознанной инструкции.
Типично функция выполняет следующие действия:
• Проверки на входе и возврат 0 в случае ошибок. Проверки весьма опциональны, в то же время все известные мне RISC процессоры имеют команды фиксированной длины и многие также выравнивают их по какой-то границе, поэтому вполне разумно было бы осуществлять подобные проверки заранее по cmd.ip.
• Получение очередной порции данных из базы. Можно использовать функции ::ua_next_byte/::ua_next_word/::ua_next_long/::ua_next_qword. Следует учитывать, что эти функции пользуются текущим значением cmd.ea и увеличивают его после окончания работы на соответствующий размер, поэтому если было взято данных более, чем необходимо, то значение cmd.ea должно быть соответственно откорректировано.
• Реализуется распознавание инструкции с занесением результата в глобальную переменную cmd.
• Возврат из функции размера команды в байтах. Это важно, не забыть выставить корректную длину распознанной команды в байтах в поле cmd.size и вернуть ее из функции. Т.к. после выхода из функции IDA будет считать, что набор байт, находящийся начиная с обработанного адреса и длиной cmd.size является единым элементом и уже более не будет предлагать адреса для анализа, находящиеся в пределах этого элемента. И так будет вплоть до того момента, пока не будет произведен undefine либо через GUI, либо программным путем используя функцию ::do_unknown_range.
Вернуться к началу Перейти вниз
Посмотреть профиль
erithion



Количество сообщений : 25
Дата регистрации : 2006-09-18

СообщениеТема: Re: IDA Pro: процессорный модуль   Пн 6 Ноя - 11:25

Стадия 2: Emulation


Эта стадия пожалуй заслуживает внимания более всех остальных. Уж если со стадией Analysis все четко и ясно буквально с двух слов, то в данном случае все наоборот. Поэтому обо всем по порядку.

Вспомним предыдущую стадию анализа. Он производит либо одну инструкцию за раз, либо вообще не производит. Таким образом становится понятно, что для того, чтобы произвести две, три и более инструкций необходим некий “контроллер”, который бы каждый раз указывал что же далее. Это и есть обязанность Emulation стадии. И обычно простая реализация функции делает следующее:
• На своем входе получает в знакомой глобальной переменной cmd очередную инструкцию и производит обработку ее операндов. Под обработкой подразумевается сохранение/модификация соответствующей информации о каждом операнде в базу в зависимости от его типа. Например: для непосредственных значений можно вызвать ::doImm функцию; для операндов команд адресации данных – добавить ref посредством вызова ::ua_add_dref; для операндов команд переходов запланировать адрес на создание кода ::auto_make_code, на создание процедуры ::ua_make_proc или просто на локальный переход ::ua_add_cref;
• Анализирует, обеспечивает ли обработанная инструкция т.н. ordinary flow, т.е. передает ли управление после себя на следующую инструкцию. И в случае истины, следующая инструкция “планируется” т.н. ordinary flow способом - ::ua_add_cref с указанием в качестве третьего параметра значения fl_F (xref.hpp).
• Возвращает размер инструкции в байтах.

Теперь становится понятно, откуда берутся последующие адреса для анализа. Первое, это ordinary flow, второе – извлечение адресов из операндов инструкций переходов.
Но обнаруживается, что стадия Emulation семантически гораздо более перегружена. Поскольку такой способ работы фактически производит блоки инструкций (когда в целом блоком является набор инструкций, каждая из которых передает управление неявно только низлежащей инструкции), то сразу вспоминается популярная работа К.Сифуэнтэс, где подобный термин вводится для распознавания функций. И именно это и имеет место в этой стадии – создание функций. Но прежде необходимо прояснить, что же скрывается за словами “планирование адреса”.
Невидимым режиссером на этой стадии выступает Auto Analyzer (auto.hpp). Он имеет в своем составе несколько очередей, у каждой из которых свой приоритет. Это означает, что до тех пор пока не будут обработаны все очереди с высокими приоритетами, черед более низких не наступит. Элементами, которые добавляются в любую из очередей служат линейные адреса. Под обработкой подразумевается, что для каждого линейного адреса в очереди будет вызвана функция стадии Emulation, которая должна будет “прогнать” приведенную выше схему для инструкции. После этого адрес удаляется из очереди.
Но при этом, каждая из этих очередей также имеет свое функциональное назначение, которое и отличает ее от всех остальных. Интересующие нас сейчас очереди:
• AU_CODE – конвертирование адресов в “голый” код, высокий приоритет.
• AU_PROC – содержит адреса старта будущих функций, более низкий приоритет.
• AU_USED – все остальное, в том числе создание функций, низкий приоритет.
Типичные API функции для очередей, используемые при планировании:
• ::auto_mark_range – универсальная функция для добавления диапазона адресов в указанную очередь
• ::autoMark – добавляет один адрес в указанную очередь, используя ::auto_mark_range функцию
• ::auto_make_code добавляет один адрес в очередь AU_CODE, используя ::autoMark
• ::auto_make_proc добавляет один адрес последовательно в обе - AU_CODE и AU_PROC, используя ::autoMark

И теперь вот как дело обстоит с созданием функций:
Сначала некий адрес помещается в очередь AU_PROC. Впоследствии это приведет к тому, что инструкция с этим адресом поступит на обработку в Emulation во время работы низкоприоритетной очереди AU_USED. И частью будущей функции станут все адреса, которые будут пройдены через ordinary code flow, т.е. с использованием ::ua_add_cref.
Функция ::ua_add_cref вообще-то служит для проставления перекрестных ссылок типа code. И это бывает только тогда, когда она используется без fl_F значения в качестве третьего параметра. Но для всех типов параметров она обеспечивает ordinary code flow.
И как только будет обработан последний адрес, добавленный через ::ua_add_cref, считается, что границы новой функции определены.
После этого Auto Analyzer переходит к следующим адресам в очереди(ях).

В свое время, разрабатывая процессорный модуль, мне довелось потратить некоторое время, прежде чем придти к осознанному пониманию факта, что независимо от того, какая из очередей обрабатывается в данный момент, будь то AU_CODE или AU_USED, реализация для них все равно идентична. А учет текущих очередей начинается много позднее, на этапе трассировки стека и создания стековых переменных. Поэтому пока в своей реализации об очередях заботиться не следует.
Таким образом, на данном этапе можно уже сказать, что анализ кода и даже создание функций обеспечен.


Последний раз редактировалось: (Вт 7 Ноя - 8:06), всего редактировалось 1 раз(а)
Вернуться к началу Перейти вниз
Посмотреть профиль
erithion



Количество сообщений : 25
Дата регистрации : 2006-09-18

СообщениеТема: Re: IDA Pro: процессорный модуль   Пн 6 Ноя - 11:27

Стадия 3: Generation


Это на мой взгляд самая простая стадия из всех и предназначена для вывода на экран.
Для нее в структуре processor_t отводится два поля:
• processor_t::u_out для вывода мнемоники
• processor_t::u_outop для вывода операнда
Когда IDA решает, что пора выводить инструкцию на экран, происходит вызов функции из поля processor_t::u_out, которая обычно делает следующее:
• Инициализирует буфер для вывода через вызов ::init_output_buffer (ua.hpp), поскольку все API вывода сохраняют всю информацию в указанный буфер.
• Делает вызов функции ::OutMnem (ua.hpp), которая по индексу из cmd.itype обнаруживает необходимую мнемонику в указанном ранее массиве инструкций.
• Для каждого присутствующего операнда в инструкции совершает вызов функции ::out_one_operand (ua.hpp) с указанием номера выводимого операнда, начинающегося с 0. Это приводит к тому, что соответствующий операнд извлекается из массива операндов cmd.Operands и происходит вызов функции processor_t::u_outop с параметром операнда.
• Делает вызов ::term_output_buffer (ua.hpp), что подготавливает все сохраненные данные буфера к выводу на экран.
• Вызывает ::MakeLine (lines.hpp) для вывода содержимого буфера на экран в качестве очередной строки.
Функция для processor_t::u_outop должна обеспечить вывод операнда на экран. Поскольку операнды могут быть типа immediate values, register, displacement, phrase, memory, near, да к тому же кто-то может ввести еще и свои типы, то предоставляется возможность вывести каждый из типов операндов по-своему. Например, поставить скобки вокруг displacement операнда или вывести список регистров.
Множество функций для вывода находятся в ua.hpp. Также может помочь использование lines.hpp. Например, можно использовать так называемые тэги при выводе. Это маркеры, описывающие цвет части строки, которую они окружают. Включаются они с помощью ::out_tagon (lines.hpp), ::out_tagoff (lines.hpp) – выключаются.
Следует обратить внимание, что на этой стадии также не следует изменять базу. В любом случае, API функции вывода неплохо комментированы, а при возникновении затруднений стоит подсмотреть реализации других процессорных модулей из SDK.
Вернуться к началу Перейти вниз
Посмотреть профиль
erithion



Количество сообщений : 25
Дата регистрации : 2006-09-18

СообщениеТема: Re: IDA Pro: процессорный модуль   Пн 6 Ноя - 11:28

Продолжение следует...
Вернуться к началу Перейти вниз
Посмотреть профиль
Спонсируемый контент




СообщениеТема: Re: IDA Pro: процессорный модуль   

Вернуться к началу Перейти вниз
 
IDA Pro: процессорный модуль
Предыдущая тема Следующая тема Вернуться к началу 
Страница 1 из 1

Права доступа к этому форуму:Вы не можете отвечать на сообщения
eXTracted INternals :: Cтатьи :: Win32 reversing-
Перейти: