Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

Видеокурс программиста и крэкера 5D 2O17
(актуальность: октябрь 2O17)
Свежие инструменты, новые видеоуроки!

  • 400+ видеоуроков
  • 800 инструментов
  • 100+ свежих книг и статей

УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Полная перекомпиляция программы write.exe или тестируем демо-версию IdaPro 5.6

Обсудить статью на форуме

Массу крэкерских инструментов, видеоуроков и статей вы сможете найти на видеокурсе от нашего сайта. Подробнее здесь.

Автор: Erfaren <erfaren@rambler.ru>

В настоящее время существует широко известный и достаточно высококачественный интеллектуальный дизассемблер IdaPro от выпускника мехмата МГУ Ильфака Гильфанова (Ilfak Guilfanov). Всегда интересно знать, насколько хорош этот инструмент. Например, как много и что именно нужно изменить в декомпилированном коде, выдаваемом IdaPro, скажем для простейшей GUI программы, которую можно найти в папке Windows, чтобы скомпилированная версия этой программы заработала снова, практическим ничем не отличаясь от исходной программы? Т.е., чем меньше телодвижений нужно делать, чтобы перекомпилировать дизассемблерный файл в работающее приложение, тем, очевидно, более качественен инструмент нашего Ильфака. Ну и конечно эти телодвижения не должны быть слишком уж изощренными, по крайней мере для небольших программ.

Естественно, тестировать можно любую версию дизассемблера. Но поскольку, на данный момент, на сайте разработчика http://hex-rays.com/idapro/idadown.htm доступна уже демо-версия 5.6, то мы и воспользуемся ею, тем более что нам достаточно будет даже ограниченных возможностей этой версии.

Главное ограничение демо-версии, отсутствие возможности сохранения ассемблерного кода в файл, но нас это не должно сильно напрягать, так как Ida оставила нам лазейку сохранения листинга кода в файл через буфер обмера (Ctrl-Ins или Ctrl-C / Shift-Ins или Ctrl-V). Правда, при этом сохраняются и адреса команд, но их очень легко убрать в полученном файле листинга. К этому мы еще вернемся, а пока займемся настройками «Иды».

Мы выберем наименьшую GUI-шную программу, которую можно найти на наших компьютерах под управлением Windows NT. У меня это программа write.exe (обёртка для WordPad.exe из каталога по умолчанию Program FilesWindows NTAccessories).

Для тестирования у меня было три системы. Две под управлением XPюши, с сервис паком 3, но разных сборок и одна под Windows 2003 Server. У XPюши write.exe имел одну и ту же версию 5.1.2600.0, но был разных размеров 5632 и 22528 байт. Как оказалось, «лишние» байты занимал не вирус или троян, а данные ресурсов. В данном случае вместо двух иконок для первого файла мы имеем четыре иконки для второго. Общий размер ресурсов (вместе с манифестом), соответственно, 2092 и 18692 байт.

Для Windows 2003 у write.exe версия 5.2.3790.0, размером 5632 байта. Кстати, этот файл отличается от подобного файла XPюши практически на треть (и не только за счет ресурсов). Так что испытывать мы будем все эти версии, но начнем с меньшей версии из Windows XP.

Настройка IdaPro v. 5.6


Для максимальной эффективности декомпиляции воспользуемся следующими настройками.

На странице «Welcome to the PE executable file loading Wizard» отмечаем галку в опции «Analysis options». Если мы хотим, чтобы эта галка стояла по умолчанию, то тогда просто заменяем в файле IDAPro56cfgkernel.xml строку


<checkbox X="analysis_c" caption="Analysis options" onClick="onClick_analysis_c">

на


<checkbox checked="true" X="analysis_c" caption="Analysis options" onClick="onClick_analysis_c">

Однако изменять файл kernel.xml следует в последнюю очередь, так как после этого становятся недоступны некоторые страницы настроек.

Следующую страницу Визарда «Segment Creation» оставляем без изменений (сегмент импорта создаем, а сегмент ресурсов – нет).

Далее, на странице «Kernel Options» нам надо снять галку по умолчанию с опции «Automatically hide library functions», так как нам не незачем скрывать функции, которые мы собираемся перекомпилировать. Чтобы не делать это постоянно, надо отредактировать файл IDAPro56cfgida.cfg . Там мы видим следующее определение:


