Driver'ınızı Anti-Cheat'lerden gizlemek

Durum
Üzgünüz bu konu cevaplar için kapatılmıştır...
Üye
Katılım
23 Eyl 2020
Mesajlar
36
Tepki puanı
27
5 HİZMET YILI
Giriş

1) Öncelikle driver ve client arasında iletişim kurmanız gerekli (standart ioctl kullanmayın)
Örnek;
C:
#include <ntddk.h>

const WCHAR sc_wszDeviceNameBuffer[]    = L"\\Device\\Comm_Test";
const WCHAR sc_wszDeviceSymLinkBuffer[] = L"\\DosDevices\\Comm_Test";

NTSTATUS IRPRead(PDEVICE_OBJECT pDriverObject, PIRP pIrp)
{
    UNREFERENCED_PARAMETER(pDriverObject);

    char szBuffer[255] = "Test";
    strcpy(pIrp->AssociatedIrp.SystemBuffer, szBuffer);

    pIrp->IoStatus.Status = STATUS_SUCCESS;
    pIrp->IoStatus.Information = strlen(szBuffer);
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}

NTSTATUS IRPWrite(PDEVICE_OBJECT pDriverObject, PIRP pIrp)
{
    UNREFERENCED_PARAMETER(pDriverObject);

    char szBuffer[255] = { 0 };
    strcpy(szBuffer, pIrp->AssociatedIrp.SystemBuffer);

    pIrp->IoStatus.Status = STATUS_SUCCESS;
    pIrp->IoStatus.Information = strlen(szBuffer);
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}

NTSTATUS MajorFunctionCall(PDEVICE_OBJECT pDriverObject, PIRP pIrp)
{
    PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
    switch (pStack->MajorFunction)
    {
        case IRP_MJ_READ:
            IRPRead(pDriverObject, pIrp);
            break;

        case IRP_MJ_WRITE:
            IRPWrite(pDriverObject, pIrp);
            break;

        default:
            pIrp->IoStatus.Status = STATUS_SUCCESS;
            IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    }
    return STATUS_SUCCESS;
}


VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject)
{
    UNREFERENCED_PARAMETER(pDriverObject);

    DbgPrint("Driver unload rutini çağırıldı!\n");

    UNICODE_STRING symLink;
    RtlInitUnicodeString(&symLink, sc_wszDeviceSymLinkBuffer);

    IoDeleteSymbolicLink(&symLink);
    if (pDriverObject && pDriverObject->DeviceObject)
    {
        IoDeleteDevice(pDriverObject->DeviceObject);
    }
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
{
    UNREFERENCED_PARAMETER(pRegistryPath);

    if (!pDriverObject)
    {
        DbgPrint("Comm_Test driver entry null!\n");
        return STATUS_FAILED_DRIVER_ENTRY;
    }

    DbgPrint("Driver yüklendi, system range başlangıcı %p, Entry: %p\n", MmSystemRangeStart, DriverEntry);

    pDriverObject->DriverUnload = &OnDriverUnload;

    NTSTATUS ntStatus = 0;
  
    UNICODE_STRING deviceNameUnicodeString, deviceSymLinkUnicodeString;
    RtlInitUnicodeString(&deviceNameUnicodeString, sc_wszDeviceNameBuffer);
    RtlInitUnicodeString(&deviceSymLinkUnicodeString, sc_wszDeviceSymLinkBuffer);

    PDEVICE_OBJECT pDeviceObject = NULL;
    ntStatus = IoCreateDevice(pDriverObject, 0, &deviceNameUnicodeString, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject);
    if (ntStatus != STATUS_SUCCESS)
    {
        DbgPrint("Comm_Test IoCreateDevice başarısız oldu! Status: %p\n", ntStatus);
        return ntStatus;
    }

    ntStatus = IoCreateSymbolicLink(&deviceSymLinkUnicodeString, &deviceNameUnicodeString);
    if (ntStatus != STATUS_SUCCESS)
    {
        DbgPrint("Comm_Test IoCreateSymbolicLink başarısız! Status: %p\n", ntStatus);
        return ntStatus;
    }

    for (ULONG t = 0; t <= IRP_MJ_MAXIMUM_FUNCTION; t++)
        pDriverObject->MajorFunction[t] = &OnMajorFunctionCall;

    pDeviceObject->Flags |= DO_BUFFERED_IO;


    return STATUS_SUCCESS;
}
C++:
#include <Windows.h>
#include <string>
#include <iostream>

static const std::string    gsc_szSymLink    = "\\\\.\\Comm_Test";
static HANDLE                gs_hDriver        = INVALID_HANDLE_VALUE;

void HataMesaji(const std::string & szError, DWORD dwErrorCode)
{
    char szErrorMessage[4096] = { 0 };

    auto dwFlags = DWORD(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK);
    FormatMessageA(dwFlags, NULL, dwErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), szErrorMessage, _countof(szErrorMessage), NULL);

    printf("%s | Hata: %u - Açıklama: %s\n", szError.c_str(), dwErrorCode, szErrorMessage);
}

