ÀÌ ¹®¼¿¡´Â À¯Àú ·¹º§ Áï, Ring 3±ÇÇÑ¿¡¼ API Hook¸¦ ÇÏ´Â ¹æ¹ý¿¡ ´ëÇØ¼ ¼³¸íÇÕ´Ï´Ù.
( Ring 0±ÇÇÑ¿¡¼ API Hook¸¦ ÇÏ´Â ¹æ¹ý¿¡ ´ëÇØ¼´Â ´ÙÀ½ ¹®¼¿¡¼ ¼³¸íÇϰڽÀ´Ï´Ù.
Ȥ½Ã³ª CPU¿¡¼ Á¦°øÇÏ´Â Ring¿¡ ´ëÇØ¼ ¸ð¸£½Å´Ù¸é °ü·Ã ¹®¼¸¦ ¸ÕÀú Àо±â¸¦ ±ÇÇÕ´Ï´Ù. )
API Hook°ú °ü·ÃÇÏ¿© ÀÎÅͳݿ¡¼ ÀÚ·áµéÀÌ ¸¹ÀÌ ÀÖ´Â °ÍÀÌ »ç½ÇÀÌÁö¸¸ ¼³¸íÀÌ ³Ê¹« ¾î·Æ°Å³ª
°ü·Ã ¼Ò½º°¡ À־ ³Ê¹« ºÒ¾ÈÁ¤ÇÏ°Ô µ¹¾Æ°¡´Â °æ¿ì°¡ ¸¹½À´Ï´Ù. µû¶ó¼ °£´ÜÇÑ API Hook¸¦ ±¸ÇöÇØº¸°í
½ÇÁ¦·Î »ç¿ëÇÒ ¼ö ÀÖ´Â Hook Äڵ忡 ´ëÇØ¼ ¼³¸íÇÏ·Á°í ÇÕ´Ï´Ù.
API HookÀ̶õ, Win32 ¾ÖÇø®ÄÉÀ̼ǿ¡¼ »ç¿ëÇÏ´Â API¸¦ ³»°¡ ¸¸µç ÇÁ·Î±×·¥¿¡¼ °¡·Îæ ÈÄ
°¡·Îæ µ¥ÀÌÅÍÀÇ ³»¿ëÀ» º¸°Å³ª ¶Ç´Â ±× API¸¦ È£ÃâÇÏÁö ¸ø Çϵµ·Ï ÇÏ´Â °ÍÀ» ¸»ÇÕ´Ï´Ù.
API HookÀ» ÇÏ´Â ¹æ¹ý¿¡´Â ´ÙÀ½°ú Å©°Ô ´ÙÀ½°ú °°ÀÌ µÎ °¡Áö ¹æ¹ýÀÌ ÀÖ½À´Ï´Ù.
1. IAT( ÀÓÆ÷Æ® ¾îµå·¹½º Å×À̺í )
¾ÖÇø®ÄÉÀ̼ǿ¡¼ Win32 API¸¦ È£ÃâÇϱâ À§Çؼ´Â API°¡ ½ÇÁ¦·Î ¾î´À À§Ä¡¿¡ ÇØ´çÇÏ´ÂÁö ¾Ë¾Æ¾ß ÇÕ´Ï´Ù.
ÀÌ·¯ÇÑ APIÁÖ¼ÒµéÀº IAT¶ó´Â °÷¿¡ ÀúÀåµÇ°Ô µÇ°í ÀÌ Å×À̺íÀÇ °ªÀ» ÅëÇØ¼ ¾ÖÇø®ÄÉÀ̼ǿ¡¼´Â API¸¦ È£Ãâ ÇÒ ¼ö ÀÖ°Ô µË´Ï´Ù.
ÀÌ ¶§ ÀÌ Å×À̺íÀÇ °ªÀ» ¼öÁ¤Çؼ ³»°¡ ¿øÇÏ´Â ÁÖ¼Ò·Î Á¡ÇÁÇϵµ·Ï ÇÏ¿© APIÇÔ¼ö¸¦ °¡·Îç ¼ö ÀÖ½À´Ï´Ù.
ÀÌ ¹æ¹ýÀº API HookÁß¿¡¼ °¡Àå ½¬¿î ¹æ¹ýÀ̳ª IAT¸¦ ÂüÁ¶ÇÏÁö ¾Ê°í API¸¦ È£ÃâÇÏ´Â ¾ÖÇø®ÄÉÀ̼ÇÀÌ Àֱ⠶§¹®¿¡
½ÇÁ¦·Î »ç¿ëÇÏ´Â°Ç ºÒ°¡´ÉÇÕ´Ï´Ù. ´ëÇ¥ÀûÀ¸·Î µ¨ÆÄÀÌ·Î ¸¸µé¾îÁø ÇÁ·Î±×·¥Àº IAT¸¦ »ç¿ëÇÏÁö ¾Ê°í ÀÚüÀûÀ¸·Î
Å×À̺íÀ» °®°í ÀÖ°í ±×·¯ÇÑ Å×À̺íÀ» »ç¿ëÇϱ⠶§¹®¿¡ µ¨ÆÄÀÌ·Î ¸¸µé¾îÁø ¾ÖÇø®ÄÉÀ̼ÇÀº ÈÅÀÌ ºÒ°¡´ÉÇÏ°Ô µË´Ï´Ù.
2. Trampoline Hook ( Æ®·¥Æú¶óÀÎ ÈÅ )
Trampoline HookÀº API ÄÚµå ÀÚü¸¦ º¯°æÇÏ´Â °ÍÀ» ÀǹÌÇÕ´Ï´Ù.
ÄÚµå ÀÚü¸¦ º¯°æÇÑ´Ù°í ÇØ¼ ¸¹Àº º¯°æÀÌ ÀϾ´Â °ÍÀº ¾Æ´Ï°í ÀÌÀü ¹®¼¿¡¼ Å©·¢¹Ì¸¦ Å©·¢Çß´ø °Í°ú ºñ½ÁÇϰÔ
ÇÔ¼ö¿¡ ½ÃÀÛ ÄÚµå¾Õ¿¡ 5byte Jmp±â°è¾î Äڵ带 »ðÀÔÇÏ¿© ³»°¡ ¸¸µç ÇÔ¼ö·Î Á¡ÇÁÇϵµ·Ï ÇÏ´Â °Í ÀÔ´Ï´Ù.
ÀÌ ¹æ½ÄÀº ¸Å¿ì °·ÂÇϸç ÇÏÀÌÆÛ ½º³ÀÀ̳ª ½º³×±×ÀÕ °°Àº °æ¿ì¿¡´Â TextOut°è¿ÀÇ API¸¦ HookÇÏ¿© ÅØ½ºÆ® ĸÃÄ
±â´ÉÀ» °³¹ß ÇÒ ¼ö ÀÖ°í, BitBlt¸¦ HookÇÏ¿© ȸé ĸÃÄ ¹æÁö ¸ðµâÀ» °³¹ß ÇÒ ¼öµµ ÀÖ½À´Ï´Ù.
Áï, »ó¿ë ¾ÖÇø®ÄÉÀ̼ǵµ °£È¤ ¾²ÀÌ¸ç ¿ì¸®°¡ »ç¿ëÇÒ ¹æ¹ýÀº ÀÌ ¹æ½ÄÀ» ÀÌ¿ëÇØ API Hook¸¦ ÇÏ°Ô µÉ °Í ÀÔ´Ï´Ù.
º»·ÐÀ¸·Î µé¾î°¡±âÀü¿¡ Trampoline HookÀÌ ¾î¶°ÇÑ ¹æ½ÄÀÎÁö ÀÌÇØÇϱâ À§ÇØ
Trampoline Hook¸¦ ÀÌ¿ëÇÏ´Â ¾ÖÇø®ÄÉÀ̼ÇÀÌ ¾î¶°ÇÑ ¹æ½ÄÀ¸·Î API¸¦ Hook´ÂÁö »ìÆìº¸°Ú½À´Ï´Ù.
´ë»ó ¾ÖÇø®ÄÉÀ̼ÇÀº ÇÏÀÌÆÛ ½º³ÀÀÌ¸ç ¿ì¼± ÇÏÀÌÆÛ ½º³ÀÀ» ¶ç¿ó´Ï´Ù.
ÀÏ´Ü ÀÌ »óÅ¿¡¼ TextOutA¿¡ APIÄڵ带 º¸¸é ´ÙÀ½°ú °°½À´Ï´Ù.
( µ¨ÆÄÀÌ IDE¿¡¼ µð¹ö±ëÇØº¸´Â ȸéÀÔ´Ï´Ù. VC2005¿¡¼´Â ÇÔ¼ö¿¡ À̸§ÀÌ ³ª¿ÀÁö ¾Ê±â ¶§¹®¿¡ »ç¿ëÇÏÁö ¾Ê¾Ò½À´Ï´Ù. )
´ÙÀ½°ú °°Àº ÄÚµå·Î ÀÌ·ç¾îÁ® ÀÖ´Ù´Â °ÍÀ» º¸½Ç ¼ö ÀÖÀ¸¸ç ù ºÎºÐÀº mov edi, edi·Î ½ÃÀÛÇÏ°Ô µË´Ï´Ù. ( Windows xp sp2 ±âÁØ. )
±×·¸´Ù¸é TextOutA°¡ ÇÏÀÌÆÛ ½º³À¿¡ ÀÇÇØ ÈÅÀÌ µÇ¾úÀ» °æ¿ì ¾î¶»°Ô ¹Ù²î´Â º¸°Ú½À´Ï´Ù.
( Âü°í : TextOutA°¡ ÈÅÀÌ µÇ´Â ½ÃÁ¡Àº »ç¿ëÀÚ°¡ ÇÏÀÌÆÛ ½º³À¿¡°Ô ÅØ½ºÆ® ĸÃÄ ¸í·ÉÀ» ³»¸° ÈÄ ÈÅÀÌ µÇ°í ¹Ù·Î ÈÅÀÌ ÇØÁ¦ µÇ°Ô µË´Ï´Ù.
¸¸¾à Å×½ºÆ®¸¦ ÇÏ·Á¸é OnPaint ½ÃÁ¡¿¡ TextOutA¸¦ È£ÃâÇϵµ·Ï Çϰí Text From an Object under Cursor¸Þ´º¸¦ ÀÌ¿ëÇØ¾ß ÇÕ´Ï´Ù. )
À§¿Í °°ÀÌ 0xE9 xxxxx ( xx ´Â ³» ÇÔ¼ö°¡ ÀÖ´Â ÁÖ¼Ò. ÀÌ À̹ÌÁö¿¡¼ ±â°è¾î Äڵ带 º¸½Ã¸é 0xE9´ÙÀ½¿¡ ³ª¿À´Â ÁÖ¼Ò°¡
Á¶±Ý ÀÌ»óÇÏ°Ô º¸ÀÏ ¼ö Àִµ¥ 0xE9¿¡ °æ¿ì´Â »ó´ëÁÖ¼Ò¸¦ »ç¿ëÇϱ⠶§¹®ÀÔ´Ï´Ù. ÀÌ¿¡ ´ëÇØ¼´Â ´ÙÀ½¿¡ ¼³¸íÇÏ°Ô µË´Ï´Ù. )
ÇüÅ·ΠÇÏÀÌÆÛ ½º³ÀÀÌ ¸¸µé¾î ³õÀº ÄÚµå·Î Á¡ÇÁ½Ã۵µ·Ï ÇÕ´Ï´Ù.
ÀÌ ºÎºÐÀº ÇÏÀÌÆÛ ½º³À¿¡¼ »ç¿ëÇÏ´Â Hook ÇÔ¼ö ÄÚµåÀÔ´Ï´Ù.
¶ÇÇÑ ½ÇÁ¦·Î, ÀÌ ÁÖ¼Ò¿¡ ¸ðµâÀÌ ¿Ã¶ó¿Í ÀÖ´Â °ÍÀ» È®ÀÎ ÇÒ ¼ö ÀÖ½À´Ï´Ù. ( ÁÖ¼Ò´Â ½Ã½ºÅÛ¿¡ µû¶ó¼ ´Ù¸¦ ¼ö ÀÖ½À´Ï´Ù. )
// APIHookExample.cpp : Defines the entry point for the console application. // #include "stdafx.h" #includeextern "C" { __declspec(dllexport) void InstallHook(); } extern "C" { __declspec(dllexport) void UninstallHook(); } int _tmain(int argc, _TCHAR* argv[]) { printf("API Hook ¿¹Á¦°¡ ½ÇÇàµÇ¾ú½À´Ï´Ù.\nÁ¾·áÇÏ·Á¸é ¿£Å͸¦ ÀÔ·ÂÇϼ¼¿ä."); InstallHook(); while (TRUE) { ::Sleep(30); if (GetKeyState(VK_RETURN) < 0) { break; } } return 0; }
// APIHookExampleDLL.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" #include#include #ifdef _MANAGED #pragma managed(push, off) #endif ///////////////////////////////////////////////////// // ¸ðµç ÇÁ·Î¼¼½º¿¡¼ °øÀ¯ µÉ º¯¼ö¸¦ ¼±¾ðÇÕ´Ï´Ù. ///////////////////////////////////////////////////// #pragma data_seg(".APIHookSection") HHOOK hHook = NULL; #pragma data_seg () ///////////////////////////////////////////////////// // Àü¿ªÀ¸·Î »ç¿ëÇÒ º¯¼ö¸¦ ¼±¾ðÇÏ¿´½À´Ï´Ù. HINSTANCE g_hInst = 0; // API HookÀ» ÇÑ ÈÄ ÈÅÀ» ÇØÁ¦½Ã ¿ø·¡ÀÇ ÄÚµå·Î µÇµ¹¸®±â À§ÇØ // ¼±¾ðÇÏ¿´½À´Ï´Ù. BYTE cbOldCode[5] = { 0x00, }; ///////////////////////////////////////////////////// LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam); ///////////////////////////////////////////////////// // ±âº»ÀûÀÎ Àü¿ªÈÅ ·çƾÀÔ´Ï´Ù. ///////////////////////////////////////////////////// LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam) { return CallNextHookEx( hHook, nCode, wParam, lParam); } extern "C" __declspec(dllexport) void InstallHook() { hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMessageProc, g_hInst, 0); } extern "C" __declspec(dllexport) void UninstallHook() { UnhookWindowsHookEx(hHook); } ///////////////////////////////////////////////////// BOOL WINAPI MyExtTextOutW( __in HDC hdc, __in int x, __in int y, __in UINT options, __in_opt CONST RECT * lprect, __in_ecount(c) LPCWSTR lpString, __in UINT cbCount, __in_ecount_opt(c) CONST INT * lpDx) { //if (cbCount == 0) //{ // return FALSE; //} /*HDC hDC; hDC = ::GetDC(0); ::TextOutA(hDC, 0, 0, "A", 1); //::TextOutW(hDC, 0, 0, _T("A"), 1); ::ReleaseDC(0, hDC);*/ return TRUE; } BOOL InstallAPIHook_ExtTextOutW() { BYTE *pDrawTextWAddress; DWORD dwOldProtect; DWORD dw; pDrawTextWAddress = (BYTE *)GetProcAddress(GetModuleHandle(_T("GDI32.Dll")), "ExtTextOutW"); if (pDrawTextWAddress == NULL) { ::OutputDebugString(_T("ExtTextOutW APIÀÇ ÁÖ¼Ò¸¦ ¾ò¾î¿À´Âµ¥ ½ÇÆÐÇÏ¿´½À´Ï´Ù.")); return FALSE; } VirtualProtect(pDrawTextWAddress, 5, PAGE_WRITECOPY, &dwOldProtect); memcpy(cbOldCode, pDrawTextWAddress, 5); *pDrawTextWAddress = 0xE9; pDrawTextWAddress++; *((DWORD *)(pDrawTextWAddress)) = ((DWORD)MyExtTextOutW) - ((DWORD)pDrawTextWAddress +4); VirtualProtect(pDrawTextWAddress, 5, dwOldProtect, &dw); return TRUE; } BOOL UnInstallAPIHook_ExtTextOutW() { BYTE *pDrawTextWAddress; DWORD dwOldProtect; DWORD dw; pDrawTextWAddress = (BYTE *)GetProcAddress(GetModuleHandle(_T("GDI32.Dll")), "ExtTextOutW"); if (pDrawTextWAddress == NULL) { ::OutputDebugString(_T("ExtTextOutW APIÀÇ ÁÖ¼Ò¸¦ ¾ò¾î¿À´Âµ¥ ½ÇÆÐÇÏ¿´½À´Ï´Ù.")); return FALSE; } VirtualProtect(pDrawTextWAddress, 5, PAGE_WRITECOPY, &dwOldProtect); memcpy(pDrawTextWAddress, cbOldCode, 5); VirtualProtect(pDrawTextWAddress, 5, dwOldProtect, &dw); return TRUE; } BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch(ul_reason_for_call) { case DLL_PROCESS_ATTACH: ///////////////////////////////////////////////////// // DLLÀÌ ÇØ´ç ÇÁ·Î¼¼½º·Î AttachµÇ¾ú½À´Ï´Ù. ///////////////////////////////////////////////////// g_hInst = hModule; InstallAPIHook_ExtTextOutW(); break; case DLL_PROCESS_DETACH: ///////////////////////////////////////////////////// // DLLÀÌ ÇØ´ç ÇÁ·Î¼¼½º·Î DetachµÇ¾ú½À´Ï´Ù. ///////////////////////////////////////////////////// UnInstallAPIHook_ExtTextOutW(); break; } return TRUE; } #ifdef _MANAGED #pragma managed(pop) #endif