8(495)909-90-01
8(964)644-46-00
pro@sio.su
Главная
Системы видеонаблюдения
Охранная сигнализация
Пожарная сигнализация
Система пожаротушения
Система контроля удаленного доступа
Оповещение и эвакуация
Контроль периметра
Система домофонии
Парковочные системы
Проектирование слаботочных сетей
Аварийный
контроль
Раздел: Документация

0 ... 85 86 87 88 89 90 91 ... 102

находим пункт Set Next Statement. Нажимаем F5 для возобновления работы про. граммы, и... она действительно возобновляет свою работу! А теперь откомпилируем наш проект в чистовом варианте (то есть без отладочном информации) и попробуем реанимировать приложение в голом машинном коде. Пользуясь тем обстоятельством, что Windows — это действительно многозадачная среда, в которой крушение одного процесса не мешает работе всех остальных, запустим свой любимый дизассемблер (например, IDA PRO) и проанализируем таблицу импорта отлаживаемой программы (вообше-то это может сделать и бесплатно распространяемый dumpbin, но его отчет не так нагляден).

Целью нашего поиска будут функции Trans!ateMessage/DispatchMessage и перекрестные ссылки, ведущие к циклу выборки сообщений (листинг А.13).

Листинг А.13. Поиск функций TranslateMessage/DispatchMessage в таблице импорта

.idata:004040E0 : BOOL stdcel1 IranslateMessageCconst MSG *lpMsg)

extrn Transatew.essage:dword : DATA XRr.F: WinKein@16+71*r

: WinMainP16*80*r LONG stdcall D:spatchMessageA(const MSG *lpMsg) extrn DispatchMessageA:dwcrd DATA XREF: WinMain@16+94*r

.idata:004C40EC ,idata:004040EC .idata:004040E4 .idata:004040E4 .i data-.00404018

С функцией DispatchMessage связана всего лишь одна перекрестная ссылка, со всей очевидностью ведущая к искомому циклу обработки сообщений, дизас-семблерный код которого выглядит так (листинг А.14).

Листинг А.14. Дизассемблерный листинг функции обработки сообщений

.text:004С1050 .text:00401050 .text:00401050 .text:004С1056 .text:00401058 .text:004C105A .text:0040105A .text:004C105A .text .-0040105A .text:0040105A .text:0040105A .text:0040105A .text:0040105E .text:00401060 .text:00401061 .text:00401063 .text:00401063 .text:00401063 .text:00401065 .text .-00401067 .text:00401067 .text:00401067

mov ed\ dS:GcLMcssagcA первый вызов GetMessageA (это еще не цикл, это только его преддверье)

p-jsh 0. wsgFilterMax

push 0: wMsgFilterMin

lea осх. [esp+2Ch+Msg] ECX указывает на область памяти, через которую GetMessageA станет возвращать сообщение, текущее значение ESP может быть любым, главное, чтобы оно указывало на действительную область памяти (см. карту памяти, если значение ESP оказалось искажено настолько, -то вывело его в "космос")

push0

pjshесх

mcvesi. eax

callcd : GetMessageA

вызываем GetMessageA

: hWnd : lpMsg

test eax. eax jz short loc 4010AD проверка на наличие необработанных сообщений в очереди


*- Программная часть

273

.text:ОО4О1077 .text:0040-077 .text:00401G77

text:0040IC77 ext:00401C7B .text:00401078 .text:0040107B .text:00401C7F .text:00401C8D ,text:00401081 .text:00401082 .text:00401C82 ,text:00401C82 .text:00401084 .text:00401086 .text:00401086 .text:00401C86 .text:00401C88 .text:0040108C .text:0040108D .text:00401CSD .text:0040138D .text:004C108F .text:00401093 .text:00401G94 .text:00401094 .text:0040109A •text:0040109Л text:0040109A •text:0040109C •text:0040109E -text:004010A2 text:004010A4 text:00401 OAS text:004010A5 text:004010A5 text:004010A7 •text:00401CA9 text:004010A9 •text:004010A9 •text:00401CAB

text;004C10AC text;004010AD text:00401CAD text:004ClOAD •te>!t:004010B! text:004010B? text:00401033 •text:004010B6 text:0040ICB6