bool ReadRoutine()
{
    auto dwReadCount    = 0UL;
    char szBuff[255]    = { 0 };
    if (ReadFile(gs_hDriver, szBuff, sizeof(szBuff), &dwReadCount, NULL) == FALSE)
    {
        ShowErrorMessage("ReadFile başarısız!", GetLastError());
        return false;
    }

    printf("Mesaj içeriği: %s Boyut: %u\n", szBuff, dwReadCount);
    return true;
}

bool WriteRoutine()
{
    printf("Mesajı girin: ");

    auto szMessage = std::string("");
    std::cin >> szMessage;

    auto dwMessageSize = static_cast<DWORD>(szMessage.size());

    auto dwWriteCount = 0UL;
    if (WriteFile(gs_hDriver, szMessage.c_str(), dwMessageSize + 1, &dwWriteCount, NULL) == FALSE)
    {
        ShowErrorMessage("WriteFile başarısız!", GetLastError());
        return false;
    }

    printf("Mesaj gönderildi! Boyut: %u İçerik boyutu: %u\n", dwWriteCount, dwMessageSize);
    return true;
}

int main()
{
    printf("İletişim CLI'ı başladı! Hedef device: %s\n", gsc_szSymLink.c_str());

    gs_hDriver = CreateFileA(gsc_szSymLink.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if (!gs_hDriver || gs_hDriver == INVALID_HANDLE_VALUE)
    {
        ShowErrorMessage("CreateFileA başarısız!", GetLastError());
        return 1;
    }
    printf("Handle başarıyla oluşturuldu: %p\n", gs_hDriver);

    printf("--------------------------------------\n");

    char pInput = '0';
    while (pInput != 'x')
    {
        printf("Lütfen seçin:\n1 --> Mesajı oku\n2 --> Mesaj yaz\nx --> Exit\n");
        std::cin >> pInput;

        switch (pInput)
        {
            case '1':
            {
                ReadRoutine();
            } break;

            case '2':
            {
                WriteRoutine();
            } break;

            case 'x':
                return 0;

            default:
                continue;
        }
    }


    return 0;
}

2) MmUnloadedDrivers ve PiDDBCachetable gibi izleri temizleyin
Örnek;
C++:
bool driver::ClearMmUnloadedDrivers(HANDLE device_handle)
{
    ULONG buffer_size = 0;
    void* buffer = nullptr;

    NTSTATUS status = NtQuerySystemInformation(static_cast<SYSTEM_INFORMATION_CLASS>(nt::SystemExtendedHandleInformation), buffer, buffer_size, &buffer_size);

    while (status == nt::STATUS_INFO_LENGTH_MISMATCH)
    {
        VirtualFree(buffer, 0, MEM_RELEASE);

        buffer = VirtualAlloc(nullptr, buffer_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
        status = NtQuerySystemInformation(static_cast<SYSTEM_INFORMATION_CLASS>(nt::SystemExtendedHandleInformation), buffer, buffer_size, &buffer_size);
    }

    if (!NT_SUCCESS(status))
    {
        VirtualFree(buffer, 0, MEM_RELEASE);
        return false;
    }

    uint64_t object = 0;

    auto system_handle_inforamtion = static_cast<nt::PSYSTEM_HANDLE_INFORMATION_EX>(buffer);

    for (auto i = 0u; i < system_handle_inforamtion->HandleCount; ++i)
    {
        const nt::SYSTEM_HANDLE current_system_handle = system_handle_inforamtion->Handles[i];

        if (current_system_handle.UniqueProcessId != reinterpret_cast<HANDLE>(static_cast<uint64_t>(GetCurrentProcessId())))
            continue;

        if (current_system_handle.HandleValue == device_handle)
        {
            object = reinterpret_cast<uint64_t>(current_system_handle.Object);
            break;
        }
    }

    VirtualFree(buffer, 0, MEM_RELEASE);

    if (!object)
        return false;

    uint64_t device_object = 0;

    if (!ReadMemory(device_handle, object + 0x8, &device_object, sizeof(device_object)))
        return false;

    uint64_t driver_object = 0;

    if (!ReadMemory(device_handle, device_object + 0x8, &driver_object, sizeof(driver_object)))
        return false;

    uint64_t driver_section = 0;

    if (!ReadMemory(device_handle, driver_object + 0x28, &driver_section, sizeof(driver_section)))
        return false;

    UNICODE_STRING us_driver_base_dll_name = { 0 };

    if (!ReadMemory(device_handle, driver_section + 0x58, &us_driver_base_dll_name, sizeof(us_driver_base_dll_name)))
        return false;

    us_driver_base_dll_name.Length = 0;

    if (!WriteMemory(device_handle, driver_section + 0x58, &us_driver_base_dll_name, sizeof(us_driver_base_dll_name)))
        return false;

    return true;
}
C++:
    ClearMmUnloadedDrivers(device_handle);

3) Poolları allocate etmeyin


