Подтвердить что ты не робот

Инъекция С++ DLL

Я знаю, что есть различные вопросы и книги по этому поводу, но я не могу заставить свою С++ DLL вставлять в любые процессы.

Код для вставки DLL:

#include <iostream>
#include "windows.h"

bool Inject(DWORD pId, char *dllName);

using namespace std;

int main()
{
    Inject(600, "C:\\d.dll");
    return 0;
}

bool Inject(DWORD pId, char *dllName)
{
    HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, false, pId);
    if(h)
    {
        LPVOID LoadLibAddr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
        LPVOID dereercomp = VirtualAllocEx(h, NULL, strlen(dllName), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        WriteProcessMemory(h, dereercomp, dllName, strlen(dllName), NULL);
        HANDLE asdc = CreateRemoteThread(h, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddr, dereercomp, 0, NULL);
        WaitForSingleObject(asdc, INFINITE);
        VirtualFreeEx(h, dereercomp, strlen(dllName), MEM_RELEASE);
        CloseHandle(asdc);
        CloseHandle(h);
        return true;
    }
    return false;
}

и DLL, которую я пытаюсь ввести:

#include <windows.h>
#include <stdio.h>

BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
switch (reason)
    {
      case DLL_PROCESS_ATTACH:
           MessageBox (0, "From DLL\n", "Process Attach", MB_ICONINFORMATION);
        break;

      case DLL_PROCESS_DETACH:
           MessageBox (0, "From DLL\n", "Process Detach", MB_ICONINFORMATION);
        break;

      case DLL_THREAD_ATTACH:
           MessageBox (0, "From DLL\n", "Thread Attach", MB_ICONINFORMATION);
        break;

      case DLL_THREAD_DETACH:
           MessageBox (0, "From DLL\n", "Thread Detach", MB_ICONINFORMATION);
        break;
    }

    return TRUE;
}

Я не знаю достаточно С++, чтобы узнать, где это происходит. Я запускаю Process Explorer в процессе, который я пытаюсь ввести (процесс запускается как администратор, а также), но он не вводится. Когда я запускаю его, ничего не происходит, никаких идей?

4b9b3361

Ответ 1

Не выполняйте MessageBox с DllMain. Зачем? См:

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

Здесь вам нужно положить OutputDebugString:

BOOL APIENTRY DllMain(HMODULE hModule, DWORD nReason, VOID* pvReserved)
{
    pvReserved;
    TCHAR pszMessage[1024] = { 0 };
    _stprintf_s(pszMessage, _T("GetCurrentProcessId() %d, hModule 0x%p, nReason %d\r\n"), GetCurrentProcessId(), hModule, nReason);
    OutputDebugString(pszMessage);
    /*switch(nReason)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }*/
    return TRUE;
}

Еще одна вещь, чтобы убедиться, что вы загружаете DLL правильной битности. Win32 DLL в процесс Win32 или x64 DLL в процесс x64.

UPDATE. Я помещаю это в комментарий: вот исходный код для проекта Visual Studio 2010, который делает следующее: SVN или Trac.

  • Вы помещаете идентификатор процесса в исходный код
  • Исполняемый файл создает удаленный поток и загружает библиотеку
  • Библиотека начинается с DllMain и генерирует отладочный вывод
  • DebugView показывает результат
  • ProcessExplorer показывает созданный поток, а также напечатан его идентификатор

Ответ 2

Проблема, с которой вы, вероятно, столкнулись, заключается в том, что адрес LoadLibraryA() в вашем приложении может не совпадать с целевым процессом из-за ASLR - технология, разработанная специально для предотвращения действий, которые вы пытаетесь сделать. Современные версии Windows (Vista +) по умолчанию включены для системных DLL

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

Ответ 3

Учетная запись администратора не обязательно должна владеть привилегией SE_DEBUG. Если вы работаете под управлением Vista/Win7, убедитесь, что UAC отключен. Используйте этот код, чтобы включить его, прежде чем пытаться открыть память процесса:

BOOL EnableDebugPrivilege()
{
    HANDLE hToken;
    LUID luid;
    TOKEN_PRIVILEGES tkp;

    if(!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ))
    {
        return FALSE;
    }

    if(!LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &luid ))
    {
        return FALSE;
    }

    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = luid;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if(!AdjustTokenPrivileges( hToken, false, &tkp, sizeof( tkp ), NULL, NULL ))
    {
        return FALSE;
    }

    if(!CloseHandle( hToken ))
    {
        return FALSE;
    }

    return TRUE;
}

Ответ 4

Я бы начал с кем-то другого рабочего примера и пошел оттуда. Примеры проектов, учебники и объяснения в CodeProject действительно прочны.

Вот один из Hooking и DLL.

И другое. И google search для вас.

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

Настройка UI-Access на true и наличие вашего исполняемого файла в C:/Program Files/, а также наличие вашей цифровой подписи dll помогает получить доступ к некоторым защищенным окнам в Windows. Вот статья в которой обсуждаются некоторые из этих вещей.

Надеюсь, что это поможет.

Ответ 5

SetWindowsHookEx также может вставлять вашу DLL в другой процесс.