ключевой процесс GETORIX | INT3 Спецвыпуск: Хакер, номер #066, стр. 066-054-4 .text:000291AC STR R3, [R4,R5] .text:000291B0 MOV R0, R4 [блокировка окна] .text:000291B4 BL _EnableWindow_CWnd__QAAHH_Z ; CWnd::EnableWindow(int) .text:000291B8 LDR R0, [R4,#0x20] .text:000291BC MOV R3, #0 [указатель на обработчик — NULL] .text:000291C0 MOV R2, #0x1F4 [500 мс] .text:000291C4 MOV R1, #1 .text:000291C8 BL SetTimer [устанавливаем таймер] .text:000291CC B loc_291DC [локальный безусловный переход] Функция начинается с проверки на наличие ключа в поле ввода. Если ключ не введен, то его значение заменяется кодом «00000». Далее из ключа удаляются все пробелы, символы переноса и табуляции (функции CString::TrimLeft и CString::TrimRight), затем строковое значение ключа переводится в числовое функцией _wtol. Кроме того, в этом блоке кода нашего внимания требуют две вещи. Первая — то, что программа написана с использованием WinCE MFC, о чем говорят строки типа CString::operator=(char const *) или CWnd__MessageBoxW. Такое положение вещей несколько усложняет исследование: теперь, в отличие от WinAPI, строка представлена не просто адресом на данные в памяти, а адресом на объект CString, в котором содержится адрес на данные в памяти. Соответственно, и операции будут выполняться над этими объектами, например: CString::TrimRight. Вторая вещь — это таймер. Здесь нужно внимательно посмотреть на параметр lpTimerFunc, установленный в NULL. Благодаря этому моменту мы узнаем, что через 500 мс будет сгенерировано событие WM_TIMER, которое должно быть перехвачено и обработано либо внутри MESSAGE_MAP (для MFC), либо внутри основной функции окна (для WinAPI). Изучим код по адресу loc_291DC, куда осуществляется безусловный локальный переход. Здесь с некоторого адреса в R3 загружается флаг, его проверка на равенство нулю создает еще одно ветвление. Если этот флаг не равен нулю, то окно регистрации разблокируется, а таймер останавливается и затем принимается решение об успешной регистрации (см. выше). Если же R3 равен единице, происходит вызов функции по адресу 29594 («Код начала функции принятия решения»). код начала функции принятия решения .text:000291D8 loc_291D8 ; CODE XREF: .text:000291E8 .text:000291D8 BL sub_29594 .text:000291DC loc_291DC ; CODE XREF: .text:000291CC .text:000291DC LDR R3, [R4,R5] [чтение флага окончания очереди] .text:000291E0 MOV R0, R4 .text:000291E4 CMP R3, #0 [если он равен нулю — продолжаем обработку] .text:000291E8 BEQ loc_291D8 [вызов функции обработчика сообщений] .text:000291EC MOV R1, #1 .text:000291F0 BL _EnableWindow_CWnd__QAAHH_Z ; CWnd::EnableWindow(int) .text:000291F4 LDR R0, [R4,#0x20] .text:000291F8 MOV R1, #1 .text:000291FC BL KillTimer [остановка таймера] По адресу 29594 как раз и находится функция приема и передачи сообщений. Таким образом, флаг, загружаемый в R3, определяет, пуста ли очередь сообщений. Если она не пуста, вызов функции продолжается в цикле снова и снова, пока не будет выставлена единица. код функции обработки сообщений .text:0002959C MOV R3, #0 ; wMsgFilterMax .text:000295A0 MOV R2, #0 ; wMsgFilterMin .text:000295A4 MOV R1, #0 ; hWnd |