Вот столкнулся с такой проблемой: При перехвате NtCreateThread я получаю уведомление не только тогда, когда один процес создает поток в другом процессе (через CreateRemoteThread), но и еще когда один процесс запускает другой. Причем в последнем случае (для любых процессов) этот адрес = 7C8106F5 (адресное пространство Kernel32.dll) Функция не экспортируемая. Судя по исходникам w2k - это BaseProcessStartThunk Т.е. получается для различия необходимо тока найти адрес BaseProcessStartThunk и с ним сравнивать, а вот как его найти? Или есть другой метод распознавания?
Не понял, тебе нужно отличить запуск первого родного потока в процессе от внедрения чужого потока? Если так, тогда почему бы просто не запросить кол-во потоков целевого процесса и сравнить с 0, например?
или к примеру когда в импорте программы есть DLL которая при своей инициализации запускает парочку потоков. Так что по кол-ву потоков - как-то не то будет.
Посмотрев исходники w2k то выясняется довольно печальный факт: И при CreateRemoteThread и при CreateProcessW вызывается NtCreateThread, где в контексте EIP = адресу промежуточной функции BaseThreadStartThunk - при создание потока и BaseProcessStartThunk при создании процесса. По всем другим показателям, данные практически одинаковы. Так что для того чтобы отличить создание основного потока программы от внедрения чужого потока нужно знать адреса BaseProcessStartThunk и BaseThreadStartThunk Но всё равно это не решает проблему. Потому как можно вызвать NtCreateThread со специальными параметрами, которые будут выглядеть также как и вызов при создании основного потока. Вообще основная идея такая: Необходимо однозначно определить факт внедрения чужого потока.
slesh А если вызывается RtlCreateUserProcess(), а из неё RtlCreateUserThread() ? Решение должно быть универсальным, тоесть не связано с контекстом. Можно выполнить развёртку стека(бактрейс), определив родительскую апи, но также поток процесс может быть создан вручную, без всяких внешних апи, кроме сервисов. Возможный вариант, собственно таким образом в юзермоде и детектились когдато удалённые потоки - SystemObjectInformation.CreatorProcessId, это позволяет найти родитель обьекта, причём нужна перезагрузка для установки некоторых флажков в реестре(динамически это выполнить невозможно даже из ядра). Я бы поступил так: перечисляем все потоки процесса, которому принадлежит текущий и определяем время их создания. Основываясб на том факте, что время создания обьекта уникально и его нельзя изменить(в юзере разумеется), мы легко можем найти первый поток.
Помог товариш Great ) Чуть запутался в ходе запуска процесса, по этому по ошибке думал что до первого потока чтото может быть запущено уже. Решение нашел простое: Получать KernelTime и UserTime для приложения в котором запускается поток. При создании процесса они равны 0.
slesh Неверное решение. Если создать процесс с остановленным потоком и есчо несколько потоков, то выполнять инициализацию процесса бедет не тот, который создан первым, а тот который начнёт исполняться первым
Для меня тут важно именно, чтобы нельзя было создать поток в уже работающем приложении. Так что для этих целей, метод подходит.
2 Clerk ну тут и не должна быть особо серьезная защита. + еще парочка защиты от изменения контекста и записи в память. Хотя у меня будет мониторится загрузка драйвера, реестр, открытие физ памяти, работа с памятью ядра через NtSystemDebugControl. Так что для данного проекта будет достаточно. Ring0 эксплоиты во внимания не берутся, потому как это отдельная тема.
Ага. Что-то типо проактивной защиты. Но для спец целей, по этому не требуется высокой надежности и тем более конкуренции существующим продуктам )
2 karabas_barabas откуда такой негатив? Я же сказал - спец цель! т.е. не для продажи и не для какой-либо другой коммерческой выгоды.
Так. Обсуждения "для чего это надо, кто это купит" выходит за рамки этого раздела. Уважайте друг друга. Для всех разъяснений есть личка.
TermoSINteZ Модеров ведь можно поменять.. Если нечего сказать, то не встревайте. На форуме общаются люди, помните.