(스포일러 주의) 두근두근 문예부와 자체 수정 코드

인터넷에서 두근두근 문예부라는 게임이 유행인 모양이다. 독자들 역시 픽션과 현실을 구분을 잘 하므로 설정들을 진지하게 받아들이는 사람은 없을 것이다. 그러나 한 십 년 전에 각종 픽션들을 과학적으로 증명해보는 시리즈가 유행했듯, 우리도 한 번 검증해볼 수는 있지 않을까. 까놓고 얘기하면 Ren’Py라는 그 장르를 위한 스크립트 언어로 제작한 건데 이 악물고 이러니 저러니 하는 것도 이상할 것이다. 그러니까 너무 진지하게 보지 마시고 흥미 본위로 보시길. 덤으로 제목에 표기했듯 본문은 스포일러 덩어리이므로, 그런 거 싫어하시는 분들은 보지 말 것.

기본 체크

나무위키를 살펴보면 다음과 같은 말이 있다.

게임 제작자 중 한 명과 개인적인 친분이 있어 이런저런 말을 많이 들었다고 한다. 원래 기획했던 게임의 방향과 강도를 100으로 친다면 지금 발매된 게임은 30정도 밖에 안된다는 등의 말을 한 적이 있다. 게임이 다른 게임이나 윈도우 자체에 침투할 정도였다고 하는데 바이러스로 오해받을 수도 있으므로 자제한 듯.

일단 다른 게임에 침투하는 건 어렵지 않다. 스팀은 이상하게도, 게임 폴더의 생성/쓰기/수정 권한을 Program Files 폴더처럼 강력하게 설정하지 않기 때문이다. 원래 거기다 그냥 설치하면 윗 폴더의 권한이 계승되므로 Program Files 산하 폴더의 경우 자유로운 생성/쓰기/수정이 불가능한데, mod 같은 것들 때문에 Program Files에 설치할 경우에도 상속을 끊고 인위적으로 더 낮게 설정한 모양이었다.

하지만 윈도우 자체에 침투하는 것은 얘기가 다르다. 일단 두근두근 문예부는 관리자 권한을 요구하지 않는다. 거기다 코드사인도 되어있지 않는데, 그런 프로그램이 윈도우를 장악하면 완벽한 바이러스 아닌가. 제 4의 벽을 넘기 전에 그 동네의 골목대장인 백신한테 머리채를 붙잡혀 검역소로 끌려가지 않으면 다행일 것이다. 물론 코드사인을 했더라도, 그런 악성 프로그램을 배포한 경우는 그 인증서의 평판이 바닥으로 떨어져 윈도우의 SmartScreen에 걸린다.

캐릭터 파일의 인식 범위

chr 파일에 실제 캐릭터의 데이터가 들어있지 않은 건 다들 알 것이다. 그렇다면 게임은 이 파일들을 어떻게 쓰는 걸까? 그래도 게임 내에서는 해당 캐릭터를 비유하는 소재이니 무결성 체크, 혹은 최소한 변경 날짜나 사이즈 체크는 하는 걸까? Process Monitor로 한 번 확인해 보았다.

오직 존재 확인만

일단 무결성 체크를 하지 않는다는 건 확실해 졌지만, 한 가지 더 확인을 해 보자. steam에서 게임을 설치하면, 해당 게임이 자신의 폴더를 읽고 쓰고 수정할 수 있도록 권한을 열어준다. 여기서 chr 파일들에 대한 읽기 권한을 없애보았다.

유저의 읽기 권한을 빼앗으면 캐릭터가 죽는다.

그럼 죽는다. 당연하지만 그녀들은 관리자일 수 없었고, 플레이어일 수도 없었다. 관리자 권한을 굳이 쓰지 않아도 내 권한으로는 읽기와 수정 모두 가능했지만, 그녀들은 유저 프로그램의 한계조차 탈출하지 못했다. 그렇다면 chr 파일들을 빈 파일로 대체하면 어떨까?

chr 파일들을 빈 파일로 대체했다.

파일들이 빈 껍데기만 남아도 관계 없다.

파일 사이즈나 무결성같은 걸 체크하지는 않는 모양이다. 비록 실제 내용이 있는 파일들이 아니라 단순 떡밥이었더라도 약간 아쉬웠다. 그러면 그걸 디렉토리로 대체해버리면 어떨까?

