"사수좌의 날에서 나가토가 입력한 프로그램, 그거 진짜 소스 코드래요."
하루히 2기에 대한 이야기를 오덕오덕거리다가 진형군이 이런 멘트를 했습니다.
이미 12화의 기타 코드는 실제 코드로 알려져있었고 쿄토 애니라면 충분히 있을 수 있는 일이죠... .
이 떡밥을 물자마자 당장 하루히 11화, 사수좌의 날(The Day of Sagittarius)을 돌려보았습니다.
그리고 아래는 그 코드를 캡쳐한 것입니다.
하루히의 SOS단과 컴퓨터연구부(이하 컴연)가 네트워크 게임 대전을 하게 됩니다.
이때 게임은 컴연에서 직접 제작한 전략 SLG 게임입니다. 게임 제목의 사수좌의 날입니다.
그런데 어찌된 영문인지 SOS단이 계속 지게 됩니다.
나가토는 컴연 쪽이 프로그램 수정으로 게임상에서 자기들의 위치를 파악할수 없게끔 만들어 둔것을 발견하고
어떻게 저떻게 리버니 엔지니어링을 했는지, 핵(hack)을 만드는지, DoS를 날리는지 잘 모르겠지만,
암튼 결국 SOS단이 이기게 된다(그래서 우리 단장님은 기뻐하셨다.)라는 아주 감동적인 스토리입니다.
로버트 레드포드 아저씨가 나왔던 스니커즈 이후 가장 감동적인 컴퓨터를 주제로 한 영상물입니다, 그려... .
본론으로 돌아가봅시다.
우선 이 코드의 대부분은 몇개의 Cmd 콘솔창에서 이뤄집니다.
이것을 보면 "type" 명령어로 텍스트를 뿌렸거나 "copy con" 을 이용하며 Cmd 상에서 소스 파일을 만들고 있는 것으로 추측됩니다.
하지만 실제로 자세히 보면 여러개의 콘솔창의 소스 코드가 같습니다.
아뭏든 이 상황을 짐작해보면, 현재 나가토의 PC에는 컴파일러와 링커는 있으되 IDE가 없다는 사실을 알수 있습니다.
마치 Turbo-C 1.5 나 리눅스 기본 환경같은 상황이군요.
이젠 소스를 볼까요?
이 콘솔창, 아주 건방집니다.
가로 스크롤바도 안보이는 주제에 가로 스크롤이 되어 앞부분이 잘 보이지 않습니다.
소스를 잘보면 대체로 Process를 건드리는 것이라고 추측됩니다.
함수가 가장 먼저 눈에 뜁니다.
CreateToolhelp32Snapshot()은 지정한 프로세스들이 사용하고 있는 힙(heap)과 모듈, 그리고 쓰레드의 현재 모습을 얻어오는 API 라고 MSDN께서 말씀해 주십니다. ^^ (http://msdn.microsoft.com/en-us/library/ms682489(VS.85).aspx)
프로세스 상태를 구하는 것은 후킹과 리버스 엔지니어링의 시작!
이를 통해 나가토는 후킹을 이용해 자신들의 PC에 설치된 (컴연을 검색하는 루틴이 빠진)게임을 수정할려고 하는 것이라고 유추할수 있습니다.
sub_03 콘솔을 봅시다.
(http://msdn.microsoft.com/en-us/library/ms684320(VS.85).aspx)
OpenProcess() 함수가 반겨주네요. OpenProcess()는
아마도 현재 자신들의 게임에 무언가 작업을 걸려고 준비 중인가 봅니다.
짤방에는 나오진 않지만 그전에 살짝
(http://msdn.microsoft.com/en-us/library/ms684834(VS.85).aspx)
이란게 지나가는데 프로세스 스냅샵으로 얻은 현재 프로세스의 핸들을 구해 OpenProcess()로 강제로 열려는가 봅니다.
또한 코드를 아무리 봐도 socket이나 pipe 같은 네트워크 함수는 찾을 수 없었습니다.
순수히 로컬의 프로세스를 변형시켜 TCP 패킷을 짜맞추려는가 봅니다.
이것은 전형적인 프로세스 변형을 통한 온라인 게임 공격방식!! 게임의 TCP 패킷 프로토콜을 몰라도 변형과 서버 공격이 가능하다는 장점이 있고 여전히 서버 개발자를 괴롭히는 악질 해킹기법입니다.
main() 함수가 등장했습니다.
자막에 가려져 잘 안보이지만 상당히 간단합니다.
{
MessageBox(NULL,_TEXT("Start simurator and hit return key!!"),_TEXT("Simulator Injector"),MB_OK);
GetProcessList();
}
이제까지 만든 함수는 결국 GetProcessList() 라는 녀석이군요.
함수 이름 참 민망합니다.
프로세스 리스트를 보여줌과 동시에 프로그램 변형을 함께 시도하는군요.
어이, 나가토~ 함수를 둘로 쪼게시게.
나라면,
DoInjection(hGame);
으로 할 것이네.
그런데 여기서 주목해야 할 것은 MessageBox()가 MB_YESNO 가 아니라 MB_OK란 사실입니다.
리턴값도 체크하지 않아요.
결국 이 프로그램은 쿈의 의사와 관계없이 무조건 실행시켜버리겠다는 나가토의 무서운 의지가 담겨져 있습니다.
ESC를 누르건, Enter를 누르건, 클릭질을 하던 무조건 프로그램은 실행됩니다.
멈출 방법은 오직 작업관리자에서 프로세스 강제로 끝내는 수밖에 없습니다.
실행 모습입니다.
오~~ 고증이 철저하군요. MB_OK 답게 OK 버튼 하나만 떴습니다.
리턴값 체크 없으니 [X] 눌러도 프로그램은 실행될 수 밖에 없습니다.
하지만 애니메이션상에 버그는 보이네요.
이 프로그램은 이미 실행되었으니 콘솔창에 캐릿은 캐리지 리턴 되어야 하는데 그냥 떠있습니다. ^^
MB_OK 인 주제에 뭔 허가를 바랍니까?
쿈이 싫다고 하면 프로세스 강제로 끝낼 건가요?
이거 쿈이 컴맹, 아니 프맹이라는 사실을 이용한 외계 로봇의 농간입니다.
점심시간에 SOS단 홈페이지(http://www.haruhi.tv/) 를 뚝딱 만든 쿈이지만,
역시 바이너리 프로그래밍은 전혀 알지 못하는 프맹이란 사실이 만천하에 드러났습니다.
프로세스 인젝션 기법으로 컴연을 이겼고...
단장님과 그 추종자들은 기분이 좋아 덩실덩실 춤을 추십니다. 응?
안돼, 나가토... 미래를 위해 프밍 따윈 잊고 너도 수능 목표를 공대말고 의약대 & 사법고시를 목표로... .
거봐, 프로세스 인젝션을 하던 뭘 하던 앞에 나설수 있는건 개발자가 아니라니까! 흐흐흑
아뭏든 사수좌의 날을 재분석 함으로써 우리는 다음과 같은 사실을 알수 있었습니다.
2) 단순하면서도 강력한 프로세스 인젝션 방식을 취함으로써 서버를 속이고 게임에서 이겼다.
3) 프로세스 인젝션은 CreateToolhelp32Snapshot()으로 프로세스 스냅샵을 얻고,
Process32First()로 프로세스의 핸들을 얻은 다음,
OpenProcess()로 강제로 목표 프로세스를 연다.
그 다음에 무언가를 한다. <-- 사실은 이게 젤 어렵다.
4) 개발자 맘대로 강제로 실행하고 싶을때는 MessageBox() 리턴체크 없이 MB_OK를 쓰자.
5) 역시 쿄토 애니는 먼치킨이다아아아아아~~
그리고 추가로 하루히 위키(http://wiki.sos-dan.com/wiki/The_Day_of_Sagittarius)에서 다음과 같은 사실을 알 수 있었습니다.
1) VC++ 이 아닌 볼랜드 C (Borland C)였다는군요.
2) 소스코드를 분석한 덕후가 일본에 있었습니다!!! 아마 블루레이였기에 소스 분석이 더 쉽게 가능했을리라 생각됩니다.
(http://blog.proj.jp/ituki/data/2006/20060615.SimInject.org.cc)
저도 프로세스 인젝션 소스 분석과 공부를 위해서
어쩔수 없이 하루히 블루레이를 사야겠습니다.
