안녕하세요.
순수 취미와 보안의 관점에서 게임가드가 보호하는 프로세스공간의 기억기페이지를 변조하기 위한 한가지 접근법을 테스트하여 본 결과를 공개합니다.
게임가드가 Ring3과 Ring0준위에서 목적하는 프로세스를 보호한다는것은 잘 알려진 사실입니다.
제가 DLL 인젝션기법으로 대상프로세스에의 Attache는 일단 성공하였습니다. (Ring0준위의 접근법)
분석결과를 종합하면 다음과 같습니다.
1. 게임가드는 Ring3준위에서 인라인패치한 주소의 내용이 변경되지 않도록 리얼타임으로 감시하여 복원합니다.
게임가드는 대체로 보안과 직접적으로 관계되거나 크리티컬한 대부분의 API(LoadLibraryA, LoadLibraryW, ReadProcessMemory, WriteProcessMemory ...) 들을 인라인패치합니다. Olly나 다른 디버거로 패치된 API들의 선두주소에 가보면
JMP ==> (게임가드의 인젝션된 모듈내의 주소 )
와 같이 변조된것을 확인할수 있습니다.
만일 Attache시킨 모듈에서 이 패치된 내용을 변경시키면( WriteProcessMemory()를 호출하지 않고 직접 메모리에 접근...) 게임가드는 즉시에 변경된 페이지를 복원시킵니다.
만일 원격프로세스에서 WriteProcessMemory()함수를 사용하여 해당 주소에 접근하려고 하면 당연히 가드에 의해 실패하게 됩니다.
2. 게임가드는 인라인패치한 주소외에도 페지보호속성이 PAGE_READEXCUTE인 령역의 변경여부를 실시간으로 감시하여 복원합니다.
테스트의 목적으로 인라인패치되지 않은 WS2_32.dll의 WSASend()함수의 머리부를 직접 접근하여 변경시켜보았습니다. 변경후 다시 해당 주소의 메모리를 읽어보면 원래와 같음을 확인할수 있습니다.
3. 게임가드의 구성요소인 별도의 프로세스는 API들이 패치되어있지 않습니다.
이게 무슨 소리냐?~ 앞에서 WriteProcessMemory()함수를 호출하여 보호되는 프로세스의 메모리에 접근하려고 하면 API가 실패를 귀환한다고 하엿죠? 하지만 게임가드의 프로세스상황에서 WriteMemory()나 OpenProcess() 함수들을 사용하여 보호되는 프로세스에 접근하면 성공한다는 뜻입니다. 즉 게임가드의 프로세스에 인젝션하여 보호되는 프로세스에 접근할수 있는 가능성이 있다는것입니다.
하지만... API의 호출은 일단 성공하였지만 프로세스내에 로딩된 게임가드모듈에 의해 다시 원래대로 복원되여버립니다.
앞으로 Ring0 준위에서 보호되는 프로세스의 페이지를 변조하려고 시도하는 경우 게임가드가 어떻게 대처하는가에 대한 테스트결과를 추가로 올리려고 합니다. 아마 역시 실패하리라는 예감이 지배적이지만...
결론을 적어본다면 게임가드의 페이지 보호기능을 무력화하지 안고서는 성공할수 없다고 봅니다.



