티스토리 뷰
MASM을 이용해 구현한 32Bit Trampoline API Hooking을 소개하고 실습을 진행해 보겠다. 32Bit Trampoline API Hooking 기법은 앞에서도 C언어로 구현하는 것을 소개했다. 기법자체는 다시 소개하지 않을 생각이다. 그냥 5Byte를 Jump문으로 Overwrite해서 API Hooking을 진행하는 기법이다.
api_hooking.asm
1-12 : 이전과 같은 내용의 기본적인 선언문이다. winmm.dll의 용도는...?
14-17 : 각종 함수들의 proto를 작성한다.
19-21 : data 섹션에 필요한 문자열(DLL, API명)을 저장한다.
24-26 : bss 섹션에 필요한 것들을 미리 선언한다.
28 : DLL이 Injection되면 자동으로 호출되는 DllEntry를 선언한다.
29-40 : DLL Injection이 성공했을 때 API Hooking 을 진행하기 위해서,
LoadApiHook 함수를 호출해 해당 API의 Hooking 을 진행한다.
38번째 줄의 저 코드는 굳이 필요한걸까..? (확인해보고 이따 알려줌!!)
49-52 : SetWindowsHookEx API를 통해 DLL Injection을 진행할 때 사용되는 함수이다.
Windows의 특정 이벤트가 호출될 때 이 함수가 호출된다. (지금은 그냥 써논거..)
이 함수는 Source에서 Destination으로 count수의 데이터를 복사하는 함수이다. isExecute의 값에 따라서 해당 메모리구역의 권한을 다르게한다. (PAGE_READONLY, PAGE_EXECUTE_READ) 근데 사실 PAGE_EXECUTE_READ로 통일해도 전혀 문제는 없는것같다.
69 : 값 복사전 API의 메모리영역에 권한을 연다고 생각하면 된다.
71-74 : 여기는 그냥 일반적인 데이터의 복사라고 생각하면된다.
rep movsb 는 자주 사용되는 명령어니까 눈에 익혀두도록 하자.
76 : 복사 후 API의 메모리영역에 권한을 다시 원래대로 돌려놓는다.
이 함수는 Target API를 Hooking하는 과정이 담긴 함수이다.
86 : StubOrg는 Target API의 제일 앞 기존 5Byte를 저장해두기 위한 Byte배열을 선언한다.
87 : StubHook은 Target API의 제일 앞에 덮어쓰기 위한 5Byte를 저장하기 위한 Byte배열을
선언한다. Hook Function으로 Jump하는 코드가 저장될것이다.
88 : Hook Function을 마치고 Target API의 원래 루틴으로 돌아오기 위한 Jump문을 저장하
기 위한 5Byte공간의 Byte배열을 선언한다.
C언어로 구현할때와 다르게 MASM으로 구현할때에는 UnHook, Hook을 반복하며 Hook Function이 진행되는 것이 아니라 Target API의 앞 5Byte를 Hook Function의 가장 뒤에 삽입하고 [ Target API + 5 ] 지점으로 Jump하는 방법으로 진행되는 기법을 사용한다.
90-100 : Target API의 주소를 읽어오는 API 호출이다.
103 : Target API의 앞 5Byte를 StubOrg Byte배열에 복사한다. (읽어오는 거니까 READ_ONLY)
107-113 : StubHook Byte배열을 Jump문으로 채우는 코드이다.
Jump의 타겟은 Short Jump로 Target API 에서 Hook Function 을 빼서 구한다.
그러나 Jump 문으로 Target API의 앞 5Byte를 차지했으니 5Byte를 더 뺀다.
116 : StubHook을 Target API의 제일 앞 5Byte에 덮어쓴다. (Overwrite)
119 : Target API의 기존 5Byte인 StubOrg를 Hook Function 바로 뒤 5Byte에 덮어쓴다.
( 뒤에서 보면 알겠지만 byte 5 dup(0x90) 으로 자리를 차지하고 있다. )
121-126 : Hook Function 을 마치고 [ Target API + 5 ] 으로 돌아오기 위한 Jump문을 만든다.
Hook Function 의 바로 뒤 10Byte에 넣어줄 코드 OrgJmpStub이다.
129-131 : Hook Function + 5 지점에 위에서 생성한 OrgJmpStub을 복사한다.
MyMessageBoxW 함수는 기존의 Target API 인 MessageBoxW API가 호출될 때 마다 기존 API가 호출되기에 앞서 호출되는 함수를 정의하는 것이다.
144 : call MyMessageBoxWJMP 이 부분이 Target API를 호출하는 것과 똑같은 것이다.
145-146 : 그리고 반환값을 조정하여 IDCANCEL로 고정시킨다.
148-150 : 매우매우 중요한 포인트이다. Target API의 앞 5Byte를 여기서 호출하고
[ Target API + 5 ] 지점으로 점프하는 코드를 넣어줘야 하기 때문에 10Byte
의 여유공간을 만들어줘야 한다 !!!
실습
DLL을 Injection하기 위한 방법으로는 MASM으로 작성한 SetWindowsHookEx API 코드를 사용했다.
아래 코드는 SetWindowsHookEx API를 사용한 DLL을 Injection해주기 위한 Injecter.exe 코드이다.
우선 Injeter.asm를 먼저 컴파일을 진행해보겠다.
이제 injector.exe를 실행시켜 실행되는 Process에 대해 해당 DLL을 Injection해보도록 하자.
이 상태에서 Target Process 인 victim.exe를 실행시켜보자.
이런 프로그램이 실행되고 화면을 클릭하면 이런 MessageBox가 뜬다. 여기서 어떤 버튼을 누르냐에 따라서 다른 결과가 담긴 또 다른 MessageBox가 화면에 뜬다.
그러나 MessageBoxW API의 반환값을 IDCANCEL으로 후킹해놨기때문에 어떤 버튼을 누르든 cancel이 담긴 Messagebox가 뜨는것을 확인할 수 있다.
SetWindowsHookEx API를 이용해서 DLL Injection을 진행하지 않고 SimpleInjector32.exe를 이용해서도 정상적으로 인젝션되고 API Hooking까지 진행되는 것을 확인했다.
사실상 어떤 방법으로든 DLL Injection 성공하면 API Hooking은 성공하는 것 같다 !
[ 출처 ]
'Reversing > Assembly' 카테고리의 다른 글
[Assembly] MIPS로 작성한 Bubble Sort 예제코드 (1) | 2020.04.08 |
---|---|
[Assembly] 순서없이 배우는 MIPS 개념정리. (1) | 2020.04.08 |
[MASM] MASM으로 작성한 SetWindowsHookEx을 이용한 DLL Injection. (0) | 2020.03.11 |
[MASM] MASM(Microsoft Assembler) 시작하기 (x32, x64) (0) | 2020.03.10 |
[Assembly] 순서없이 막 익히는 ARM Assembly (0) | 2020.02.26 |