얼마전부터 mp3 저장하는 뻘짓 유틸리티를 만들기 위해 모 사이트에서 WSASend, WSARecv 함수를 후킹하여 좋아하는 mp3 파일을 수집하고 있었습니다.

그런데 잘 동작하다가 인터넷익스플로러가 종종 잘못된 연산으로 종료되더군요.


지금까지 써왔던 api hook 코드가 잘못되었나 싶어 어셈코드부터 다 뜯어보았습니다.


그래도 원인을 알 수 없더군요.
할 수 없이 기존의 쓰던 훅코드를 지우고 Microsoft Research 에서 배포하는 Detours 를 통해 훅을 해서 테스트 하였습니다. 그랬더니 역시나 익스플로러가 종료되더군요.
사실 어셈이나 인젝션한 DLL 에서 잘못되었다면 익셉션 직전의 콜스택이 저렇게 되면 안되는 것인데..
머.. 어쨋든 Detours에서도 같은 증상을 나타내니 코드를 하니씩 제거해 나가면서 테스트를 해보았습니다.

그래서 결국 찾은 것이 아래와 같은 코드더군요.

  362                         EmptyClipboard();

  363                         size_t nSize = strlen(szTemp)+1;

  364                         BYTE* hData = (BYTE*)GlobalAlloc(GMEM_FIXED, nSize);

  365                         memcpy(hData, szTemp, nSize);

  366                         //HANDLE hCp = GetClipboardData(CF_TEXT);

  367                         SetClipboardData(CF_TEXT, hData);

  368                         CloseClipboard();

  369                         GlobalFree(hData);

  370                         sndPlaySoundA(lpWaveRes, SND_MEMORY|SND_ASYNC);


그래서 아래와 같이 바꿔보았습니다.

   68                         EmptyClipboard();

   69                         size_t nSize = strlen(szTemp);

   70                         HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, nSize);

   71                         BYTE* hData = (BYTE*)GlobalLock(hMem);

   72                         memcpy(hData, szTemp, nSize);

   73                         SetClipboardData(CF_TEXT, hData);

   74                         CloseClipboard();

   75                         GlobalUnlock(hMem);

   76                         GlobalFree(hData);

   77                         sndPlaySoundA(lpWaveRes, SND_MEMORY|SND_ASYNC);


이렇게 하니 인터넷익스플로러가 종료하지 않더군요.

아직도 정확히 무엇때문에 종료가 된 건지는 정확히 규명이 되지 않았지만, 쓰레드가 많이 동작하는 경우 GlobalAlloc 에 GMEM_FIXED 를 사용하는 것을 자제해야겠습니다. ^^;


  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기