티스토리 뷰
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이 동작한다는 것을 확인할 수 있다.
'Reversing > Concept' 카테고리의 다른 글
[Reversing] x64 IAT Hooking을 이용한 API Hooking (C언어) (0) | 2020.04.13 |
---|---|
[Reversing] x32 IAT Hooking을 이용한 API Hooking (C언어) (0) | 2020.04.09 |
[Reversing] Trampoline API Hooking 전체코드. (0) | 2020.03.14 |
[Reversing] x86 환경 5Byte 패치를 통한 Trampoline API Hooking (0) | 2020.03.14 |
[Reversing] DLL Injection (0) | 2020.03.05 |