Как написать dll, которая выскакивает в сообщении? - PullRequest
0 голосов
/ 25 апреля 2020

Ну, в основном мне нужно написать DLL на C ++, которую я вставлю в notepad.exe. Предполагается, что эта DLL откроет всплывающее сообщение или окно с моим именем в нем. Проблема в том, что я немного новичок с DLL, и я начал неделю go. У меня проблемы с открытием окна или сообщения с помощью DLL, используя "windows .h". Я пытался использовать MessageBox, но он не работает.

это мой инжектор, из которого я взял: https://www.fxp.co.il/showthread.php?t=15051062

#include <iostream>
#include <direct.h>
#include <windows.h>
#include <Tlhelp32.h>

LPCTSTR SzToLPCTSTR(char* szString);
char* GetCurrentDir();
void WaitForProcessToAppear(LPCTSTR lpcszProc, DWORD dwDeley);
DWORD GetProcessIdByName(LPCTSTR lpcszProc);
BOOL InjectDll(DWORD dwPid, char* szDllPath);

int main()
{
    char szProc[MAX_PATH], szDll[MAX_PATH];
    char* szDllPath = (char*)malloc(MAX_PATH);
    LPTSTR lpszProc = NULL;
    while (true)
    {
        std::cout << "Process: ";
        std::cin >> szProc;
        std::cout << "DLL Injection: ";
        std::cin >> szDll;
        szDllPath = GetCurrentDir();
        strcat_s(szDllPath, MAX_PATH, "\\");
        strcat_s(szDllPath, MAX_PATH, szDll);
        std::cout << "Waiting for process..." << std::endl;
        WaitForProcessToAppear(SzToLPCTSTR(szProc), 100);
        if (InjectDll(GetProcessIdByName(SzToLPCTSTR(szProc)), szDllPath)) std::cout << "Injection succeeded!" << std::endl;
        else  std::cout << "Injection failed!" << std::endl;
        std::cout << "\n";
    }
    return 0;
}

char* GetCurrentDir()
{
    char* szRet = (char*)malloc(MAX_PATH);
    _getcwd(szRet, MAX_PATH);
    return szRet;
}
LPCTSTR SzToLPCTSTR(char* szString)
{
    LPTSTR lpszRet;
    size_t size = strlen(szString) + 1;
    lpszRet = (LPTSTR)malloc(MAX_PATH);
    mbstowcs_s(NULL, lpszRet, size, szString, _TRUNCATE);
    return lpszRet;
}
void WaitForProcessToAppear(LPCTSTR lpcszProc, DWORD dwDeley)
{
    HANDLE hSnap;
    PROCESSENTRY32 peProc;
    BOOL bAppeared = FALSE;
    while (!bAppeared)
    {
        if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
        {
            peProc.dwSize = sizeof(PROCESSENTRY32);
            if (Process32First(hSnap, &peProc))
                while (Process32Next(hSnap, &peProc) && !bAppeared)
                    if (!lstrcmp(lpcszProc, peProc.szExeFile))
                        bAppeared = TRUE;
        }
        CloseHandle(hSnap);
        Sleep(dwDeley);
    }
}
DWORD GetProcessIdByName(LPCTSTR lpcszProc)
{
    HANDLE hSnap;
    PROCESSENTRY32 peProc;
    DWORD dwRet = -1;
    if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
    {
        peProc.dwSize = sizeof(PROCESSENTRY32);
        if (Process32First(hSnap, &peProc))
            while (Process32Next(hSnap, &peProc))
                if (!lstrcmp(lpcszProc, peProc.szExeFile))
                    dwRet = peProc.th32ProcessID;
    }
    CloseHandle(hSnap);
    return dwRet;
}
BOOL InjectDll(DWORD dwPid, char* szDllPath)
{
    DWORD dwMemSize;
    HANDLE hProc;
    LPVOID lpRemoteMem, lpLoadLibrary;
    BOOL bRet = FALSE;
    if ((hProc = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD, FALSE, dwPid)) != NULL)
    {
        dwMemSize = strlen(szDllPath) + 1;
        if ((lpRemoteMem = VirtualAllocEx(hProc, NULL, dwMemSize, MEM_COMMIT, PAGE_READWRITE)) != NULL)
            if (WriteProcessMemory(hProc, lpRemoteMem, (LPCVOID)szDllPath, dwMemSize, NULL))
            {
                lpLoadLibrary = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
                if (CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadLibrary, lpRemoteMem, 0, NULL) != NULL)
                    bRet = TRUE;
            }
    }
    CloseHandle(hProc);
    return bRet;
}

И это моя DLL:

#include <windows.h>

BOOL WINAPI DllMain( HMODULE hModule,
                       DWORD  fdwReason,
                       LPVOID lpvReserved
                     )
{
    if (fdwReason == DLL_PROCESS_ATTACH)
        MessageBox(NULL, L"Injected by Matan Oshri", L"Hello World", MB_OK);
    return TRUE;
}

Пожалуйста, дайте мне знать, если увидите какую-либо ошибку. Я ценю всю помощь, которую я могу получить. Спасибо.

1 Ответ

0 голосов
/ 27 апреля 2020

Сначала я могу внедрить DLL с примером кода, убедитесь, что Dll, injector.exe и notepad.exe находятся в одинаковых битах (как правило, notepad.exe начинается с 64-разрядной версии). Я получаю код ошибки = 5, если я использую 32-битные DLL или injector.exe с 64-битными notepad.exe

Секунда, согласно документу CreateRemoteThread :

hProcess

