본문 바로가기

My Study/Programming&Theory

Immunity Debugger Hard Hooking

일반적으로 hard 후킹하면 다들 생각하고 있는 것이 있죠. 맞습니다.

만약 kernel32.dll의 WinExec 함수를 하드후킹한다면 해당 함수 내부의 코드 5Byte를 jmp코드로 바꾸죠.
그리고 응용 프로그램에서 해당 함수가 호출되면 제가 만든 루틴으로 jmp문을 타고 들어오게 됩니다.
이 때부터 전 파라미터를 조작해버릴수도 있고 리턴 값을 조작해버릴 수도 있습니다.

예전엔 이 과정을 C로 테스팅해보고 실제로 사용도 해봤습니다.
만약
explorer.exe의 LoadLibrary 함수의 파라미터를 모니터링 할 때 순서입니다.

1. LoadLibrary를 하드후킹하는 코드를 작성하고 dll로 만든다.
2. dll injection을 사용해 해당 dll을 explorer.exe 프로세스에 injection한다.
3. 후킹이 성공되고 explorer에서 LoadLibrary가 호출 됬을 때
    dll 내부 Hook루틴에서는 파라미터들 값을 낚아챈다.
4. 낚아챈 값을 파일로 저장하거나 파이프 통신을 사용해 내 프로세스에서 그 결과를 출력한다.


이런식으로 작동하게 되죠.

하지만 이번엔
Immunity Debugger에서 python 스크립트를 사용해 디버깅 중 하드후킹을 수행해 특정 함수의 인자를 모니터링 해보는 것입니다.


Immunity Debugger에서는 immlib라는 아주 좋은 라이브러리를 제공해주는데 해당 라이브러리를 사용하면 짧은 코드로 후킹 작업을 할 수 있습니다. 일단 구현은 "파이썬 해킹 프로그래밍" 책을 보면서 구현해 보았고 후킹되는 함수는 달리해보았습니다.
 
 


Immunity Debugger를 보면 아래 command 창이 있습니다. 해당 창에서 windbg 명령어도 사용이 가능하며
위 그림과 같이 ! 를 붙히면 \PyCommands 폴더에 있는 python 스크립트를 실행할 수 있습니다. ( py 빼고 입력 )

이제 ezbeat.py 코드를 보기전에 
후킹 당할 프로그램 코드와 ( C언어 ..-_-; 방금 위에서 말해놓고!! ) 후킹 결과화면을 보겠습니다.
후킹은 WinExec 함수를 후킹하였고 모니터링 할 값은 파라미터 2개와 리턴 값입니다.
 
 


단순히 계산기와 메모장 하나씩 각각 다른 속성으로 띄워주는 프로그램입니다. 

실행 순서
1. 위 프로그램 Immunity Debugger에 붙힘
2. ezbeat.py 실행
3. 프로그램 실행
4. ezbeat.py 실행
5. log창 확인


해당 프로그램을 Immunity Debugger에 붙히고 ezbeat.py를 돌린 후 실행시켜보겠습니다.


성공적으로 후킹이 되었습니다.


log창을 확인 결과입니다.

훅이 2번 걸렸고 각각의 인자들은 저렇습니다.
그런데 첫번째 호출됬을 때 두번째 인자로 SW_NORMAL(0x01) 을 주었는데 왜 0x00으로 나왔냐..라고 궁금해하실 분들도 계실탠데.. 저도 왜 저런가 궁금해서 WinExec 함수 내부를 봐봤더니 

 


저 부분에서 두번째 인자가 1일경우 점프를 하게 되고 "EBP+0xC" 자리에 ESI(0x00) 값으로 채워지는 것을 확인했습니다.
그냥 그런가보다 하고 넘어가주세요...;; 

이제 ezbeat.py 코드를 보겠습니다.


주석은 최대한 자세히 달아보았습니다. 
immlib 나 각 라이브러리에 있는 자세한 함수 설명은
http://debugger.immunityinc.com/Documentation/ 

이쪽으로 가시면 더욱 자세히 볼 수 있습니다.

이제 후킹 된 실제 어셈 코드를 봐보도록 하겠습니다. 
WinExec 후킹 전 코드 일부분입니다.


후킹 후 코드 일부분입니다.

잘 비교해 보시면 어떤 부분이 달라졌는지 알 수 있습니다.
원본 코드는 어디로..?;; 일단 JMP문을 따라 들어가보겠습니다.



열심히 분석해서 주석을 달아놨습니다.
즉, 위 코드를 전체적인 그림으로 봐보면

여기서 얻을 인자 같은 것은 python코드를 짜는 사람 마음이기 때문에 후킹 코드와 원하는 값 저장할 크기는 유동적입니다.
그리고 python 코드를 보시면 getAllLog() 함수를 사용해 메모리로부터 값을 가져온다고 했는데 바로
0x00000080위치에서 가져오는 것 입니다. 실제로 저 위치에 있는 리턴 값을 0x64로 바꿔보고 실행해보겠습니다.


그리고 제가 알던 후킹방법하고 다른 점은 JMP로 덮힌 코드를 후킹 코드 내부에서 실행한다는 것입니다.
음... 나머지는.. 다들 알아서 해보시면 알 수 있을 것입니다. 글을 쓰다 잠시.. 정신놓고 어딜 갔다와서 갑자기 이상하네요.ㅠㅠ


Immunity 디버거에서 파이썬을 실행시킬 땐 PyCommand를 사용하는데
PyCommand를 만들 때 기본적인 템플릿이 존재합니다.

첫번째는 파라미터를 받아들이는 main()함수를 정의
두번째는 문자열을 리턴해야 한다는 것


위 코드를 잘보면 main함수의 인자로 받을 수 있게끔 args를 써주었고 리턴도 하고 있는 것을 볼 수 있다.
이것을 잘 응용하면 더욱 편하게 디버깅을 할수 있을 것 같네요..

'My Study > Programming&Theory' 카테고리의 다른 글

Remote Library Injection  (4) 2011.12.29
OpenProcess를 막는 방법은??  (11) 2011.12.20
ScreenSaver 만들어보기  (3) 2011.11.30
API vs MFC  (1) 2011.11.30
Prefix list in executive component  (0) 2011.09.02