Projektowanie stron WWW od podszewki

Artykuły na każdy temat

[C++] DLL Injection czyli wstrzykiwanie DLL do obcego procesu

Dodano 05.06.2012r. o 21:46
Dzisiejszy wpis proponuje potraktować jako swojego rodzaju publiczną myślodsiewnie. Materiałów w sieci na ten temat jest tak wiele, że każdy znajdzie coś dla siebie. Ostatnimi czasy trochę się bawię w DLL Injection oraz hookowanie funkcji. Te drugie zagadnienie postaram się opisać w następnym artykule. Oczywiście jak to zazwyczaj bywa przed napisaniem czegokolwiek rozejrzałem się po sieci czy nie ma czegoś interesującego. Natrafiłem na cztery fajne moim zdaniem materiały, które za chwilę zalinkuję, gdyż uznałem że może i Wam się przydadzą. Oto one:
W trzecim materiale poziom trudności został określony jako 2/3 z czym się nie zgadzam ale coż Razz Żeby nie przedłużać całej tej farsy podaję kod:
Kod:
#include <iostream>
#include <windows.h>
#include <tlhelp32.h>

using namespace std;

// Jakieś tam deklaracje/prototypy funkcji?
DWORD GetProcessIdByName(CHAR* Name);
BOOL FileExists(CHAR* Path);
BOOL InjectDLL(DWORD PID, CHAR* Path);

// Argumenty pominięto choć można je wykorzystać - co kto lubi Razz
INT main()
{
    // Można po PID lub szExeFile - co kto lubi Smile
    // MAX_PATH powinno wystarczyć -> http://en.wikipedia.org/wiki/Filename#Comparison_of_filename_limitations
    CHAR ProcessName[MAX_PATH], LibraryName[MAX_PATH], LibraryPath[MAX_PATH] = {0};
    DWORD PID = 0;

    while(1)
    {
        cout << "Process: ";
        cin >> ProcessName;
        cout << "DLL: ";
        cin >> LibraryName;

        if((PID = GetProcessIdByName(ProcessName)) != 0)
        {
            GetFullPathName(LibraryName, MAX_PATH, LibraryPath, NULL);

            if(FileExists(LibraryPath))
            {
                cout << (InjectDLL(PID, LibraryPath) ? "Wstrzyknieto" : "Nie wstrzyknieto") << endl;
            }
            else
            {
                cout << "Nie znaleziono biblioteki" << endl;
            }
        }
        else
        {
            cout << "Nie znaleziono procesu" << endl;
        }
    }

    return EXIT_SUCCESS;
}

DWORD GetProcessIdByName(CHAR* Name)
{
    PROCESSENTRY32 pe;
    HANDLE Snapshot;
    DWORD ret = 0;

    Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    pe.dwSize = sizeof(PROCESSENTRY32);

    if(Snapshot != INVALID_HANDLE_VALUE)
    {
        if(Process32First(Snapshot, &pe))
        {
            do
            {
                if(!lstrcmpi(Name, pe.szExeFile))
                {
                    ret = pe.th32ProcessID;
                    break;
                }
            }
            while(Process32Next(Snapshot, &pe));
        }

        CloseHandle(Snapshot);
    }

    return ret;
}

BOOL FileExists(CHAR* Path)
{
    DWORD Attributes = GetFileAttributes(Path);

    return (Attributes != INVALID_FILE_ATTRIBUTES && !(Attributes & FILE_ATTRIBUTE_DIRECTORY));
}

BOOL InjectDLL(DWORD PID, CHAR* Path)
{
    HANDLE Process, Thread;
    LPVOID RemoteMemoryAddress;
    LPTHREAD_START_ROUTINE LoadLibraryAddress;
    BOOL ret = FALSE;

    // Dla opornych PROCESS_ALL_ACCESS może się przydać
    if((Process = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD, FALSE, PID)) != NULL)
    {
        DWORD MemorySize = strlen(Path) + 1;

        // Dla opornych PAGE_EXECUTE_READWRITE może się przydać
        if((RemoteMemoryAddress = VirtualAllocEx(Process, NULL, MemorySize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READ)) != NULL)
        {
            if(WriteProcessMemory(Process, RemoteMemoryAddress, Path, MemorySize, NULL))
            {
                LoadLibraryAddress = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");

                if((Thread = CreateRemoteThread(Process, NULL, 0, LoadLibraryAddress, RemoteMemoryAddress, 0, NULL)) != NULL)
                {
                    ret = TRUE;
                    CloseHandle(Thread);
                }
            }

        }

        CloseHandle(Process);
    }

    return ret;
}
I kod źródłowy najbanalniejszej biblioteki do testów:
Kod:
#include <windows.h>

BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
    switch(reason)
    {
        case DLL_PROCESS_ATTACH:
            MessageBox(NULL, "DLL_PROCESS_ATTACH", "", MB_OK);
        break;

        case DLL_PROCESS_DETACH:
            MessageBox(NULL, "DLL_PROCESS_DETACH", "", MB_OK);
        break;

        case DLL_THREAD_ATTACH:
            MessageBox(NULL, "DLL_THREAD_ATTACH", "", MB_OK);
        break;

        case DLL_THREAD_DETACH:
            MessageBox(NULL, "DLL_THREAD_DETACH", "", MB_OK);
        break;
    }

    return TRUE;
}
Sory, że nie ma kolorowania składni ale nie przewidziałem takiej możliwości.

Komentarze

Brak komentarzy

Dodaj komentarz

Zostaw komentarz jeżeli możesz! Nie bądź przysłowiowym botem! Nie bądź obojętny! Ciebie to nic nie kosztuje, a mi sprawi uśmiech na twarzy.
Zezwolono używać: BBCode
Zabroniono używać:
znaczników HTML

(Wymagany)

(Wymagany, niepublikowany)

(Nie wymagana)

Token:

Obrazek dla bota

(Przepisz tylko cyfry!)

(Wymagana)