본문 바로가기

Server/Security

스핵... 어떻게 막을 것인가?!

* Speed Hack
 
스핵을 사용하게 되면, 게임의 밸런스가 무너지고 이는 게임의 재미요소를 극도로 반감 시키는 불량 요소의 으뜸일 것입니다.
또한, 유저의 스핵은 인터넷 라인을 통해 급속도로 퍼지기 때문에 미연에 필수적으로 방어를 해 두어야 합니다.
 
우선, 스핵의 기본 원리와 대책을 강구하도록 하겠습니다. 컴퓨터의 타이머는 네트워크 게임에 있어서 게임의 여러요소들의 동기화를 맞출때 유용합니다. 컴퓨터의 클럭은 달라도, 시간은 같게 흐르니까요. 주로 애니메이션을 출력할때 유용한데요.
 
스핵은 우리의 유용한 타이머를 요상하게 조작하여,  에니메이션을 이상하게 만들죠. 에니메이션뿐 아니라 그 에니메이션 수행에 따른 프로그램 로직에도 영향을 줄수 있습니다.
 
방법1.
-------------------------------
주로. 시스템타임을 얻을경우, 다음 주요한 3가지 API 를 사용합니다.
  GetTickCount()
  timeGetTime()
  QueryPerformanceCounter()
유용하게 쉽게 사용되지만, 3가지 API 는 모두 스핵의 영향을 받습니다.

방법2.
-------------------------------
다음 API 는 일반적인 스핵의 영향권 밖입니다. 왜냐면, 이것은 시간을 체크하는 메인보드 상의 칩이 다르기 때문이죠,
  _ftime()
  _ftime64()
  GetSystemTime()
 
SYSTEMTIME 구조체의 wMilliseconds 라는 멤버를 사용하지면 밀리세컨드의 값이 넘어옵니다. wMilliseconds 의 값이 0이 될때, 1초가 지났음을 알수 있죠. 로직을 잘짜면 사용할 수 있습니다. _ftime(), _ftime64 일경우엔 각각의 구조체에 wMilliseconds 와 같은 역할을 하는 멤버가 있습니다
 
하지만, 이 API 의 단점이 있습니다. Win2000 이상의 OS 환경에서는 잘 동작하지만, 역시나 그 이하버전의 OS 에서는 제대로 동작을 하지 못합니다. 그래서 정밀한 시간 체크가 불가능합니다.
예전에 테스트해본결과, 10의 자리를 날려먹습니다 (결과적으로 에니메이션등이 끊기게 됩니다.)
또한 스핵이 SetSystemTime() API 를 이용하던가 해서, 시스템 시간을 빠르게 돌리면 어쩔수 없겠죠..
(아마 이렇게 되면, 테스크바의 윈도우 시계도 빨리 돌거라 예상됩니다..^^;; )

방법3.
-------------------------------
결국, 2가지 시간계산 방법을 병행하는 방법만이 남았습니다.
1) 평소에는 timeGetTime() 으로 시간을 체크한다
2) 그러는 와중에 GetSystemTime() 과 비교를 수행한다
3) 만약에 두개의 시간이 비슷하지 않다면(여기서는 Boundary 가 존재하겠죠.. timeGetTime() 에서 얻어진 시간을 기준으로 양쪽으로 +-5 정도가 적당할듯합니다), GetSystemTime() 에서 얻어진 값으로 시간 체크를 한다.
4) 결과적으로 Win98 에서도 정밀한 시간체크가 가능하며, 사용자가  스핵을 쓴다면, Win98 에서는 부드럽지 않은 에니메이션만 보게 될것입니다.

_ftime 이나 GetSystemTime 역시 후킹의 대상입니다. 별 관계 없습니다. 더 나은 방법으로는 그리 정밀하진 않지만 WM_TIMER 를 사용해서 시간누적치를 후킹의 대상이 되지 않는 OS 의 타이머와 비교하는 되니까요. ㅎ
또 다른 방법으로는 CPU 의 리얼타임 클럭 카운터인 rdtsc 를 이용하는 것인데요, 이것에서 CPU 클럭을 나누면 실시간을 얻을 수 있습니다. 하지만, 한가지 단점이 있는데 노트북처럼 CPU 클럭을 중간에 멋대로 바꿔서 전원관리 하게되면 낭패. (speed step 기술)


[결론]
스핵의 유일한 대처법은 서버에서 체크해준다... 쿵!