![]() |
eXeL@B —› Программирование —› Перехват CreateProcess и внедрение с установкой перехватов |
Посл.ответ | Сообщение |
|
Создано: 27 июля 2009 03:46 · Поправил: multiarc · Личное сообщение · #1 Реализовывал ли кто-нибудь? может сразу дадите наставления по поводу... Интересует вариант в юзермод. Перехват ZwCreateUserProcess, ZwCreateProcess, ZwCreateProcessEx сами по себе результата не дают (нормального). Вариант ждать до самого вызова ZwResumeThread и прямо перед его вызовом делать внедрение. Но нет уверенности что именно тот ZwResumeThread который нам надо будет перехвачен, например из другого потока, при одновременном создании например 2 процессов из 2 разных потоков, или создание процесса в одном, а Resume в другом, или же вообще перехват ручного создания процесса... Подскажите если кто копал как быть, что перехватывать, что учитывать, чтобы сделать внедрение в новый только что созданные процесс. Интересует реализация в 2k8 (используется в основном ZwCreateUserProcess), XP (ZwCreateProcessEx), 2k3 (ZwCreateProcessEx), 2k0 (ZwCreateProcess). Видел где-то статью по поводу, но очень давно, если кто знает дайте ссылку) ![]() |
|
Создано: 27 июля 2009 09:56 · Личное сообщение · #2 |
|
Создано: 27 июля 2009 11:03 · Личное сообщение · #3 |
|
Создано: 27 июля 2009 12:36 · Личное сообщение · #4 |
|
Создано: 27 июля 2009 17:34 · Личное сообщение · #5 Есть подозрение, что проблемы возникают с загрузкой библиотек. Т.е., скажем, вешаемся на LoadLibrary. Но, если на процедуре инициализации (DllMain или как оно там) куда-то сохраняются адреса автоматически импортируемых функций, то дальше возникнут ошибки, если мы в импорте подменим эти функции. В LoadLibrary система подгружает библиотеку, заполняет таблицу импорта и сразу выполняет код инициализации. Если внимательно покопаться в исходниках (windows 2000), можно обнаружить, что в конечном итоге вызывается функция LdrLoadDll из ntdll.dll Да простит меня Майкрософт: NTSTATUS LdrLoadDll ( IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *DllHandle ) /*++ Routine Description: This function loads a DLL into the calling process address space. Arguments: DllPath - Supplies the search path to be used to locate the DLL. DllCharacteristics - Supplies an optional DLL characteristics flag, that if specified is used to match against the dll being loaded. DllName - Supplies the name of the DLL to load. DllHandle - Returns a handle to the loaded DLL. Return Value: TBD --*/ { return LdrpLoadDll(DllPath,DllCharacteristics,DllName,DllHandle,TRUE); } Видно, что вызывается некоторая (внутренняя, неэкспортируемая) функция LdrpLoadDll, имеющая заголовок: NTSTATUS NTAPI LdrpLoadDll( IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *DllHandle, IN BOOLEAN RunInitRoutines ) Последний параметр - выполнять ли процедуру инициализации после загрузки. В вызываемой функции LdrpLoadDll нужно найти место, где этот параметр проверяется, туда и внедряться. Это будет происходить после загрузки Dll, когда уже можно править адреса импортируемых функций для перехвата, но до того, как будет вызвана процедура, которая иначе сработала бы с неправленными адресами. ![]() |
|
Создано: 27 июля 2009 21:56 · Личное сообщение · #6 Nowar > В вызываемой функции LdrpLoadDll нужно найти место, где этот параметр проверяется, туда и внедряться. Таких мест два(без учёта вызова тлс) - LdrpCallInitRoutine(), или выполняющая нотификацию модулей LdrpRunInitializeRoutines(). Только вот попадёте вы на дедлок, когда тред будет ждать сам себя, критические секции никто не отменял. ![]() |
|
Создано: 28 июля 2009 14:17 · Личное сообщение · #7 Clerk пишет: Контекст получаем, регистр Eip содержит указатель на BaseProcessStartThunk(), она передаёт управление на пользовательский код, указатель на который в регистре Eax.Вот один из указателей заменяем на свой, загружаем свой модуль и возвращаем управление обратно. будет не мало танцев с бубном, ибо надо ждать загрузки, передавать управление обратно, менять контекст опять и запускать на выполнение вновь, лучше всего всё таки использовать APC для нотификации готовности процесса к внедрению. И ещё вопрос, если сразу кто знает, лень ковыряться в документации : если процессоров больше, чем 1, то APC будет выполняться вместе с потоком или всё таки поток подождёт выполнения APC и потом выполниться сам? По логике вещей он должен ждать выполнения APC. ?? ![]() |
|
Создано: 28 июля 2009 21:24 · Поправил: Clerk · Личное сообщение · #8 > будет не мало танцев с бубном Не вижу никаких проблем. Получаем контекст, записываем в Eax указатель на обработчик, оригинальный сохраняем например в Ebx, сохраняем контекст и всё. > если процессоров больше, чем 1, то APC будет выполняться вместе с потоком или всё таки поток подождёт выполнения APC и потом выполниться сам? > По логике вещей он должен ждать выполнения APC. ?? Поток не должен знать ничего о числе процессоров. Поток выполняет выполняет доставленную апк, комуже есчо её выполнять ![]() ![]() |
|
Создано: 28 июля 2009 22:00 · Поправил: multiarc · Личное сообщение · #9 Clerk пишет: Не вижу никаких проблем. Получаем контекст, записываем в Eax указатель на обработчик, оригинальный сохраняем например в Ebx, сохраняем контекст и всё. Я о том, что проще будет хукать ZwResumeThread, проверять тот ли поток, который нам надо, перед её выполнением делать внедрение, затем позволить выполниться ZwResumeThread. что-то вроде того : Code:
Вот что я имел ввиду про отсутсвие танцев с бубном... по-моему это немного проще, да и мало ли кому вздумается чего сделать с контекстом потока до того как он начал выполняться но после того как мы его например изменим похучив ZwCreateUserProcess. ![]() |
![]() |
eXeL@B —› Программирование —› Перехват CreateProcess и внедрение с установкой перехватов |