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

ВИДЕОКУРС ВЗЛОМ
выпущен 1 марта!


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


Исследование телефонного справочника




Очень удобно, когда все крэкерские инструменты, книги и статьи в одном месте. Используйте сборник от EXELAB - вот тут.

Картина маслом!

или

Исследование телефонного справочника


Программа: TelSpr2[FIT SoftWare]

Download: http://ray.smalhost.com/research/telspr2/telspr2_research.zip

Автор: Ray

E-mail: Ray@smalhost.com

Инструменты: OllyDebugger, Hiew, PE Tools/LordPE, ImpRec, PEiD/DiE, VC++, калькулятор

Уровень: для начинающих


Вкратце:

  1. Ручная распаковка

  2. Отключение ограничений демо-режима

  3. Перестройка ресурсов

  4. Внедрение своей секции с кодом

  5. Написание простейшего компаратора для сравнения файлов

  6. Написание патча для исследуемой программы


Итак.. приступим

TelSpr2 – это старенькая, но интересная для исследования программа.

При запуске она выдает нам вот такой вот надоедливый Nag-screen:


Взлом телефонного справочника


Посмотрим чем упакована наша подопечная.

PEiD говорит,что TesSpr2.exe упакована с помощью UPX 0.80 - 0.84 -> Markus & Laszlo.


Взлом телефонного справочника


TelSpr2.exe в PEiD v0.95

Взлом телефонного справочника



Взлом телефонного справочника

Взлом телефонного справочника


Попробовав распаковать программу самим же upx’ом получаем вот такой ответ:


Взлом телефонного справочника


Запускаем OllyDebugger и открываем в нем TelSpr2.exe.

На сообщение о том,что код упакован и предложение произвести анализ кода

отвечаем отрицательно.


Взлом телефонного справочника



В результате оказываемся вот в таком месте:


Взлом телефонного справочника


Именно с этого места начинается код упаковщика.

Теперь нам надо попасть на OEP(Original Entry Point),оригинальную точку входа.

OEP - это начало распакованной программы.

В командной строке плагина CommandBar пишем: hr esp-4


Взлом телефонного справочника

Command Bar –– плагин для OllyDebugger


При запуске программы регистр esp (указатель на вершину стека) в операционных системах w2k и xp практически всегда равен 12FFC4.


Взлом телефонного справочника

Окно стека


В процессе своей работы упаковщик производит множество операции со стеком.

Соотвественно, перед переходом на OEP, он должен поправить стек, чтобы при запуске

распакованной программы он имел вышеприведенное значение (esp=12FFC4).

Т.е командой hr esp-4 мы ставим Hardware breakpoint on access(hr - hardware read) по адресу 12FFC4-4=12FFC0.

После установки бряка запускаем программу(F9).

И сразу же останавливаемся на установленном бряке в таком месте:


Взлом телефонного справочника


Здесь 0045C53C jmp TelSpr2.004092F0 происходит прыжок на OEP.


Жмем F7 и останавливаемся на OEP:


Взлом телефонного справочника

Original Entry Point


Это и есть адрес начала программы 004092F0 (OEP).

Теперь программа распакована и находится в памяти.


С помощью плагина OllyDump снимаем дамп(Plugins->OllyDump->Dump debugged process).

Ставим галочки в следующих местах: Fix raw size,Rebuild import, и

выбираем Method2:Search DLL & API name string in dumped file.

Нажимаем Dump и сохраняем файл.


Взлом телефонного справочника

OllyDump –– плагин для OllyDebugger


Для того,чтобы TelSpr2 могла корректно вызывать необходимые функции

надо восстановить таблицу импорта.


Запускаем запакованный экзешник, запускаем ImportReconstructor и

в списке процессов выбираем TelSpr2.exe.


В строке OEP пишем OEP-Image Base(указан в окне Log):00400000

Т.о. получаем: OEP-Image Base => 0x004092F0 - 0x00400000 = 0x000092F0

Жмем IAT AutoSearch, для авто-поиска адреса таблицы импорта.


Взлом телефонного справочника


Import Reconstructor v1.7


Получаем такое сообщение:


Взлом телефонного справочника


