Начинающий
- Статус
- Оффлайн
- Регистрация
- 27 Фев 2026
- Сообщения
- 11
- Реакции
- 3
• Спуфер писался без вайбкодинга и прочей хуйни лично мной на протяжении 2 месяцев (каждый день по чуть-чуть, т.к. очень много теории изучалось)
• Тестился лично мной только в пабге (с момента спуфа прошло 3 недели, бана на нью акке пока нет)
• Насчет обхода геймгварда, даже не тестив, уверен на 100% (самый нищий во вселенной античит, который юзается только таким же нищим фасткапом)
• Считаю, что если чуть доработать, сможет конкурировать с оверпрайс приватными спуферами.
• СРАЗУ ДЛЯ ТЕХ, КТО БУДЕТ СПРАШИВАТЬ : "ой, а для валорантика работает?" -Нет, не работает и не будет работать. В жизни вы не найдете бесплатного спуфера, который сможет на изи обойти вангуард. Там уже нужно прикладывать очень много мозгов, работать с hypervisor или с dma.
• Драйвер не прописывается в автозагрузку. После ребута всё сбросится, так что маппить нужно при каждом запуске системы.
--КОД--
• Тестился лично мной только в пабге (с момента спуфа прошло 3 недели, бана на нью акке пока нет)
• Насчет обхода геймгварда, даже не тестив, уверен на 100% (самый нищий во вселенной античит, который юзается только таким же нищим фасткапом)
• Считаю, что если чуть доработать, сможет конкурировать с оверпрайс приватными спуферами.
• СРАЗУ ДЛЯ ТЕХ, КТО БУДЕТ СПРАШИВАТЬ : "ой, а для валорантика работает?" -Нет, не работает и не будет работать. В жизни вы не найдете бесплатного спуфера, который сможет на изи обойти вангуард. Там уже нужно прикладывать очень много мозгов, работать с hypervisor или с dma.
• Драйвер не прописывается в автозагрузку. После ребута всё сбросится, так что маппить нужно при каждом запуске системы.
ИНСТРУКЦИЯ К ЗАПУСКУ ПОШАГОВО ДЛЯ САМЫХ МАЛЕНЬКИХ ЧАЙНИКОВ :
Примечание : делать все уже на фулл чистой винде с полным форматированием диска
1) Подготовка:
Нужна Visual Studio 2022 и Windows Driver Kit (WDK). Если WDK не стоит, шаблонов Kernel Mode не будет.
2) Создание проекта:
Создай Empty KMDF (Kernel Mode Driver). В Source Files кидай файл с расширением .c и вставляй код.
3) Настройка билда:
Ставь конфигурацию на Release, платформу на x64.
Заходи в свойства проекта (Properties):
Driver Signing -> General: Sign Mode ставишь в Off.
Inf2Cat -> General: Run Inf2Cat ставишь в No.
Жми Ctrl+Shift+B. Файл .sys забирай в папке x64\Release.
4) Загрузка в систему:
Для обхода подписи используй kdmapper. Кидай маппер и свой .sys в одну папку.
Запускай CMD от админа и пиши:
kdmapper.exe твой_драйвер.sys
Важно: перед маппингом выруби Secure Boot в BIOS, иначе драйвер не прокинется в память.
5) Проверка результата:
Диски: wmic diskdrive get serialnumber
Сеть: getmac
Примечание : делать все уже на фулл чистой винде с полным форматированием диска
1) Подготовка:
Нужна Visual Studio 2022 и Windows Driver Kit (WDK). Если WDK не стоит, шаблонов Kernel Mode не будет.
2) Создание проекта:
Создай Empty KMDF (Kernel Mode Driver). В Source Files кидай файл с расширением .c и вставляй код.
3) Настройка билда:
Ставь конфигурацию на Release, платформу на x64.
Заходи в свойства проекта (Properties):
Driver Signing -> General: Sign Mode ставишь в Off.
Inf2Cat -> General: Run Inf2Cat ставишь в No.
Жми Ctrl+Shift+B. Файл .sys забирай в папке x64\Release.
4) Загрузка в систему:
Для обхода подписи используй kdmapper. Кидай маппер и свой .sys в одну папку.
Запускай CMD от админа и пиши:
kdmapper.exe твой_драйвер.sys
Важно: перед маппингом выруби Secure Boot в BIOS, иначе драйвер не прокинется в память.
5) Проверка результата:
Диски: wmic diskdrive get serialnumber
Сеть: getmac
ПРО НАЧИНКУ, ЗАВИСИМОСТИ И ОСОБЕННОСТИ ДЛЯ ДЖУНИОРОВ ИЛИ ПРОСТО ТЕХ, КТО ХОЧЕТ РАЗОБРАТЬСЯ В ЭТОЙ ТЕМЕ:
-В большинстве нищих спуферов типы тупо переписывают адреса функций в таблицах драйверов (MajorFunction). Я же юзаю легальные фильтры, которые встраиваются в стек устройств как это нужно по документации (IoAttachDeviceToDeviceStack)
-Нищие спуферы перехватывают только 1 запрос - IOCTL_STORAGE_QUERY_PROPERTY. Даже EAC в 26 году читает серийники минимум тремя способами: IOCTL (простой), SCSI Pass Through (команда Inquiry), NVMe Pass Through (для новых дисков), SMART (Predict Failure). В моем спуфаке закрыты все эти векторы, т.к. код лезет в SCSI-команды, парсит VPD страницы (0x80 и 0x83), для NVMe отдельная обработка.
-Большинство MAC-спуферов просто лезут в реестр или используют NDIS-протоколы, которые фулл тайм детект еаком. Я юзаю WFP (Windows Filtering Platform): это тот же механизм, через который работают фаерволы и антивирусы. Код регистрирует каллут на уровне L2 (ethernet-кадры) и прямо в пакетах подменяет MAC-адрес отправителя.
-В целом спуфер PatchGuard никак не триггерит, джиттер не на коленке воркает, а ну и еще я SEH-блоки добавил для защиты от крашей.
-В большинстве нищих спуферов типы тупо переписывают адреса функций в таблицах драйверов (MajorFunction). Я же юзаю легальные фильтры, которые встраиваются в стек устройств как это нужно по документации (IoAttachDeviceToDeviceStack)
-Нищие спуферы перехватывают только 1 запрос - IOCTL_STORAGE_QUERY_PROPERTY. Даже EAC в 26 году читает серийники минимум тремя способами: IOCTL (простой), SCSI Pass Through (команда Inquiry), NVMe Pass Through (для новых дисков), SMART (Predict Failure). В моем спуфаке закрыты все эти векторы, т.к. код лезет в SCSI-команды, парсит VPD страницы (0x80 и 0x83), для NVMe отдельная обработка.
-Большинство MAC-спуферов просто лезут в реестр или используют NDIS-протоколы, которые фулл тайм детект еаком. Я юзаю WFP (Windows Filtering Platform): это тот же механизм, через который работают фаерволы и антивирусы. Код регистрирует каллут на уровне L2 (ethernet-кадры) и прямо в пакетах подменяет MAC-адрес отправителя.
-В целом спуфер PatchGuard никак не триггерит, джиттер не на коленке воркает, а ну и еще я SEH-блоки добавил для защиты от крашей.
--КОД--
spoofer by wannaflex:
#include <ntifs.h>
#include <ntddk.h>
#include <ntstrsafe.h>
#include <ntdddisk.h>
#include <scsi.h>
#include <nvme.h>
#include <ndis.h>
#include <fwpsk.h>
#include <fwpmk.h>
#pragma warning(disable: 4201 4214 4100 4054)
#define TAG_CORE 'xfDM'
typedef struct _X_EXT {
PDEVICE_OBJECT Lower;
UCHAR Serial[20];
BOOLEAN Init;
BOOLEAN Net;
} X_EXT, *PX_EXT;
typedef struct _X_LNK {
LIST_ENTRY List;
PDEVICE_OBJECT Filter;
} X_LNK, *PX_LNK;
static struct {
LIST_ENTRY Head;
KSPIN_LOCK Lock;
ULONG64 Seed[2];
HANDLE Wfp;
UINT64 Call;
} g;
NTSTATUS ObReferenceObjectByName(PUNICODE_STRING, ULONG, PACCESS_STATE, ACCESS_MASK, POBJECT_TYPE, KPROCESSOR_MODE, PVOID, PVOID*);
extern POBJECT_TYPE* IoDriverObjectType;
static __forceinline ULONG64 __stdcall Rnd() {
KLOCK_QUEUE_HANDLE h;
KeAcquireInStackQueuedSpinLock(&g.Lock, &h);
ULONG64 x = g.Seed[0], y = g_Seed[1];
g.Seed[0] = y;
x ^= x << 23; x ^= x >> 17; x ^= y ^ (y >> 26);
g.Seed[1] = x;
KeReleaseInStackQueuedSpinLock(&h);
return x + y;
}
static __forceinline VOID __stdcall Apply(PX_EXT e, PUCHAR d, ULONG l) {
if (!e->Init) {
for (int i = 0; i < 20; i++) e->Serial[i] = "0123456789ABCDEF"[Rnd() % 16];
e->Init = TRUE;
}
RtlCopyMemory(d, e->Serial, l > 20 ? 20 : l);
}
static NTSTATUS __stdcall Cmp(PDEVICE_OBJECT d, PIRP i, PVOID c) {
PX_EXT e = (PX_EXT)d->DeviceExtension;
PIO_STACK_LOCATION s = IoGetCurrentIrpStackLocation(i);
if (i->PendingReturned) IoMarkIrpPending(i);
if (!NT_SUCCESS(i->IoStatus.Status) || !i->AssociatedIrp.SystemBuffer) return i->IoStatus.Status;
ULONG code = s->Parameters.DeviceIoControl.IoControlCode;
ULONG out = s->Parameters.DeviceIoControl.OutputBufferLength;
__try {
if (code == IOCTL_STORAGE_QUERY_PROPERTY) {
PSTORAGE_DEVICE_DESCRIPTOR p = (PSTORAGE_DEVICE_DESCRIPTOR)i->AssociatedIrp.SystemBuffer;
if (p->SerialNumberOffset && (p->SerialNumberOffset + 4 < out)) Apply(e, (PUCHAR)p + p->SerialNumberOffset, 8);
}
else if (code == IOCTL_SCSI_PASS_THROUGH_DIRECT || code == IOCTL_SCSI_PASS_THROUGH) {
PSCSI_PASS_THROUGH p = (PSCSI_PASS_THROUGH)i->AssociatedIrp.SystemBuffer;
PUCHAR ptr = (code == IOCTL_SCSI_PASS_THROUGH_DIRECT && i->MdlAddress) ?
(PUCHAR)MmGetSystemAddressForMdlSafe(i->MdlAddress, NormalPagePriority) : ((p->DataBufferOffset && p->DataBufferOffset < out) ? (PUCHAR)p + p->DataBufferOffset : NULL);
if (ptr && p->Cdb[0] == SCSIOP_INQUIRY && (p->Cdb[1] & 0x1) && (p->Cdb[2] == 0x80 || p->Cdb[2] == 0x83)) Apply(e, ptr + 4, 8);
}
else if (code == IOCTL_NVME_PASS_THROUGH) Apply(e, ((PNVME_IDENTIFY_NAMESPACE_DATA)i->AssociatedIrp.SystemBuffer)->SerialNumber, 20);
} __except (1) { i->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR; }
return i->IoStatus.Status;
}
static NTSTATUS __stdcall Dsp(PDEVICE_OBJECT d, PIRP i) {
PX_EXT e = (PX_EXT)d->DeviceExtension;
PIO_STACK_LOCATION s = IoGetCurrentIrpStackLocation(i);
if (s->MajorFunction == IRP_MJ_DEVICE_CONTROL || s->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) {
IoCopyCurrentIrpStackLocationToNext(i);
IoSetCompletionRoutine(i, Cmp, NULL, 1, 1, 1);
return IoCallDriver(e->Lower, i);
}
if (s->MajorFunction == IRP_MJ_PNP && s->MinorFunction == IRP_MN_REMOVE_DEVICE) {
IoSkipCurrentIrpStackLocation(i);
NTSTATUS st = IoCallDriver(e->Lower, i);
IoDetachDevice(e->Lower);
IoDeleteDevice(d);
return st;
}
if (s->MajorFunction == IRP_MJ_POWER) PoStartNextPowerIrp(i);
IoSkipCurrentIrpStackLocation(i);
return IoCallDriver(e->Lower, i);
}
static VOID NTAPI L2(const FWPS_INCOMING_VALUES0* v, const FWPS_INCOMING_METADATA_VALUES* m, PVOID l, const VOID* c, const FWPS_FILTER* f, UINT64 ctx, FWPS_CLASSIFY_OUT* out) {
PNET_BUFFER_LIST nbl = (PNET_BUFFER_LIST)l;
if (nbl) {
for (PNET_BUFFER nb = nbl->FirstNetBuffer; nb; nb = nb->Next) {
PUCHAR r = NdisGetDataBuffer(nb, 14, NULL, 1, 0);
if (r) { r[6] = 0x00; r[7] = 0x15; r[8] = 0x5D; r[9] = 0xDE; r[10] = 0xAD; r[11] = (UCHAR)(__rdtsc() & 0xFF); }
}
}
out->actionType = FWP_ACTION_PERMIT;
}
static NTSTATUS __stdcall Att(PDRIVER_OBJECT drv, PCWSTR name, BOOLEAN net) {
UNICODE_STRING us;
RtlInitUnicodeString(&us, name);
PDRIVER_OBJECT tgt = NULL;
if (!NT_SUCCESS(ObReferenceObjectByName(&us, 64, NULL, 0, *IoDriverObjectType, KernelMode, NULL, (PVOID*)&tgt))) return 0xC0000001;
for (PDEVICE_OBJECT c = tgt->DeviceObject; c; c = c->NextDevice) {
PDEVICE_OBJECT f = NULL;
if (NT_SUCCESS(IoCreateDevice(drv, sizeof(X_EXT), NULL, c->DeviceType, 0, 0, &f))) {
PX_EXT e = (PX_EXT)f->DeviceExtension;
e->Lower = IoAttachDeviceToDeviceStack(f, c);
if (e->Lower) {
e->Net = net;
f->Flags |= (c->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE));
f->Flags &= ~DO_DEVICE_INITIALIZING;
PX_LNK l = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(X_LNK), TAG_CORE);
if (l) { l->Filter = f; ExInterlockedInsertTailList(&g.Head, &l->List, &g.Lock); }
} else IoDeleteDevice(f);
}
}
ObDereferenceObject(tgt);
return 0;
}
VOID __stdcall Unload(PDRIVER_OBJECT drv) {
if (g.Wfp) { FwpsCalloutUnregisterById(g.Call); FwpmEngineClose(g.Wfp); }
while (!IsListEmpty(&g.Head)) {
PLIST_ENTRY le = ExInterlockedRemoveHeadList(&g.Head, &g.Lock);
PX_LNK l = CONTAINING_RECORD(le, X_LNK, List);
IoDetachDevice(((PX_EXT)l->Filter->DeviceExtension)->Lower);
IoDeleteDevice(l->Filter);
ExFreePoolWithTag(l, TAG_CORE);
}
}
NTSTATUS DriverEntry(PDRIVER_OBJECT drv, PUNICODE_STRING reg) {
LARGE_INTEGER t;
KeQueryTickCount(&t);
g.Seed[0] = t.QuadPart; g.Seed[1] = __rdtsc();
InitializeListHead(&g.Head);
KeInitializeSpinLock(&g.Lock);
for (ULONG i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) drv->MajorFunction[i] = Dsp;
drv->DriverUnload = Unload;
Att(drv, L"\\Driver\\stornvme", 0);
Att(drv, L"\\Driver\\storahci", 0);
FWPM_SESSION sess = {0};
if (NT_SUCCESS(FwpmEngineOpen(NULL, RPC_C_AUTHN_WINNT, NULL, &sess, &g.Wfp))) {
FWPS_CALLOUT call = {0};
call.calloutKey = (GUID){0x87654321, 0x1234, 0x4321, {0x88,0x77,0x66,0x55,0x44,0x33,0x22,0x11}};
call.classifyFn = L2;
FwpsCalloutRegister(g.Wfp, &call, &g.Call);
}
return 0;
}
Последнее редактирование:
