Хотел обратиться к Клерку насчет его движка. В общем, С++ протатипы кривые, но я их подогнал как надо. На х64 работать движок не будет, это я открыл америку Вопросы у меня, их 2. 1) Код (Text): DWORD status = IdpAddReference(&SomeReference,4); Я правильно понимаю, SpaceSize это размер референса ? 2) Код (Text): LONG __stdcall MyVEH(PEXCEPTION_POINTERS e) { //__asm{int 3} if(e->ExceptionRecord->ExceptionFlags!=NULL) { //non continuable exception return 0; } if(e->ExceptionRecord->ExceptionCode==IDP_BREAKPOINT) { return EXCEPTION_CONTINUE_EXECUTION; } /*if(e->ExceptionRecord->ExceptionCode==IDP_SINGLE_STEP) { }*/ return 0; } Если я правильно понимаю IDP_BREAKPOINT будет при исключении, после мне нужно заменить на правильный адресс,передать управление на мою функцию перехватчик, и в конце снова заменить референце, на то что поставил движок? И еще когда может сработать IDP_SINGLE_STEP?
#IDP_BREAKPOINT - возникло исключение при доступе к необходимому региону. Контекст изменён для отката фолта(после перезапуска инструкции она успешно отработает). Ip указывает на адрес инструкции вызвавшей фолт. #IDP_SINGLE_STEP - после перезапуска инструкции возникнет трассировочный останов. При этом происходит восстановление контекста(селекторов). Ip указывает на следующую инструкцию за той, которая вызвала фолт. Например: Ip: mov eax,dword ptr ds:[eax] Ip': В Eax должна быть ссылка на регион, допустим из диапазона [0x30000 % 0x31000], пусть 0x30123. Так как она разбита, то в Eax будет 0x123. Происходит обращение к сегменту с нулевой базой: 0:[0x123]. Это приводит к фолту. Двиг получает управление, определяет к какой области памяти произошло обращение, если к [0x30000 % 0x31000], то выбирает заранее созданный дескриптор необходимого сегмента и загружает его селектор в сегментные регистры. Тоесть Ds будет селектором LDT. Далее выполняется нотификация VEH с событием #IDP_BREAKPOINT. После возврата обращение происходит к исходному сегменту: 0x30000:[0x123], после исполнения инструкции возникает трас. останов и двиг вновь получает управление. Он сбрасывает TF и вызывает снова VEH с событием #IDP_SINGLE_STEP.
Спасибо за подробный ответ, буду обрабатывать данные при IDP_SINGLE_STEP, но еще про SpaceSize вопрос остался
Если нужно отслеживать доступ к региону [0x30000 % 0x31000], то размер его SpaceSize = 0x31000 - 0x30000. Это размер структуры адресуемой через ссылку.
Это мне понятно теперь, но зачем целый регион? Ну допустим мне нужен перехват функи, тогда перехват сработает на IDP_SINGLE_STEP, мне вообще не ебет какой размер там региона брать. Главное перехват, непонятно просто зачем вообще тогда нужно SpaceSize
Ip = f(Ptr), не наоборот. Размер нужен для опредедения целевого региона и создания дескриптора для него.
Ладно, короче достал сорсы завтра маны еще почитаю. Надо этот хитрый вопрос изучить. Клерк его на вирустеч рассматривал, правда там уже все подтерли.
Вся суть в равенстве Seg:[Offset] = Offset:[Seg]. Далее логически подумав вы придёте к полному пониманию вопроса.
Кстате тут пример просили по перехвату на с++. Создал свой простой примерчик, лень искать указатель в user32!MessageBox. Вот он: Код (Text): #include <Windows.h> #include "idp.h" LONG some=0x777; PLONG RepSome; LONG __stdcall MyVEH(PEXCEPTION_POINTERS e) { //__asm{int 3} if(e->ExceptionRecord->ExceptionFlags!=NULL) { //non continuable exception return 0; } if(e->ExceptionRecord->ExceptionCode==IDP_BREAKPOINT) { return EXCEPTION_CONTINUE_EXECUTION; } if(e->ExceptionRecord->ExceptionCode==IDP_SINGLE_STEP) { //код обработчика //__asm{int 3} MessageBox(0,L"Catched",0,0); return EXCEPTION_CONTINUE_EXECUTION; } return 0; } VOID Test() { int a = 34; a /= *RepSome; MessageBox(0,L"End Test()",0,0); } void main() { IdpInitializeEngine(); IdpAddVeh(NULL,MyVEH); RepSome = &some; //__asm{int 3} DWORD status = IdpAddReference(&RepSome,4); Test(); IdpRemoveVeh(MyVEH); }
Ну сделайте список указателей, в чём проблема-то? Кстати, КК как-то предлагал использовать старший бит указателя в качестве признака невалидности: обращение по ядерным адресам из лузер-мода будет также вызывать исключение, но отпадает необходимость хранить сам указатель. Клерку респекты конечно за техники.
19841204 то есть? В текущей реализации есть возможность перехватить сразу несколько АПИ функция? И вопрос к Клерку или КристалИС. Планируется порт под х64 системы? Насколько тяжело будет портануть под них? А то твой загрузчик длл из памяти помниться портил, было все нормально - возможно и IDP можно портануть?
ок, с работой и применением разобрались хоть и смутно. самый главный минус- один референс Код (Text): VOID Test(IN DWORD param1, IN DWORD param2) { int a = 34; a /= *RepSome; MessageBox(0,L"End Test()",0,0); } а если допустим такой код как добраться до параметров тут? Код (Text): if(e->ExceptionRecord->ExceptionCode==IDP_SINGLE_STEP) { //код обработчика //__asm{int 3} MessageBox(0,L"Catched",0,0); return EXCEPTION_CONTINUE_EXECUTION; }