RVA(Relative Virtual Address) - виртуальный адрес относительно ImageBase,т.е.

относительное виртуальное смещение таблицы импорта.

Нажимаем Get Imports, и видим в каждой строке Yes.

Значит мы правильно определили OEP.

Теперь нажимаем Fix Dump и сохраняем нормальную таблицу в наш дамп.

В окне Log получаем сообщение ...saved successfully.


Запускаем то, что получилось и..наша программа вылетает с фолтом…


Взлом телефонного справочника

Взлом телефонного справочника


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

Нажимаем Ctrl+N и просматриваем список импортируемых функций.

Находим функцию GetFileSize. Возможно программа проверяет, изменился ли ее размер или нет. Ставим бряк на GetFileSize. Запускаем нашу программу. Отладчик останавливается на вызове функции. Смотрим на стек:


Взлом телефонного справочника


Переходим по адресу вызова функции и станавливаемся вот в таком месте:


Взлом телефонного справочника


По адресу 004057С1 происходит контроль размера программы. Обратите внимание, что в случае несовпадения размера в локальную переменную dword ptr ss:[ebp-14] попадает значение 0x2711. Скорее всего на выходе будет проверяться наличие в результате значения 0x2711.

По адресу 004057C6 меняем je на jmp:

je short TelSpr2.004057CF -> jmp short TelSpr2.004057CF


Осмотревшись можно заметить чуть выше такую же проверку. В функцию CreateFileA передается имя открываемого файла TelSpr2.exe. Результат работы функции ложится в регистр eax, а затем сверяется с -1. Таким образом, если имя было не TelSpr2.exe, то в

dword ptr ss:[ebp-14] попадает 0x2711, которое на выходе скорее всего проверяется.


Взлом телефонного справочника


Немного ниже,по адресу 004057E4 меняем jbe на jmp:

jbe short TelSpr2.004057ED -> jmp short TelSpr2.004057ED


Взлом телефонного справочника


А вот, собственно, и сама проверка на выходе:


Взлом телефонного справочника


Можно было бы просто исправить одну эту проверку, чтобы не править несколько предыдущих.

Сохраняем изменения в TelSpr2.exe и запускаем.Программа запустилась без ошибок.


Теперь займемся Nag-screen'ом.

Загружаем в отладчик TelSpr2.exe. Нажимаем Ctrl+N и просматриваем список импортируемых функций. Ищем функцию DialogBoxParamA. Именно эта функция отвечает за показ нашего Nag-screen’a. Ставим не нее бряк.


Взлом телефонного справочника

Запускаем программу по F9. Отладчик останавливается в таком месте, смотрим на стек:


Взлом телефонного справочника


Нажимаем Ctrl+G, для того, чтобы совершить переход на требуемый адрес и вводим этот адрес.


Взлом телефонного справочника


Жмем Ok и тут же оказываемся на месте, откуда была вызвана DialogBoxParamA.


Взлом телефонного справочника


Видим,что в строке 00407FB4 call dword ptr ds:[<&user32.DialogBoxParamA>; USER32.DialogBoxParamA

происходит вызов диалога из библиотеки USER32.Это и есть наш Nag-screen.

В строке 00407F9B je short TelSpr2.00407FC9 происходит условный переход, который перепрыгивает через наш Nag-scree, но он не получает управления до тех пор, пока программа не зарегистрирована.. Изменим его на безусловный переход:

00407F9B je short TelSpr2.00407FC9 -> 00407F9B jmp short TelSpr2.00407FC9

Запускаем программу(F9).И.. никакого Nag-screen'а.


Взлом телефонного справочника


TelSpr2 без Nag-screen’a


Теперь надо отключить ограничение по времени, т.к. программа работает всего одну минуту.

Итак, открываем окно с импортируемыми функциями и ищем функцию, работающую со временем. Находим функцию SetTimer, которая создает таймер с заданным временем. В MSDN’е можно посмотреть назначение параметров этой функции. В ней 3-й параметр определяет время окончания работы таймера в миллисекундах. Ставим на нее брейкпоинт при импорте. Запускаем по F9 программу и тут же останавливаемся в начале SetTimer. Смотрим на содержимое стека. Видим там 3-й параметр Timeout равный 300 ms. Но это не то, что нам надо, т.к. мы ищем таймер, работающий 1 минуту, а 1 минута – это 60 000 мс. Следовательно пропустим этот вызов. Жмем F9, смотрим на стек и.. снова не то, что надо. Еще раз F9, еще и.. в этот раз значением третьего параметра в SetTimer наблюдаем искомые 60 000 мс.


Взлом телефонного справочника


Нажимаем Ctrl+G для перехода по адресу и вводим адрес вызова SetTimer, т.е. 00408578.

Останавливаемся и осматриваемся вокруг. Посмотрев чуть выше вызова функции таймера видим передаваемые ей параметры, одним из которых является значение 0x0EA60 –– это одна минута(в миллисекундах).

А еще немного выше видим условный переход : je short TelSpr2.0040857E , который перепрыгивает через вызов функции SetTimer, в случае если программа зарегистрирована. Заменим его на безусловный джамп.


Взлом телефонного справочника

Увеличение времени работы до.. бесконечности :)

