Показаны сообщения с ярлыком лень. Показать все сообщения
Показаны сообщения с ярлыком лень. Показать все сообщения

воскресенье, 18 марта 2012 г.

script for .idt/.ids files making

Suddenly™ I discovered that even recent version of IDA Pro hasn`t ids files for fresh MFC modules (for example mfc100.dll/mfc110.dll from Visual Studio 2010/2011). Running dll2idt.exe produces nothing:
Convert DLL to IDT file. Copyright 1997 by Yury Haron. Version 1.5
File: mfc100.dll     ... illegal structure or has no export names
So I decided to make needed .ids files by myself. But I am too lazy to make .idt/.ids files manually so I wrote simple perl script for this boring task

Main idea is very simple - we can run dumpbin /exports on some .dll module and then read all ordinal/VA pairs. Next we can download from MS corresponding .pdb file for this .dll module and dump it with pdbdump (I already posted script for downloading pdb files). Next you can parse this dump and find VA/names pairs. Finally with all of this info you can produce .idt file (or even .ids file with -z option if you have idsutils installed)

воскресенье, 18 декабря 2011 г.

про тестирование

а вот например меня тут давеча спросили - поскольку wincheck для извлечения смещений структур и адресов всякого использует статический анализ кода, то как происходит проверка стат. анализатора на куче версий windows ? Это хороший вопрос тащемта, тем более что ничего внятного про такую задачу в этих ваших интернетах по моему не написано и пришлось как обычно все делать на коленке самому.
Правильный ответ - Максимальная Автоматизация всего процесса с помощью адовой смеси perl/bat скриптов

Получаем pdb

Как известно microsoft в отличие от практически всех остальных софтоклепательных компаний предоставляет .pdb файлы от почти всех своих системных модулей. Было бы глупо не воспользоваться такой шикарной возможностью при создании эталонных данных для тестов. Соотв-но обработка любого файла начинается с получения его .pdb файла и последующего дампа этого .pdb с помощью пропатченной мною версии pdbdump

Cуществует множество способов получить .pdb. На мой вкус самый простой - использовать программу symchk.exe из Debugging Tools for Windows:
"C:\Program Files\Debugging Tools for Windows (x86)\symchk.exe" %1  /s SRV*%tmp%\ida\*http://msdl.microsoft.com/download/symbols /v 2>log

В файле log интересна следующая строчка:
DbgSizeOfImage      0x0001d000
DbgChecksum         0x0001df9b
PdbFilename         C:\DOCUME~1\USER\LOCALS~1\Temp\ida\6to4svc.pdb\FD2DAD64D03E4365A5116D01DCB424031\6to4svc.pdb 

PdbSignature        {FD2DAD64-D03E-4365-A511-6D01DCB42403}

Простой perl script парзит данный log, и в случае успеха копирует скачанный .pdb файл рядом с исходным бинарным, после чего запускает pdbdump, перенаправляя его вывод в файл с именем исходного PE файла и расширением .pdmp

Формирование эталонных данных

Для проведения тестов нужны файлы с эталонными данными, которые мне лениво набивать для каждого файла вручную, поэтому они также генерятся полуавтоматически. Эти данные хранятся в файле с именем исходного PE файла и расширением .et. Файл .et выглядит примерно так (взято из 32/win7/nosp/ntkrnlpa.et):
KiDebugRoutine 1689BC
KdDebuggerDataBlock 128C08

M DbgkLkmd_cblist 12DB20
PspLegoNotifyRoutine 369EE0

EPROCESS.ObjectTable F4


Для получения .et файла нужно натравить на .pdmp файл perl script make_et.pl, который распарзит выход pdbdumpа и извлечет всякие нужные адреса и смещения нужных полей в нужных структурах и сохранит их . Этот скрипт крайне прост и практически не отличается от ранее публиковавшегося. Здесь есть один тонкий момент - некоторых имен в .pdb файле может не быть. Так например в pdb от ntkrnlpa.exe от windows 7 нет переменной DbgkLkmd_cblist - она должна быть добавлена вручную. Соотв-но скрипт сначала зачитывает из уже имеющегося файла .et все строчки с символом M в начале строки (флажок, означающий что данная строчка была добавлена вручную) и сохраняет их в новой версии .et файла. Так гарантируется что однажды вручную добавленные поля никогда не будут потеряны. Как вы можете догадаться, эта функциональность также была добавлена благодаря моей выдающейся лени например

Собственно тесты

Это самая скучная часть повествования. Из общей с wincheck кодовой базы была написана специальная программа с оригинальным именем test.exe, которая делает ровно то же что и анализатор в wincheck, только еще умеет распечатать результаты в stdout. Есс-но что программа имеет 32 и 64 битные версии. Далее запускается еще один perl script, который рекурсивно ездит с помощью модуля File::Find по директориям с тестовыми данными, находит все .et файлы, запускает test.exe для исходного PE файла и сравнивает получившиеся результаты с эталонными данными. Все не найденное или не совпавшее с эталонными данными пишется в лог.
Скрипт этот имеет два режима работы - проверить вообще все, либо (что бывает значительно чаще) совершенно конкретный модуль. Откуда он знает какой файл относится к какому модулю ? Ему говорит об этом отдельный perl package PEIdent, ф-ции в котором выглядят примерно так:

sub is_hal
{
  my $fname = lc(shift);
  return ($fname eq 'hal.dll')      ||

         ($fname eq 'halapic.dll')  ||
         ($fname eq 'halmps.dll')   ||
         ($fname eq 'halacpi.dll')  ||
         ($fname eq 'halaacpi.dll') ||
         ($fname eq 'halmacpi.dll')
 ;
}

Думаю что основная идея из этого кусочка понятна. Далее можно формировать кортежи из двух указателей на ф-ции - is_XX & do_XX, вторая вызывается если первая вернула не ноль. Еще далее из этих кортежей можно составить список кортежей, по которому можно пройтись с именем .exe/.dll/.sys файла, найти его тип модуля, вызвать нужную ф-цию для обработки. В эти списки можно добавить кортежи только для отдельных типов модулей или для всех pe файлов и так далее

Добавление нового эталонного значения

Изредка возникает необходимость добавить еще одно (или не одно) поле в .et файлы для определенного модуля. Поскольку лень моя чудовищна - это делается с помощью все того же make_et.pl. К нему дописывается еще одна (или не одна) строчка - имя переменной, которую мы хотим получить из .pdmp или поле и структура. Этот скрипт точно так же обходит рекурсивно директорию с тестовыми данными и делает свое грязное дело по изменению .et файлов, генерируя при этом отчет - для какого файла что не нашлось. По моему это единственное место когда требуется ручное вмешательство с помощью анализа кода в IDA Pro

Добавление нового файла

Бывает также иногда необходимость добавить либо файлы с какой-либо версии windows, либо совершенно новый тип модуля. Если нужно добавить новый тип модуля для анализа - правится PEIdent и прочие использующие его скрипты. Затем просто запускаются два скрипта:
  1. make_pdmp.pl - рекурсивно ездит по директориям с тестовыми данными, ищет файлы, у которых отсутствуют .pdb/.pdmp файлы, скачивает все недостающее и вызывает pdbdump, при этом пишется два лога - для тех файлов, скачать .pdb к которым не удалось, и для всех вновь добавленных. Я думал что можно было бы make приспособить для этого дела - но тогда пришлось бы руками в нем прописывать все добавленные файлы с полными путями. Ручной рекурсивный обход дерева каталогов оказался намного проще
  2. все тот же make_et.pl для получения эталонных данных для вновь добавленных файлов
Как следует из описания если нужно просто добавить некоторое количество файлов (например давеча я добавил файлы от 32битной w2k3 sp1) - их нужно просто скопировать в нужную директорию и запустить простой .bat файл

Организация каталогов

Чтобы не потеряться в куче файлов - .exe/.dll/.sys, а также соотв-щих им .pdb/.pdmp/.et (размер этого добра сейчас составляет что-то около 6Gb) - нужна правильная организация каталогов. Директорий с тестовыми данными две - одна для 32бит, другая для 64 (и на самом деле эти директории могут лежать на разных машинах). В каждой директории есть папки с именем версии windows, откуда был взят набор файлов, примерно такие:
32/w2k/sp4
32/xp/sp1
32/xp/sp2
32/xp.64/sp1
и так далее

В каждой папке лежит весь наборчик файлов данной битности от данной версии windows. Благодаря тому что любой скрипт для манипуляции с файлами ездит по директориям рекурсивно - всегда можно задать директорию, в которой нужно отработать - например тестировать только xp версии, скачать pdb от 32/w2k3/sp1 etc etc

Должен заметить что подобная организация тестов значительно ЗНАЧИТЕЛЬНО МЕГАЗНАЧИТЕЛЬНО экономит время тестирования/поиска багов/добавления новых переменных/новых типов модулей/новых версий windows

воскресенье, 1 мая 2011 г.

perl binding for C++ objects

а вот например нас периодически спрашивают, как можно прикрутить к perlу большие и развесистые объекты C++, из которых биндинг осуществляется к весьма немногим методам (как почти всегда и бывает).
Например для автоматической генерации биндингов дико хорош swig. Но и у него периодически рвет крышу при парзинге развесистых заголовков. В качестве prooflink см. например как сделан биндинг писона к ida pro в ida sdk - для этого большинство заголовочных файлов были жестоко отпатчены на предмет вставки где попало макроса SWIG
Но есть например и другой способ, про который я не помню где вычитал и потому буду нагло считать, что придумал его сам.
Допустим что у нас есть некий C++ объект и мы хотим прикрутить его к perl:

class SomeUsefullClass
{
 public:
  SomeUsefullClass();
  ~SomeUsefullClass();
  // this is our methods for binding
  int MakeMeIncredibleRich(int howMuch);
  int StoreResults(const char *fname);

  // тут еще гора методов, которые мы не хотим биндить
 protected:
  SomeShittyClass m_Worker;
  SomeOtherShittyClass m_Serializer;
  // и тут еще гора методов, не имеющих к биндингу никакого отношения
};

C весьма высокой вероятностью если такое описание реального класса подсунуть swig, то его стошнит (заметим в скобках что нам еще придется указать всю кучу использованных header files). А если немного помедитировать над приведенным выше описанием, то можно заметить, что нам не нужны все кишки и потроха реального класса - например swigу можно было бы подсунуть ровно то что нам нужно

четверг, 17 февраля 2011 г.

partial structs matcher

У меня довольно часто возникает необходимость отреверсить всякие разные структуры данных. Учитывая что я крайне ленив и например часть структур может быть уже есть в раздаваемых империей добра microsoft pdb файлах - возникла идея написать некую прогу, которой можно было бы дать pdb (ну или выход pdbdump) и всякие разные критерии, по которым она бы сама нашла всех подходящих кандидатов
Немного подумав список критериев можно сократить до:
  1. Размер структуры - равен в точности X, меньше X или больше X
  2. Тип поля по некоторому смещению. Является указателем, имеет длину X, предположительно имеет тип Y etc
Соотв-но был написан простой perl package, точнее даже 3, которые умеют делать следующие вещи:
  • pdbparse.pm - собственно парзить файл, полученный из pdb с помощью pdbdump
  • pdbiter.pm - строить ленивые итераторы с учетом критериев поиска
  • lazylist.pm - просто реализация ленивых списков, потыренная из книжки Higher-Order Perl
Например я хочу найти список структур, у которых первое поле (по смещению 0) предположительно является LIST_ENTRY, поле по смещению 0x38 - указатель (неважно на что), а общий размер структуры не меньше 0x100 байт.
Получается примерно такой адовый кусок кода:
my $iter = off_cond(
     off_cond(
       size_cond(plain_iter($res), sub { return ($_[0] >= 0x100); }),
        0x0, sub { my $aref = shift; return $aref->[2] =~ /LIST_ENTRY/ } ),
        0x38, sub { my $aref = shift; return $aref->[3]; }
)
Пройдясь этим итератором по pdb от vista 64 бита мы получим ровно три структуры, отвечающие всем заданным критериям поиска:
  • _KALPC_MESSAGE
  • _ALPC_PORT
  • _ETW_GUID_ENTRY
Исходный код всех трех запчастей под катом. Слабонервным питонщикам и беременным лучше этого не видеть, бгг

воскресенье, 25 июля 2010 г.

Ищем по metal-archives.com

Потребовалось мне тут давеча много и нудно искать всякие разнообразные альбомы на митал-архивах. И поскольку я обладаю всеми доблестями perl программиста (лень, нетерпимость, высокомерие, если кто не знал), то решил я это дело немножечко автоматизировать
Поиск по CPAN не дал ничего (Perl’s killer feature, ага), что очень странно - неужто никто из матерых perlовщиков не слушает металл например ? Пришлось писать самому. Сорец прилагается