파일들을 폴더로 대체해보았다.

폴더가 되는 건 참을 수 없었던 모양이다.

폴더가 되면 죽는다. 그 이유는 언어의 파일 존재 유무 체크 여부가, 해당 객체가 파일인지 폴더인지도 확인하기 때문이다. 이로서 이 작품의 체크 루틴이 단순히 그 언어의 파일 존재 여부 체크 함수로만 이루어져 있음을 확인했다.

오래된 미래: 자체 수정 코드

요즘에는 메타 픽션 게임에서 종종 자기 자신을 인식하고 세계(게임)를 개변하는 장치로 ‘게임의 수정’이라는 소재가 쓰이는 모양이다. 하지만 이것은 ‘자체 수정 코드(self-modifying code)’라는 개념으로 전혀 새롭지도, 무섭지도 않다. 오히려 프로그램은 고정된 것이라고 믿는 사람들이 잘못된 것이며, 심지어 요즘엔 한 물 가서 (네이티브 수준에서는) 거의 안 쓰이기까지 한다.

프로그램을 어느 정도 배운 사람들은 여러가지 상황 중 하나를 선택해서 반복해서 돌려야 할 때 if-else나 case문을 생각하겠지만, 옛날에는 이러기엔 컴퓨팅 파워의 제약이 컸다. 구체적으로는 램 용량도 많이 잡아먹고 시간도 오래 걸리게 된다. 따라서 고칠 부분만 메모리 상에서 간단하게 고쳐서 돌리면, 램도 적게 먹고 시간도 훨씬 빠르게 되었다. 요즘도 성능이 제약된 임베디드 머신에선 종종 쓰이는 테크닉이다.

하지만 컴퓨팅 파워가 커지고 대다수의 고정된 프로그램에 맞추어 최적화를 하다 보니, 성능 차이도 크게 나지 않으면서 디버깅만 귀찮고 보안 문제가 생겨서 요즘은 많이 쓰지 않는다. 특히 W^X 보안(흔히 NX 비트, DEP라고 부르는 것으로, 실행할 수 있는 메모리는 쓰지 못하고, 쓸 수 있는 메모리는 실행할 수 없다는 보안 개념) 개념이 등장하면서, 네이티브 수준에서는  바이러스, 백신을 제외하고는 리스크가 커졌다.

그래도 내가 이 개념을 처음 접했던 Beautiful Code에서 언급한 것처럼 가상 머신류 언어(Python, C# 등)에서는 이런 최적화가 종종 쓰이고, eval문으로 이런 인터페이스를 제공하는 경우도 있다. 물론 보안 문제가 해결된 건 아니므로 eval문은 보통 권장되지 않는다. 게다가 Ren’Py, Python이라는 두 단계 레이어가 더 있는 이 프로그램에서 연출을 위해 이런 기법을 썼다간 디버깅 지옥에 안 그래도 무거운 프로그램이 더 무거워질 것이다. 코드사인 인증서도 없는 프로그램이 네이티브 코드 수준에서 자기를 수정했다간 백신에 걸릴 거라는 건 차치하고라도.

마지막 제동 장치: Ctrl+Alt+Del

옛날부터 윈도우의 구원자는 Ctrl+Alt+Del이었다. 윈도우 자체를 멈추지 않는 이상, 어떤 프로그램으로 이 조합을 막기는 매우 어려울 것이다. 막았다면 그것은 바이러스인게 확실하기 때문에 깔리기 전에 백신이 삭제할 것이다. 이제 시판되기 시작한 따끈따끈한 Windows Internals 7판을 인용하며 이 글을 마무리한다.

어떠한 어플리케이션도 Ctrl+Alt+Delete 키 조합을 가로챌 수 없고, 또한 Winlogon이 이것을 받지 못하게 할 수 없기 때문에 SAS는 안전하다. Win32k.sys는 Ctrl+Alt+Delete 키 조합을 예약해둬서 윈도우 입력 시스템(Win32k 내의 raw 입력 스레드에 구현되어 있다)이 이 키를 발견하면 … (중략)… 하지만 윈도우 단축키 처리 코드에는 특수한 상황에 대한 처리가 돼 있어서 Ctrl+Alt+Delete 키 조합은 가로채기를 위한 후킹이 불가능하다.

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.