ADIM 1: Fonksiyon pointer'ını bulmak
Bu fonksiyon pointer'ı için gerekenler:
1) Usermode'dan çağırılabilir olmalı
2) PatchGuard bulunmamalı
3) Parametreleri olmalı
4) Funciton Call'dan önce en az bir parametrenin temizlenmemiş olması gerekir

İlk olarak guard_dispatch_icall için xref'leri bulmamız gerekiyor. guard_dispatch_icall tüm fonksiyon pointerlarının istenmeyen kodları çalıştırmasını önlemek için control flow korumalı driverlar tarafından çağırılan fonksiyondur. Eğer bunu xref ederseniz bir driverin tüm fonksiyon pointerlarını bulabilirsiniz. Image integrity check'ten sonra RAX'ta bulunan fonksiyonu çağıracaktır.

Bazı sebeplerden dolayı guard dispatch icall bu fonksiyon pointerlarını kullanmamızı engellemiyor, control flow guard hiçbir işe yaramıyor.
Bağlantıları görmek için lütfen Giriş Yap


Genellikle Syscall'ların önünde "Nt" bulunur, bu yüzden bir "Nt" fonksiyonu arayalım.
Bağlantıları görmek için lütfen Giriş Yap


Syscall ile çağırılan fonksiyon pointer'ınızı (v8) bulduktan sonra kendi fonksiyonumuza ayarlayabilir, girdiğimiz parametreler ile geçirebiliriz.
Sadece 1 byte parametre alanına ihtiyacınız var! ekstra input / output ile iletişim kurmak için Usermode'da bir buffer ayırabilir ve bu buffer aracılığıyla iletişim kurmak için MmCopyVirtualMemory / KeStackAttachProcess kullanabilirsiniz.


ADIM 2: Usermode'dan çağırmak ve her şeyi bir araya getirmek

Fonksiyonu çağırma şekliniz, ne tür bir fonksiyonu kullandığınıza bağlı, eğer standart bir syscall ile çağırılan ntoskrnl içerisindeki bir fonksiyon pointeri ise
C++:
HMODULE  hModule = LoadLibrary(L"ntdll.dll");

fonksiyon = (FonksiyonPointeri)GetProcAddress(hModule, "");

Input'unuzu bu fonksiyonun parametrelerinden geçirin, izleri temizleyin ve read/write ekleyin.​
 
Son düzenleme:
Onaylı Üye
Katılım
1 May 2019
Mesajlar
50
Tepki puanı
5
Ödüller
5
Yaş
32
7 HİZMET YILI
heryerde bunu arıyodum bi türlü bulamadım emeğine sağlık
 
Mustafa Kemal Atatürk
Uzman Üye
Katılım
4 Ocak 2017
Mesajlar
185
Çözümler
1
Tepki puanı
13
Ödüller
7
9 HİZMET YILI
Denemek gerek ve deneyeceğim ellerine sağlık
 
Onaylı Üye
Katılım
23 Eyl 2020
Mesajlar
51
Tepki puanı
1
Ödüller
1
5 HİZMET YILI
Nice been looking something like these couldn't code. It's so nice that users share stuffs here. Kudos! :200iq:
 
Onaylı Üye
Katılım
16 Ara 2018
Mesajlar
51
Tepki puanı
0
Yaş
29
7 HİZMET YILI
çok teşekkürler işime yaradı sagol
 
je veux mourir
Uzman Üye
Katılım
23 Eyl 2020
Mesajlar
230
Tepki puanı
16
Ödüller
3
Yaş
24
Sosyal
5 HİZMET YILI
öncelikle teşekkürler , bu tarz kodları hangi uygulamalarda yazılıyor yada nasıl öğrenebilirm bir fikrin varmı ?
 
Durum
Üzgünüz bu konu cevaplar için kapatılmıştır...
Üst