В исследуемой программы отключена возможность поиска. Включен только поиск по первым трем буквам Ф.И.О. абонента:


Взлом телефонного справочника


Теперь надо включить возможность поиска по другим полям.

Запускаем программу под отладчиком по F9. Переходим в Olly, нажимаем Ctrl+N(список импортируемых функций) и ставим бряк на EnableWindow. Эта функция включает, либо отключает возможность ввода данных в определенное поле. Эта функция получает на входе 2 параметра: дескриптор контрола HWND hWnd и логическое значение BOOL bEnable.


Выбираем программе поиск и тут же останавливаемся в отладчике на такой поляне:

В окне стека видим следующее:


Взлом телефонного справочника


Обратите внимание, что второй параметр ф-и установлен в False, т.е. поле ввода неактивно.

Переходим по адресу вызова EnableWindow и осматриваемся вокруг.


Взлом телефонного справочника


Немного оглянувшись замечаем обильный и повсеместный вызов функций EnableWindow, параметрами которых являются нули(не активное окно) и значения:

3F3 – ФИО

3F4 – Населенный пункт

3F5 – Улица

3F6 – Дом

3F7 – Квартира

3F8 – Телефон


Параметр, который заталкивается в стек перед 3F3 – это 0С5.Меняем его на nop. В остальных случаях перед 3F* заталкиваем в стек 1, т.е. перед 3F* пишем push 1. Тем самым активируем остальные пункты поиска.


Взлом телефонного справочника


Сохраняем измененную программу и перезагружаем ее в Olly.

В результате получаем активированными все поля:


Взлом телефонного справочника


Теперь сделаем возможным поиск по активированным пунктам.

Нажимаем Ctrl+N(список импортируемых функций) и ставим бряк на GetWindowTextA:


Взлом телефонного справочника


Ставим бряк на GetWindowTextA


Переходим в нашу программу. Выбираем поиск, нажимаем кнопку “Искать” и тут же останавливаемся в отладчике на вызове функции GetWindowTextA. Смотрим как обычна в стек на адрес вызова.


Взлом телефонного справочника


Перейдя к вызову GetWindowTextA в строке по адресу 00406A3A видим интересующий нас джамп.


Взлом телефонного справочника


Коррекция джампа jnz на je


В строке по адресу 00406A30 происходит сравнение константной величины FFFFBEF1 с величиной типа DWORD(int), хранящейся по адресу, на который указывает указатель, т.е. ds:[40D4E4]. Сразу после этого сравнения стоит условный переход jnz. Т.е.Jump if Not Zero - перейти по указанному адресу, если не установлен флаг нуля.

Если бы значение по адресу ds:[40D4E4] было бы равно FFFFBEF1, то после выполнения команды cmp автоматически установился бы флаг нуля, что говорило бы о том, что сравниваемые значения равны. Изменим этот джамп в нашу пользу. Заменим его на je - Jump if equal. Все. Сохраняемся. Тестируем. Ок. Все остальные пункты также работают.


Теперь надо бы включить остальные пункты поиска в поиске по организациям. Ставим бряк на GetWindowTextA. Переходим с квартирных телефонов на телефоны организаций. Включаем поиск. Нажимаем на кнопку искать и тут же брякаемся на вызове функции GetWindowTextA.

