반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- IAT Hooking
- hacking
- Windows Kernel Debug
- C언어 패킷캡쳐
- vcruntime.dll
- 네트워크 바이트 오더
- pcap packet
- 개발하기
- apphelp.dll
- 윈도우 커널 드라이버
- Msvcrt.dll
- Windows Kernel
- Network Byte Order
- 해킹
- Windows Kernel Driver
- 포너블
- packet capture
- 윈도우 커널 디버깅
- 윈도우 커널
- Windows
- 시스템해킹
- ucrtbase.dll
- vcruntime140.dll
- HackCTF
- arudino
- pcap packet capture
- pwnable
- 바이트 오더
- windows kernel debugging
- 개발 환경 준비
Archives
- Today
- Total
미친해커
[Reversing] Trampoline(Inline) Hooking x86 Step 2 본문
반응형
How to patch the top 5 bytes of the API
이제 후킹하고 싶은 API의 상위 5 바이트를 패치하는 것만 남았다. 기본적으로 DLL의 함수들은 .text
섹션에 존재한다. 해당 섹션의 메모리 보호 옵션은 보통 ER---
로 쓰기 권한이 빠져있다. 그렇기 때문에 먼저 쓰기 권한을 부여해야만 한다. Windows API 중 특정 영역의 메모리 보호 옵션을 수정하는 함수는 VirtualProtect
함수가 있다.
#include <stdio.h>
#include <windows.h>
int main(int argc, char *argv[])
{
// GetModuleHandleA 함수로 hModule을 구한다.
HMODULE hModule = GetModuleHandleA("user32.dll");
// 만약 GetModuleHandleA 함수로 구하지 못하였다면 LoadLibraryA 함수로 DLL을 로드한다.
if (hModule == NULL)
hModule = LoadLibraryA("user32.dll");
// GetProcAddress 함수를 이용해 주소를 가져옴
PVOID pMessageBoxA = (PVOID)GetProcAddress(hModule, "MessageBoxA");
// 원본 메모리 보호 옵션을 저장할 변수
DWORD OldProtect;
/*
VirtualProtect 함수를 사용해 MessageBoxA 주소로부터 5바이트 만큼의 메모리 보호 옵션을
PAGE_EXECUTE_READWRITE(ERW--)로 변경한다.
*/
if (VirtualProtect(pMessageBoxA, 5, PAGE_EXECUTE_READWRITE, &OldProtect) == FALSE)
{
printf("VirtualProtect Failed\n");
return -1;
}
printf("Changed the top 5 bytes memory protection option in MessageBoxA to ERW--\n");
}
Changed the top 5 bytes memory protection option in MessageBoxA to ERW--
위 문자열이 출력되면 정상적으로 MessageBoxA 함수의 상위 5바이트의 메모리 보호 옵션이 수정된 것이다. 수정된 이후에는 해당 영역의 데이터를 수정할 수 있게 된다. 이제 본격적으로 후킹을 시도해보자.
Let's try Trampoline Hooking!!
후킹 함수가 호출되었을 때 원본 함수를 호출하기 위해서는 꼭 다시 원본 코드로 복원 후 호출해야 하고 호출이 끝난 후에는 다시 후킹 코드로 패치해줘야 후킹이 유지될 수 있다.
#include <stdio.h>
#include <windows.h>
BYTE HookCode[5] = { 0xE9, 0x00, 0x00, 0x00, 0x00 };
BYTE OriginCode[5] = { 0x00, 0x00, 0x00, 0x00, 0x00 };
int __stdcall NewMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
// 상위 5 바이트를 원본 코드로 패치
memcpy(MessageBoxA, OriginCode, 5);
// lpText 변수를 조작해 함수를 정상적으로 실행
int ret = MessageBoxA(hWnd, "Hooked..!", lpCaption, uType);
// 다시 후킹 코드로 패치
memcpy(MessageBoxA, HookCode, 5);
// 반환값 전달
return ret;
}
int main(int argc, char *argv[])
{
// GetModuleHandleA 함수로 hModule을 구한다.
HMODULE hModule = GetModuleHandleA("user32.dll");
// 만약 GetModuleHandleA 함수로 구하지 못하였다면 LoadLibraryA 함수로 DLL을 로드한다.
if (hModule == NULL)
hModule = LoadLibraryA("user32.dll");
if (hModule == NULL)
{
printf("[-] user32.dll not found\n");
return -1;
}
printf("[+] user32.dll found!\n");
// GetProcAddress 함수를 이용해 주소를 가져옴
PVOID pMessageBoxA = (PVOID)GetProcAddress(hModule, "MessageBoxA");
if (pMessageBoxA == NULL)
{
printf("[-] MessageBoxA not found\n");
return -1;
}
printf("[+] MessageBoxA found!\n");
// 원본 메모리 보호 옵션을 저장할 변수
DWORD OldProtect;
/*
VirtualProtect 함수를 사용해 MessageBoxA 주소로부터 5바이트 만큼의 메모리 보호 옵션을
PAGE_EXECUTE_READWRITE(ERW--)로 변경한다.
*/
if (VirtualProtect(pMessageBoxA, 5, PAGE_EXECUTE_READWRITE, &OldProtect) == FALSE)
{
printf("VirtualProtect Failed\n");
return -1;
}
printf("[*] Changed the top 5 bytes memory protection option in MessageBoxA to ERW--\n");
printf("[+] Calculate relative jump length\n");
// 점프할 상대거리 계산후 변수에 저장
*(DWORD *)(HookCode + 1) = (ULONG_PTR)NewMessageBoxA - (ULONG_PTR)pMessageBoxA - 5;
printf("[*] Patch code : 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",
HookCode[0],
HookCode[1],
HookCode[2],
HookCode[3],
HookCode[4]
);
// 원본 5 바이트 백업
memcpy(OriginCode, pMessageBoxA, 5);
printf("[*] Original code : 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",
OriginCode[0],
OriginCode[1],
OriginCode[2],
OriginCode[3],
OriginCode[4]
);
// 후킹 코드로 패치
memcpy(pMessageBoxA, HookCode, 5);
printf("[+] Trampoline Hooking Success!\n");
printf("Press the any key...");
getchar();
// 후킹된 MessageBoxA 함수 호출
MessageBoxA(NULL, "Not Hooked...!", "Trampoline Hook", 0);
return 0;
}
[+] user32.dll found!
[+] MessageBoxA found!
[*] Changed the top 5 bytes memory protection option in MessageBoxA to ERW--
[+] Calculate relative jump length
[*] Patch code : 0xE9 0x1B 0x09 0xAD 0x8A
[*] Original code : 0x8B 0xFF 0x55 0x8B 0xEC
[+] Trampoline Hooking Success!
Press the any key...
정상적으로 실행되었다면 Press the any key가 출력되었을 때 아무 키를 입력하게 되면 코드와 다르게 Not Hooked...!
가 아닌 Hooked...!
라는 메시지를 출력한다.
반응형
'Reversing > Hooking' 카테고리의 다른 글
[Reversing] Trampoline(Inline) Hooking x64 Step 1 (0) | 2022.05.03 |
---|---|
[Reversing] Trampoline(Inline) Hooking x64 Step 0 (0) | 2022.05.03 |
[Reversing] Trampoline(Inline) Hooking x86 Step 1 (0) | 2022.04.27 |
[Reversing] Trampoline(Inline) Hooking x86 Step 0 (0) | 2022.04.27 |
[Reversing] IAT Hooking Step 2 (0) | 2022.02.03 |
Comments