Znajdowanie adresu tabeli SSDT na Windowsach 64-bitowych (x64)

Jak już od jakiegoś czasu wiadomo, udało mi się stworzyć bypassa do PatchGuarda, dzięki czemu mogę modyfikować kod jądra systemu, w tym tabelę SSDT - dlatego też napisałem funkcję, która wyszuka KeServiceDescriptorTable w obrazie jądra. W 32-bitowych Windowsach nie było problemu, ponieważ KeServiceDescriptorTable była eksportowana, tutaj (64-bit) jest jednak inaczej - tabelę musimy wyszukać sobie sami. Rzućmy okiem na kod funkcji KiSystemServiceStart w IDA Pro: Poniżej funkcji KiSystemServiceStart znajduje się funkcja KiSystemServiceRepeat, w której na rejestr r10 trafia adres naszego celu - tabeli SSDT. Jest to adres relatywny, więc będziemy musieli go przeliczyć. Funkcja KiSystemServiceStart nie różni się między wersjami 64-bitowych Windowsów i zawsze poniżej jej jest funkcja KiSystemServiceRepeat, dlatego też będzie ona łatwym do wyszukania w jądrze celem. Nasza funkcja powinna poszukać zaznaczone bajty. Następnie, mając już wyszukany adres z naszymi bajtami wewnątrz KiSystemServiceStart, musimy wyszukać pierwszą instrukcję LEA (Load Effective Address), więc szukamy dwóch bajtów 0x8d4c. Po znalezieniu ich mamy adres instrukcji "lea r10, KeServiceDescriptorTable", tudzież "lea r10, 00239147h". No tak ale 00239147h to adres relatywny i nie ma tam tabeli, więc musimy wyliczyć bezpośredni adres. Z tym nie będzie żadnego problemu, ponieważ do adresu z instrukcją LEA, który znaleźliśmy musimy doliczyć 7 (bo taki jest rozmiar instrukcji) a następnie do wyniku dodać 00239147. Otrzymamy bezpośredni adres tabeli - i zwracamy go w funkcji. To wszystko. Nasza funkcja powinna wyglądać mniej więcej tak:
ULONGLONG GetKeServiceDescriptorTable64() {    //Pattern do wyszukania funkcji KiSystemServiceStart    char KiSystemServiceStart_pattern[13] = "\x8B\xF8\xC1\xEF\x07\x83\xE7\x20\x25\xFF\x0F\x00\x00";    //Granice dla skanu    ULONGLONG CodeScanStart = (ULONGLONG)&_strnicmp;    ULONGLONG CodeScanEnd = (ULONGLONG)&KdDebuggerNotPresent;    //Inne potrzebne zmienne    UNICODE_STRING Symbol;    ULONGLONG i, tbl_address, b;    //Pętla wyszukująca KiSystemServiceStart    for (i = 0; i < CodeScanEnd - CodeScanStart; i++)    {      //Czy sygnatura odpowiada aktualnemu adresowi ?      if (!memcmp((char*)(ULONGLONG)CodeScanStart +i, (char*)KiSystemServiceStart_pattern,13))      {        //Jeśli tak - to szukamy lea r?? - opcody: 4c 8d        for (b = 0; b < 50; b++)        {          //Ustawiamy tbl address          tbl_address = ((ULONGLONG)CodeScanStart+i+b);          //Sprawdzamy czy to lea tam jest, jeżeli tak to wyciągamy          //drugi parametr czyli adres relatywny do tabeli SSDT          if (*(USHORT*) ((ULONGLONG)tbl_address ) == (USHORT)0x8d4c)            return ((LONGLONG)tbl_address +7) + *(LONG*)(tbl_address +3);        }      }    }    //Tutaj dojdzie wykonywanie kodu, jeżeli kod mimo wszystko nie znajdzie tabeli    return 0; }

UWAGA: By zmodyfikować tą tabelę w systemie Windows 64-bit konieczne będzie wyłączenie ochrony kodu jądra - Kernel Patch Protection (aka PatchGuard). Aby to zrobić należy włączyć w systemie debbugera jądra (kernel debugger). Ewentualnie można uruchomić system w trybie awaryjnym, bowiem w trybie awaryjnym również nie jest inicjowany PatchGuard. Pozdrawiam, Kill1212

Komentarze

  1. dobry posty i blog:) dopiero nie dawno znalazlem twoj blog ale bardzo mi sie podoba bo interesuje sie tematem RE, fajnie ze laczysz teorie z praktyka czyli zamieszczasz rowniez kod C, dzieki

    OdpowiedzUsuń
  2. Hej, próbowałem samemu dojść do tego co napisałeś. Mógłbyś napisać z jakich symboli korzystasz. Odpaliłem Ide, otworzyłem ntoskrnl, i nie ma śladu po funkcjach KiSystemService... Symbole są z serwera(win7 x64 free) Mój system oczywiście się pokrywa. Byłbym wdzięczny za wszelkie sugestie.

    ps Windbg natomiast potrafić te funkcje zdeasemblować.

    OdpowiedzUsuń
  3. ladan8, trzeba pliczek z symbolami zlokalizować odpowiedni i IDA normalnie zobaczy te symbole.

    OdpowiedzUsuń
  4. Wszystkie informacje bardzo przydatne

    OdpowiedzUsuń
  5. miło się czyta te wpisy!

    OdpowiedzUsuń

Prześlij komentarz