Правильный ответ - Максимальная Автоматизация всего процесса с помощью адовой смеси perl/bat скриптов
Получаем pdb
Как известно microsoft в отличие от практически всех остальных софтоклепательных компаний предоставляет .pdb файлы от почти всех своих системных модулей. Было бы глупо не воспользоваться такой шикарной возможностью при создании эталонных данных для тестов. Соотв-но обработка любого файла начинается с получения его .pdb файла и последующего дампа этого .pdb с помощью пропатченной мною версии pdbdumpCуществует множество способов получить .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 и прочие использующие его скрипты. Затем просто запускаются два скрипта:- make_pdmp.pl - рекурсивно ездит по директориям с тестовыми данными, ищет файлы, у которых отсутствуют .pdb/.pdmp файлы, скачивает все недостающее и вызывает pdbdump, при этом пишется два лога - для тех файлов, скачать .pdb к которым не удалось, и для всех вновь добавленных. Я думал что можно было бы make приспособить для этого дела - но тогда пришлось бы руками в нем прописывать все добавленные файлы с полными путями. Ручной рекурсивный обход дерева каталогов оказался намного проще
- все тот же make_et.pl для получения эталонных данных для вновь добавленных файлов
Организация каталогов
Чтобы не потеряться в куче файлов - .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
Должен заметить что подобная организация тестов
Комментариев нет:
Отправить комментарий