#define AF2_HFLIRT      0x0004  // Automatically hide library functions
.
Это значение входит в содержимое переменной ANALYSIS2, которое нам следует уменьшить на 4. Однако это переменная встречается в данном файле несколько раз, определяя по умолчанию различные настройки для разных процессоров. Можно изменить их все (заменим последнюю шестнадцатеричную цифру D на 9), а можно найти только нужный нам случай. Это будет секция:


#ifdef __PC__            // INTEL 80x86 PROCESSORS
. . .
ANALYSIS2 = 0x3FFD        // Enable 'noret' analysis. Enable SP analysis
#endif // __PC__

Вместо исходной строки пишем:


ANALYSIS2 = 0x3FF9

Следующие страницы настроек Визарда будут «PC Processor Options» и «File loading». Их мы оставляем без изменений. Проверяем, смотрим. Все как надо. Теперь можно поменять и файл kernel.xml, описанный выше. После этого страницы «Kernel Options» и «PC Processor Options» станут недоступными, но тем лучше для нас. Нужные нам настройки там останутся, а лишних кликов мышью делать придется меньше.

Дизассемблинг write.exe


Загрузим нашего «подопытного кролика», в данном случае, файл WINDOWSsystem32write.exe версии 5.1.2600.0, размером 5632 байта, в дизассемблер IdaPro v. 5.6. Работаем под управлением XPюши. Интернет доступен.

Думаю, что процесс загрузки остаточно очевиден, и мы можем, наконец-то лицезреть вожделенный ассемблерный листинг.

Однако сразу бросается в глаза отсутствие прототипов структур write.exe на вкладке Structures и «облегченное» использование прототипов функций в секции .idata.

Как оказалось, со структурами просто вышел глюк. Если удалить вкладку со структурами (Alt-F3) и затем снова восстановить ее (через меню, либо по Shift-F9), то все нужные структуры появятся. Только не забудьте прокрутить окно вверх, а то будет казаться, что восстановлена только одна структура вместо трех необходимых.

Кстати, эти структуры можно сразу сохранить в файл (предварительно раскрыв их «серым» плюсом) через буфер обмена, скажем, в файл write.lst.

По поводу прототипов, IdaPro, например, пишет:


; Imports from SHELL32.dll
; HINSTANCE __stdcall ShellExecuteA(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd)

extrn ShellExecuteA:dword
.
В данном случае правильной будет запись (так как мы имеем 6 параметров, каждый размером 4 байта, всего 6*4 = 24 байта)


extrn ShellExecuteA@24:dword

либо


extrn _imp__ShellExecuteA@24:dword
.
В таком виде (плюс лидирующий символ подчеркивания «_», который добавляет компилятор) эти имена функций присутствуют в библиотечных lib-файлах, которые нам нужно будет подгружать при компиляции ассемблерного кода. Понятно, что мы может внести все нужные изменения вручную, но зачем, если по-хорошему, то это задача «Иды».

Конкретно, это означает, что отладочная информация из соответствующих pdb-файлов не была автоматически загружена из Интернета (с сайта Microsoft.com). По этому поводу Ильфак Гильфанов пишет в своей документации, что в этом случае, он типа не виноват, это все происки зловредной Виндозы. Мол, он грузит отладочные символы из Интернета или локально не сам, а через системную WINDOWSsystem32imagehlp.dll . А она де может отказать в загрузке, по только ей известным причинам. Но мы то верим в это с большим трудом, так как в предыдущей версии IdaPro 5.5 (ее уже нет на сайте Ильфака, но при желании можно найти в бескрайних просторах Сети) отладочные pdb-файлы прекрасно грузятся автоматом из Интернета, даже через прокси-сервер. Но не будем ради этого возвращаться на предыдущую версию. Ситуация в нашем случае такова. Под Windows XP (разных сборок) демо-версия «Иды» категорически отказывается подгружать автоматом или пулеметом, то бишь, вручную отладочные символы, а Windows 2003 Server «соглашается» делать это только локально, т.е. загружать pdb-файлы с жесткого диска. «Ида» при этом ругается, на сервере:


pdb(. . ./IDApro56/Temp/write.exe): Unknown error, code: 0x806D0012
,
а в русскоговорящей XPюше:


pdb(. . ./IDApro56/Temp/write.exe): Класс не зарегистрирован
.
Но поскольку лезть во внутренности «Иды», в нашу задачу не входит, то мы продолжим наши исследования в серверной ОСи и расскажем, как можно работать без отладочных символов, если они, по каким-либо причинам, недоступны.

