Что значит инжектировать dll файл

Инжект DLL в современных Metro-приложениях

Ижект DLL – одна из самых старых техник, используемая для выполнения своего кода в приложениях в ОС Windows. Обычно этот метод используется для изменения стандартного поведения приложения или добавления нового функционала.

Ижект DLL – одна из самых старых техник, используемая для выполнения своего кода в приложениях в ОС Windows. Обычно этот метод используется для изменения стандартного поведения приложения или добавления нового функционала.

Инжект DLL в процесс – относительно простая задача: необходимо создать удаленный поток, где будет вызываться LoadLibrary, используя метод CreateRemoteThread или NtCreateThreadEx. Для получения доступа к инжектируемому процессу вам необходимы некоторые привилегии, однако их получение выходит за рамки этой статьи.

Когда вы попытаетесь инжектировать библиотеку в Metro-приложение в Windows 8, то обнаружите, что хотя инжектируемый код и работает корректно, ваша DLL НЕ загрузится. Метод LoadLibrary возвратит FALSE, и метод GetLastError возвратит ERROR_ACCESS_DENIED.

Ну, подумаете вы… Современные UI-приложения имеют ограниченные доступ к ресурсам системы и запускаются в «песочнице», так что подобные проблемы ожидаемы.

Во время исследования методов по добавлению нового функционала в приложение Windows Mail, поставляемое вместе Windows 8, и перехвату функций в современных UI-приложениях посредством Deviare, нам нужно выяснить, почему LoadLibrary возвращает FALSE.

На сцену выходит реверс-инжиниринг

Мы начнем с анализа метода LoadLibrary. Он вызывает LoadLibraryEx с dwFlags=0 и выполняет некоторые проверки. Первая остановка.

Если вы хотите загрузить упакованный объект (package), то должны использовать LoadPackagedLibrary API. Если вы хотите загрузить обычную DLL, то должны использовать LoadLibrary[Ex]. В документации на LoadPackagedLibrary говорится о том, что путь не может быть абсолютным или содержать «..», однако эти проверки в основном делаются в методе LoadLibraryEx. Единственное отличие между LoadLibrary и LoadPackagedLibrary — в параметре dwFlags, который равен 4 или 0.

Кроме того, LoadLibraryEx будет формировать поисковый путь для обнаружения DLL, а затем вызовет недокументированный метод LdrLoadDll. Поскольку мы хотим напрямую указать путь к библиотеке, то, соответственно, сразу будем вызывать метод LdrLoadDll.

Хотя LdrLoadDll корректно нашел DLL, при использовании SpyStudio для проверки ошибок, мы обнаружили, что при вызове метода NtOpenFile возникла ошибка STATUS_ACCESS_DENIED. Мы установили, что это проблема имеет отношение к безопасности.

Используя утилиту icacls.exe, мы установили дополнительные привилегии на DLL-файл, чтобы позволить чтение и запуск в процессах с низким уровнем достоверности (low integrity processes). Также мы добавили нового пользователя в Windows 8 с именем «ALL APPLICATION PACKAGES» в список пользователей с правами на чтение и запуск DLL-кода.

NtOpenFile выполнил начальные проверки безопасности, однако DLL все равно не загружена.

Продолжая исследовать LdrLoadDll, мы перешли в режим ядра из NtCreateSection API и выяснили, что функция CiValidateImageHeader библиотеки ci.dll возвращает ошибку STATUS_INVALID_IMAGE_HASH, после чего мы добавили цифровую подпись к файлу. Для предупреждения будущих проблем, вместо самоподписанного сертификата, мы использовали настоящий.

Теперь с функцией CiValidateImageHeader все ок, но далее функция CiValidateImageData возвращает ту же самую ошибку. Далее мы добавили параметр /ph при использовании утилиты SignTool.exe для включения страниц хэшей в подписываемый процесс.

Ну, подумали мы: теперь DLL подписана, с привилегиями все ок. Попробуем еще раз.