Дескриптор процесса, в котором должен быть создан поток. Дескриптор должен иметь PROCESS_CREATE_THREAD , PROCESS_QUERY_INFORMATION , PROCESS_VM_OPERATION , PROCESS_VM_WRITE и права доступа PROCESS_VM_RE 1026 * может не работать без этих прав на определенных платформах . Для получения дополнительной информации см. Безопасность процесса и Права доступа .

(Хотя приведенный выше пример работает для меня без PROCESS_QUERY_INFORMATION и PROCESS_VM_READ )

В-третьих, есть что-то, что стоит улучшить в вашем коде:

char* szDllPath = (char*)malloc(MAX_PATH);
szDllPath = GetCurrentDir();
/*{
char* szRet = (char*)malloc(MAX_PATH);
_getcwd(szRet, MAX_PATH);
return szRet;
}*/

Это приведет к утечке памяти первого приложения.

LPCTSTR SzToLPCTSTR(char* szString);

Мы можем использовать строку Unicode напрямую.

пример:

#include <iostream>
#include <direct.h>
#include <windows.h>
#include <Tlhelp32.h>

//LPCWSTR SzToLPCTSTR(char* szString);
//char* GetCurrentDir();
void WaitForProcessToAppear(LPCWSTR lpcszProc, DWORD dwDeley);
DWORD GetProcessIdByName(LPCWSTR lpcszProc);
BOOL InjectDll(DWORD dwPid, LPCWSTR szDllPath);

int main()
{
    while (true)
    {
        std::wstring szProc, szDll;
        std::wstring szDllPath;
        std::wcout << L"Process: ";
        std::wcin >> szProc;
        std::wcout << L"DLL Injection: ";
        std::wcin >> szDll;
        WCHAR dir[MAX_PATH] = { 0 };
        GetCurrentDirectoryW(MAX_PATH, dir);
        szDllPath = dir;
        szDllPath += L"\\";
        szDllPath += szDll;

        std::wcout << L"Waiting for process..." << std::endl;
        WaitForProcessToAppear(szProc.c_str(), 100);
        if (InjectDll(GetProcessIdByName(szProc.c_str()), szDllPath.c_str())) std::wcout << L"Injection succeeded!" << std::endl;
        else  std::wcout << L"Injection failed!" << std::endl;
        std::wcout << L"\n";
    }
    return 0;
}

//char* GetCurrentDir()
//{
//    char* szRet = (char*)malloc(MAX_PATH);
//    _getcwd(szRet, MAX_PATH);
//    return szRet;
//}
//LPCWSTR SzToLPCTSTR(char* szString)
//{
//    LPTSTR lpszRet;
//    size_t size = strlen(szString) + 1;
//    lpszRet = (LPTSTR)malloc(MAX_PATH);
//    mbstowcs_s(NULL, lpszRet, size, szString, _TRUNCATE);
//    return lpszRet;
//}
void WaitForProcessToAppear(LPCWSTR lpcszProc, DWORD dwDeley)
{
    HANDLE hSnap;
    PROCESSENTRY32 peProc;
    BOOL bAppeared = FALSE;
    while (!bAppeared)
    {
        if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
        {
            peProc.dwSize = sizeof(PROCESSENTRY32);
            if (Process32First(hSnap, &peProc))
                while (Process32Next(hSnap, &peProc) && !bAppeared)
                    if (!lstrcmp(lpcszProc, peProc.szExeFile))
                    {
                        bAppeared = TRUE;
                        break;
                    }
        }
        CloseHandle(hSnap);
        Sleep(dwDeley);
    }
}
DWORD GetProcessIdByName(LPCWSTR lpcszProc)
{
    HANDLE hSnap;
    PROCESSENTRY32 peProc;
    DWORD dwRet = -1;
    if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
    {
        peProc.dwSize = sizeof(PROCESSENTRY32);
        if (Process32First(hSnap, &peProc))
            while (Process32Next(hSnap, &peProc))
                if (!lstrcmp(lpcszProc, peProc.szExeFile))
                {
                    dwRet = peProc.th32ProcessID;
                    break;
                }
    }
    CloseHandle(hSnap);
    return dwRet;
}
BOOL InjectDll(DWORD dwPid, LPCWSTR szDllPath)
{
    DWORD dwMemSize;
    HANDLE hProc;
    LPVOID lpRemoteMem, lpLoadLibrary;
    BOOL bRet = FALSE;
    if ((hProc = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, dwPid)) != NULL)
    {
        dwMemSize = (wcslen(szDllPath) + 1) * sizeof(WCHAR);
        if ((lpRemoteMem = VirtualAllocEx(hProc, NULL, dwMemSize, MEM_COMMIT, PAGE_READWRITE)) != NULL)
            if (WriteProcessMemory(hProc, lpRemoteMem, (LPCVOID)szDllPath, dwMemSize, NULL))
            {
                lpLoadLibrary = GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW");
                if (CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadLibrary, lpRemoteMem, 0, NULL) != NULL)
                    bRet = TRUE;
            }
    }
    CloseHandle(hProc);
    return bRet;
}

Наконец, в соответствии с ограничениями в DllMain:

  • Вызов функций в User32.dll или Gdi32.dll. Некоторые функции загружают другую DLL, которая не может быть инициализирована.

Вы не можете использовать MessageBox в DllMain, но вы можете использовать OutputDebugStringW вместо того, чтобы показать сообщение, и использовать DebugView для проверки строки отладки. DLL:

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        OutputDebugStringW(L"Injected DLL_PROCESS_ATTACH by Matan Oshri");
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

Или используйте консольный API для вызова консоли:

DWORD dwSize;
WCHAR string[] = L"Hello World";
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        AllocConsole();
        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), string, 12, &dwSize, NULL);
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...