Я пишу трэйсер. В данный момент разрабатываю драйвер, который окучивает тестовое приложение. Сигналом к началу работы является int 3. После int 3 драйвер: * устанавливает флаг TF (меняет EFLAGS в стеке), и на все следующие до самой смерти потока команды генерируется int 1) * заменяет команду int 3 на команду nop - в реальных приложениях замена будет осуществляться на первый байт команды, затёртой int 3 (так же, как это, насколько я знаю, делают все отладчики). Все бы хорошо, но работает система только при первом запуске. На втором и последующих запусках выполнения команды int 3 не происходит. Тестовое приложение выглядит так: Code (Text): void printmem(unsigned char* p, int c) { printf("dump="); for(unsigned char* x=(unsigned char*)p;x<(unsigned char*)p + c;x++) printf("%.2X ", *x); printf("\n"); } int main() { unsigned char* p = NULL; __asm { call _nextline; _nextline: pop p; } printf("Before int3\n"); printmem(p, 0x40); __asm { nop; nop; int 3; } printf("After int3\n", p); printmem(p, 0x40); return 0; } то есть, оно дампит кусок main-а. При первом запуске наблюдаю, помимо прочего, 0x90 0x90 0xCC (соответствует ассемблерной вставке nop nop int 3) до, и 0x90 0x90 0x90 - после (мой обработчик int3 меняет 0xCC на 0x90). При втором запуске - 0x90 0x90 0x90 как до, так и после. Такое ощущение, что где-то как-то страницы, хранящие код тестового приложения закэшировались. Соответственно, вопрос - что это может быть, и как это побороть? Upd. Назвал тему, не очень хорошо подумав. PE-загрузчик тут, возможно, и не причем.
PE-загрузчик наверное действительно не виноват. Ошибка может быть в драйвере. И вот в чём может быть проблема: вот ты встретил int 3, и, возможно, запомнил где-то, что int 3 уже было, и ты затёр его nop'ом. Поскольку драйвер висит всё время в памяти, то при следующем запуске он уже int 3 не ловит. Вряд ли страницы закэшируются, но если это действительно произошло, то виноват механизм "Prefetching" (для ускорения запуска программ) и то, что при перезаписи памяти из драйвера его содержимое почему-то не обновляется. Но вряд ли оно так.
эта страница с кодом CC замененным на 90 считается не-модифицированной потому что есть такая штука Copy-on-Write - страница ставится как READ_ONLY а если туда идет запись то создается новая копия по исключению но драйвер пишет везде без возникновения исключения (если WP сброшен, но раз тебе пишется значит у тебя сброшен) поэтому система при перезагрузке страницы берет ее не из дискового файла (где CC есть) а из кеша где СС уже 90 для проверки поставь флаги на секцию кода - erw бороться кстати с этим тебе будет не так-то просто - VitrualProtect не экспортируется в ядре