Предотвратить инъекцию Dll из Dll C ++ - PullRequest
4 голосов
/ 26 февраля 2012

У меня есть некоторые сомнения по поводу анти-DLL инъекции в C ++. У меня есть игра на C ++, у меня проблемы с хакерами с DLL-инъекцией. Тогда мне нужно это предотвратить.

Я нахожу оттуда извещающий крюк:

MSDN - Хуки уведомлений

Но я понятия не имею, как его использовать.

Можно ли уведомить крючок для предотвращения инъекции DLL?

Как это возможно? (С и пример лучше).

Может быть из dll? (С примером лучше).

Спасибо, что прочитали этот пост.

PS: простите за мой английский.

Ответы [ 2 ]

6 голосов
/ 26 февраля 2012

Забудьте, если вы не делаете очень сложные вещи, это не сработает.Под сложным я подразумеваю что-то вроде обфускации кода, технологию анти-отладки, используемую в Skype.Просто посмотрите на этот разговор .

. Вы можете потратить кучу времени, пытаясь предотвратить инъекцию DLL, в конце концов, кто-то потратит меньше времени, чем вы, и обойдет вашу защиту.Я думаю, что было бы лучше потратить время на архитектуру, которая была бы более защищенной и защищенной от взлома (например, подсчет очков на сервере и т. Д.).

Это игра в кошки-мышки, в которую нельзя выиграть.

2 голосов
/ 20 декабря 2017

Этот вопрос старый, но я кратко отвечу на него в лучшей форме для тех, кто случайно наткнулся на него после правильного ответа.

Вы не можете полностью предотвратить внедрение кода из своего собственного процесса, ноВы можете попытаться сделать некоторые трюки без перехвата других процессов.Это не рекомендуется, потому что вам нужно иметь опыт и знания для задач более низкого уровня, особенно для того, чтобы он работал правильно и не мешал функционированию вашего собственного программного обеспечения, однако ...

Асинхронные вызовы процедур (APC) - этореализация из ядра Windows.Он в основном используется для внедрения кода в другие запущенные процессы, Windows сам использует его для множества вещей, таких как уведомления, отправляемые конкретным процессам.Когда процесс пользовательского режима вызывает QueueUserApc (KERNEL32), будет вызван NtQueueApcThread (NTDLL).NtQueueApcThread (NTDLL) выполнит системный вызов, который вызовет NtQueueApcThread (NTOSKRNL), который не экспортируется NTOSKRNL - для всех, кто интересуется, NTOSKRNL - это ядро ​​Windows, а системный вызов - не более чем переход от пользователя-режим в режиме ядра, так как системные подпрограммы API-интерфейса существуют в памяти режима ядра, подпрограммы NTDLL для NTAPI являются заглушками системных вызовов, которые управляют ядром Windows.Когда вызывается NtQueueApcThread (NTOSKRNL), он использует KeInitializeApc и KeInsertQueueApc (оба они экспортируются NTOSKNL).Когда APC фактически передается целевому процессу, KiUserApcDispatcher (NTDLL) будет вызываться локально внутри процесса, если только APC не выполняется более широким способом для обхода этого действия (99% времени это не будет предотвращено).Это означает, что у вас есть возможность перехватывать это поведение и предотвращать внедрение APC в ваш собственный процесс с помощью одного локального перехвата в вашем собственном процессе посредством байтового исправления (также известного как «inline hooking») KiUserApcDispatcher, экспортируемого NTDLL.Единственная проблема, с которой вы столкнетесь, заключается в том, что она недокументирована и официально не поддерживается Microsoft;вам нужно выяснить, как работают параметры и как предотвратить, чтобы подпрограмма обратного вызова блокировала подлинные запросы, необходимые для обеспечения функциональности вашего собственного программного обеспечения.Это, однако, будет включать предотвращение внедрения APC в режиме ядра, а не только атаки в пользовательском режиме.

