Сейчас на форуме: tyns777, zds, JustLife, 2nd, morgot, Rio (+5 невидимых)

 eXeL@B —› Программирование —› Перехват CreateProcess и внедрение с установкой перехватов
Посл.ответ Сообщение


Ранг: 58.1 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 27 июля 2009 03:46 · Поправил: multiarc
· Личное сообщение · #1

Реализовывал ли кто-нибудь? может сразу дадите наставления по поводу... Интересует вариант в юзермод. Перехват ZwCreateUserProcess, ZwCreateProcess, ZwCreateProcessEx сами по себе результата не дают (нормального). Вариант ждать до самого вызова ZwResumeThread и прямо перед его вызовом делать внедрение. Но нет уверенности что именно тот ZwResumeThread который нам надо будет перехвачен, например из другого потока, при одновременном создании например 2 процессов из 2 разных потоков, или создание процесса в одном, а Resume в другом, или же вообще перехват ручного создания процесса... Подскажите если кто копал как быть, что перехватывать, что учитывать, чтобы сделать внедрение в новый только что созданные процесс. Интересует реализация в 2k8 (используется в основном ZwCreateUserProcess), XP (ZwCreateProcessEx), 2k3 (ZwCreateProcessEx), 2k0 (ZwCreateProcess).
Видел где-то статью по поводу, но очень давно, если кто знает дайте ссылку)



Ранг: 481.4 (мудрец), 109thx
Активность: 0.180
Статус: Участник
Тот самый :)

Создано: 27 июля 2009 09:56
· Личное сообщение · #2

PsSetCreateProcessNotifyRoutine нет?

-----
Реверсивная инженерия - написание кода идентичного натуральному





Ранг: 58.1 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 27 июля 2009 11:03
· Личное сообщение · #3

Нужен юзермод и внедрение после инициализации всех библиотек, т.е. перед самым вызовом ZwResumeThread



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 27 июля 2009 12:36
· Личное сообщение · #4

Контекст получаем, регистр Eip содержит указатель на BaseProcessStartThunk(), она передаёт управление на пользовательский код, указатель на который в регистре Eax.
Вот один из указателей заменяем на свой, загружаем свой модуль и возвращаем управление обратно.



Ранг: 13.7 (новичок)
Активность: 0.010
Статус: Участник

Создано: 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, когда уже можно править адреса импортируемых функций для перехвата, но до того, как будет вызвана процедура, которая иначе сработала бы с неправленными адресами.



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 27 июля 2009 21:56
· Личное сообщение · #6

Nowar
> В вызываемой функции LdrpLoadDll нужно найти место, где этот параметр проверяется, туда и внедряться.
Таких мест два(без учёта вызова тлс) - LdrpCallInitRoutine(), или выполняющая нотификацию модулей LdrpRunInitializeRoutines(). Только вот попадёте вы на дедлок, когда тред будет ждать сам себя, критические секции никто не отменял.




Ранг: 58.1 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 28 июля 2009 14:17
· Личное сообщение · #7

Clerk пишет:
Контекст получаем, регистр Eip содержит указатель на BaseProcessStartThunk(), она передаёт управление на пользовательский код, указатель на который в регистре Eax.Вот один из указателей заменяем на свой, загружаем свой модуль и возвращаем управление обратно.

будет не мало танцев с бубном, ибо надо ждать загрузки, передавать управление обратно, менять контекст опять и запускать на выполнение вновь, лучше всего всё таки использовать APC для нотификации готовности процесса к внедрению. И ещё вопрос, если сразу кто знает, лень ковыряться в документации : если процессоров больше, чем 1, то APC будет выполняться вместе с потоком или всё таки поток подождёт выполнения APC и потом выполниться сам? По логике вещей он должен ждать выполнения APC. ??



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 28 июля 2009 21:24 · Поправил: Clerk
· Личное сообщение · #8

> будет не мало танцев с бубном
Не вижу никаких проблем. Получаем контекст, записываем в Eax указатель на обработчик, оригинальный сохраняем например в Ebx, сохраняем контекст и всё.
> если процессоров больше, чем 1, то APC будет выполняться вместе с потоком или всё таки поток подождёт выполнения APC и потом выполниться сам?
> По логике вещей он должен ждать выполнения APC. ??
Поток не должен знать ничего о числе процессоров.
Поток выполняет выполняет доставленную апк, комуже есчо её выполнять




Ранг: 58.1 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 28 июля 2009 22:00 · Поправил: multiarc
· Личное сообщение · #9

Clerk пишет:
Не вижу никаких проблем. Получаем контекст, записываем в Eax указатель на обработчик, оригинальный сохраняем например в Ebx, сохраняем контекст и всё.

Я о том, что проще будет хукать ZwResumeThread, проверять тот ли поток, который нам надо, перед её выполнением делать внедрение, затем позволить выполниться ZwResumeThread. что-то вроде того :
Code:
  1. typedef struct{
  2.     ULONG Length;
  3.     ULONG Unknown1;
  4.     ULONG Unknown2;
  5.     PWSTR pwsImageFileName;
  6.     ULONG Unknown4;
  7.     ULONG Unknown5;
  8.     ULONG Unknown6;
  9.     PCLIENT_ID pcidClient;
  10.     ULONG Unknown8;
  11.     ULONG Unknown9;
  12.     ULONG Unknown10;
  13.     ULONG Unknown11;
  14.     ULONG Unknown12;
  15.     ULONG Unknown13;
  16.     ULONG Unknown14;
  17.     ULONG Unknown15;
  18.     ULONG Unknown16;
  19. }PROCESS_UNKNOWN, *PPROCESS_UNKNOWN;
  20.  
  21. CallBackHook_ZwCreateUserProcess(
  22.          PHANDLE ProcessHandle,
  23.          PVOID Parameter1,
  24.          PVOID Parameter2,
  25.          PVOID Parameter3,
  26.          PVOID ProcessSecurityDescriptor,
  27.          PVOID ThreadSecurityDescriptor,
  28.          PVOID Parameter6,
  29.          PVOID Parameter7,
  30.          PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
  31.          PVOID Parameter9,
  32.          PPROCESS_UNKNOWN ppuUnknown
  33.          )
  34. {
  35.    //ZwCreateUserProcess сама создаёт ещё и поток. Тут сохраняем CLIENT_ID ентого процесса
  36. }
  37.  
  38. Hook_ZwResumeThread(
  39.          HANDLE  ThreadHandle,
  40.          PULONG  SuspendCount
  41.          )
  42. {
  43.    //получаем TID, смотрим в списке, если таковой имеется, 
  44.    //внедряемся, удаляем CLIENT_ID из списка и позволяем затем выполниться настоящей ZwResumeThread
  45. }

Вот что я имел ввиду про отсутсвие танцев с бубном... по-моему это немного проще, да и мало ли кому вздумается чего сделать с контекстом потока до того как он начал выполняться но после того как мы его например изменим похучив ZwCreateUserProcess.


 eXeL@B —› Программирование —› Перехват CreateProcess и внедрение с установкой перехватов
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати