Всем привет хотел так перехватывать некоторые апи установить SetUnhandledExceptionFilter глобальный оброботчик и писать в начало 0xCC но вот о чем подумалось допустим мы получили нотификацию EXCEPTION_BREAKPOINT case EXCEPTION_BREAKPOINT: { MessageBox(0, "Breakpoint found", NULL, 0); //replace with CLD for test breakaddr = ((BYTE*)(ContextRecord->Eip)); *breakaddr = 0xFC; // set single_step ContextRecord->EFlags |= 0x100; //ContextRecord->Eip++; return ExceptionContinueExecution; } case EXCEPTION_SINGLE_STEP: { MessageBox(0, "Stepped fine, time to reset breakpoint", NULL, 0); *breakaddr = 0xCC; // reset trap flag ContextRecord->EFlags &= ~(0x100); return ExceptionContinueExecution; } но после того как мы восстановим оригинальный байт взведем single step flag что если другой поток успеет в это время вызвать функцию и обойти хук пока мы не вернули 0xCC обратно ? а можно ли так ловим EXCEPTION_BREAKPOINT но не взводим single step flag и не восстанавливаем первый байт а просто изменяем eip на наш трамплин с первой инструкцией а он передаст управление уже второй инструкции внутри функции типа так case EXCEPTION_BREAKPOINT: { MessageBox(0, "Breakpoint found", NULL, 0); ContextRecord->Eip = trampoline; return ExceptionContinueExecution; } в итоге он вызовет трамплин трамплин функцию а функция вернет управление в юзер код откуда нас и вызвали можно ли так это безопасно в многопотоке ? [append] тута исходник полный http://www.rohitab.com/discuss/topic/36211-c-hooking-functions-with-breakpoints-and-seh/
Правильный ответ: можно. Вычисляете длину первой инструкции функции, например, сохраняете ее в буфере (для начала путь он будет полон nop'ов), который находится вслед за обработчиком перехваченной функции, в конце буфера с сохраненной инструкцией-прыжок на адрес следующий за этой первой инструкцией в функции, которую вы перезаписали на инт 3. Никаких проблем нет кроме одной. Сплайсенг с джампом на процедуру обработчика будет ничем не хуже ибо хоть так хоть эдак патч АП же.
ясно я примерно так и думал да мне это не принципиально единственное что я хотел выиграть это возможность перехватить функции размером меньше 5 байт вот заодно еще вопрос а интересно как нибудь можно отличить что экспортируемое имя из DLL это функция а не переменная ну кроме того что проверить адрес чтобы имел атрибут на выполнение но ведь и секции с данными могут дать такой атрибут я просто хотел автоматически в цикле пройтись по всему экспорту из какой нить DLL и прописать в начало каждой функции 0xCC но ведь если это будут данные то получится косяк вот и хотелось бы отличить я посмотрел несколько "нормальных" DLL там все экпортируемые данные лежат в секции .data и впринципе можно проверить что бы экпортируемый символ имел адрес с атибутом выполнение но еще вполне легально из секции .text экспортируются таблицы виртуальных функций например в msvcrt.dll поэтому можно просто запортачить хранимые в них адреса методов этим 0xCC да и вообщше если попадется не стандартная DLL с атрибутом execute в секции .data и экпортрующая пероеменные то проблем можно огрести по полной
Тру, то что вы начали использовать тф. Есчо немного размышления и вы придёте к отложенной передаче управления и маршрутизациям. Затем следует период отвращения к патчам и рассовая ненависть далее к патчам. Это нормальный процесс развития, мы прошли через это.