8초 랙에 숨겨진 진실

@codemaru · June 30, 2011 · 6 min read

최근에 회사 제품에 서비스를 추가하는 코드를 작성할 일이 있었습니다. 간단한 시스템 서비스 파일을 윈도우 폴더에 복사하고 등록하고 실행하는 간단한 코드인데 이 놈을 추가하고 나서는 초기 로딩이 무지하게 느려지는 현상이 있더군요. 그것도 매번 딱 정확하게 8초가 지연되는 묘한 현상이 있었습니다. 새로 만든 서비스가 무려 600kb가 넘는 바람에, 실제 크기는 23kb인데 Themida 프로텍트를하니 크기가 무지막지하게 커지더군요. 그래서 그걸 가상 파일 시스템에서 꺼내서 기록하는데 지연이 될까란 생각이 들었습니다. 가상 파일 시스템에 저렇게 큰 놈을 넣어본 적은 없었거든요. 그래서 코드에 로그를 추가하기 시작했습니다. 생각보다 어디서 지연이 되는지를 찾기가 쉽지 않더군요. 결국 이잡듯이 한줄한줄마다 로그를 죄다 추가했습니다. 그러자 아래 결과처럼 로그가 나오더군요. 헐킈. 44초의 wriatea와 52초의 closea 사이에 수행하는 함수는 단 하난, CloseHandle 헉.~ 이건 멀까?

8            md 0

윈도우는 왜 우리 파일만 CloseHandle을 하는데 8초나 지연을 시킬까요? 근데 또 왜 유독 그놈의 서비스 파일만 8초나 지연이 될까요? 온갖 생각을 다했습니다. “CloseHandle slow” 따위로 구글링을 했죠. 정말 다양한 이야기가 있었습니다. 심지어는 NTFS의 성능을 운운하는 이야기들까지 있더군요. 그런데 우리는 고작 600kb짜리 서비스잖아요. 구글링을 한 30분쯤 했는데도 뾰족한 답은 없더군요. 그러다 불현듯 스치는 생각. 백신. 후킹. 필터. 그렇습니다. 그 PC에 백신이 설치가 되어 있었드랬죠. MS Security Essential이란 놈이 말입니다. 실시간 감시기를 중지하고 프로그램을 켰습니다.

8            md 1

원래 이랬어야 하는 거겠죠. 그놈이 범인이 맞았습니다. 그러면 이제 어떻게 해야 할까요? 백신이 문제니깐 그냥 그러고 끝내면 될까요? 안되겠죠. 저희 제품은 백신이 설치 되어 있으면 매번 8초씩 로딩이 느려지는 현상이 있습니다. 이럴수는 없잖아요. 얄팍하게 확장자를 exe가 아닌 걸로 변경해 봤습니다. 히지만 요즘 백신, 그렇게 호락호락하지 않더군요. 몇 가지 꼼수를 써보다가 안되서 그냥 파일을 기록하지 않기로 했습니다. 일단 먼저 읽어서 우리가 가지고 있는 버퍼랑 똑같으면 말이죠. 물론 최초 설치 시에는 느려지지만 그 담부터는 기록하지 않으니깐 8초같은 어마어마한 랙은 발생하지 않았습니다.

근데 600kb짜리 파일 하나 검사하는데 8초는 좀 심한거 아닌가요? MS Security Essesntial 말이죠. Themida로 프로텍트해서 그럴까요? 어쨌든 좀 심했어요. 8초는 ㅠㅠ~ 파일 I/O가 비정상적으로 느리다면 일단 백신부터 의심해 보세요.

덧) 서비스 설치 코드를 작성하다 알게 된 사실인데요. 여러분들이 서비스 조작 코드를 막 싸지르다보면 의도하지 않은 결과가 나올 수 있습니다. 무슨 말이냐하면 서비스를 설치하고 구동하는 데에는 관리자 권한이 필요한데, 정지시키고 삭제하는데는 일반 권한으로도 되거든요. 그래서 서비스 설치 코드를 삭제, 설치 이렇게 만들고(MSDN 샘플이 그렇게 되어 있습니다), 그 코드를 그냥 실행 한다면 일반 계정에서 실행했을때 서비스가 사용안함 되는 요상한 문제가 생길 수 있습니다.

덧2) 비교해서 파일을 복사하는 것과 그냥 막 복사하는 것 사이에는 어떤 차이가 있을까요? 비교해서 복사하는게 더 우아해 보이시나요? 근데 해킹을 막는 입장에서 본다면 막 복사하는게 더 좋습니다. 왜냐하면 if문이 많다는건 손쉽게 우회될 수 있다는 걸 의미하기 때문입니다.

@codemaru
돌아보니 좋은 날도 있었고, 나쁜 날도 있었다. 그런 나의 모든 소소한 일상과 배움을 기록한다. 여기에 기록된 모든 내용은 한 개인의 관점이고 의견이다. 내가 속한 조직과는 1도 상관이 없다.
(C) 2001 YoungJin Shin, 0일째 운영 중