EasyHook 이용시 주의(?) 사항

최근에 EasyHook 라이브러리를 이용해서 후킹을 할 일이 있어서 코드를 작성했는데
explorer.exe 프로세스에 injection 을 할 때 크래시가 발생하더군요. >.<

이리저리 살펴본 결과 EasyHook 라이브러리 내에 문제의 소지가 있는 코드조각이 좀 있었습니다. 

thread.c 파일의 RhInjectLibrary( ) 함수와 entry.cpp 파일의 HookCompleteInjection() 함수를 살펴보면 아래와 같은 내용이 있습니다. 

Info->LoadLibraryW = (PVOID)GetProcAddress(hKernel32, "LoadLibraryW");
Info->FreeLibrary = (PVOID)GetProcAddress(hKernel32, "FreeLibrary");
Info->GetProcAddress = (PVOID)GetProcAddress(hKernel32, "GetProcAddress");
Info->VirtualFree = (PVOID)GetProcAddress(hKernel32, "VirtualFree");
Info->VirtualProtect = (PVOID)GetProcAddress(hKernel32, "VirtualProtect");
Info->ExitThread = (PVOID)GetProcAddress(hKernel32, "ExitThread");
Info->GetLastError = (PVOID)GetProcAddress(hKernel32, "GetLastError");

Info 구조체는 리모트 프로세스에 생성한 스레드의 파라미터로 넘어가는 파라미터 블럭인데요.
hook 코드를 담고있는 dll 을 로드등의 작업을 위한 함수 포인터들이 저장됩니다. 

단순히 GetProcAddress() 함수를 이용해서 함수들의 포인터를 얻어옵니다. 
문제는 만일 현재 프로세스가 로드한 kernel32.dll 의 EAT 가 후킹되어있는 경우입니다

제 테스트 머신 (windows xp sp3) 의 explorer.exe 의 경우 GetProcAddress() 함수가 ShimEng!StubGetProcAddress() 함수로 바뀌어있더군요. (이런 젠장... )

해결방법은 아래와 같습니다.

1. 디스크상의 kernel32.dll 를 오픈한다.
2. PE 를 분석해서 Export table 에 기록된 함수들의 RVA 를 구한다. 
3. 2번에서 구한 RVA + 현재 메모리상의 kernel32.dll 의 베이스 주소를 더한다. 

PE 구조에 대해서 알고계신다면 구현하는데 크게 어려움은 없을것 같습니다. :-)
(사실은 구현한 코드의 양이 좀 많아서 올리기 귀찮아서.....)


덧글

  • seyool 2011/01/08 00:50 # 삭제 답글

    새해에 복 많이 받으시고,,
    부자되세요~ :-)
  • somma 2011/01/10 09:51 # 삭제

    돈줘...부자되게.. ㅡㅡ;;
  • 맘마 2016/03/27 04:29 # 삭제 답글

    코드까지 주면 ㅈㅈㅈ
댓글 입력 영역