티스토리 뷰

반응형
Trampoline API Hooking 기법은 DLL Injection이 성공했다고 가정했을 때 DllMain이 자동적으로 호출되고 그에 따라서 DLL_PROCESS_ATTACH의 코드가 실행되는 것을 이용해 진행한다.

따라서 모든 API Hooking 기법은 DLL Injection이 선행되어야한다. (Code Injection도 가능 !!)

 

Trampoline API Hooking 기법은 기존 API의 가장 앞 5Byte의 코드를 따로 저장하고, 그 대신 내가 임의로 호출시킬 함수로의 JMP문을 기존 API의 가장 앞 5Byte에 저장한다. ( x86에서의 JMP문은 5Byte이다. - Short Jump ) 그리고 기존의 5Byte는 내가 임의로 호출시키는 함수 제일 마지막에 실행하고, 다시 기존 API의 시작 + 5 부분으로 JMP문을 수행하는 기법이다.

  → MASM 으로 작성할 때 해당 방법을 이용했다.

 

또 다른 방법으로 진행할 수 있는데 Hooking함수 진입시 UnHook함수를 호출해 해당 API를 기존 형태로 돌려놓고 모든 작업을 마치고 Hooking함수를 마치기 전에 다시 Hook함수를 호출해 해당 API를 후킹하는 방법이 존재한다.

  → C언어로 작성할 때 해당 방법을 이용했다.

 

 

 

 

 

 

이 포스팅에서는 C언어를 이용한 두 번째 방법을 사용했다. MASM을 이용해서 진행하는 첫 번째 내용은 다음 포스팅에서 다루도록 한다. ( 곧 링크 추가될 예정 )

 

이 포스팅에서는 DLL을 구성하는 코드만 소개한다.

이 DLL을 Process에 Injection하는 과정은 DLL Injection 포스팅을 참고하자.

 

 

Trampoline32.dll

 

5-12 : 내가 원하는 함수로 JMP하는 코드를 작성할 구조체선언. 구조체로 처리하려면 #pragma

        선언을 반드시 해줘야한다. (삽질 오지게함... 즈엔장~)

        그냥 BYTE JMP_5Byte[5] 와 같이 사용해도 똑같이 동작한다. 

13 : Target API의 가장 앞 5Byte 원본을 저장하기 위한 Byte 배열을 선언한다.

 

 

18 : WINAPI를 안 넣어주면 안된다 ㅡㅡ. 진짜 어이없음.....

     해당 API가 호출되고 바로 호출되는거니까 인자를 그대로 넣어두면 그대로 사용가능!!

21 : Hooking Function을 실행하기 전에 일단 정상적인 API함수를 사용하기 위해서

     UnHookAPI 함수를 호출해 후킹을 해제한다. 

23 : Hooking Function을 마치고 반환하기전에 다시 Target API를 후킹한다.

 

 

Target API를 후킹하기 위함 함수이다.

 

33-37 : 해당 API의 주소를 읽어오고 첫 Byte가 0xE9(JMP) 인지 검사를 진행한다.

39 : 해당 API에 임의의 값을 덮어써야하기 때문에 PAGE_EXECUTE_READWRITE 권한을 준다.

41-43 : Target API의 앞 5Byte에 덮어쓰기 위한 값을 JMP_5Byte 구조체에 저장한다.

          Short Jump이기 때문에 두 API의 주소 차이를 이용해 값을 정한다.

          5를 더 빼는 이유는  JMP문으로 이미 5Byte를 차지했기 때문이다.

45 : Target API의 기존 5Byte를 Byte배열 OrgFP2에 저장한다.

47 : 생성한 JMP문을 Target API의 5Byte에 덮어쓴다.

48 : PAGE_EXECUTE_READWRITE였던 권한을 이전 권한으로 다시 원상복구한다.

 

 

Target API에 후킹되어있는 것을 원상복구하기 위한 함수이다.

 

59-63 : 해당 API의 주소를 읽어오고 첫 Byte가 0xE9(JMP)가 아닌지 검사한다.

65, 69 : hookAPI 함수에서의 VirtualProtect와 용도가 동일하다.

67 : Target API의 앞 5Byte를 저장해둔 기존 API 5Byte로 덮어쓴다.

     이로써 해당 API는 Hooking 이전의 상태인 원래상태로 돌아간다.

 

 

DLL Injection 성공시 자동으로 호출되는 DllMain 함수이다.

DLL_PROCESS_ATTACH 부분이 자동으로 호출되는 것을 이용해 API Hooking 함수를 호출해 Hooking을 진행하게 된다. DLL_PROCESS_DETACH 부분에 UnHooking을 진행해도 된다.

 

 

실습

DLL Injection은 SimpleInjector32.exe를 사용해 진행했다.

대상 Process는 Victim.exe로 내부적으로 MessageBoxW API를 사용하며 목표는 모든 클릭 결과가 Cancel이 나오게 하는 것이다. 원래는 클릭 버튼에 따라 결과가 MessageBox로 출력된다.

 

victim.exe

 

우선 실행중인 Process에 DLL을 Injection하는 방법을 선택했기 때문에 victim.exe를 실행한다.

 

 

victim.exe의 화면을 클릭하면 위와같이 뜨고 어떤 버튼을 클릭하냐에 따라 다른 메세지창이 출력되는 프로그램이다. 예를 클릭하면 yes, 아니오를 클릭하면 no, 취소를 클릭하면 cancel이 출력된다.

 

 

이제 SimpleInjector32.exe를 이용해 해당 Process에 DLL Injection을 수행하자.

 

 

Inject 버튼을 누르면 DllMain에서 가장먼저 호출해주는 MessageBoxA API가 호출되며 정상적으로 DLL이 Injection 되었다는 것을 알 수 있다. ( 궁금하면 Process Explorer를 통해 확인할 수 있다. )

 

 

이 상태에서 화면을 클릭하면 내가 작성한 Hooking Function이 먼저 호출되었다는 증거로 "Call Hooking API" 가 담긴 MessageBox가 뜬다. 여기서 확인을 누르면 기존의 흐름으로 진행된다.

 

 

동일하게 아니오 버튼을 눌렀지만 위와같이 cancel이 뜨는것을 확인할 수 있다.

정상적으로 Hooking Function이 호출되었고 반환값으로 IDCANCEL이 반환된 것을 알 수 있다.

 

 

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함