loc 401077:

: начало цикга обработки сообщений

: CODE XREF: WinMdTnP16*A9vj

mov eax. Lesp+2Cb+Msg.hwnd] lea edx. [esp+2Ch+Msg] EDX указывает на область памяти, используемую для передачи сообщений

pusn edx push esi push eax call ebx вызываем функцию TranslateAcceleratorA

lpMsg hAccTable hwnd

Trans1ateAcceleratorA

test eax. eax jnz snort loc 40109A проверка на наличие в очереди необработанных сообщений

lea есх. [esp+2Ch+Msg]

push есх: lpMsg

call езр: TranslateMessage

вызываем функцию TranslateMessage.если есть что транслировать

lpMsg

CODE XREF: WinMain@16+86Aj

wMsgFilterMax

wMsgFilterMin

hWnd lpMsg

GetMessageA

lea edx. [esp+2Ch+MsgJ push edx

call ds:OispatchMessageA : диспетчеризуем сообщение

1ос 40109А:

push0

pushС

!eaeax. [esp+34h+Msg]

push0

pusheax

calledi ; читаем очередное сообщение из очереди

test eax. eax jnz short loc 401077 : вращаем цикл обработки сообщений

pop ebp pop ebx

ioc 4010AD:: CODE XREF: WinMain@16+67*j

moveax. Lesp+24h+Msg.wParam]

poped i

popes-:

addesp. ICh

retnlOh

WinMain@16endp


Мы видим, что цикл обработки сообщении начинается с адреса 4Q1050h, и именно на этот адрес следует передать управление, чтобы возобновить работу упавшей программы. Пробуем сделать это, и... программа работает! Разумеется, настоящее приложение оживить намного сложнее, поскольку цикл обработки сообщений в нем рассредоточен по большому количеству функций, отождествить которые при беглом дезассемблировании невозможно. Тем не менее приложения, построенные на основе общедоступных библиотек (например, MFC, OVL), обладают вполне предсказуемой архитектурой, и .реанимировать их вполне возможно.

Рассмотрим, как устроен цикл обработки сообщений в MFC. Большую часть своего времени исполнения MFC-приложения проводят внутри функции CWinThread: -.Run(void), которая периодически опрашивает очередь на предмет поступления свежих сообщений и рассылает их соответствующим обработчикам. Если один из обработчиков споткнулся и довел систему до критической ошибки, выполнение программы может быть продолжено в функции Run. В этом-то и заключается ее главная прелесть!

Функция не имеет явных аргументов, но принимает скрытый аргумент this, указывающей на экземпляр класса CWinThread или производный от него класс, без которого функция просто не сможет работать. К счастью, таблицы виртуальных методов класса CWinThread содержат достаточное количество «родимых пятен», чтобы указатель this можно было воссоздать вручную.

Загрузим функцию Run в дизассемблер и отметим все обращения к таблице виртуальных методов, адресуемой через регистр ЕСХ (листинг А.15).

Листинг А.15. Дизассемблерный листинг функции Run (фрагмент)

.text-.6C29919D n2k Trasnlate nai .text:6C29929D

CODE XREF: MFC42 5715+lFTj Ч-С42 5715+67vj ...

text:6C29919D

mov

eax. [esi]

text:6C29919F

mov

ecx. esi

text:6C299IAl

call

oword ptr [eax+64h]

: CWinThread

text:6C2991A4

test

eax. eax

text:6C2991A6

tz

short loc 6C2991DA

text:6C2991A8

mov

eax. [esi]

text:6C2991AA

lea

ebp. [es1+34h]

text:6C2991AD

pusr

ebp

text:6C2991AE

mov

ecx. esi

text:6C2991BC

cai"

dword ptr [eax+6Ch]

: CWinThread

text:6C2991B3

test

eax, eax

text:6C2991B5

jz

short loc 6C2991BE

text:6C2991B7

push

1

text:6C2991B9

nov

[esp+I4h]. ebx

text:6C2991BD

pop

eci

text:6C2991BE

text:6C2991BE loc

6C2991BE:

; CODE XREF:

text:6C2991BE

push

ebx

: wRemovelisg



0 ... 85 86 87 88 89 90 91 ... 102