ethical.blue Magazine

// Cybersecurity clarified.

Podpięcia do funkcji API za pomocą Microsoft Detours

13.04.2022   Dawid Farbaniec
...

Słowem wstępu

Podpięcia (ang. hooks) do funkcji mogą mieć różne zastosowania. Jednym z nich jest np. możliwość monitorowania wywoływanych funkcji przez wybrany program. Pozwala to częściowo na analizę zachowania aplikacji, czyli "co program robi". Ogólną sztukę przechwytywania wywołań funkcji określa się po angielsku frazą API hooking. Istnieją też negatywne zastosowania tego typu mechanizmu. Można go spotkać też w złośliwym oprogramowaniu (ang. malware). Podpięcie pozwala przechwycić wywołanie funkcji i np. zafałszowanie jej wyniku. Wyobraźmy sobie funkcję, która wyświetla listę procesów, zakładane jest podpięcie, następuje przechwycenie, a argumenty (lista procesów) są modyfikowane poprzez usunięcie wybranych pozycji. W ten właśnie sposób VXer może ukryć swój złośliwy proces. W tym wpisie jednak zostanie przedstawione etyczne zastosowanie API hooking'u. Dla ułatwienia działań początkującym i ogólnej wygody użyta będzie biblioteka Microsoft Detours.

Przy przechwytywaniu wywołania funkcji za pomocą Microsoft Detours, przepływ jest kierowany przez funkcje pośredniczące takie jak funkcja przekierowująca oraz tzw. trampolina.

Prosty, działający przykład 🧪

Prezentowany przykład wymaga utworzenia dwóch projektów (oprócz biblioteki detours):
Program wstrzykujący (injector.exe) — uruchamia proces do monitorowania i wstrzykuje w niego bibliotekę .dll.
Wstrzykiwana biblioteka (library.dll) — przechwytuje wywołania zdefiniowanych funkcji API.

Mechanizm działania programu injector.exe polega w skrócie na utworzeniu nowego procesu wybranej aplikacji i wstrzyknięcia do niej biblioteki dynamicznej (.dll), której zadaniem jest przechwytywanie wywołań określonych funkcji API.

Natomiast kolejny listing prezentuje kod biblioteki dynamicznej, która jest wstrzykiwana do procesu. Zawiera ona m.in. prototypy przechwytywanych funkcji oraz definicje, w których możemy określić dodatkowe działania np. zapisanie argumentów funkcji do pliku raportu czy nawet ich modyfikacja.

Dokładny opis poszczególnych funkcji biblioteki Detours można znaleźć w dokumentacji:
https://github.com/microsoft/detours/wiki

Dodanie kolejnych funkcji, które mają być monitorowane polega na umieszczeniu prototypów analogicznie do:
VOID(WINAPI* pSleep)(DWORD) = Sleep;

VOID WINAPI MySleep(DWORD dwMilliseconds);

Dopisaniu funkcji pośredniczącej:

VOID WINAPI MySleep(DWORD dwMilliseconds)

{
    FILE* pLogFile;

    setlocale(LC_CTYPE, "");

    _wfopen_s(&pLogFile, L"log.txt", L"a+");

    fwprintf(pLogFile, L"Monitorowany program zasnął (funkcja Sleep) na %i milisekund.", dwMilliseconds);

    fclose(pLogFile);

    return pSleep(dwMilliseconds);
}

I na koniec dodanie wywołań funkcji DetourAttach() oraz DetourDetach() dla nowych funkcji, które mają być monitorowane.

Program wstrzykujący bibliotekę DLL (injector.exe)
#include <Windows.h>

#include "..\detours\detours.h"

#pragma comment(lib, "..\x64\Debug\detours.lib")

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
    _In_ PSTR szCmdLine, _In_ int iCmdShow)
{
    STARTUPINFOA si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOW;
    ZeroMemory(&pi, sizeof(pi));

    BOOL injected = FALSE;

    injected = DetourCreateProcessWithDllExA(
        "prog1.exe", NULL, NULL, NULL, TRUE,
        CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED,
        NULL, NULL, &si, &pi, "library.dll", NULL);

    if (injected == TRUE)
    {
        MessageBox(0, L"Biblioteka DLL została wstrzyknięta w proces.",
            L"Informacja", MB_OK + MB_ICONINFORMATION);
    }
    else
    {
        MessageBox(0, L"Nie udało się wstrzyknąć biblioteki DLL.",
            L"Błąd", MB_OK + MB_ICONERROR);
    }

    ResumeThread(pi.hThread);

    WaitForSingleObject(pi.hProcess, INFINITE);

    CloseHandle(&si);
    CloseHandle(&pi);

    return EXIT_SUCCESS;
}

Wstrzykiwana biblioteka DLL (library.dll)
#include <Windows.h>

#include <cstdio>
#include <clocale>
#include "..\detours\detours.h"

#pragma comment(lib, "..\x64\Debug\detours.lib")

VOID(WINAPI* pSleep)(DWORD) = Sleep;
VOID WINAPI MySleep(DWORD dwMilliseconds);

VOID WINAPI MySleep(DWORD dwMilliseconds)
{
    FILE* pLogFile;

    setlocale(LC_CTYPE, "");

    _wfopen_s(&pLogFile, L"log.txt", L"a+");

    if (pLogFile != NULL)
    {
        fwprintf(pLogFile, L"Monitorowany program zasnął (funkcja Sleep) na %i milisekund.", dwMilliseconds);

        fclose(pLogFile);
    }

    return pSleep(dwMilliseconds);
}

extern "C" __declspec(dllexport) void nothing(void) {
    return;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    if (DetourIsHelperProcess())
        return TRUE;

    if (fdwReason == DLL_PROCESS_ATTACH)
    {
        DetourRestoreAfterWith();

        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());

        DetourAttach(&(PVOID&)pSleep, MySleep);
        DetourTransactionCommit();
    }
    else if (fdwReason == DLL_PROCESS_DETACH)
    {
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());

        DetourDetach(&(PVOID&)pSleep, MySleep);
        DetourTransactionCommit();
    }

    return TRUE;
}

Zakończenie

Dziękuję za czas poświęcony na przeczytanie tego wpisu.

Wykaz literatury

https://github.com/ethicalblue/Microsoft-Detours-Example [access: 2022-04-13]
https://github.com/microsoft/Detours [access: 2022-04-13]

ethical.blue Appz

Categories

Archives


Donate to ethical.blue Magazine website maintenance with cryptocurrency or PayPal.

aspnet
Connections: 2

bitcoin diesel