Внедрение C ++ DLL

Я знаю, что есть различные вопросы и книги по этому вопросу, но я не могу внедрить мою C ++ 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;
}

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

 Hans Passant07 июн. 2012 г., 14:56
Ваш код лишен какой-либо проверки ошибок, кроме OpenProcess. Поэтому убедитесь, что вы не знаете, почему это не работает.
 Bali C07 июн. 2012 г., 13:35
@ Джимми Как бы я это проверил?
 Jimmy07 июн. 2012 г., 14:21
вы можете проверитьmsdn.microsoft.com/en-us/library/aa291232(v=VS.71).aspx или в качестве альтернативы запустить процесс от имени администратора
 Jimmy07 июн. 2012 г., 12:58
Вы проверили, что у вас есть разрешения (разрешения отладки), чтобы открыть процесс?
 Roman R.11 июн. 2012 г., 16:03
ДелатьOutputDebugString вместоMessageBoxи проверьте это с помощью DebugView. Вы можете достичьMessageBox, но вы просто не можете видеть, как это правильно вызывается изDllMain.

Ответы на вопрос(5)

Учетная запись администратора не обязательно должна обладать привилегией 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;
}
 Bali C07 июн. 2012 г., 16:42
Спасибо, rkosegi, я попробовал это, но это не сработало. У меня уже отключен UAC.

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

Вот один наХукинг и DLL.

А такжедругой, Ипоиск Гугл для тебя.

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

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

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

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

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

 Bali C11 июн. 2012 г., 16:32
Спасибо, я не знал об ASLR. Есть ли ссылки, где я могу найти код, который будет делать это?
 24 мар. 2014 г., 22:41
Похоже, что рандомизация происходит только при запуске, верно?stackoverflow.com/questions/8568901/…
 25 мар. 2014 г., 00:16
Эта логика реализована в загрузчике, что означает, что каждый раз, когда DLL отображается в адресном пространстве приложения загрузчиком. Это включает в себя библиотеки DLL, извлеченные путем связывания через библиотеки импорта (при запуске) или библиотеки DLL, загруженные через LoadLibrary () / LoadLibraryEx ().

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

Решение Вопроса

Не делайMessageBox отDllMain, Зачем? Увидеть:

DLL_PROCESS_ATTACH failing to execute on Windows 7 C++ Some reasons not to do anything scary in your DllMain Don’t use standard library/CRT functions in static initializers/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 процесс.

ОБНОВИТЬ. Я поднимаю это из комментария: вот исходный код для проекта Visual Studio 2010, который делает это:SVN или жеTrac.

You put process identifier into source code The executable creates remote thread and loads library The library starts from DllMain and generates debug output DebugView shows you the output ProcessExplorer shows you the thread created, and you also have its identifier printed
 11 июн. 2012 г., 16:15
Я добавил фрагмент кода, чтобы вы могли его попробовать (см. Выше)
 11 июн. 2012 г., 16:31
+ #include <tchar.h>
 Bali C12 июн. 2012 г., 16:24
Спасибо, но все равно нет радости. Я компилировал в CodeBlocks, пытался в VS, но все еще ничего не происходит. Нет ошибок, которые я вижу, просто нет сообщения.
 Bali C11 июн. 2012 г., 16:13
Спасибо за ссылки, я должен создать функцию и вызвать функцию из DllMain тогда?
 Bali C11 июн. 2012 г., 16:26
Компилятор не распознает_stprintf_s а также_T, Я пропускаю заголовок? Документы говорятstdio.h но я добавил это. Спасибо

Ваш ответ на вопрос