Существует множество способов внедрения кода в процесс, и APC - просто один из них.Другой распространенный метод - создание удаленных потоков.Когда процесс пользовательского режима атакует другой процесс с помощью удаленного создания потока, он обычно вызывает CreateRemoteThread (KERNEL32).Это приведет к RtlCreateUserThread (NTDLL), а RtlCreateUserThread вызовет NtCreateThreadEx (NTDLL).NTDLL выполнит системный вызов, а затем NtCreateThreadEx (неэкспортированная подпрограмма из ядра Windows) будет вызвана в памяти режима ядра.В конце концов, у целевого процесса будет локально вызываться LdrInitializeThunk, а RtlUserThreadStart также будет вызываться локально.Обе эти процедуры экспортируются NTDLL.Это тот же сценарий, что и в случае с APC ... Вы можете исправлять LdrInitializeThunk локально, однако вы должны сделать это правильно, чтобы не допустить подлинную функциональность в вашем собственном программном обеспечении.

Эти два метода не являются полностью защищенными, нет«полное» решение.Есть много способов внедрить код в процесс, и есть очень сложные методы, чтобы обойти указанные решения от меня самого.Насколько я помню, антивирусная программа боролась с анти-RCE / самозащитой, как и анти-чит-системы.Вам следует также заняться разработкой драйверов устройств в режиме ядра, это позволит вам регистрировать обратные вызовы режима ядра, которые могут вам помочь.

Первый обратный вызов, на который вы должны обратить внимание: ObRegisterCallbacks . Это позволяет вам получать уведомление о обратном вызове перед операцией всякий раз, когда NtOpenProcess вызывается из ядра Windows. Это означает, что процессы пользовательского режима также будут запускать его, поскольку NtOpenProcess в конечном итоге вызывается в режиме ядра после того, как NTDLL выполнит системный вызов. Я не могу точно вспомнить, запускаются ли API-интерфейсы обратного вызова в самой заглушке NtOpenProcess или если она углубляется в процедуры Ob * только в режиме ядра, но вы можете легко проверить это с помощью WinDbg с удаленной отладкой ядра или с помощью Interactive Disassembler (target ntoskrnl.exe) и используйте символические ссылки, предоставленные Microsoft). ObRegisterCallbacks поддерживает уведомления для создания и дублирования дескриптора для процесса и потоков процессов, вы можете лишить права доступа, которые вы не хотите, разрешать для запрошенного дескриптора.

Второй обратный вызов, на который вы должны обратить внимание, будет PsSetCreateThreadNotifyRoutineEx . Эта процедура обратного вызова позволит вам получать уведомления всякий раз, когда в системе происходит создание нового потока; Вы можете отфильтровать его для своего собственного процесса, и, если создается мошенническая нить, прервать нить.

Третий обратный вызов, на который вы должны обратить внимание, будет PsSetLoadImageNotifyRoutineEx . Этот обратный вызов предоставит уведомление всякий раз, когда новый модуль загружается в процесс; еще раз, вы можете фильтровать для своего собственного процесса. Если вы обнаружите мошеннический модуль, вы можете попытаться, чтобы ваш вызов процесса LdrUnloadDll (NTDLL) был нацелен на базовый адрес вновь загруженного образа, однако счетчик ссылок для модуля должен быть равен 0, чтобы его можно было выгрузить. В этом случае вы можете попробовать "хакерские" методы, такие как вызов NtUnmapViewOfSection / NtFreeVirtualMemory. Имейте в виду, что если вы испортили мошеннический загруженный модуль, и он установил исправления байтов памяти, чтобы перенаправить поток выполнения к своим собственным подпрограммам, если вы не восстановите их, ваш процесс потерпит крах, когда на них будут ссылаться.

Это некоторые идеи, обычно те, которые обычно используются. Обратные вызовы в режиме ядра очень популярны среди программ безопасности и анти-чит-программ. Что касается создания потоков, вы будете заинтересованы в максимально возможном смягчении этого -> если вы будете искать только неконтролируемые загрузки DLL, то вам не хватит рефлексивной загрузки DLL. Также помните о других методах внедрения кода, таких как перехват потоков, использование памяти общего окна с использованием цепочки вызовов ROP, исправление DLL на диске и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...