2016. 8. 24. 15:58ㆍIT-개발/좋은 Library
아직 안써봤지만, 내용이 워낙 알차서 남겨봅니다. Hooking 이라는게 참~ 안정성이 중요한거 같은데~~
다음에 진짜 써보고 후기를 올리든지 해야지~ ㅠㅠ
API Hooking - 64비트를 고려해야 한다면? EasyHook!
지난 번에 "Trampoline API Hooking" 방식을 알아봤는데요.
Win32 API 후킹 - Trampoline API Hooking ; http://www.sysnet.pe.kr/2/0/1231
이 방법의 단점은, 아쉽게도 x64 지원이 안된다는 것입니다. 물론, 이래 저래 뜯어고치면 되겠지만 '안정성'을 확보할 수 있는 실력이 안된다면 ^^ 차선책을 고려해볼 수 있습니다. 그렇게 선택될 수 있는 첫번째가 그 누구도 아닌 '마이크로소프트' 스스로 개발한 후킹 라이브러리가 있으니, 바로 "Detours"가 그것입니다.
Detours 라이브러리를 이용한 Win32 API - Sleep 호출 가로채기 ; http://www.sysnet.pe.kr/2/0/631
음... 그런데, 역시 단점이 없지 않습니다. 32비트/64비트 모두 지원하긴 하지만, 무료 버전은 32비트만 지원하고 64비트까지 지원하려면 반드시 유료 버전을 구매해야 합니다.
저 같은 평범한 개발자가 $9,999 를 지불하기에는 좀 그러하니, 다음으로 생각해 볼 것이 무료 중에 제법 안정적인 라이브러리가 없나 찾아보게 됩니다. 다행히, 이번달(2012-02) 마이크로소프트웨어 잡지에서 소개된 "EasyHook" 이 괜찮은 후보가 될 것 같습니다.
EasyHook - The reinvention of Windows API Hooking ; http://easyhook.codeplex.com/
LGPL 라이선스이기 때문에 상용에도 쓸 수 있고 DLL 로 링크해서 사용하면 아무런 문제가 없습니다. 그러다 만약 버그가 있다면 소스 코드를 다운로드 받아 버그를 수정한 후 원 저작자에게 알리면 버그 패치된 버전이 나올 것이고, 다시 그 DLL 을 링크해서 사용하면 됩니다.
'마이크로소프트웨어'에 기사를 쓴 '권용휘'님은 "Powered by EasyHook" 로고를 반드시 포함해야 한다고 했는데... 약간 오해가 있지 않나 싶습니다. 원 저작자는 이에 대해 다음과 같이 설명하고 있는데요.
그저 그래줬으면 감사하다는 것이지, 강제 사항은 아닙니다. 사실, 이걸 강제사항으로 넣으면 또 이상할 수도 있는데요. 가령 예를 들어서, UI 가 없는 Library 개발자라면 쓰지 말라는 것이나 다름없으니까요. 게다가 이렇게 라이브러리를 공개한 경우 '감시'수단이 현실적으로 적절하지 않습니다. 아래의 Q&A에서 원 저작자는,
Licensing question ; http://easyhook.codeplex.com/discussions/236073
소스 코드를 가져다 쓰는 것 조차도, EasyHook 과 같은 라이브러리를 만들려는 것이 아니라면 자신은 괜찮다는 입장을 취하고 있습니다. (물론, 공식 문서화 된 답변은 아니므로 이런 내용에 기대어 오버해석하는 것은 좋지 않습니다. ^^)
어쨌든, "Powered by" 로고에 대해서는 제가 질문을 올려놨는데 어떤 답이 오는지 한번 지켜보는 것도 재미있을 것 같습니다. ^^
About "Powered By" logo. ; http://easyhook.codeplex.com/discussions/330548
그건 그렇고, 이제 라이브러리를 사용해 봐야겠지요. ^^
오늘 날짜 기준으로 안정화된 버전이라고 알려진 2.6 을 다운로드 받아 압축을 풀어놓고 자신의 C/C++ 프로젝트에서 EasyHook32.dll (또는 EasyHook64.dll) 을 링크한 후, 기본 소스를 다음과 같이 작성할 수 있습니다.
#include "stdafx.h" #include "Win32Wrapper.h" #include "..\Libraries\easyhook.h" #if defined(_AMD64_) #pragma comment(lib, "..\\Libraries\\EasyHook64.lib") #else #pragma comment(lib, "..\\Libraries\\EasyHook32.lib") #endif WIN32WRAPPER_API void fnWin32Wrapper_Hook(void) { ... } WIN32WRAPPER_API void fnWin32Wrapper_Unhook(void) { ... }
그럼, 지난 번에 했던 CoGetClassObject 후킹을 EasyHook 버전으로 한번 바꿔볼까요? ^^ 다행히 "마이크로소프트웨어" 잡지에 실린 기사에 자세한 설명이 되어 있어서 쉽게 다음과 같이 포팅을 할 수 있었습니다.
DWORD ACLEntries_CoGetClassObject[1] = { (DWORD)-1 }; HOOK_TRACE_INFO g_h_CoGetClassObject= {NULL}; HRESULT WINAPI New_CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo, REFIID riid, LPVOID *ppv) { if (CanBeActivated(rclsid) == FALSE) { return REGDB_E_CLASSNOTREG; } return CoGetClassObject(rclsid, dwClsContext, pServerInfo, riid, ppv); } WIN32WRAPPER_API void fnWin32Wrapper_Hook(void) { HMODULE hModule = ::LoadLibrary(L"Ole32.dll"); FARPROC farProc = ::GetProcAddress(hModule, "CoGetClassObject"); if (farProc == NULL) { return; } LhInstallHook(farProc, New_CoGetClassObject, NULL, &g_h_CoGetClassObject); LhSetExclusiveACL(ACLEntries_CoGetClassObject, 1, &g_h_CoGetClassObject); } WIN32WRAPPER_API void fnWin32Wrapper_Unhook(void) { LhUninstallAllHooks(); }
이전과 다른 점이 있다면, 소스 코드가 훨씬 더 간결해졌다는 점을 들 수 있겠고, 무엇보다도 x64/x86 모두 동작한다는 장점이 있습니다. (이렇게 잘 만들어진 라이브러리를 가져다 쓰는 것은 너무너무 행복한 일입니다. ^^)
이번에도 역시, 첨부한 소스코드는 "닷넷"에서 C/C++ DLL 함수를 불러서 처리하게 했고 이번에는 다음과 같이 Hook/Unhook 버튼을 두어 실행시에 테스트가 가능하도록 했습니다.
첨부된 파일은 위의 코드를 포함한 예제 프로젝트입니다.
'IT-개발 > 좋은 Library' 카테고리의 다른 글
wxwidget - 설치 (펌) (0) | 2016.08.25 |
---|---|
WXWIDGET (펌) (0) | 2016.08.24 |
Boost 설치 (펌) - 기타링크 (0) | 2016.08.24 |