TextHooker란 프로그램들을 아시나요? 사실 대부분의 일본산 비주얼노벨 게임을 하신 분들이라면 비슷한 프로그램들을 상당히 많이 알고 계실겁니다.

제일 유명한 것이라면 TextHooker중에서 제일 대중에게(?) 퍼진 Oh! TextHooker가 있습니다. 이외에도 4chan에서 만든것으로 추정?되는 AGTH(Anime Game Text Hooker)와 중국에서 만든것으로 보이는 VNR(Visual Novel Reader) 등이 있습니다. 상당히 많은 프로그램들이 있는데 이들의 공통점은 공통적으로 쓰이는 API(대표적인 것이 TextOut())를 후킹해서 문자열을 끌어낸다음 번역기나 사용자사전을 써서 번역된 문장을 출력하는 것이 목적입니다.



각종 TextHooker의 할아버지뻘인 Oh! TextHooker 지금도 돌아가는 게임이 있다! (출처:http://ohhara.sarang.net/ohthk/scrshots.html)

 


가장 최신의 기술로 무장했고 편의성도 훌륭한 VNR의 모습. 출처 : https://namu.wiki/w/VNR


API후킹 기술은 사실 어둠의 영역에서도 자주 사용되었고 빛의 영역에서도 상당수 이용됩니다. 대표적인 어둠의 영역은 키보드의 이벤트를 후킹해서 키입력 로그를 만들어 해킹하는 곳에 사용되는 것을 말 할 수 있습니다. 하지만 대개 이런 부류는 백신에서 쉽게 잡아냅니다. 빛의 영역은 시각장애인용 TTS프로그램을 들 수 있습니다. 마우스를 움직이면 마우스 아래에 있는 문장을 읽어들여서 TTS로 읽는 것이지요. 이런 프로그램은 상당히 종류가 많습니다. 그런데 리눅스에서는 이런류의 프로그램이 사실상 없습니다. Firefox나 Chrome의 확장에서는 있는 것 같지만 인터넷 웹환경에 한해서만 작동하기 때문에 한계가 있습니다.


애초에 이런 게임들이 당연히 (일본어판) Windows전용이다보니 참 문제가 많습니다. 리눅스에서 굴린다는 것 부터가 이미 글러먹은 것이지요. 그것도 번역기를 통하려고보니 더 엉망진창이고요. Wine은 DLL injection이나 API Table같은 기술이 잘 먹히지 않습니다. 본래의 API와 외부 구조는 비슷하지만 내부 구성이 다르기 때문입니다. (내부 구성까지 같으면 Wine은 Windows의 저작권에 위배되는 프로그램이 됩니다.) 즉 VNR이나 Oh! Text Hooker는 정상적인 동작이 보증되지 않습니다.

애매한 것으로 Mort란 것이 있기는한데 이건 OCR을 쓴 것이니 넘어가도록 합시다.(이전에 제가 Mort의 기술을 써서 리눅스에서 비슷하게 굴린적이 있습니다.)


그런데 API 후킹의 원리는 API의 외부 구성을 그대로 만들고 본래의 API대신 자신이 끼어들어 이리저리 조작한 후 본래의 API를 호출하는 원리입니다. (본래의 API를 호출하지 않으면 프로그램이 정상적으로 돌지는 않을 겁니다. 문자열이 나와야 하는데 안 나온다거나...)그런데 이거 Wine이 하는 짓하고 비슷합니다. http://moordev.tistory.com/83 그래서 저는 여기서 이런 방법은 어떤지 제안을 한 적이 있습니다. 해 본 결과 폭망이었지만 (애초에 구조가 달라서 먹히지 않습니다.) 역으로 리눅스에서 Wine으로 게임을 굴리면서 후킹하는 것은 어렵지 않게 구현할 수 있었습니다. gdi.so소스를 뜯어고치면 TextOut()함수를 내 마음대로 돌아가게 하는 것은 어렵지도 않고 CreateFont()함수도 고쳐버리면 폰트도 내 마음대로 바꿀 수 있게 되는 겁니다.(이건 AppLocale의 원리와 같습니다.)


그래서 sprintf함수로 문장을 처리하는 게임을 타겟으로 삼아 Wine에서 구현한 sprintf함수 조작한 다음 sprintf 출력 문장을 디버그창에 띄우게 했더니...의외로 잘 나오네요.


......이거 잘하면 리눅스용 후커도 만들 수 있을 것 같습니다. 번역 엔진이 문제이기는 한데 그건 그냥 구글번역을 통하면 될 듯하고 Chrome하고 연동하는 방법을 쓰면 구글번역기능도 쉽게 쓸 수 있을 듯 합니다. 하지만 이건 윈도용 게임이야기이고 리눅스용 게임은.....나중에 생각하도록 합시다. 아직 리눅스용 게임은 이러한 물건은 적으니까요.



,