1. 파일 포맷 분석
얼마 전에 본인은 Windows용 MS 한글 IME가 내부적으로 사용하는 한자 사전 파일의 분석을 시도한 적이 있었다.
그 결과 파일의 내부 구획과 구조가 상당수 파악되었다. 해당 프로그램이 한글 독음으로부터 한자 정보를 어떻게 얻어 오고 한자로부터 독음, 부수, 획수 등의 정보를 어떻게 얻는지까지도 모두 알아 냈다.
정체를 알 수 없는 구조체들의 숫자들이 의미하는 것도 규칙성을 파악해서 과반은 해독했다. 데이터가 대놓고 압축이나 암호화가 돼 있지는 않은 덕분이었다.
하지만 제일 중요한 문자열 단어 단위로 저장된 정보들은 끝내 얻지 못했다.
이런 것들을 저장하는 용도로 동일한 포맷의 spell trie/tree 같은 게 여러 개 있는데, 이 중에서 가장 간단하고 작은 형태의 테이블을 얻었으며(노드 몇백 개짜리..) 이걸 풀이해 낸 레퍼런스 결과물까지도 역으로 얻었다.
다시 말해 이 작은 테이블로부터 저 결과물이 어떻게 나오는지 그 방식만 알아낼 수 있으면 나머지 진짜 해독해야 하는 더 방대한 테이블까지 사실상 몽땅 해독이 가능해진다.
여기까지 진행됐는데도 더 나아가는 건 도저히 무리였다. 그 이상부터는 각 노드와 노드가 어떻게 연결돼서 한자어나 한자어 훈이 나오는지.. 탐색을 어디부터 시작해야 할지, 단서를 어디서 얻을 수 있을지 추적이 되질 않았다.
지금까지 투입한 시간이 참 아깝기도 했지만 어쩔 수 없이 여기서 눈물을 머금고 포기하게 됐다. 이게 제일 중요한 정보였는데 말이다.
마소의 한국어 IME야 일본어 IME의 내부 구조의 영향을 받은 게 굉장히 많은데, 저 파일의 자료구조 역시 일본어 IME의 DB 내부 구조를 아는 사람에게는 절대로 낯선 형태가 아닐 것이라고 짐작만 해 본다.
답답한 마음에 MS 한글 IME의 내부를 디버깅까지 해 봤다. 그래 봤자 아무 디버깅 단서가 없는 복잡한 0과 1 기계어 천지 속에서 의미 있는 결과가 나오지는 못했고, 단지 쟤들이 DB 파일 전체를 memory mapped file로 걸어서 사용한다는 결론만을 얻을 수 있었다.
아, 내가 갑자기 이거 추적을 한 이유, 동기, 계기는 뭐냐 하면..
날개셋 한글 입력기에서 '조합 안에 조합 생성' 입력 도구를 사용해 봤는데, MS IME의 API를 사용하는 한글-한자 단어 변환 기능이 유난히 동작이 느리고 랙이 심한 걸 발견했기 때문이다. 실제로 테스트를 해 보니 MS IME API는 주어진 한글 단어로부터 한자어를 얻는 게 수십 ms 이상이 걸릴 정도로 느린 편이었다.
그래서 DB 파일 포맷을 알면 내가 저 파일로부터 한자어 리스트를 직접 더 빨리 얻을 수도 있지 않을까 하는 무모한 도전을 해 봤는데.. 뭐 소기의 목적을 다 이루지는 못했다. 파일의 전체 구조가 어떨지 궁금하다.
다만, 내 추측에 따르면 내부의 파일 구조가 검색에 그렇게 효율적인 형태는 아닌 것 같다. 짐작건대 수백~수천 회 이상의 선형 검색이 발생하기라도 하지 않나 싶다.
뭔가, 남이 짜 놓은 C/C++ 코드를 읽는 것뿐만 아니라 이렇게 복잡한 바이너리 파일 구조를 읽으면서 오프셋을 따라가고 추적하는 것..
메모리와 레지스터, 스택 상태를 살피면서 남이 짜 놓은 프로그램을 디버거로 분석하는 것은 프로그래머 내지 소프트웨어 엔지니어로서 필요한 또 다른 스킬인 것 같다.
2. 매크로/스크립트 기능
어느 정도 규모가 있는 업무용 프로그램에는 일괄 처리와 자동화를 위한 매크로 기능이 있다. 도스 시절에는 key 매크로가 많이 쓰였지만, 그건 요즘 같은 GUI 운영체제의 사정에는 잘 맞지 않기 때문에 스크립트 기반으로 가는 추세이다.
어떤 형태로든 이런 기능은 어느 프로그램에서나 어렵지만 강력한 고급 기능으로 취급받곤 한다.
헥사(바이너리) 에디터에 이런 프로그래밍 기능이 있어서 열어 놓은 파일 전체를 거대한 바이트 배열로 접근 가능하고 현재 cursor 위치가 인자로 주어진다면..
여기서부터 분석을 시작했을 때 구조체에 채워지는 값, 여기서 몇 오프셋에 있는 값만치 이동한 곳에 있는 다른 구조체의 값 등등... 을 출력하는 스크립트를 작성할 수 있고 이걸 이용하면 아까 같은 바이너리 파일 읽기나 역공학, 디버깅 같은 작업을 아주 수월하게 할 수 있을 것이다.
그래픽 에디터도 마찬가지다. 2차원 그래픽 툴은 디자이너가 보는 관점과 프로그래머가 보는 관점이 약간 차이가 있다.
프로그래머는 새로운 그림을 그린다기보다는 화면 캡처나 기존 그림을 보정하는 용도로 이런 프로그램을 사용한다.
그렇기 때문에 좌표 같은 걸 매번 마우스로 힘들게 지정하는 게 아니라.. '정확하게 이 구간의 화면 캡처를 몇 번 하라, 색깔이 이런 조건을 만족하는 구간의 테두리를 짤라내라' 이런 명령은 프로그래밍 가능한 체계가 있으면 매우 도움이 된다.
뭐, 거대한 2차원 캔바스에 공식만으로 기하학적인 그림을 그리는 프로그래밍은 덤이고 말이다.
또한 요즘 그래픽 데이터에는 픽셀이 RGB로만 구성된 게 아니라 알파 채널이란 게 있다. 이건 RGB처럼 색깔을 유일하게 구성하는 요소가 아니라 색깔에 추가적으로 붙는 정보이다.
이건 색깔 자체가 아니다 보니 편집하는 방식이 에디터마다 통일돼 있거나 일관성이 있지가 않다. 색깔은 전혀 안 건드리고 알파만 50%로 할지, 아니면 색깔도 건드리면서 알파도 건드릴지, 기존 알파값에다 상대적으로 알파를 더할지 같은 것 말이다.
이런 식으로 일정 구역이나 조건을 만족하는 픽셀에 대해 알파값을 일관되게 고치고 싶을 때 프로그래밍 기반 매크로가 있으면 굉장히 유용하다.
포토샵 같은 그래픽 에디터를 띄웠는데 화면 하단에 마치 옛날 QuickBasic의 immediate 윈도우처럼 그림을 명령어로 조작하는 입력란이 있다면.. 뭔가 그래픽 에디터답지 않은 공대감성이 느껴질 것 같다. =_=;;
3. 개체에 대한 드래그 좌표의 자동 보정
2차원 공간에서 사각형 형태의 여러 개체들을 만들고 배치하는 기능이 있는 프로그램을 생각해 보자. 벡터 드로잉 기능이 있는 파워포인트나 워드 프로세서 같은 프로그램들이 떠오를 것이다.
그리고 일반인이 쓸 일은 잘 없겠지만 개발툴에 내장돼 있는 대화상자/폼 디자이너도 좋은 예이다.
요즘은 그런 프로그램들이 워낙 똑똑해진지라, 개체를 하나 클릭해서 몸통을 마우스로 끌어 보면 개체가 그냥 곧이곧대로만 움직이지 않는다. 옆이나 위의 주변 컨트롤과 나란히, 가지런하게 배치되게 반경 n픽셀 이내의 대충 비슷한 위치를 방황하고 있으면 프로그램이 알아서 '요기?'라고 가이드라인을 제시해 준다.
그 상태에서 마우스 왼쪽 버튼에서 손을 떼면 프로그램이 제시한 정확한 위치에 개체가 달라붙는다. Shift나 Alt 같은 modifier key를 누른 상태로 마우스를 끌어야 그런 보정 위치가 아니라 곧이곧대로 마우스 포인터가 있는 위치에 개체가 자리잡게 된다. Ctrl은 드래그 하는 개체에 대해서 이동/복사 모드를 전환하는 key이니까..
Visual Basic/C# .NET이 제공하는 폼 편집기는 Visual C++이 제공하는 구닥다리 rc 파일 기반의 재래식 대화상자 편집기보다 훨씬 더 똑똑하기 때문에 주변 컨트롤의 위치들을 토대로 온갖 방식으로 자동 달라붙기를 시도해 준다.
xcode도 만만찮았던 걸로 기억한다.
개인적으로는 이런 부류의 기능이 비트맵 그래픽 에디터에도 있으면 좋겠다는 생각을 한다.
그림의 일부 영역을 select할 때.. 색깔이 급격하게 변하는 경계 근처에 가 있으면 정확하게 보정된 위치에 착 달라붙게 프로그램이 보정 위치를 자동으로 제시하는 것 말이다. 그래서 사용자가 불편하게 이미지를 확대해서 조심스럽게 다루지 않아도 되게 말이다.
물론 방대한 크기의 비트맵으로부터 그런 경계 패턴을 인식하는 것은 많아야 수십 개의 개체 좌표값만 계산하면 되는 벡터 드로잉이나 대화상자 폼 편집기보다 힘든 일일 것이다. 그리고 그래픽 에디터라는 게 프로그래머보다는 디자이너가 더 자주 다루는 물건이고, 디자이너는 컴퓨터스럽고(= 도트 노가다 지향적이며) 경계 구분이 분명하고 기하학적인 이미지보다는... 실물 사진을 더 많이 다룰 테니, 수지가 안 맞아서 저런 기능이 들어가지는 않을 것이다. =_=;;
4. 디버깅과 범죄 수사의 유사점
혼자 오랫동안 해 온 생각인데..
강력 범죄 수사랑 컴퓨터 프로그램 디버깅은 절차와 성격 면에서 서로 좀 비슷한 구석이 있어 보인다.
사건이 발생했다는 112 신고는 프로그램에서 무슨 문제가 발생했다는 버그 신고와 같다.
핏자국, 시신, 어지럽혀진 사건 현장 같은 건 프로그램이 뻗은 모습 내지 각종 디버그 로그와 메모리 덤프에 대응한다.
경찰이 사건을 재구성하고 원인을 추적하는 건 두 말할 나위 없이 프로그래머가 동일 상황을 재현해서 버그를 발견하려고 애쓰는 것과 같다.
버그를 잡는 건 당연히 범인 검거이다. 반대로 미제 상태로 공소시효가 끝나는 건 버그를 못 잡은 채로 해당 프로그램의 지원 내지 버전업이 끝나는 것과 같다.
예전에 본인은 법조인이 컴퓨터 프로그래밍과 비슷한 구석이 있다고 글을 쓴 적이 있는데..
형사가 범죄 현상에서 이상한 것 하나라도 놓치지 않고 실마리를 발견하여 사건을 해결하는 능력은 프로그래머의 디버깅 능력과 일맥상통하는 구석이 있어 보인다. 음, 그러고 보니 그걸 한 단어로 추리력이라고 부르는구나.
5. 롤러코스터
2008년 3월, 에버랜드에는 'T 익스프레스'라고 세계구급의 목재 롤러코스터가 개장했다.
그리고 그로부터 10년 뒤인 지난 2018년 5월, 경주월드에서는 낡은 기존 롤러코스터이던 '스페이스 2000'을 철거하고 '드라켄'이라는 더 높고 짜릿한 신기록급 롤러코스터를 개장했다.
선박이나 건물뿐만 아니라 롤러코스터를 봐도 목재와 철재의 차이를 알 수 있어 보인다.
목재인 T 익스프레스는 무슨 비행기도 아닌 것이 운행하는 데 날씨 제약을 많이 받으며 혹한기 동계 휴무도 있으며.. 또 결정적으로 빽빽한 지지대들을 설치하느라 층 위에 층을 놓을 수 없다. 롤러코스터 하면 생각나는 배배 꼬인 나선형 선로조차도 만들 수 없다.
항공 사진에서 복층으로 입체 교차하는 듯이 보이는 일부 구간은 거기에만 부득이하게 금속 기둥과 지지대가 예외적으로 조금 설치돼 있다.
그에 반해 드라켄은 얼마나 뻥 뚫린 황량한 형태인지..?? =_=;; 저런 걸 목재로는 구현할 수 없다.
층 위에 층을 만들 수 없는 게 프로그래머의 눈으로 보기엔 무슨 과거 Doom 엔진 기반의 맵 같다. 물론 Doom 엔진으로는 경사진 바닥도 표현할 수 없긴 하다만.. (오로지 평평한 바닥만)
3D 맵으로 뫼비우스의 띠나 클라인 항아리 같은 걸 편법으로라도 구현할 수 있으려나 모르겠다.. ^^
Posted by 사무엘