В статьях Ms Rem по перехвату апи говорится, что надо остановить все потоки перед установкой перехвата, нельзя ли создать критическую секцию и вней установить перехват?
Хочу уточнить, т.к. я не найду причин останавливать все потоки, кроме как если следить что бы eip потока не стал на первых 5-6 байтах процедуры. Если не делать эту проверку, то можно ведь реализовать через критическую секцию, быстрее будет работать и проще алгоритм?
Чето я нифига не понял суть этой идеи. Как можно синхронизироваться с помощью критической секции с чужим потоком, который про нее знать не знает, и тем более не думает ее захватывать. А при практическом применении перехвата апи лучше либо делать это еще до запуска процесса, что снимает необходимость в таких предосторожностях, либо вобще не делать никаких перехватов в зермоде (имхо лучший вариант).
Я имел в виду процедуру StopThreads, она останавливает все потоки в текущем процессе. Что если сделать так EnterCriticalSection->Установка перехвата ->LeaveCriticalSection. И еще один вопрос: как отловить момент, когда в адресном пространстве процесса загружена только ntdll.dll, что бы изменить у нее таблицу экспорта, таким образом установить перехват? Сейчас изучаю создание процесса ZwCreateProcess ZwCreateThread CsrClientCallServer в этот момент загружена ntdll.dll? ZwResumeThread
Да, но я пользовался немного другим методом. Хукаю ZwCreateThread, при ее вызове записываю код в новый процесс и меняю стартовый адрес первого потока на свой код. Потом в этом коде делаю спайсинг всего что мне нужно и вызываю оригинальную точку входа потока.
Ms Rem Ставлю MessageBox перед ZwResumeThread и смотрю через ProcessExplorer, показывает что в этот момент нет длл в целевом процессе. Так же пробовал сам перебирать все модули Код (Text): EnumModule proc uses ebx edi esi dwProcId:dword LOCAL me32:MODULEENTRY32 invoke CreateToolhelp32Snapshot,TH32CS_SNAPMODULE,dwProcId .if eax mov ebx,eax int 3 invoke Module32First,ebx,addr me32 .while eax mov eax,dwProcId .if eax==me32.th32ProcessID sstr_ me32.szModule .endif invoke Module32Next,ebx,addr me32 .endw invoke CloseHandle,ebx .endif ret EnumModule endp результат тот же. „в этот момент загружена ntdll.dll?“ Да, но я пользовался немного другим методом Поясни, плз, загружена ли в этот момент ntdll.dll
Я со сплайсингом разобрался по твоим статьям, спасибо. Хочу уточнить, что если кто-то еще установит перехват при помощи сплайсинга, только я пропишу jmp XXXX, а второй перехват push XXXX ret - ведь возникнет ошибка, не известно может после Jmp следует обрывок опкода, а второй перехватчик воспримит его как команду...
Хм, чето я тебя опять не понял. Какой обрывок опкода? То что следует после jmp это безразлично, так как все опкоды которые jmp перекрывает копируются и исполняются в отдельном буфере. Если перехватчики сделаны корректно (сделан пересчет смещений в командах содержащих rel32), то их можно друг на друга ставить любое число.
Если второй перехватчик пишет push XXXX ret и просто дизасемблирует длины команд, не анализируя содержимого, т.е. сохраняет первые 6 байт Jmp XXXX - 5байт db 123 ;например он воспримит db 123 как какую-то команду, и при вызове целевой апи - выполнит ее, что приведет к завершению процесса Я имею в виду если второй перехватчик использует другой алгоритм перехвата, то возможны ошибки. Еще идея у меня, что если перехватывать ZwWriteVirtualMemory ZwProtectVirtualMemory и блокировать доступ к перехваченным тобой апи.
Еще один вопрос на который не могу ответить Создаю процесс средствами ntdll.dll в XP (пример из Неббета) и CsrClientCallServer возвращает invalid_handle. Скажи в чем может быть дело? Может в 2k и в XP разные константы передаются в эту процедуру, т.к. я в kernel32.dll смотрел, там совсем другие числа. И не совпадает определение структуры(csr, первый параметр в CsrClientCallServer) в неббете и в kernel32(может опечатка в книге?) разница в 4 байта. Можешь глянуть
Ошибки от кривых рук всегда возможны. Ты там создаешь поток а не процесс, а csrss при этом информируется по разному. По части информирования о создании процесса, константы и структуры одинаковы по крайней мере в 2000 и XP, а вот с потоками они различаются. Все зависит от того, для чего тебе нужен поток. Если просто исполнять код, то csrss информировать не нужно, а если нужен полноценный win32 поток, то лучше пользуйся функциями kernel32 а не занимайся ерундой. Если нужно запустить юзермодный код из ядра, то используй APC.
"Ты там создаешь поток а не процесс" да, просто ошибки именно в создании потока. Спасибо за консультацию Заказал книгу Соломон, Русинович "Внутреннее устройство 2003 XP 2k" там все это почитаю
Ms Rem "...сделан пересчет смещений в командах содержащих rel32..." Я с твоего сайта качал калькулятор длин команд, там видел флаг OP_REL32, кажется это то что мне надо, как его использовать?