MasterGH Опубликовано 24 июня, 2011 Поделиться Опубликовано 24 июня, 2011 Я ни разу не делал обработку исключений (SEH) на Ассемблере. Xipho, может быть ты делал и знаешь быстрое решение? Я знаю есть мануалы, но пока мне их некогда читать.Вот пример АА на CE (в комментариях указано где нужно обработать SEH):[ENABLE]alloc(newmem,2048)label(returnhere)label(originalcode)label(_cmpString)label(_valueString)label(_pValueString)label(_pCmpString)newmem: pushfd pushad push ecx //+44(4 + 4*9 + 4) или 11 двордов lea eax, [esp+4*B+0ac] lea ebx,[_cmpString] mov [_pCmpString], ebx lea ebx,[_pCmpString] // прооверка строки "GetPlayerFaction" по [esp+ac] cld mov ecx,#16 lds esi,[eax] //<<< здесь нужна обработка исключения в случае если по eax нет указателя на строку les edi,[ebx] cmpsb jnz short originalcode // если строки совпали, то записать по [esp] "999999" lea ebx,[_valueString] mov [_pValueString], ebx lea ebx,[_pValueString] mov ecx,7 lds esi,[ebx]les edi,[esp] //<<< здесь нужна обработка исключения в случае если по esp нет указателя на строку cld rep movsboriginalcode: pop ecx popad popfd mov eax,[ecx] mov edx,7EFEFEFF jmp returnhere db 90 90 90 90 90_pCmpString:dd 0_pValueString:dd 0_cmpString: //"GetPlayerFaction"db 47 65 74 50 6C 61 79 65 72 46 61 63 74 69 6F 6E 00_valueString: // "999999"db 39 39 39 39 39 39 00"SpazGame.exe"+157790:jmp newmemnopnopreturnhere:[DISABLE]"SpazGame.exe"+157790:mov eax,[ecx]mov edx,7EFEFEFFdealloc(newmem)Есть ещё один вариант "не париться" с ассемблером, а сделать dll-инжект на языке высокого уровня с обработкой исключений в секциях try ... catch. Но всё-таки может быть кто-то в курсе обработки на ассемблере? Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 24 июня, 2011 Поделиться Опубликовано 24 июня, 2011 Статья Джереми ГордонаМакрос для облегчения обработки исключительных ситуаций. При использовании в СЕ вряд ли пригодится, но, на всякий:@TRY_BEGIN MACRO Handler Pushad ;сохраняем текущее состояние Mov esi, offset Handler ; Адрес нового исключения push esi ; сохраняем старое исключение push dword ptr fs: [0] ;устанавливаем новый Handler Mov dword ptr fs: [0], esp ENDM@TRY_EXCEPT MACRO Handler Jmp NoException&Handler ;исключений нет, делаем переходHandler: Mov esp, [esp + 8] ;исключение есть, получаем старое значение ESP pop dword ptr fs: [0] ;востанавливаем старое исключение add esp, 4 ; значение ESP перед тем, как SEH был установлен Popad ; востанавливаем старое состояниеENDM@TRY_END MACRO HandlerJmp ExceptionHandled&Handler ; исключение было обработано@TRY_EXCEPTNoException&Handler: ;исключений нет pop dword ptr fs: [0] ;востанавливаем старое исключение add esp, 32 + 4 ; значение ESP перед тем, как SEH был установлен32 для pushad и 4 для смещения Handler (состояние не восстанавливается)ExceptionHandled&Handler:; исключение было обработано, или его вообще не былоENDMВышеописанный макрос используется так:@TRY_BEGIN HandlerName ; Код в этом месте будет проверен на исключения.@TRY_EXCEPT HandlerName ; Код в этом месте будет выполнен, если исключение произойдет.@TRY_END HandlerName ; Нормальное выполнениеПример программы:Чтобы откомпилировать эту программу, Вам потребуется 32 бит. Turbo AssemblerTASM32 /ml SEHTLINK32 SEH, SEH, , IMPORT32.LIB.386p.model flat, stdcallEXTRN ExitProcess:PROCEXTRN MessageBoxA:PROC; Определяем @TRY_BEGIN, @TRY_EXCEPT и @TRY_END макрос здесь.data SzCaption Db ' SEH на Ассме ', 0 SzException Db ' Исключение было обработано!! ', 0dh, 0ah Db ' Нажмите ОК для завершения ', 0 SzNoException Db ' Исключений нет ', 0.codeWinMain:@TRY_BEGIN Zero_Address_Access Mov Ebx, 0 ; подготовка для записи в адрес 0 Mov [Ebx], ebx ; пишим, по адресу 0 (нарушение доступа)@TRY_EXCEPT Zero_Address_Access ; этот код выполнится, если исключение произойдет. call MessageBoxA, 0, offset szException, offset szCaption, 0 Jmp ExitProgram@TRY_END Zero_Address_Access ; нормальное выполнениеExitProgram:call MessageBoxA, 0, offset szNoException, offset szCaption, 0 call ExitProcess, 0END WinMainPS. Применение этого макроса - самый простейший способ )) Жаль, что его нельзя применить в автоассемблере СЕ ) Впрочем, если постараться, то можно попробовать что-то подобное сделать. Надо подумать. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 24 июня, 2011 Автор Поделиться Опубликовано 24 июня, 2011 Я вот всё равно не пойму, когда исключение срабатывает при обращении к несуществующему адресу, то как определяется чему должен установиться EIP? Есть быстрый ответ? Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 24 июня, 2011 Поделиться Опубликовано 24 июня, 2011 Через стек. В макросе это видно. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 24 июня, 2011 Автор Поделиться Опубликовано 24 июня, 2011 Ты мне не смог помочь (даже не указал где это видно)... макросы меня путают. Я вытягивать информацию не люблю. Буду сам разбираться. Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 27 июня, 2011 Поделиться Опубликовано 27 июня, 2011 Отрывок из статьи, ссылку на которую давал выше:внутрипоточный обработчик исключенийЭтот тип обработчиков обычно используется для защиты некоторых локальных областей кода и устанавливается путем изменения значения, сохраненного системой в памяти по адресу FS:[0]. Каждый поток в вашей программе имеет свое уникальное значение в сегментном регистре FS, так что этот тип обработчиков исключений является поточно-зависимым. Он будет вызываться только в том случае, если исключение происходит во время выполнения кода, защищенного этим обработчиком.Значение в FS - 16-разрядный селектор, который указывает на "Блок информации Потока" ("Thread Information Block", TIB), - структуру, которая содержит важную информацию о каждом потоке. Самое первое двойное слово (DWORD) в TIB указывает на структуру, которую мы будем называть - структурой "ERR".Структура "ERR" состоит как минимум из двух двойных слов, как показано на следующей схеме:1st dword +0 Указатель на следующую структуру ERR (расположенную выше по цепочке).2nd dword +4 Указатель на имеющийся обработчик исключений.Установка внутрипоточного обработчика исключенийТеперь мы можем увидеть, как просто можно установить этот тип обработчиков исключений:Пример: PUSH OFFSET HANDLER PUSH FS:[0] ;Адрес следующей структуры ERR. MOV FS:[0],ESP ;Помещаем в FS:[0] адрес только что созданной структуры ERR. ... ... ;Здесь находится защищенный обработчиком код. ... POP FS:[0] ;Восстанавливаем в FS:[0] адрес предыдущей ERR, которая ;до этого была следующей в цепочке вверх после текущей ERR. ;Тем самым, мы удаляем текущий обработчик исключений. ADD ESP, 4h ; Очищаем стек от остатков ненужной нам более структуры ERR. RET ;*********************** HANDLER: ... ... ;Здесь находится код обработчика исключений. ... MOV EAX,1 ;Возможные возвращаемые значения и их описание: ;eax=1 исключение не было обработано (система вызовет ;следующий по цепочке внутрипоточный обработчик); ;eax=0 перезагрузить контекст и продолжить выполнение ;программы. RETИз этого отрывка следует, что при обработке исключений система передает управление на адрес, указанный в обработчике исключений потока. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 27 июня, 2011 Автор Поделиться Опубликовано 27 июня, 2011 Спасибо Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения