Anti Cheats บางตัวอาศัยหลักการตรวจสอบแบบง่ายๆ เช่นการตรวจสอบชื่อไฟล์ที่รันอยู่ในขณะนั้น หรือ Title ของตัวโปรแกรม ผมจะยกตัวอย่างเรื่องของการตรวจสอบ Title ของโปรแกรม ทั้งนี้ตัวอย่างจะมีทั้งฝั่ง Anti Cheats และฝั่งของการ Bypass เพื่อให้เข้าใจกันทั้งสองฝ่าย
Ex.1 Code การตรวจสอบการเปิด Cheat Engine 6.3 แบบง่ายๆ
#include <windows.h>
#include <iostream>
using namespace std;
void main()
{
while(1)
{
if(FindWindowA(NULL,"Cheat Engine 6.3"))
{
printf("Detected Cheat Engine...\n");
exit(0);
}
Sleep(500);
}
}
จากโค๊ดตัวอย่างนี้พอจะมองการทำงานออกดังนี้คือ เมื่อเปิดโปรแกรม CE 6.3 แล้ว ตัวโปรแกรมจะหาค่า Title ออกมาได้และจะหยุดการทำงานของโปรแกรม
ดังนั้นการบายพาสแบบง่ายๆของเราก็จะมีดังต่อไปนี้
- เปลี่ยน Title ของตัว CE 6.3 เป็นชื่ออื่น การเปลี่ยน Title ของ WindowApplication ผมขอใช้ Tool ตัวนึงแล้วกันนะครับ คือ Window Title Changer โดยการเปิดโปรแกรมขึ้นมา แล้วทำการเปลี่ยน Title ของตัว CE 6.3 เป็นชื่ออื่น
จะเห็นได้ว่าเมื่อเปิด CE 6.3 แล้วโปรแกรมยังทำงานอยู่ไม่ปิดตัวเอง แสดงว่าการบายพาสของเราสามารถใช้งานได้
- Nop การทำงานของโปรแกรม วิธีนี้จะยากขึ้นมาหน่อย แต่สำหรับคนที่ใช้ Debugger เป็นคงไม่น่าจะมีปัญหา ผมเปิดกับ IDA ก็จะเห็น Assembly ดังนี้
.text:00401000 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:00401000 _main proc near ; CODE XREF: __tmainCRTStartup+10A p
.text:00401000
.text:00401000 argc = dword ptr 4
.text:00401000 argv = dword ptr 8
.text:00401000 envp = dword ptr 0Ch
.text:00401000
.text:00401000 push esi
.text:00401001 mov esi, ds:__imp__FindWindowA@8 ; FindWindowA(x,x)
.text:00401007 push offset WindowName ; "Cheat Engine 6.3"
.text:0040100C push 0 ; lpClassName
.text:0040100E call esi ; FindWindowA(x,x) ; FindWindowA(x,x)
.text:00401010 test eax, eax
.text:00401012 jnz short loc_401035
.text:00401014 push edi
.text:00401015 mov edi, ds:__imp__Sleep@4 ; Sleep(x)
.text:0040101B jmp short loc_401020
.text:0040101B ; ---------------------------------------------------------------------------
.text:0040101D align 10h
.text:00401020
.text:00401020 loc_401020: ; CODE XREF: _main+1B j
.text:00401020 ; _main+32 j
.text:00401020 push 1F4h ; dwMilliseconds
.text:00401025 call edi ; Sleep(x) ; Sleep(x)
.text:00401027 push offset WindowName ; "Cheat Engine 6.3"
.text:0040102C push 0 ; lpClassName
.text:0040102E call esi ; FindWindowA(x,x) ; FindWindowA(x,x)
.text:00401030 test eax, eax
.text:00401032 jz short loc_401020
.text:00401034 pop edi
.text:00401035
.text:00401035 loc_401035: ; CODE XREF: _main+12 j
.text:00401035 push offset Format ; "Detected Cheat Engine...\n"
.text:0040103A call ds:__imp__printf
.text:00401040 add esp, 4
.text:00401043 push 0 ; Code
.text:00401045 call ds:__imp__exit
.text:0040104B ; ---------------------------------------------------------------------------
.text:0040104B pop esi
.text:0040104B _main endp ;
หากเราต้องการจะบายพาสก็ให้ทำการ nop ที่ .text:00401012 จำนวน 2byte ก็จะสามารถปิดการทำงานตรงส่วนนี้ได้
- การ Hook Windows API ในเมื่อเรารู้ว่าการตรวจสอบ Anti Cheat ของตัวโปรแกรม คือการใช้ FindWindowA แล้ว
เราก็สามารถบายพาสให้การส่งค่าของฟังก์ชั่นเป็นค่า NULL ตลอด ทำให้ไม่สามารถตรวจจับได้ และเป็นวิธีที่ไม่ต้องแก้ไขไฟล์อีกด้วย ตัวอย่าง antihack.dll ของตัวโปรแกรมๆ นึง เน้นว่าตัวอย่างนะครับ
จะเห็นได้ว่ามีการตรวจสอบ Title เยอะมาก ซึ่งการที่จะต้องมานั่ง patch nop โปรแกรมคงแก้หลายจุด(ในกรณีต้องใช้เครื่องมือในการโกงหลายอย่าง แต่ถ้าอย่างเดียวก็แก้ตัวที่ต้องใช้ละกัน :p) เอาละครับมาเขียน Code กันซักหน่อยแบบง่ายๆ
#include <windows.h>
#include <detours.h>
#pragma comment (lib, "detours.lib")
HWND*(__stdcall*pFindWindowA)(LPCTSTR ,LPCTSTR ) = NULL;
HWND __stdcall myFindWindowA(LPCTSTR lpClassName,LPCTSTR lpWindowName)
{
return NULL;
}
BOOL __stdcall DllMain(HMODULE module, DWORD reason, LPVOID reserved)
{
if(reason == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(module);
pFindWindowA = (HWND*(__stdcall*)(LPCTSTR ,LPCTSTR ))DetourFindFunction("User32.dll","FindWindowA");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)pFindWindowA, myFindWindowA);
DetourTransactionCommit();
}
else if(reason == DLL_PROCESS_DETACH)
{
}
return TRUE;
}
จาก Code ข้างต้นผมใช้ Microsoft Detours3.0 นะครับ เสร็จแล้วก็เอา dll ที่คอมไพล์ได้ไปฉีดใส่โปรแกรมที่ต้องการบายพาส แค่นี้ก็เสร็จแล้ว เป็นการบายพาสเบื้องต้น ไม่ได้ยุ่งยากอะไร ^^
อ้างอิง
FindWindowA : http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499%28v=vs.85%29.aspx
Window Title Changer : http://www.murgee.com/window-title-changer/
Microsoft Detours : http://research.microsoft.com/en-us/projects/detours/