На этот раз камнем преткновения стала функция SeGetImageRequiredSigningLevel, которая находится в ntoskrnl.exe. SeGetImageRequiredSigningLevel проверяет минимальные требования к сертификату при загрузке DLL внутри WinRT-приложения.

Мы решили, что нужно подписать нашу DLL кросс-сертификатом, который используется для подписи драйверов режима ядра.

Исследования были остановлены, поскольку на данный момент у нас нет кросс-сертификата, однако мы обнаружили, что один из параметров ядра определяет, какой тип сертификата проверяется функцией SeGetImageRequiredSigningLevel.

В этом посте объясняется метод ручного обхода посредством WinDbg защитных проверок и запуска недостоверных приложений в устройстве Surface. Следуя схожей процедуре, мы можем обойти защитные проверки и корректно смапировать и заинжектить DLL в WinRT-приложениях в версии Windows для настольных ПК.

Перед началом нашего исследования, у нас уже был рабочий метод по инжекту DLL в WinRT-приложениях: нужно скопировать DLL-файл в папку System32. Хотя для этого и нужны права администратора, но в этом случае вы можете использовать метод LoadLibrary без указания пути к библиотеке, поскольку System32 является папкой, где по умолчанию происходит поиск библиотек. К тому же, поскольку вы используете относительный путь, некоторые проверки безопасности отменяются. Еще один плюс – вам не нужно подписывать файл!

Однако мы, как и множество компаний, хотим избежать разрастания папки System32 и храним файлы в той же директории, где находится приложения. Именно поэтому мы и начали наше исследование.

Источник

DLL Injection

DLL инъекция дает возможность выполнять свой код в адресном пространстве уже запущенного процесса. Многие используют инфицирования для написания читов для игр, выполнения вредоносных действий для системы и т.п. Но данный прием не обязательно применять для реализации коварных планов, а например, для обновления своего приложения.

Алгоритм работы очень просто, нам нужно создать поток в процессе и внедрить в него выполнения нашего кода. Для примера, мы инфицируем explorer.exe и выведем сообщение об этом.

Опишем структуру, через которую мы получим необходимые нам данные:

typedef FARPROC (WINAPI *LPMessageBox)(HWND, LPCWSTR, LPCWSTR, UINT);

typedef struct _InjectData <
char title[50];
char msg[50];
LPMessageBox MessageB;
> InjectData, *PInjectData;

static DWORD WINAPI InjectionMain(LPVOID lpParams) <

PInjectData info = (PInjectData)lpParams;

info->MessageB(NULL, (LPCWSTR)info->msg, (LPCWSTR)info->title, MB_OK);
return 0;
>

В нашем примере она довольно таки проста. В нем мы не выполняем подгрузку DLL, хотя для большинства задач вам это может быть необходимо, для этого необходимо передать указатели на ф-ции LoadLibrary и GetProcAddress, также как мы это делам для MessageBoxA, и при помощи их подгружать необходимые вам DLL.

Теперь нам нужно получить доступ к explorer.exe, записать наш код, данные в адресном пространстве процесса и создать поток в процессе для выполнения нашего кода.

Опишем ф-цию которая возвращает идентификатор процесса:

DWORD getProcessID() <
DWORD processID = 0;
HANDLE snapHandle;
PROCESSENTRY32 processEntry = <0>;

if ( (snapHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE ) <
return 0;
>

processEntry.dwSize = sizeof (PROCESSENTRY32);
Process32First(snapHandle, &processEntry);
do <
if ( wcscmp(processEntry.szExeFile, PROCESSNAME) == 0 ) <
return processEntry.th32ProcessID;
>
> while (Process32Next(snapHandle,&processEntry));

if ( snapHandle != INVALID_HANDLE_VALUE ) <
CloseHandle(snapHandle);
>

BOOL setPrivilege(HANDLE hToken, LPCTSTR szPrivName, BOOL fEnable) <
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
LookupPrivilegeValue(NULL, szPrivName, &tp.Privileges[0].Luid);
tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof (tp), NULL, NULL);
return ((GetLastError() == ERROR_SUCCESS));
>