Переходим по адресу вызова ф-и, указанному в стеке и меняем джамп jnz на je.


Взлом телефонного справочника


Немного потрассировав(пройдя по коду вниз, нажимая F8) код увидим ниже еще один нужный нам переход:


Взлом телефонного справочника

Коррекция джампа

Изменяем переход je на jnz.

Сохраняем изменения и запускаем.Теперь в нашем распоряжении имеется полностью рабочая программа.


Однако это еще не все. Если вызвать информацию о программе, можно увидеть следующее сообщение:


Взлом телефонного справочника


Придется его немного поправить. Запускаем Hiew и ищем в файле TelSpr2.exe строку “Незарегистрированная копия”. Жмем Alt+F8, чтобы сменить кодировку.


Взлом телефонного справочника


Теперь давим F7 и вводим искомую строку:


Взлом телефонного справочника


В результате находим искомую строку:


Взлом телефонного справочника


Жмем F3 и вводим, что нам надо:


Взлом телефонного справочника


Жмем F9 для сохранения изменений и выходим.

Запускаем наш TelSpr2.exe, вызываем информацию о программе и получаем такое сообщение:


Взлом телефонного справочника


А теперь можно набросать какой-нибудь простейший патчер. Этим мы сейчас и займемся.

Но для начала надо определить, по каким адресам и какие байты были нами исправлены. Не будем же мы все это записывать на бумажке. Значит нужно набросать еще и простенький компаратор.

Итак, приступим. Для кодинга я использую Code::Blocks + VC++9(выдранный из студии).

Ниже я привожу код нашего компаратора с некоторыми комментариями.


#include <stdio.h>
 #include <windows.h>
 
