Merhaba,
@flusya23
Anladığım kadarıyla bir tür AC sınıfında engelleme yapmaya çalışıyorsunuz. Öncelikle şunları belirtmek isterim.
Oyunlar da hile, oyun sunucusu tarafından sağlanan sabit limit altı bir değeri, DPR (Data pointer) kullanarak limit üstü değere yükseltmek ve sunucunun yasakladığı bir değeri driver tarafından güvenilir olarak gösterip tersine döndürmeyi sağlar.
Bunun en basit şekilde ifadesi ise şu şekilde mümkündür, hilenin kendisi aslında oyun için bir tehdit değildir. Hileyi yasaklamak yerine, hileyi oyuna güvenli olarak tanıtmayı sağlayan driver'i yasaklamak gerekiyor.
Bu örneğimiz de, EAC yani (Easy Anti Cheat) tarafından güvenli olarak görülen ancak şu an warez'e düşmüş bir LD' yani Load Driveri öncelikle tanıyalım;
//Creates DeviceIoRequest for DiskIoctlSmartReceiveDriveData in Disk.sys
bool __fastcall HwidGen::1(int a1, struct _DEVICE_OBJECT *a2, __int64 a3)
{
bool v3; // bl
unsigned __int16 *v4; // r12
struct _DEVICE_OBJECT *v5; // rbp
int v6; // edi
__int64 v7; // rsi
int v8; // edi
unsigned __int64 v9; // rbp
unsigned __int64 v10; // rdi
unsigned __int64 v11; // rdx
unsigned __int64 v12; // r11
char v13; // cl
char v14; // al
unsigned __int16 v16[4]; // [rsp+30h] [rbp-C8h]
char *v17; // [rsp+38h] [rbp-C0h]
char v18; // [rsp+40h] [rbp-B8h]
char v19; // [rsp+4Ah] [rbp-AEh]
char v20; // [rsp+6Eh] [rbp-8Ah]
char v21; // [rsp+6Fh] [rbp-89h]
char v22; // [rsp+70h] [rbp-88h]
char v23[127]; // [rsp+71h] [rbp-87h]
v3 = 0;
v4 = a3;
v5 = a2;
v6 = a1;
if ( a2 && a3 )
{
v7 = AllocateWrapper(529i64);
if ( !v7 )
return v3;
*v7 = 0i64;
*(v7 + 8) = 0i64;
*(v7 + 16) = 0;
sub_1F610(&v18, 0i64, 0x21ui64);
v19 = -20;
if ( IoBuildDeviceIoControlRequest(&qword_7BF38[42], v5, &v18, 0x21u, v7, 0x211u) >= 0 )// DiskIoctlSmartReceiveDriveData
{
v8 = v6 - 2;
if ( !v8 )
{
v9 = v7 + 0x46;
v10 = 40i64;
goto LABEL_9;
}
if ( v8 == 1 )
{
v9 = v7 + 0x24;
v10 = 20i64;
LABEL_9:
if ( v9 && v10 > 0 )
{
sub_1F610(&v22, 0i64, 0x80ui64);
sub_1F2C0(&v22, v9, v10);
v11 = v10 - 1;
v12 = 0i64;
if ( v10 - 1 > 0 )
{
do
{
v13 = *(&v22 + v12);
v14 = v23[v12];
v12 += 2i64;
*(&v20 + v12) = v14;
*(&v21 + v12) = v13;
}
while ( v12 < v11 );
if ( v11 > 0 )
{
do
{
if ( *(&v22 + v11) != 32 )
break;
*(&v22 + v11--) = 0;
}
while ( v11 );
}
}
v17 = &v22;
CopyStr(v16, &v22);
v3 = MultiByteToUnicode(v4, v16) >= 0;
}
goto LABEL_17;
}
}
LABEL_17:
FreePoolWithTag(v7);
return v3;
}
return 0;
}
//Creates DeviceIoRequest for IOCTL_STORAGE_QUERY_PROPERTY in storport.sys
bool __fastcall HwidGen::2(int a1, __int64 a2, __int64 a3)
{
bool v3; // di
unsigned __int16 *v4; // r13
struct _DEVICE_OBJECT *v5; // r12
int v6; // ebx
unsigned __int64 v7; // rsi
int *v8; // rax
int *v9; // rbp
char *v10; // rcx
int v11; // ebx
unsigned __int64 v12; // rdx
unsigned __int64 v13; // rcx
unsigned __int64 v14; // rcx
unsigned __int64 v15; // rbx
__int64 v17; // [rsp+30h] [rbp-B8h]
int v18; // [rsp+38h] [rbp-B0h]
unsigned __int16 v19[4]; // [rsp+40h] [rbp-A8h]
char *v20; // [rsp+48h] [rbp-A0h]
char v21[128]; // [rsp+50h] [rbp-98h]
__int64 a1a; // [rsp+F8h] [rbp+10h]
v3 = 0;
v4 = a3;
v5 = a2;
v6 = a1;
v7 = 0i64;
if ( a2 && a3 )
{
a1a = 0i64;
v18 = 0;
v17 = 0i64;
if ( IoBuildDeviceIoControlRequest(0x2D1400u, a2, &v17, 0xCu, &a1a, 8u) < 0 )// SCSIPort - IOCTL_STORAGE_QUERY_PROPERTY
return v3;
if ( HIDWORD(a1a) <= 0x28 )
return v3;
v8 = AllocateWrapper(HIDWORD(a1a));
v9 = v8;
if ( !v8 )
return v3;
sub_1F610(v8, 0i64, HIDWORD(a1a));
v18 = 0;
v17 = 0i64;
if ( IoBuildDeviceIoControlRequest(0x2D1400u, v5, &v17, 0xCu, v9, HIDWORD(a1a)) < 0 )
goto LABEL_29;
v10 = v9 + HIDWORD(a1a);
v11 = v6 - 2;
if ( v11 )
{
if ( v11 != 1 || !v9[6] )
goto LABEL_29;
v12 = v9 + v9[6];
if ( v12 >= v9 && v12 < v10 )
{
v13 = &v10[-v12];
if ( v12 )
{
if ( v13 > 0 )
{
do
{
if ( !*(v7 + v12) )
break;
++v7;
}
while ( v7 < v13 );
}
goto LABEL_24;
}
LABEL_29:
FreePoolWithTag(v9);
return v3;
}
}
else
{
if ( !v9[4] )
goto LABEL_29;
v12 = v9 + v9[4];
if ( v12 >= v9 && v12 < v10 )
{
v14 = &v10[-v12];
if ( v12 )
{
if ( v14 > 0 )
{
do
{
if ( !*(v7 + v12) )
break;
++v7;
}
while ( v7 < v14 );
}
goto LABEL_24;
}
goto LABEL_29;
}
}
LABEL_24:
if ( v12 && v7 > 0 )
{
v15 = 0x7Fi64;
if ( v7 < 0x7F )
v15 = v7;
sub_1F2C0(v21, v12, v15);
v20 = v21;
v21[v15] = 0;
CopyStr(v19, v21);
v3 = MultiByteToUnicode(v4, v19) >= 0;
}
goto LABEL_29;
}
return 0;
}
//Function seems to return various registry paths
signed __int64 __fastcall HwidGen::3(unsigned int a1)
{
unsigned int v1; // ecx
int v2; // ecx
int v3; // ecx
int v4; // ecx
unsigned int v6; // ecx
int v7; // ecx
int v8; // ecx
unsigned int v9; // ecx
int v10; // ecx
int v11; // ecx
int v12; // ecx
unsigned int v13; // ecx
int v14; // ecx
int v15; // ecx
if ( a1 <= 0xC )
{
if ( a1 == 12 )
return 0xFFFF8B002A221952i64; // \Registry\Machine\Hardware\Description\System\CentralProcessor\0
if ( a1 > 6 )
{
v6 = a1 - 8;
if ( !v6 )
return 0xFFFF8B002A221840i64; // SystemProductName
v7 = v6 - 1;
if ( !v7 )
return 0xFFFF8B002A221864i64; // \Registry\Machine\Hardware\DeviceMap\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0
v8 = v7 - 1;
if ( !v8 )
return 0xFFFF8B002A221922i64; // Identifier
if ( v8 == 1 )
return 0xFFFF8B002A221938i64; // SerialNumber
}
else
{
if ( a1 == 6 )
return 0xFFFF8B002A22181Ai64; // SystemManufacturer
v1 = a1 - 1;
if ( !v1 )
return 0xFFFF8B002A2216CEi64; // \Registry\Machine\System\CurrentControlSet\Control\SystemInformation
v2 = v1 - 1;
if ( !v2 )
return 0xFFFF8B002A221758i64; // ComputerHardwareId
v3 = v2 - 1;
if ( !v3 )
return 0xFFFF8B002A22177Ei64; // \Registry\Machine\Hardware\Description\System\BIOS
v4 = v3 - 1;
if ( !v4 )
return 0xFFFF8B002A2217E4i64; // BIOSVendor
if ( v4 == 1 )
return 0xFFFF8B002A2217FAi64; // BIOSReleaseDate
}
return 0i64;
}
if ( a1 <= 0x12 )
{
if ( a1 == 18 )
return 0xFFFF8B002A221B72i64; // ProductId
v9 = a1 - 13;
if ( !v9 )
return 0xFFFF8B002A2219D4i64; // ProcessorNameString
v10 = v9 - 1;
if ( !v10 )
return 0xFFFF8B002A2219FCi64; // \Registry\Machine\System\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}\0000
v11 = v10 - 1;
if ( v11 )
{
v12 = v11 - 1;
if ( !v12 )
return 0xFFFF8B002A221ADCi64; // \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion
if ( v12 == 1 )
return 0xFFFF8B002A221B5Ai64; // InstallDate
return 0i64;
}
return 0xFFFF8B002A221AC6i64; // DriverDesc
}
v13 = a1 - 19;
if ( !v13 )
return 0xFFFF8B002A221B86i64; // \Registry\Machine\Software\Microsoft\Windows\CurrentVersion\WindowsUpdate
v14 = v13 - 1;
if ( !v14 )
return 0xFFFF8B002A221C1Ai64; // SusClientId
v15 = v14 - 1;
if ( v15 )
{
if ( v15 != 1 )
return 0i64;
return 0xFFFF8B002A221AC6i64;
}
return 0xFFFF8B002A221C32i64; // \Registry\Machine\System\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}\0001
}
Burada örnek vermiş olduğum EAC tarafından güvenli görülen ve hilenin çalıştırılabilmesini sağlayan. Gerek Defender, gerekse oyun sunucusu tarafından güvenli ön yükleme yapmasına izin veren, "Yükleme Sürücüsü bir diğer adıyla Load Driver" oluyor.
Hileler, VC ile arayüz şeklinde tasarlandıkları executable doğrudan çalıştırılarak çalışan uygulamalar değildir. Bu executable datayı, yükleyici sürücüsü oyuna enject eder ve arayüz driver tarafından oyuna sunulduğundan oyun tarafından zararsız olarak görüleceğinden çalışacaktır.
İşlem kısaca şunu yapıyor;
- Windows Defender yükleyici sürücüsü tanıyor, eğer güçlü bir algoritmaya sahipse bunu anlık çözemiyor ve sürücüden şu onayı alıyor.
(Ben güvenli bir yazılımım, beni engelleme ve bırak)
- Yükleyici sürücüsü Windows Güvenliği tarafından güvenli ön yüklemeye dahil ediliyor.
- Oyun algoritması, defender tarafından güvenli sayılan sürücüyü kendinden daha üst seviye bir imza olarak görüyor ve izin veriyor.
- Sürücü, HEXDECIMAL bir yöntem kullanarak istemci tarafında bir kapı oluşturarak içerisinde barındırdığı hile yazılımının çalıştırılmasına izin veriyor. Ancak bu izin verme işlemini oyun göremiyor, ancak ve ancak yazılım tarafından oyunun tespit etmesine neden olacak bir pointer'in çalıştırılacağı ana kadar.
Peki ne yapmalısınız ?
Öncelikle, hileyi engellemek yerine piyasada bulunan AC'ler için bir nevi tersine mühendislik kullanarak ByPass edilmesini sağlayan Load Driver (Yükleme sürücülerini) tespit etmeli ve bunlara karşın misilleme metotları (Sürücünün güvenli olup olmadığını) uygulamanız gerekiyor. Her sürücü güvensiz değildir, bu nedenle profesyonel bir anlamda bunları incelemelisiniz. Windows'un ana sürücülerini de devre dışı bırakabileceğinizden bu oyun sunucusunun windows tarafından yanıtsız kalmasına da neden olabilir.
Buna örnek olarak lalaker01'in yazılımları örnek verilebilir, içerisin de bulunan sürücü tarafından Windows tarafından güvenli görülüyor, buda haliyle oyun tarafından da güvenilir olarak görülüyor.
Game sunucu kaynağına ekleyeceğiniz, şartlar ve sınırlamalar oyunun daha fazla yük altında çalışmasını sağlayacaktır.
NoMercy veya Easy Anti Cheat'in SDK sürümlerini indirmeli, ve bu tür sürücülere nasıl önlemler aldıklarını inceleyebilirsiniz.
Bunun için size önerebileceğim en başarılı web sitesi,
web sayfasıdır. (Umarım kural dışı bir bağlantı değildir)
Vakit ayırdığınız için teşekkür ederim.
Keyifli forumlar..