Подробней о правах можете почитать здесь . Не смотря на то, что ответа за 1998 год он еще актуален для XP SP3 и насколько я знаю, для Windows 7, хотя лично еще не тестил.

Теперь у нас есть все для того, что бы получить доступ к процессу:

DWORD processID = getProcessID();
HANDLE hCurrentProc = GetCurrentProcess();

if (!OpenProcessToken(hCurrentProc, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) <
addLogMessage( «OpenProcessToken Error» , GetLastError());
return 0;
> else <
if (!setPrivilege(hToken, SE_DEBUG_NAME, TRUE)) <
addLogMessage( «SetPrivlegesSE_DEBUG_NAME Error» , GetLastError());
return 0;
>
>

if (processID == 0) <
MessageBox(NULL, _T( «Process not found!» ), _T( «Error» ), MB_OK | MB_ICONERROR);
return 0;
>

processHandel = OpenProcess(PROCESS_ALL_ACCESS, false , processID);

HINSTANCE userHinstance = LoadLibrary(_T( «user32.dll» ));
injectData.MessageB = (LPMessageBox) GetProcAddress(userHinstance, «MessageBoxA» );

LPVOID lpProc = VirtualAllocEx(processHandel, NULL, ProcSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
LPVOID lpParams = VirtualAllocEx(processHandel, NULL, 1024, MEM_COMMIT, PAGE_READWRITE );
DWORD dwWritten;
if (WriteProcessMemory(processHandel, lpProc, InjectionMain, ProcSize, &dwWritten ) == 0) <
addLogMessage( «WriteProcessMemory error» , GetLastError());
return 0;
>
if (WriteProcessMemory( processHandel, lpParams, &injectData, sizeof (injectData), &dwWritten ) == 0) <
addLogMessage( «WriteProcessMemory error» , GetLastError());
return 0;
>

VirtualAllocEx — предоставляет физическую память в виртуальном адресном пространстве процесса, а WriteProcessMemory записывает наши данные в память процесса.

Теперь создадим поток в процессе, который воплотит наш коварный план в жизнь:

DWORD ThreadID;
HANDLE hThread = CreateRemoteThread(processHandel, NULL, 0, (LPTHREAD_START_ROUTINE)lpProc, lpParams, 0, &ThreadID);
if (hThread == NULL) <
sprintf_s(buffer, «Error creating thread» );
addLogMessage(buffer, 1001);
>

Источник

Как Создают Инжекторы?

Часто ли вы используете инжектор для внедрения файлов? Каждый день? А вы знали что первые инжекторы DLL файлов появлялись в открытом доступе примерно в 2010 году, это больше 11 лет назад. В то время, загрузить эту программу было крайне сложно, так как их разработка только начиналась, и они были созданы в малом количестве, к тому же просто так делиться ценным скриптом никто не хотел. В наше время скачать Инжекторы можно совершенно бесплатно и без каких либо проблем, сегодня их существует огромное количество для разных игр и не только.

Что такое инжектор?
Для начала, давайте вспомним, что такое Injector? Инжектор — это не сложная программа для внедрения в запущенное приложение динамических .dll файлов, добавляя свои или изменяя готовые данные из оперативной памяти запущеного процесса. Чаще всего эта утилита используется для онлайн игр, так как для Offline развлечений изменить параметры проще. В основном с помощью инъекции, внедряют разные читы.

Как происходит инъекция?

  1. Запускается приложение, настройки которого будут изменяться путем внедрения DLL файла.
  2. Запущенный процесс, чаще всего игра, сворачивается и запускается инжектор.
  3. В скрипте для внедрения, выбирается нужная библиотека файла с расширением .dll, а также указывается путь к папке с .exe файлом запуска игры, в которую нужно внедрять скрипт.
  4. Нажимаем кнопку «Инжектить», после этого можно развернуть развлечение и увидеть изменения.

Как создают инжекторы?
Для создания простой программы инъекции, необходим компонент Visual Studio, в которой разработчик должен написать свой код для будущего скрипта. Вот пример кода для самого простого инжектора:
При компиляции этого простого кода, в настройках указывается многобайтовая кодировка, затем происходит протект готового файла для меньшей вероятности обнаружения антивирусами. На этом наш простой и рабочий скрипт успешно создан, осталось лишь им воспользоваться и попробовать внедрить какой-либо DLL в запущенное приложение.

Источник

Внедрение своего кода в адресное пространство процессов

Intro

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

В данной статье мы займемся созданием своего DLL инжектора. Что это такое, думаю, знают все. Такой способ внедрения стороннего кода достаточно популярен и удобен.

Писать DLL Injector мы будем на C++ в среде Microsoft Visual Studio 2010. Для создания динамически подключаемой библиотеки можно использовать любой инструмент, который вам по душе. Я же для создания библиотеки выбрал CodeGear RAD Studio 2009, язык Delphi( Object Pascal ).

Как же работает DLL Injection ?

Схема работы данного метода проста:

1) поиск и получение дескриптора нужного процесса
2) выделение памяти в процессе и последующая запись пути в DLL`ке по адресу, где произошло выделение памяти
3) создание нового потока в виртуальном пространстве процесса, дескриптор которого был получен.

Начнем с создания DLL.

Как я уже говорил, для этой цели будет использоваться язык Delphi:

Теперь добавим в DLL некоторые ресурсы, а именно — форму и кнопки для управления:

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

Теперь программируем интерфейс формы DLL. На форме есть две кнопки. Первая будет «убивать» родительский процесс( т.е процесс, в виртуальном пространстве которого был создан поток, в котором, в свою очередь, выполняется код DLL ). Вторая — рисовать 10 квадратов размером 25x25px в контексте всех окон приложения, принадлежащих процессу:

Исходный код интерфейсной части можно посмотреть здесь .

Тут все достаточно просто.
Итак, динамическая библиотека написана. Теперь компилируем ее и на выходе получаем скомпилированный файл с расширением «.dll», который можно переименовать для удобства. Я переименую библиотеку в «inj.dll».

Создание DLL завершено.
Осталось лишь скопировать нашу DLL`ку в системную директорию Windows, чтобы любое приложение могло отыскать её лишь по одному имени.

Переходим к разработке инжектора. Идем в Visual Studio и создаем Пустой проект( File->New->Project->Visual C++->General->Empty Project). Вся разработка будет производиться на «чистом» WinApi.

Первым делом создадим простейший визуальный интерфейс: форма, кнопка и текстовое поле. Выглядеть это будет примерно так:

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

Для инжекта DLL в адресное пространство процессов понадобятся следующие WinApi функции:

Итак, обдумаем, как же, собственно организовать «умную» архитектуру приложения, которая была бы понятной и простой.
Я предлагаю начать с обработки щелка по кнопке 🙂

Ок, далее, переходим к реализации функции

которая служит для поиска процесса по его имени:

И, наконец, завершающая процесс инжектирования функция

Полный код инжектора можно посмотреть здесь.

Тестируем работоспособность инжектора:

Сначала инжектимся «сами в себя». При клике на кнопку «Draw» происходит рисование 10 квадратов. При клике на «Crash it!» происходит немедленное завершение «родительского» процесса. Теперь попробуем инжектиться во что-нибудь посерьезнее, например, в браузер Mozilla Firefox. Для этого необходимо поменять лишь имя процесса в первом текстовом поле и нажать на кнопку:

Как видно, инжект успешно удался. Квадраты рисуются во всех окнах, принадлежащих родительскому процессу браузера. При нажатии на кнопку «Crash it!» Mozilla FireFox немедленно закрывается.

Outro

Для чего нам это вообще нужно? Ведь наша основная цель — это взлом( игр, софта ). Так вот в дальнейшем мы, наверняка, будем использовать этот инжектор для внедрения своего кода в чужое адресное пространство. Благодаря этому можно сэкономить немало времени, сил и нервов 🙂

Источник

Читайте также:  Что значит морально сломанный человек
Оцените статью