// Функция, проверяющая размер файла long FileSize(FILE *stream) { long curpos, length; curpos = ftell(stream); fseek(stream, 0L, SEEK_END); length = ftell(stream); fseek(stream, curpos, SEEK_SET); return length; }
int main(int argc,char **argv) { if(argc < 3) { printf("Usage: FCompare.exe File1 File2\n"); return 0; } FILE* hFile1 = fopen(argv[1],"rb"); if(!hFile1) { printf("Can't open first file"); return 0; } FILE* hFile2 = fopen(argv[2],"rb"); if(!hFile2) { printf("Can't open second file"); return 0; }
// Проверим, совпадают ли размеры файлов long sizeFile1 = FileSize(hFile1); long sizeFile2 = FileSize(hFile2); if(sizeFile1 != sizeFile2) { printf("Sizes of files don't match...\n"); return 0; }
fseek(hFile1,0,SEEK_SET); fseek(hFile2,0,SEEK_SET); char Bytes_1File,Bytes_2File; printf("+----------+------------+--------+\n"); printf("|Offset |File 1\t|File 2\t |\n"); printf("+----------+------------+--------+\n");



// Читаем побайтно каждый файл и сравниваем прочитанные байты, пока не достигнут // конец файла do { Bytes_1File = fgetc(hFile1); Bytes_2File = fgetc(hFile2); if(Bytes_1File != Bytes_2File) { printf("|%#p|%08X\t|%08X|\n",ftell(hFile1),Bytes_1File,Bytes_2File); } }while(!feof(hFile1)); printf("+----------+------------+--------+\n"); // Закрываем дескрипторы обоих файлов fclose(hFile1); fclose(hFile2); return 0; }


Ну вот. Наш компаратор готов. Проверим его в действии:


Взлом телефонного справочника


Ок. Все нормально работает. В левой колонке мы видим адреса, по которым правились байты, в средней и правой колонках – байты 1-го и 2-го файлов соответственно.

Делаем след-е:


Взлом телефонного справочника


Тем самым, перенаправив вывод в файл TelSpr2.crk. Все. Нужные адреса и поправленные байты тоже есть.



Теперь напишем простенький патчер.


#include <stdio.h>
 #include <windows.h>
 
int Patch(HANDLE hFile,const int Offset,char *lpBuffer,int nBytes,DWORD nBytesWritten);
int main(int argc,char **argv) { // Массивы байтов, которыми будем патчить нужные нам адреса // Их мы взяли из результата работы FCompare.exe char Bytes_01[] = {"\xEB"}; char Bytes_02[] = {"\xEB"}; char Bytes_03[] = {"\xEB"}; char Bytes_04[] = {"\x84"}; char Bytes_05[] = {"\x90\x90\x90\x90\x90"}; char Bytes_06[] = {"\x6A\x01\x90\x90\x90\x90"}; char Bytes_07[] = {"\x01"}; char Bytes_08[] = {"\x01"}; char Bytes_09[] = {"\x01"}; char Bytes_10[] = {"\x01"}; char Bytes_11[] = {"\x74"}; char Bytes_12[] = {"\x75"}; char Bytes_13[] = {"\xEB"}; char Bytes_14[] = {"\xEB"}; char Bytes_15[] = {"\xD7"}; char Bytes_16[] = {"\xF1\xF2\xED\xEE\x20\xE2\xE7\xEB\xEE\xEC\xE0\xED\xED"}; char Bytes_17[] = {"\xFF\x20\xE2\xE5\xF0\xF1\xE8\xFF\x20\x20"}; if(argc < 2) { printf("Usage: Patcher.exe File\n"); return 0; }
// Открываем для записи файл, переданный в качестве параметра HANDLE hFile = CreateFile(argv[1], GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING,0,0); if(hFile != INVALID_HANDLE_VALUE ) { DWORD nBytesWritten = 0; // Патчим программу по указанным адресам Patch(hFile,0x00005235,Bytes_01, 1,nBytesWritten); Patch(hFile,0x000057C7,Bytes_02, 1,nBytesWritten); Patch(hFile,0x000057E5,Bytes_03, 1,nBytesWritten); Patch(hFile,0x00006A3C,Bytes_04, 1,nBytesWritten); Patch(hFile,0x00006BBE,Bytes_05, 5,nBytesWritten); Patch(hFile,0x00006BD4,Bytes_06, 6,nBytesWritten); Patch(hFile,0x00006BE9,Bytes_07, 1,nBytesWritten); Patch(hFile,0x00006BF8,Bytes_08, 1,nBytesWritten); Patch(hFile,0x00006C07,Bytes_09, 1,nBytesWritten); Patch(hFile,0x00006C16,Bytes_10, 1,nBytesWritten); Patch(hFile,0x00006D2F,Bytes_11, 1,nBytesWritten); Patch(hFile,0x00006DAA,Bytes_12, 1,nBytesWritten); Patch(hFile,0x00007F9C,Bytes_13, 1,nBytesWritten); Patch(hFile,0x0000856B,Bytes_14, 1,nBytesWritten); Patch(hFile,0x0000D78D,Bytes_15, 1,nBytesWritten); Patch(hFile,0x0000D78F,Bytes_16,13,nBytesWritten); Patch(hFile,0x0000D79D,Bytes_17,10,nBytesWritten);
printf("%s patched successfully!",argv[1]); } CloseHandle(hFile); return 0; }
int Patch(HANDLE hFile,const int Offset,char *lpBuffer,int nBytes,DWORD nBytesWritten) { // Установка файлового указателя на нужный адрес SetFilePointer(hFile,Offset-0x01,NULL,0); // Запись данных WriteFile(hFile,lpBuffer,nBytes,&nBytesWritten,NULL); return 0; }


Запустим патчер.

Взлом телефонного справочника


Ну а теперь можно заняться секциями нашего подопечного.

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

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

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

Итак, поехали. Запускаем PE Tools и открываем нашу жертву.


Взлом телефонного справочника




Теперь идем в Sections. Появляется вот такое окно:


Взлом телефонного справочника


В этом окне мы видим 5 секций нашего файла. Да… сразу видно, что здесь упаковщик похозяйничал…Но теперь-то хозяева тут мы! Перед тем, как добавлять сюда свою секцию надо бы немного прибраться. Заодно и перестроим ресурсы. Итак, из того что здесь есть нам нужны только первые две секции. Все остальное, начиная с секции ресурсов, вырежем нафиг.

Для этого выберите вырезаемую секцию, правая кнопка мыши, Kill section (from file).Таким же образом удаляем остальные секции.


Взлом телефонного справочника


После этого создаем из резервной рабочей версии исследуемой программы новую секцию ресурсов, которую мы прикрутим вместо удаленной. Для этого воспользуемся замечательной программой Resource Rebuilder v1.0 by Dr.Golova. Работать с ней очень просто:

resrebld.exe <input_file> [output_file] [options]

В нашем случае это будет выглядеть так: resrebld.exe TelSpr2.exe .rsrc -r:0x5D000

Параметр –r:0x5D000 указывает, что наша новая секция .rsrc будет иметь RVA = 0x5D000.

RVA – это относительный виртуальный адрес(Relative Virtual Address). Относительным он называется потому, что отсчитывается относительно адреса загрузки, который в свою очередь может быть равен ImageBase, но может и не быть равным ему. Подробнее читайте в замечательной статье(2 части) «Об упаковщиках в последний раз».

Почему именно 0x5D000 ? А взгляните еще раз на наши секции.

После отрезания ненужного шлака у нас осталось их две:


Взлом телефонного справочника


Итак, ответим на вопрос, почему именно 0x5D000. Этот адрес мы используем потому, что следующая секция должна располагаться по адресу, равному сумме виртуального адреса и виртуального размера предыдущей секции. Т.е.:

Адрес след. секции = Virtual Offset предыдущей секции + Virtual Size предыдущей секции. В нашем случае такой секцией(предыдущей) является UPX1.

Возьмем калькулятор и посчитаем:


Взлом телефонного справочника


При этом учтите, что SizeOfRawData не должен быть больше чем Virtual Size. Из-за таких косяков IDA может не распознать некоторые элементы. Поэтому это поле должно быть либо равно, либо меньше поля Virtual Size, т.к. SizeOfRawData – это размер инициализированных данных, которые после проецирования в память выравниваются по SectionAlignment. Ну что ж.. выполнив команду resrebld.exe TelSpr2.exe .rsrc -r:0x5D000 получаем такое сообщение:


Взлом телефонного справочника

Ок. У нас есть секция ресурсов. Надо ее прикрутить к файлу. Делаем следующие шаги:

В PE Tools правой кнопкой мыши выбираем пункт Load Section From Disk…

И загружаем созданную нами секцию ресурсов.


Взлом телефонного справочника


После закрузки редактируем хидер новой секции:


Взлом телефонного справочника


Ставим нужное нам имя новой секции , а также Virtual Offset секции.


Взлом телефонного справочника


Вместо значения Virtual Offset равного 00060000 вписываем значение Raw Offset.

Можно еще подправить характеристики:

Было:

Взлом телефонного справочника


Стало:

Взлом телефонного справочника


Теперь выходим из Sections и идем в Directories. А в директориях смотрим, чтобы RVA и Size наших ресурсов были правильными.

Взлом телефонного справочника

Сохраняем и возвращаемся в Sections.

Щелкаем правой кнопкой мыши и в появившемся меню выбираем пункт Add Section.

В результате появится такое вот окно:


Взлом телефонного справочника


Даем какое-нибудь имя нашей новоиспеченной секции, например, x-code. В поле Size of Raw Data и в Size of Virtual Data запишем значение 000010000, т.е. тем самым мы выделяем для нашей секции по 4 Кб в файле и в памяти соответственно. Теперь ставим свой выбор напротив Fill with 0x00, этим мы говорим PE Tools заполнить нашу новую секцию нулями.


Взлом телефонного справочника


Смотрим, что у нас получилось. Почти все так как надо. Но нужно подправить Virtual Offset новой секции. Как видите, он не совпадает с Raw Offset.Ну а с размерами секции все в порядке.


Взлом телефонного справочника


Выбираем в меню Edit Section Header и редактируем виртуальное смещения с 000AD000 на 000AA000.

Почему так? Потому, что Virtual Offset(секции .rsrc) + Virtual Size(секции .rsrc) = 000AA000.

Там же, в Edit Section Header, отредактируем характеристики нашей секции.


Взлом телефонного справочника






За что отвечает каждый флаг понятно из описания.


Взлом телефонного справочника


Сохраняем и идем в Optional Header. В нем пересчитываем SizeOfImage, SizeOfHeaders и Checksum. Хочу заметить, что SizeOfImage = Virtual Offset + Virtual Size последней секции.

Для их пересчета нажмите на кнопки с вопросительным знаком рядом с этими полями.


Взлом телефонного справочника


Теперь нам нужно восстановить импорт. Как это сделать было описано в начале статьи.

Восстановили таблицу импорта, запускаем и… Оk! Все замечательно работает.

Запустим PE Tools и посмотрим на секции.

Вот такой вид имеет наша программа с внедренной секцией и восстановленным импортом.




Взлом телефонного справочника


Пробуем открыть ее в Olly Debugger и… получаем от Olly вот такое сообщение:


Взлом телефонного справочника


Нда.. неприятно.. ну да ладно. Снова загружаем нашего подопечного в Hiew/PE Tools/LordPE и начинаем медитировать…

После непродолжительных медитаций обращаем внимание

на релоки(Fixup Table/Relocation Table). Релоки, скажем так, содержат указатели на базозависимые адреса в командах переходов и обращений к памяти. Т.е. если файл загружен не по тому базовому адресу, на который он рассчитан, то виндовый лоадер проходит по этим адресам и корректирует их. Если проще, то релоки содержат указатели на то, что нужно корректировать.

Смотрим в Hiew. F8 -> F10 -> Fixups.


Взлом телефонного справочника



В PE Tools. Directories -> Base Relocation Table:


Взлом телефонного справочника


Заменяем значения полей RVA и Size нулями, сохраняем изменения и пробуем.

Все хорошо. Запускается нормально и при загрузке файла в Olly больше не появляется сообщение об ошибке.

Загружаем файл снова в PE Tools.

Запоминаем Virtual Offset нашей секции .x-code(0xAA000). Переходим в Optional Header и в поле Base Of Code пишем RVA секции .x-code.Т.к. код у нас теперь будет начинаться отсюда. И запоминаем точку входа(Entry Point 0x92F0).

Взлом телефонного справочника


По адресу 0xAA000 у нас будет стоять джамп на старую EP(0x92F0). А в поле Entry Point мы вписываем новую точку входа, равную 0xAA005, т.к. команда jmp 000092F0 занимает 5 байт.

Итак.. берем в руки OllyDebugger и правим наши переходы.

Напишем простой вызов MessageBox’a. В MSDN функция MessageBox имеет следующий синтаксис:

int MessageBox(

HWND hWnd,

LPCTSTR lpText,

LPCTSTR lpCaption,

UINT uType

);

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


Итак, переходим на адрес 004AA000, нажимаем пробел и вводим команду jmp 004092F0, т.е. прыжок на старую энтропию.

Затем, начиная с адреса 004AA005(новая Entry Point) вводим последовательно команды:

 push 0
 push 004AA020
 push 004AA040
 push 0
 call MessageBoxA
 jmp 004AA000
 

Здесь, 004AA020 и 004AA040 – это адреса текстовых строк для заголовка и текста сообщения.


Взлом телефонного справочника


Сохраняем сделанные изменения и открываем нашу подопечную в Hiew’e, чтобы записать нужные нам строки для сообщения.

В Hiew’e выбираем режим Hex, нажав кнопку выбора режима работы F4.

Жмем F5 для перехода на заданный адрес и вводим первый нужный нам адрес, это .004AA020.

Хочу отметить, что адрес надо вводить вместе с впереди стоящей точкой. Подробности смотрите в документации к Hiew.


Взлом телефонного справочника


По нажатию Alt+F8 меняем кодировку на Windows-1251.


Взлом телефонного справочника


Жмем F3 -> TAB и вводим нужный текст заголовка(параметр Caption):


Взлом телефонного справочника


Для сохранения изменений нажимаем F9.

Теперь переходим на адрес .004AA040 и вводим текст нашего сообщения:


Взлом телефонного справочника


Жмем F9 для сохранения. Выходим, запускаем нашу программу и любуемся сообщением:


Взлом телефонного справочника


Нажимаем Ok и.. наша программа запускается!








Скачать статью "Исследование телефонного справочника" в авторском оформление + файлы.
пароль архива на картинке



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


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