пи%#"?ый WinAPI, е@$#ь!!! Задо%$@лся я уже писать отладчик. Все win-отладчики умеют останавливать процесс. Наверняка они это делают усыпляя все потоки (потому что DebugActiveProcessStop есть только в WinXP). Надо уметь усыплять и будить все потоки. Можно узнать список всех потоков отлаживаемого приложения через тулхелп, но в API нет ф-ии, которой можно было открыть поток по его ID. При создании нового потока система его открывает и возвращает через DEBUG_EVENT его хэндл. Поэтому можно создать динамический список потоков. А вот при завершении потока API не возвращает его хэндла - невозможно узнать - какой поток закончился и выбросить его из списка. Вот и спрашивается - как усыпить потоки и потом их разбудить. Неужели процесс НИКАК не может усыпить потоки другого процесса? Придется внедрять туда код и создавать удаленный поток?
AndreyMust19 Смотри: Код (Text): 00590A3F _NtSuspendProcess@4 mov edi,edi 00590A41 push ebp 00590A42 mov ebp,esp 00590A44 push ecx 00590A45 push esi 00590A46 mov eax,dword ptr fs:[124] 00590A4C mov al,byte ptr ds:[eax+140] 00590A52 push 0 00590A54 mov byte ptr ss:[ebp-4],al 00590A57 lea eax,dword ptr ss:[ebp+8] 00590A5A push eax 00590A5B push dword ptr ss:[ebp-4] 00590A5E push dword ptr ds:[493658] 00590A64 push 800 00590A69 push dword ptr ss:[ebp+8] 00590A6C call ntoskrnl.ObReferenceObjectByHandle 00590A71 mov esi,eax 00590A73 test esi,esi 00590A75 jl short ntoskrnl.00590A89 00590A77 push dword ptr ss:[ebp+8] 00590A7A call ntoskrnl._PsSuspendProcess@4 00590A7F mov ecx,dword ptr ss:[ebp+8] 00590A82 mov esi,eax 00590A84 call ntoskrnl.ObfDereferenceObject 00590A89 mov eax,esi 00590A8B pop esi 00590A8C leave 00590A8D ret 4 Далее: Код (Text): 00590903 _PsSuspendProcess@4 mov edi,edi 00590905 push ebp 00590906 mov ebp,esp 00590908 push ebx 00590909 push edi 0059090A mov edi,dword ptr ss:[ebp+8] 0059090D lea ebx,dword ptr ds:[edi+80] 00590913 mov ecx,ebx 00590915 call ntoskrnl.ExAcquireRundownProtection 0059091A test al,al 0059091C je short ntoskrnl.00590944 0059091E push esi 0059091F push 0 00590921 jmp short ntoskrnl.0059092C 00590923 /push 0 00590925 |push esi 00590926 |call ntoskrnl._PsSuspendThread@8 0059092B |push esi 0059092C push edi 0059092D |call ntoskrnl._PsGetNextProcessThread@8 00590932 |mov esi,eax 00590934 |test esi,esi 00590936 \jnz short ntoskrnl.00590923 00590938 mov ecx,ebx 0059093A call ntoskrnl.ExReleaseRundownProtection 0059093F xor eax,eax 00590941 pop esi 00590942 jmp short ntoskrnl.00590949 00590944 mov eax,C000010A 00590949 pop edi 0059094A pop ebx 0059094B pop ebp 0059094C ret 4 Тоесть сервис NtSuspendProcess перечисляет все потоки в процессе и суспендит их; далее чтобы вывести один потоков из спящего состояния можно выполнить NtResumeThread, никаких конфликтов с этим нет. Насчёт отладчика - можешь забыть про дебугапи, поток вызвавший NtContinue, NtRaiseException или NtSetContextThread выйдет из под отладки, далее он может отключить твой отладчик от своего процесса(NtRemoveProcessDebug) и будет выполняться уже вне отладчика, ИМХО из юзермода подобное словить невозможно
NtSuspendProcess и PsSuspendProcess есть только в WinXP. Есть чего-нибудь для совместимости с более ранними системами?
Описание нативапи тут: http://openfile.ru/200609/ Если не подходит, то делай слепок(системинфо) и перечисляй потоки и вручную суспенди Кстати вот скомпилел тестовый пример. Не используется ThreadHideFromDebugger(он тут не нужен).. > Не имеет значения трассировка, после вызова первого прерывания поток выйдет из под трассировки. > Отключает отладчик; далее завершение отладчика никак не скажется на процессе.
Фу, кое-как работает. Отладочный поток (тот, который начал отладку) не попадает в другие cpp-файлы. То есть он только занимается отладкой, а с интерфейсом общается посредством флажков (событий). Пока текущая версия умеет следующее: 1) Начинать / заканчивать отладку 2) Интерфейс отладчика может заморозить процесс / разморозить его Выкладываю проект кому интересно. Просьба - советовать по поводу внутреннего устройства dbg_core.cpp. Хочется сделать так, чтобы интерфейс программы (Main.cpp) и отладчик (dbg_core.cpp) были разъединены и интерфейс приказывал отладчику что-то сделать, вызывая его функции, а отладчик сообщал ему о событиях с помощью сообщений. Если не качается - скажите.
У меня конпилить это нету чем Вобщем как трейс сделоешь потести мою антиотладку, интересно продебажется оно или нет.
А-а-а! Тогда в уме компильни это. А твой OutsideOfDebugger.rar как проверить - надо саму программу трассировать или просто запустить и она расправится с чужой отладкой? Вот тебе exe-файл debug-версии моего проекта.
AndreyMust19 Та как хочешь так и проверяй, я так в уме дебажу ) [Не работоет, не понятно зачем ты запихал ажно 80 килобайт пустого места в файл.. Вот почитай тут 3k, но хоть дебажит немного: http://wasm.ru/pub/1/files/tut30.zip ]
Фу... прикрутил я все-таки дизассемблер к отладчику! Через dll. Теперь у меня такой вопрос: - Стоит ли разделить отладчик, код для работы с бряками и дизассемблер. Мне кажется что отладчик и код для работы с бряками лучше не разделять - будет больше мороки. А вот дизасм занести в отдельный cpp и h файлы.
Ты озверел? OpenThread Clerk Что ж ты ему ядро то советуешь. Оно тут не при чем. Из юзермода процесс суспендится перечислением всех тредов, открытием треда и суспендом каждого
Great Какое ядро.. я про сервис сказал вроде, а впрочем какая разница, всёравно работать не будет. Понравилось )
_DEN_ Great Проснулись! Теме уже месяц исполнился, а вы только увидели!!! _DEN_ Первый раз слышу о такой функции! Раньше слышал только о OpenThreadToken. Но... гляжу kernel32.dll - в таблице импорта есть OpenThread. Описание скачал. Так что... теперь кроме NtProcessSuspend можно будет суспендить потоки вручную. Ура! Вот еще вопрос по поводу срабатывания точек останова. После возникновения сообщения Exception_Breakpoint нужно: 1) проверить - совпадает ли адрес исключения с одной из установленных bp 2) Если да, то переместить ее на следующую команду 3) следующее срабатывание перемещенной bp проигнорировать, переместив ее на старое место Пункт 2 означает что без дизассемблера длин отладчику все же не обойтись. Как вариант можно не перемещать bp, а снять ее, войти в режим трассировки и при первом трассировочном исключении поставить bp назад. А вот можно ли как-то осуществить срабатывание bp без подобной мороки? И еще - в каком Intel Manual'е есть инфа про аппаратные брякпоинты?
MSoft Мда, описался, просто в просмотрщике написано - Imports/Exports, вот и написал неподумав. Описание скачал.