Заметим, что в Masm32 ( http://www.masm32.com/masmdl.htm ) прототипы функций определяются по другому. Тот же пример функции ShellExecuteA там (в Includeshell32.inc) описан следующим образом:


ShellExecuteA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
ShellExecute equ 

а сам файл прототипов подключается к проекту с помощью инструкции:


include Include/shell32.inc

Ничто не мешает нам использовать уже готовые файлы прототипов функций (стиль Iczelion’a). Это, кстати, уменьшает зависимость от pdb-файлов. Однако, лично мне кажется, что для наших целей вариант с использованием директивы extrn (или extern) более предпочтителен. Впрочем, окончательный выбор за вами.

Загрузка pdb-файлов из Интернета


Но чтобы продолжить нашу работу, нам надо вручную скачать у мелкософта отладочные символы. Проще всего это сделать, загрузив всю упаковку предлагаемых pdb-файлов для выбранной операционки с конкретным сервис паком. Для этого идем на стартовую страницу: http://www.Microsoft.com/whdc/devtools/debugging/symbolpkg.mspx#d .

Для Windows XP, sp. 3 инсталяк pdb-файлов занимает 214 Мб, а для Windows 2003 Server, sp. 2 – около 160 Мб. Можно, конечно, пытаться делать это индивидуально для конкретных файлов. Версия 5.5 «Иды» посылает следующий Get запрос, для XP-шной версии:


srv*d:TempIda*http://msdl.Microsoft.com/download/symbols/write.pdb/3b7d841d1/write.pdb
.
Для серверной ОСи, аналогичный запрос:


srv*d:TempIda*http://msdl.Microsoft.com/download/symbols/write.pdb/3e8000e61/write.pdb
.
Хотя это и Get запрос, только бесполезно передавать его непосредственно в браузере. По-видимому, нужно еще обмениваться файлами cookie с мелкософтом. Короче, геморно, это все. Проще скачать всю упаковку (или даже несколько) с символами и не париться. Что мы и сделаем.

Итак, обе упаковки с отладочными символами получены (в виде pdb-файлов) для обеих, рассматриваемых нами, операционных систем.

Ручная подгрузка pdb-файлов в IdaPro 5.6


Вручную это можно сделать двумя способами.

Первый способ заключается в том, чтобы положить файл write.pdb рядом с файлом write.exe. По крайней мере, серверная ОСь понимает это правильно, и подгружает сама нужный нам файл, в результате чего мы получаем то, к чему стремились.

Вот! Теперь мы вполне удовлетворены полученным результатом. Распознавание прототипов функций осуществлено успешно. Теперь, быстренько (так как время работы одного сеанса демо-версии ограниченно и составляет порядка 30 минут) выделяем весь полученный листинг и сохраняем в тот же файл write.lst, вставив ассемблерный листинг после описания структур.

Второй способ ручного использования pdb-файлов заключается в его непосредственном выборе из IdaPro через пункт меню File / Load file / pdb file . . . Мы просто указываем путь, выбрав маску файлов (*.*) для нужного файла символов. Заметим только, что выбор не того файла приведет к непредсказуемым последствиям по перекодировке ассемблерного листинга.

Напомним, что в двух различных сборках XPюши, «Ида» отказывается это делать, мотивируя тем, что «класс не определен». Какой класс и чего, нам объяснять не считают нужным. Можно только предположить, что это глюки самой демо-версии ибо плагин pdb.plw из версии 5.6 успешно работает в предыдущей версии «Иды» (и даже автоматом грузит символы из Интернета, в том числе, через прокси-сервер).

На случай, если нет интернета или файла write.pdb, покажем, как вручную сделать замену символов в рассматриваемом листинге write.lst. Для этого во всем файле нужно сделать замену строк из левого столбца таблицы на соответствующие строки из правого.

Таблица 1. Ручная замена символов в листинге write.lst


№	До замены	После замены	Модуль dll
1	GetStartupInfoA	_imp__GetStartupInfoA@4	Kernel32.dll
2	GetCommandLineA	_imp__GetCommandLineA@0	Kernel32.dll
3	GetModuleHandleA	_imp__GetModuleHandleA@4	Kernel32.dll
4	ShellExecuteA	_imp__ShellExecuteA@24	shell32.dll
5	_exit	_imp___exit	msvcrt.dll
6	__imp__XcptFilter	_imp___XcptFilter	msvcrt.dll
7	_cexit	_imp___cexit	msvcrt.dll
8	exit	_imp__exit	msvcrt.dll
9	_acmdln	_imp___acmdln	msvcrt.dll
10	__getmainargs	_imp____getmainargs	msvcrt.dll
11	_c_exit	_imp___c_exit	msvcrt.dll
12	__setusermatherr	_imp____setusermatherr	msvcrt.dll
13	_adjust_fdiv	_imp___adjust_fdiv	msvcrt.dll
14	__p__commode	_imp____p__commode	msvcrt.dll
15	__p__fmode	_imp____p__fmode	msvcrt.dll
16	__set_app_type	_imp____set_app_type	msvcrt.dll
17	__imp__controlfp	_imp___controlfp	msvcrt.dll
18	__imp__except_handler3	_imp___except_handler3	msvcrt.dll
19	__imp__initterm	_imp___initterm	msvcrt.dll

В данном случае, это основная суть того, что делает «Ида», подгружая файл с отладочными символами. Как видим, не очень много и, может быть, не стоило бы так заморачиваться с pdb-файлами. Однако, для больших проектов, без отладочных символов трудоемкость работы может существенно возрасти.

Получение из файла листинга ассемблерного файла


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

В общем-то, столбец с адресами можно попытаться удалить вручную. Так, например, многие редакторы (лучше с моноширинным шрифтом) поддерживают выделения столбца текста с помощью Alt + левая кнопка мыши, либо Shift + Alt + управление стрелками / PageUp / PageDown / Home / End. Но нам это делать как-то лениво, поэтому мы лучше напишем небольшой скрипт, который будет выполнять за нас эту «черную» работу. Лично мне привычен FoXPro, который, на уровне ядра, очень неплох, для любых версий. Однако в данном случае это неважно. Вы можете наваять собственный скрипт, на любом удобном вам языке.

Вот пример файла lst.prg, выполняющийся под управлением Visual FoXPro:


******************************************************************************
CLEAR
SET TALK OFF
SET SAFETY OFF

filename = "write"

infile = filename + ".lst"
outfile = filename + ".asm"

file1 = FOPEN(infile)

IF file1 < 0
  WAIT 'Не могу открыть файл: ' + infile
  QUIT
ENDIF

file2 = FCREATE(outfile)

IF file2 < 0
  WAIT 'Не могу создать файл: ' + outfile
  QUIT 
ENDIF 

End1 = FSEEK(file1, 0, 2)  && Определяем размер файла
Top1 = FSEEK(file1, 0)  && Идем в начало. Сама переменная не нужна

IF End1 <= 0  && Если файл пуст
  MESSAGEBOX('Пустой файл: ' + infile)
  QUIT 
ENDIF

pos = 0

strline = FGETS(file1)

DO WHILE NOT EOF(file1)  && На самом деле мы не можем доверять этой проверке
  Curpos1 = FSEEK(file1, 0, 1)
  
  IF Curpos1 >= End1  && Достигнут конец файла?
    pos = AT(" ", strline)
    FPUTS(file2, SUBSTR(strline, pos + 1))    
    EXIT 
  ENDIF

  IF LEFT(strline, 1) = " "
    FPUTS(file2, strline)
    LOOP
  ENDIF
  
  pos = AT(" ", strline)
  
  IF pos > 0
    FPUTS(file2, SUBSTR(strline, pos + 1))
  ELSE
    FPUTS(file2, "")
  ENDIF

  strline = FGETS(file1)
ENDDO

CLOSE ALL
QUIT 
******************************************************************************
******************************************************************************

Итак, в нашем распоряжении ассемблерный файл write.asm, который уже можно пытаться компилировать. Поэтому сейчас самое время поговорить о способах компиляции asm кода.

Компиляция ассемблерного кода


Есть множество версий разного рода ассемблеров и соответствующих программных компиляторов. Также немало и всевозможной документации по этим вопросам. Но лично мне кажется, что начинать нужно с классики жанра – знаменитого туториала от Iczelion’a ( http://wasm.ru/docs/1/Iczelions_Tutorials_(for_print).zip ) и используемого им пакета Masm32 ( http://www.masm32.com/masmdl.htm ) .

Пакет Masm32 (на сегодня 10-я версия) на самом деле имеет компилятор макро ассемблера ml.exe от 1999 года. Т.е. он много лет практически не меняется. Возможно это последняя бесплатная версия, ибо более поздние компиляторы ml.exe принадлежат Microsoft и входят в состав продуктов MS Visual Studio, по крайней мере, начиная с 7-й версии (2000 год). Так что, если у вас есть MS VC7 или выше из VS, то вы можете воспользоваться более новой версией ассемблерного компилятора.

В принципе нас устраивает любая версия Masm32, хоть бесплатная, хоть от MS. Поэтому, для чистоты эксперимента будем работать с Masm32 и компилятором от 1999 года.

Вот перечень файлов, которые нам понадобятся. Они (или аналогичные) есть также и в Visual C++ из MS Visual Studio.

Каталог Bin:

ml.exe – компилятор макро ассемблера;
ml.err – пустой текстовый файл, для вывода ошибок компилятора;
link.exe – линковшик;
rc.exe – компилятор ресурсов;
rcdll.dll – библиотека редактора ресурсов;
cvtres.exe – дополнительный компилятор ресурсов;
mspdb50.dll – общая библиотека поддержки.

Каталог Lib (для наших целей достаточно) :

kernel32.lib
shell32.lib
msvcrt.lib


Выше этих каталогов мы будем располагать следующие файлы:

write.asm – полученный с помощью IdaPro ассемблерный листинг программы write.exe;
headers.inc – файл заголовка для write.asm, описан ниже;
write.res – файл ресурсов для write.asm, описан ниже;
asm.bat – командный файл, описан ниже.

Опишем используемые нами дополнительные файлы.

Файл заголовка headers.inc


Поскольку нам нужны будут в обязательном порядке lib-файлы для используемых в ассемблерном коде функций из системных dll-лек, то сразу вставим строку


include headers.inc

после строки


.model flat

в файле write.asm. Содержимым файла headers.inc будут строки:


;============================================================================

includelib Libkernel32.lib
includelib Libshell32.lib
includelib Libmsvcrt.lib

;============================================================================

Командный файл asm.bat


Вот пример командного файла asm.bat, который мы будем использовать для наших целей:


SET FILENAME=write

:: Компиляция ресурсов (не нужна, если мы берем готовый res-файл от Resource Builder)
:: Binrc /r /v %FILENAME%.rc >a.a

:: Компиляция ассемблерного кода
Binml /c /coff /Cp /Cx /Zp1 /Gz /Zm %FILENAME%.asm > b.a
:: /c – компиляция без линковки
:: /coff – обязательная опция для формата объектного (obj) файла
:: /Cp – резервирование регистра для пользовательских идентификаторов
:: /Cx – резервирование регистра для глобальных и экспортируемых символов
:: /Zp[n] – установить выравнивание структур в n
:: /Gz – применение вызова функций типа Stdcall
:: /Zm – совместимость с версией MASM 5.10

:: Линковка (создание exe-файла)
Binlink /BASE:0x1000000 %FILENAME%.obj %FILENAME%.res /subsystem:windows >c.a
:: /BASE:0x1000000 – поскольку в листинге «Иды» указана эта база
:: Первоначально текст %FILENAME%.res можно убрать, для компиляции без ресурсов

del *.obj
:: del *.res

Здесь в текстовых файлах a.a, b.a и c.a записываются сообщения о выполнении процессов компиляции и линковки данного кода. Описание ошибок, которые мы сейчас начнем разбирать, находятся в файле b.a.

Разбор ошибок


В основном работа с ошибками будет заключаться в удалении ненужного (fake) кода. Будем исходить из случая, когда используются отладочные символы. Если мы делали замену символов вручную, на основе таблицы 1, но некоторых ошибок не будет.

Итак, компилятор ругается на строки вида:


extrn _KERNEL32_NULL_THUNK_DATA:byte:4
. . .
extrn _SHELL32_NULL_THUNK_DATA:byte:4
. . .
extrn _msvcrt_NULL_THUNK_DATA:byte:4

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

Далее, в нашем коде есть строка:


align 1000h

которая явно не нравиться компилятору. Максимум, что готов принять компилятор это значение вида


align 10h

так что этот вариант и оставим.

Также не любит компилятор строки вида:


mov     eax, large fs:0

Экспериментально выяснилось, что его смущает директива large. Убираем ее полностью, делая автозамену по всему файлу. Тем самым уменьшаем общее количество ошибок на три.

Остальные ошибки, как оказалось, связаны с директивой rva, которая встречается много раз. Например, в коде:


; ---------------------------------------------------------------------------
  align 4
__IMPORT_DESCRIPTOR_SHELL32 dd rva off_10013D8 ; Import Name Table
  dd 0FFFFFFFFh           ; Time stamp
  dd 0FFFFFFFFh           ; Forwarder Chain
  dd rva aShell32_dll      ; DLL Name
  dd rva __imp__ShellExecuteA@24 ; Import Address Table
. . .

Однако этот и оставшийся код (до конца секции) _text


. . .  
                db 'GetModuleHandleA',0
                align 4
                dd 29h dup(0)
                dd 280h dup(?)
_text           ends

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


align 10h

Ура! Компилятор согласился с нашими довольно радикальными операциями и скомпилировал объектный код в виде write.obj. Однако теперь настала очередь ругаться линковщику (файл с.а). Практически ему не нравятся все имена функций перечисленных в правой части таблицы 1, к которым оказались добавлены лидирующие символы подчеркивания (как в lib-файле), т.е. перед префиксом imp два символа нижнего подчеркивания «__» (а в описании ошибок линковщика даже три), а не один, как у нас. Но это уже не проблема, а всего лишь задача, как говорят студенты, которая решается в два хлопка автозаменой «__imp» на «_imp» в файле write.asm. Короче, хлопаем в ладоши, лишние символы удаляются, и наш код прекрасно собирается в exe-шник write.exe. И о, чудо! Программа запускается и можно работать с вызванным ею редактором WordPad.

В данном случае, мы проигнорировали линковку бинарного файла ресурсов write.res, в командном файле asm.bat, так как пока у нас нет этого файла, что однако не помешало запуститься нашей конфетке (в смысле обёртке) .

Работа с ресурсами


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

IdaPro позволяет создавать сегмент ресурсов (но мы то специально эту галку не ставили). Только это будет что-то вроде секции данных, что не очень удобно для анализа. Лучше найти подходящий редактор ресурсов, который позволит извлекать ресурсы из исполнимых файлов в нужном нам виде. И такой редактор сейчас действительно есть. Речь идет о такой чудесной программе как Resource Builder, триальную версию которой вы можете скачать с http://www.resource-builder.ru/download.html . Для демонстрации наших исследований ее возможностей вполне достаточно.

Мы не будем описывать принципы работы с Resource Builder. В программе поддерживается русский язык и документации у нее хватает. Достаточно сказать, что мы можем извлечь с помощью нее нужные нам ресурсы, как в бинарном виде write.res, так и в виде описания сценариев ресурсов – файл write.rc. Заодно мы потренируемся в модификации манифеста ресурсов. Для этого изменим, например, строку описания программы. Затем компилируем измененные ресурсы во внешние файлы, которыми можно будет уже воспользоваться.

Для наших целей мы можем воспользоваться либо уже готовым для применения бинарным файлом write.res, либо, после небольшого редактирования, файлом сценариев write.rc. В последнем случае нам надо будет раскомментировать строку:


Binrc /r /v %FILENAME%.rc >a.a

в файле asm.bat.

Изменения в файле описания ресурсов write.rc касаются, в основном, явных определений используемых констант (которые можно найти в h-файлах MS VC++) и редактирования пути для иконки write.ico, которая также создается Resource Builder’ом. Приведем конечное его содержание:


/*********************************************
File: write.rc
Generated by Resource Builder (3.0.3.25).
*********************************************/
/*
OutputExt=res
*/

//MS Visual C++ compatible header
//  #define APSTUDIO_READONLY_SYMBOLS
//  #include "afxres.h"
//  #undef APSTUDIO_READONLY_SYMBOLS
//end of MS Visual C++ compatible header

// Наши определения, взятые в MS Visual C++
#define LANG_ENGLISH                    0x09
#define VOS_NT_WINDOWS32          0x00040004L
#define VFT_APP                               0x00000001L

// Иконку, полученную в Resource Builder, переименовываем в write.ico и помещаем рядом с write.asm 
LANGUAGE LANG_ENGLISH, 1
1 ICON "write.ico"

// Version Info
1 VERSIONINFO
FILEVERSION 5, 1, 2600, 0
PRODUCTVERSION 5, 1, 2600, 0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP {
  BLOCK "StringFileInfo" {
    BLOCK "040904B0" {
      VALUE "CompanyName", "Microsoft Corporation"
      VALUE "FileDescription", "Windows Write - Обёртка для WordPad"
      VALUE "FileVersion", "5.1.2600.0 (XPclient.010817-1148)"
      VALUE "InternalName", "write"
      VALUE "LegalCopyright", "© Microsoft Corporation. All rights reserved."
      VALUE "OriginalFilename", "write"
      VALUE "ProductName", "Microsoft® Windows® Operating System"
      VALUE "ProductVersion", "5.1.2600.0"
    }
  }

  BLOCK "VarFileInfo"  {
    VALUE "Translation", 1033, 1200
  }
}

Компиляция с явным использованием ресурсного скрипта также проходит успешно. Раньше о подобных возможностях приходилось только мечтать! В Total Commander’е можно посмотреть параметры сгенерированного нами файла write.exe. Действительно, внесенные нами изменения имеют место. При желании можно также поменять и иконку. Но это оставим вам, в качестве домашнего задания.

Заметим, что размер нашего нового файла в MASM32 v.10ml.exe 1999 года), получился не намного больше исходного exe-шника (разница всего 512 байт). Можно, конечно пытаться уменьшать размер результирующего файла, но это уже не принципиально для наших целей, ибо главную задачу мы выполнили.

Перекомпиляция других версий write.exe


Для полноты картины нам еще нужно перекомпилировать XP-шную версию write.exe (который мы переименуем в write2.exe) с исходным размером 22528 байт и версию write.exe от Win2003 (который мы переименуем в write3.exe), размером также 5632 байта.

Рекомпиляция write2.exe прошла абсолютно по тому же сценарию, что и первый случай. Даже pdb-файл мы не меняли. Разницей оказались, как уже упоминалось, другие иконки (4 штуки). В коде явных различий не обнаружено. Поэтому сразу перейдем к третьему случаю.

Рекомпиляция write3.exe, несмотря на небольшое отличие в коде (если write.exe и write2.exe могут линковаться с Image Base по умолчанию (0x400000), то write3.exe – нет, так как интенсивно сканирует собственный PE-заголовок), также прошла успешно.

Таким образом, все поставленные перед собой задачи мы успешно выполнили.

Заключение


Теперь можно подвести итоги нашего тестирования демо-версии IdaPro 5.6 на примере простейшего GUI-приложения write.exe.

Как дизассемблер (отладочные способности мы не тестировали) IdaPro 5.6 вполне хорош, если не считать его глюки с загрузкой pdb-файлов. Будем надеяться, что Ильфак Гильфанов обратит на это внимание. Но даже ручная правка отладочных символов (или, как альтернатива, использование стиля программирования Iczelion’a) не портит впечатления от «Иды». Это действительно высококачественный продукт. Интересно будет еще попробовать мощь IdaPro на других приложениях, в качестве «подопытного кролика», но на более сложных, чем используемое нами.

Вот примерный перечень GUI-приложений (для XPюши) – потенциальных кандидатов на тестирование:


regedt32.exe	3584 байт
winver.exe	5632 байт
dcomcnfg.exe	6144 байт
winhlp32.exe	8192 байт
control.exe	8192 байт
eventvwr.exe	8704 байт
winmsd.exe	11776 байт

и другие.

(Оказывается, regedt32.exe имеет даже меньший размер, чем write.exe, но обнаружил это я только сейчас.)

Примечание


К данному тексту приложен файл IdaPro56Test.zip ( http://erfaren.narod.ru/Asm/IdaPro56Test.001 - измените расширение в zip), с результатами тестирования, размером 711 Кб. Можно также посмотреть pdf версию этой статьи ( http://erfaren.narod.ru/Asm/Erfaren-001-Recompilation-write-exe.pdf ).



Обсуждение статьи: Полная перекомпиляция программы write.exe или тестируем демо-версию IdaPro 5.6 >>>


Комментарии к статье: Полная перекомпиляция программы write.exe или тестируем демо-версию IdaPro 5.6

s0l 14.07.2010 10:02:08
Аффтар пешы исчо
---
s0l 14.07.2010 10:31:05
Заметил такой ньюанс:
В пдфной версии на скрине афтор использует Notepad , но адреса убирает скриптом на FoxPro, возникает вопрос: зачем? Ведь в нотпад есть замечательная функция макросов. При помощи нее без шума и пыли удаляется весь мусор ;-)
---

Материалы находятся на сайте http://e4unrusy7se5evw5.onion



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS