티스토리 뷰

반응형
x64 Trampoline API Hooking을 C언어로 구현된 예제를 소개한다.
notepad.exe 프로그램의 WriteFile API 를 후킹하는 실습을 진행해보자.

 

64비트 환경에서 Trampoline API Hooking은 32비트 환경에서와 조금 차이가 있다.

 

1. 64비트 환경에서 모든 함수는 fastcall 방식으로 호출된다.

   때문에 함수 앞부분이 32비트에서와처럼 동일하지 않다.

   ( 32비트는 모든 함수 시작부분에 동일한 프롤로그가 존재한다. )

 

2. 32비트 환경에서는 5Byte로 Short Jump문을 구현할 수 있었다.

   그러나 64비트에는 64bit 주소로 Jump를 지원하지 않는다.

   그래서 레지스터를 이용해서 Jump문을 구현하거나,

   혹은 2번째 방법으로는 ret을 이용하는 방법이 있다.

   ( 여기서 2번째 방법을 이용하는데, 이 명령어의 길이가 14Byte 이다. )

 

   또한 push 명령어는 64bit 주소를 사용할 수 없어서 아래와 같은 방법을 이용한다.

 

MASM으로 구현할 때에는 Target API 의 앞부분을 항상 검사해보고 명령어가 깨지지 않는 Byte수를 확인한 후에 진행해야한다. 그러나 C언어로 구현할 때에는 어차피 Hooking Function이 호출될 때 UnHook을 진행하고 하기 때문에 이런 걱정을 할 필요없이 그냥 14Byte Overwrite로 진행할 수 있다.

 

 


 

Trampoline.dll

 

4, 19 : 구조체를 통해 Overwrite할 코드를 저장할 공간을 만들기 위해 필수조건 !

         ( 사실 왜 필요한지 자세한 이유는 모르겠다.... 힝탱구리ㅠㅠ )

7-18 : Overwrite할 코드를 저장하기 위한 14Byte구조체 선언.

        사실 그냥 BYTE 배열로 14Byte를 저장할 공간을 만들어도 된다.

 

 

Target API 호출시 해당 API 호출전에 먼저 호출할 Hooking Function을 구현한 코드이다.

 

27-32 : Target API 호출 직전에 호출되기 때문에 같은 Parameter를 작성해두면,

          Stack에 저장되어있는 Parameter들을 모두 이용할 수 있다.

            ( 구글에 Target API를 검색하면 인자 및 반환형을 알 수 있다. )

35 : Target API를 직접 호출하기 전에 원래 모양으로 만들어줘야한다.

      지금은 Hooking을 진행했기 때문에 앞 14Byte가 Overwrite되 정상적인 모양이 아니다.

36 : 이부분에 내가 작성하고 싶은 코드를 작성하면 된다.

37 : 다시 Hooking을 진행해둬야 다음에 또 Target API가 호출되었을 때

      내가 원하는 방식으로 동작시킬 수 있다. ( 지속되는 효과를 얻기 위함이다. )

 

 

 

Target API에 Trampoline API Hooking을 진행하는 함수이다.

 

우선 내용설명에 앞서 최근 운영체제에서는 kernel32.dll 에서 코드가 직접 나오지 않고 kernelbase.dll 로 Redirect 되어서 진행되는 경우가 있다. ( 모든 API가 그런건 아니다. 때문에 조건문으로 둘중 하나로 Overwrite할 대상을 잡아야 한다. ) Redirect 되는 경우에는 코드의 시작 2Byte가 0x25FF 이다. ( 0x25FF 는 Absolute Jump 명령어이다. )

 

48-57 : Target API의 주소를 읽어오기 위한 과정이다.

          특히 54번 라인에서 조건문은 kernelbase.dll 로 Redirect 하는 API를 위한 조건문이다.

63 : Target API 가 저장된 메모리 영역의 쓰기권한을 활성화줘야 Overwrite할 수 있기 때문에

      VirtualProtect API를 통해 14Byte만큼에 대해서 PAGE_EXECUTE_READWRITE 권한을 준다.

66 : orgFP (14BYTE 공간) 에 Target API의 기존 코드를 저장한다. ( UnHooking 과정에서 사용 )

68-79 : 이제 Overwrite할 14Byte의 데이터를 구조체 변수에 저장한다.

          주석을 보면 해당 명령어에 대한 기계어를 확인할 수 있고 확인할 것은

          4Byte 씩 저장하기 때문에 "& 0xFFFFFFFF" ">> 32" 이 부분을 이해하는 것이 중요하다.

81 : 구조체 변수에 저장된 14Byte의 데이터를 Target API의 앞부분에 Overwrite한다.

85 : VirtualProtect API를 이용해 권한을 원래대로 복원한다.

 

 

 

Target API를 원래 API 모양으로 돌려주는 UnHooking 함수이다.

마찬가지로 kernelbase.dll 로 Redirect 되어있는지 확인후 진행해야 한다.

 

113 : Target API 의 앞 14Byte를 저장해둔 orgFP 를 Target API 앞 14Byte에 Overwrite.

       이렇게 하면 Target API 는 Hooking 되기 전으로 돌아간다.

 

 

 

그냥 뻔한 DllMain 함수이다. ( DLL Injection 체크용 MessageBox )

 

 


 

실습

이번 실습의 목표는 notepad.exe 프로그램의 WriteFile API를 Hooking 해 파일을 저장할 때 파일의 내용을 MessageBox를 통해 띄우는 실습이다. 간단한 예제이지만 이를 응용한다면 더욱 다양한 방법에 사용할 수 있을 것 같다.

 

 

notepad.exe 를 킨후 위 코드로 생성한 dll 파일인 Trampoline64.dll을 Injection한다. 여기서 Injection할 때 나는 RtlCreateUserThread API를 사용한 SimpleInjector.exe를 사용했지만 다른 방법을 사용해도 상관없다.

 

 

 

그러면 위와같이 DLL Injection이 성공했음을 알리는 MessageBox가 뜬것을 확인할 수 있다. 이제 대상 API가 정상적으로 Hooking 되었는지 파일을 저장해 확인해 보자.

 

 

 

간단한 내용을 입력한 후 위와같이 파일을 저장해보자.

 

 

 

내가 입력한 내용이 Hooking Function에 의해서 MessageBox로 띄워지는 것을 확인할 수 있다. 이로써 정상적으로 Trampoline API Hooking이 진행되었다는 것을 확인할 수 있다.

 

마지막으로 내용을 추가한 후 Ctrl + S 를 통해 저장해보자.

 

 

 

위와같이 정상적으로 Hooking Function이 동작한다는 것을 확인할 수 있다.

 

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
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 31
글 보관함