Online: 0x02A (42)
haker.iиfø  — Etyczny hacking_
Spreading knowledge like a virus.

Podpięcia do funkcji API za pomocą Detours

   Dawid Farbaniec    790 słów

0x01. Słowem wstępu

odpię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.

API hooking (podpięcia)

0x02. Schemat działania podpięć do funkcji

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 (rysunek 2.1).

Przechwytywanie wywołania funkcji
Rysunek 2.1. Przechwytywanie wywołania funkcji — schemat ogólny

0x03. Prosty, działający przykład 🧪

Prezentowany przykład wymaga utworzenia dwóch projektów:

  • 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.

Gotowe rozwiązanie (Solution) dla środowiska Visual Studio:
💾 interceptor-ms-detours.zip - 1,77 MB (bajtów: 1 862 206)
(Archiwum nie zawiera żadnych plików wykonywalnych tylko kod w postaci tekstowej — no virus ✅)

Mechanizm działania programu injector.exe z listingu 3.1 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 listing 3.2 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.

Listing 3.1. Program wstrzykujący bibliotekę DLL (injector.exe)

/* injector.exe (main.cpp file) https://haker.info/ 2020 */ #include <Windows.h> #include "detours.h" #pragma comment(lib, "..\\x64\\Release\\detours.lib") INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow) { 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; }

Listing 3.2. Wstrzykiwana biblioteka DLL (library.exe)

/* library.dll (main.cpp file) https://haker.info/ 2020 */ #include <Windows.h> #include <stdio.h> #include <locale.h> #include "detours.h" #pragma comment(lib, "..\\x64\\Release\\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+"); 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; }

Dodatek 0x01. Dołączenie biblioteki Microsoft Detours do projektu w Visual C++

Poniżej przedstawiono jak krok po kroku utworzyć projekt w Visual Studio (C++) korzystający z biblioteki Microsoft Detours.

Krok 1. Pobierz źródła biblioteki Microsoft Detours



Krok 2. Uruchom Visual Studio i wybierz "Kontynuuj bez kodu".



Krok 3. Utwórz puste rozwiązanie (blank solution).



Krok 4. Utwórz pusty projekt biblioteki statycznej (.lib).



Krok 5. Skopiuj źródła biblioteki Detours do folderu projektu.



Krok 6. Importuj pliki źródłowe do projektu w Visual Studio.



Krok 7. Importuj pliki nagłówkowe (.h) do projektu w Visual Studio.



Krok 8. Należy wykluczyć (exclude) z projektu plik uiimports.cpp, ale nie usuwać.



Krok 9. Utwórz nowy projekt w tym samym rozwiązaniu, będzie to aplikacja wstrzykująca.



Krok 10. Dodaj plik źródłowy main.cpp do programu wstrzykującego (injector).



Krok 11. Dodaj nagłówek detours.h do projektu programu wstrzykującego.



Krok 12. Kolejny (trzeci) projekt w rozwiązaniu to biblioteka dynamiczna (*.dll), która będzie wstrzykiwana do monitorowanych procesów.



Krok 13. Dodaj nagłówek detours.h do projektu biblioteki DLL.



Krok 14. Dodaj plik źródłowy main.cpp do biblioteki dynamicznej (wstrzykiwanej).



Krok 15. Ostatni krok do stworzenia szkieletu rozwiązania to ustalenie zależności.



0x04. Zakończenie

Wpis zawiera fragmenty projektu wykonanego przeze mnie na studiach z przedmiotu Bezpieczeństwo systemów informacyjnych w przedsiębiorstwie. Jeśli są jakieś pytania, to proszę pisać w komentarzach. Pozdrawiam.

Dawid Farbaniec

Wykaz literatury (bibliografia)

  • Microsoft Corporation, 2020 – Microsoft C/C++ Documentation – https://docs.microsoft.com/en-us/cpp/?view=vs-2019 (dostęp: 28-07-2020)
  • Microsoft Corporation, 2018 – https://github.com/microsoft/Detours (dostęp: 28-07-2020)

Tagi:  visual-cpp  security 

Komentarze czytających

Iceman napisał:
Nie mam gdzie zostawić commenta do całości, więc wsadzę tu. Mega SITE stare dobre czasy książki "Jak pisać wirusy" z 97 roku.  Właśnie odświeżam trochę info w temacie ASM, C++ i mi się to trafiło.  Będę zaglądał, a nawet kilka rzeczy zasugeruję.
 ponad 2 miesiące temu (02 lipca 2020 godz. 09:19)
Dawid (haker.info) napisał:
Dzięki za komentarz. Będę starał się rozwijać witrynę w miarę wolnego czasu.
 ponad 2 miesiące temu (02 lipca 2020 godz. 17:04)
KrutiwebCon napisał:
Многофункциональный блог независимых энтузиастов.
Полезные советы, лучшие хитрости быта, интересные самоделки и многое другое.
Предлагаем вам облегчить свою жизнь, воспользовавшись полезными советами на все случаи жизни!
Как развесить картины на стене
 ponad tydzień temu (13 września 2020 godz. 10:17)
Dawid (haker.info) napisał:
Hello Russian Friend 🙂
I want to decorate my computer room with some posters.
Thank You for the tip.
 ponad tydzień temu (13 września 2020 godz. 13:17)
kosmita napisał:
Znowu odpisujesz reklamom? Zaraz Ci zabiorę ten telefon. 😆
 ponad tydzień temu (14 września 2020 godz. 09:10)



Wszystkie treści umieszczone na tej witrynie są chronione prawem autorskim. Surowo zabronione jest kopiowanie i rozpowszechnianie zawartości tej witryny bez zgody autora. Wszelkie opublikowane tutaj treści (w tym kody źródłowe i inne) służą wyłącznie celom informacyjnym oraz edukacyjnym. Właściciele tej witryny nie ponoszą odpowiedzialności za ewentualne niezgodne z prawem wykorzystanie zasobów dostępnych w witrynie. Użytkownik tej witryny oświadcza, że z zamieszczonych tutaj danych korzysta na własną odpowiedzialność. Wszelkie znaki towarowe i nazwy zastrzeżone zostały użyte jedynie w celach informacyjnych i należą wyłącznie do ich prawnych właścicieli. Korzystając z zasobów witryny haker.info oświadczasz, że akceptujesz powyższe warunki oraz politykę prywatności.