Вопрос по dll, c++ – Внедрение C ++ DLL

22

Я знаю, что есть различные вопросы и книги по этому вопросу, но я не могу внедрить мою 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 для процесса, который я пытаюсь внедрить (процесс запускается как администратор, а также), но он не внедряется. Когда я запускаю его, ничего не происходит, есть идеи?

Ваш код лишен какой-либо проверки ошибок, кроме OpenProcess. Поэтому убедитесь, что вы не знаете, почему это не работает. Hans Passant
@ Джимми Как бы я это проверил? Bali C
вы можете проверитьmsdn.microsoft.com/en-us/library/aa291232(v=VS.71).aspx или в качестве альтернативы запустить процесс от имени администратора Jimmy
ДелатьOutputDebugString вместоMessageBoxи проверьте это с помощью DebugView. Вы можете достичьMessageBox, но вы просто не можете видеть, как это правильно вызывается изDllMain. Roman R.
Вы проверили, что у вас есть разрешения (разрешения отладки), чтобы открыть процесс? Jimmy

Ваш Ответ

5   ответов
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;
}
Спасибо, rkosegi, я попробовал это, но это не сработало. У меня уже отключен UAC. Bali C
3

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

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

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

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

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

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

6

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

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

Спасибо, я не знал об ASLR. Есть ли ссылки, где я могу найти код, который будет делать это? Bali C
Эта логика реализована в загрузчике, что означает, что каждый раз, когда DLL отображается в адресном пространстве приложения загрузчиком. Это включает в себя библиотеки DLL, извлеченные путем связывания через библиотеки импорта (при запуске) или библиотеки DLL, загруженные через LoadLibrary () / LoadLibraryEx ().
Похоже, что рандомизация происходит только при запуске, верно?stackoverflow.com/questions/8568901/…
0

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

26

Не делай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 процесс.

ОБНОВИТЬ. Я поднимаю это из комментария: вот исходный код для проекта 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
Я добавил фрагмент кода, чтобы вы могли его попробовать (см. Выше)
+ #include <tchar.h>
Спасибо, но все равно нет радости. Я компилировал в CodeBlocks, пытался в VS, но все еще ничего не происходит. Нет ошибок, которые я вижу, просто нет сообщения. Bali C
Спасибо за ссылки, я должен создать функцию и вызвать функцию из DllMain тогда? Bali C
Компилятор не распознает_stprintf_s а также_T, Я пропускаю заголовок? Документы говорятstdio.h но я добавил это. Спасибо Bali C

Похожие вопросы