Making Your own Packet Trainer on NT,XP NT,XP ±â¹ÝÀÇ ¿î¿µÃ¼Á¦¿¡¼­ÀÇ ÆÐŶ Æ®·¹ÀÌ³Ê ¸¸µé±â Written by A #Dual_Roo¢Ó ¼­·Ð ÀÌ ±Û¿¡¼­´Â NT,XP¿¡¼­ ÀÛµ¿ÇÏ´Â ÆÐŶ Æ®·¹À̳ʸ¦ ¸¸µå´Â ¹æ¹ý¿¡ ´ëÇÏ¿© ´Ù·ê °ÍÀÔ´Ï´Ù. ÇÊ¿äÇÑ µµ±¸µé M$ Visual C++ 6.0 Source Code[¼Ò½ºÄÚµå] ´ë»ó ÇÁ·Î±×·¥ ¸µÅ© ÀúÀ۱ǻóÀÇ ÀÌÀ¯·Î ¸µÅ© ÇÒ¼ö ¾ø½À´Ï´Ù. º»¹® Making Your own Packet Trainer on NT,XP ¿¡.. ¾È³çÇϼ¼¿ä? :p ÀÌ ±ÛÀ» ÅëÇØ¼­ Àú¸¦ óÀ½ ¸¸³­ ºÐµµ °Ô½Ç°Å±¸, Àü¿¡µµ ¸î¹ø º»ÀûÀÌ ÀÖ´Â ºÐµéµµ °Ô½Ç°Å¶ó°í »ý°¢ÇÕ´Ï´Ù. ¾î¤Šµç ½ÃÀÛÇÏ¿© º¸ÁÒ~ :p À̱ÛÀ» Àаí ÀÖ´Â ±×ÂÊÀº WPE[Winsock Packet Editor]¶ó´Â ÇÁ·Î±×·¥¿¡ ´ëÇÏ¿© ¾Ë°í °Ô½Ê´Ï±î? :p ¸¸¾à ¸ð¸¥´Ù°í °¡Á¤ÇÏ°í °£´ÜÈ÷ ¼³¸íÇØ µå¸®ÀÚ¸é, ¿øÇÏ´Â ÇÁ·Î±×·¥ÀÇ PacketÀ» Hooking(À̶ó´Â ¸»º¸´Ü SniffingÀÌ ¾î¿ï¸±·Á³ª? :p) ÇÏ´Â ÇÁ·Î±×·¥ ÀÔ´Ï´Ù. 9X,NT,XP¿ë ¹öÁ¯ ´Ù Á¸Àç ÇÏÁö¸¸~ :p exeÈ­ ÇØÁÖ´Â ±â´ÉÀº 9X¹öÁ¯¿¡¼­¸¸ Áö¿øµÇ°í, NT,XP¿ë¿¡¼± Áö¿øµÇÁö ¾Ê½À´Ï´Ù. ÀÌÁ¡ÀÌ ¿ì¸®ÀÇ ¸¶À½À» ¾ÆÇÁ°Ô ÇÏÁÒ T.T (±×·¸Áö ¾Ê³ª¿ä? :p) Àú´Â ±×·¡¼­ NT,XP¿¡¼­µµ ¿©·¯ºÐÀÌ Packet TrainerÀ» Á÷Á¢ ¸¸µé¼ö ÀÖµµ·Ï, ÀÌ ±ÛÀ» ÅëÇØ¼­ µµ¿Í µå¸®°íÀÚ ÇÕ´Ï´Ù~! :p ¹°·± C¾ð¾î¿¡ ´ëÇÏ¿© ¾î´ÀÁ¤µµ ¾Ë°í °Ô¼Å¾ß ¼³¸íÀÌ °¡´ÉÇÕ´Ï´Ù. T.T ¹¹~! ¾Ë°íµé °Ô½Ã´Ù´Â °¡Á¤ÇÏ¿¡ Start~ :p 1. How to WPE Hook and modify the Packet? ¾î¶»°Ô WPE´Â ÆÐŶÀ» ³¬¾Æº¸°í ¼öÁ¤ÇÒ¼ö ÀÖ´Â °É±î¿ä? :p ¹Ù·Î API Hooking À̶ó´Â ±â¼úÀ» ÅëÇÏ¿© °¡´ÉÇÕ´Ï´Ù. :p WindowsÀÇ °ÅÀÇ ¸ðµç ÇÁ·Î±×·¥µéÀº WSOCK32¶ó´Â DLL¿¡ ÀÇÇØ ExportµÇ¾î Áö´Â ÇÔ¼öµéÀ» »ç¿ëÇÏ¿© ¿ÜºÎ Åë½ÅÀ» ÇÕ´Ï´Ù. :p ±×·¸´Ü ¾Ö±â´Â? :p WSOCK32¿¡¼­ ÀûÁ¤ÇÑ ÇÔ¼öµéÀ» Hooking(³¬¾Æ) ÁÖ¸é ¿ì¸®°¡ ¿øÇÏ´Â °á°ú¸¦ ¾òÀ»¼ö ÀÖÀ»°Å¶õ ¼Ò¸® ÀÔ´Ï´Ù. :p ±×·³ ÀÌÁ¦ ºÎÅÍ API HookingÀ» ÇÏ´Â Code¸¦ ÅëÇÏ¿© ¼³¸í Çϵµ·Ï ÇÏÁÒ~ :p Yeah~! Áñ°Å¿î CodingÀ» ½ÃÀÛÇÏ¿© º¾½Ã´Ù. :p ¸ÕÀú ±âº»ÀûÀÎ Skeleton Code´Â °¢ÀÚ ÀÛ¼ºÇϼŵµ µÇ±¸¿ä~! Àç°¡ ÀÛ¼ºÇÑ°É ´Ù¿î ¹ÞÀ¸¼Åµµ º° »ó°üÀº ¾ø°ÚÁÒ? :p º»ÀÎÀÇ ÄÚµå´Â Visaul C++ 6.0¿¡¼­ ÀÛ¼ºµÇ¾ú½À´Ï´Ù~! :p //================================================================================ BOOL CALLBACK MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); /* hDlg : ´ÙÀ̾ó·Î±×ÀÇ ÇÚµé iMessage : ¸Þ½ÃÁö wParam : ¾ÆÀÌÅÛ(¸®¼Ò½º) ¹øÈ£°¡ ¿Â´Ù. lParam : ¼¼ºÎ »çÇ×ÀÌ ¿Â´Ù. */ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { DialogBox(hInstance, MAKEINTRESOURCE(IDD_DLG1), HWND_DESKTOP, MainDlgProc); /* hInstance : ÇÁ·Î±×·¥ÀÇ ImageBase¸¦ °¡¸£Å²´Ù. C¿¡¼± GetModuleHandle ÇÔ¼ö¸¦ ¾µÇÊ¿ä¾øÀÌ ÀÚµ¿ Á¦°ø µÇ¾î Áø´Ù. MAKEINTRESOURCE(IDD_DLG1) : ¸®¼Ò½º¿¡ Àû¿ëÇÑ ¾ÆÀÌÅÛ À̸§À» »ó¼ö°ªÀ¸·Î ¹Ù²Ù¾î ÁØ´Ù. HWND_DESKTOP : ºÎ¸ðÀÇ ÇÚµéÀÌ´Ù, µ¥½ºÅ©ÅéÀÇ °ªÀ» Á¦°øÇϰí ÀÖ´Ù. MainDlgProc : ¸Þ½ÃÁö ÇÁ·Î½ÃÁ®ÀÇ ÁÖ¼Ò¸¦ ´ëÀÔÇÏ¿© ÁØ´Ù. */ return 0; } BOOL CALLBACK MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) { switch(iMessage) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: return TRUE; default: return FALSE; } case WM_CLOSE: EndDialog(hDlg,0); return TRUE; default: return FALSE; } return FALSE; } //================================================================================ Á¤¸» ±âº»ÀûÀÎ ÄÚµåÁÒ? :p (ÄÚµå ±æÀ̸¦ »ý°¢Çؼ­ DialogBox»ç¿ë Çß½À´Ï´Ù.) ÀÌÁ¦ Äڵ带 Á¶±Ý¾¿ Ãß°¡ ½Ã۵µ·Ï ÇÏÁÒ. :p °¡Àå ¸ÕÀú API HookingÀ» Çϱâ À§ÇØ ÇÊ¿äÇÑ°Ç ¹«¾ùÀϱî¿ä? ´ë»ó ÇÁ·Î±×·¥À» ÁöÁ¤ÇÏ´Â ÀÏ ÀϰÍÀÔ´Ï´Ù. (±×·¸°Ô »ý°¢¾ÈÇÒ¼öµµ :p) ¸¸¾à Àú¿Í »ý°¢ÀÌ °°´Ù¸é ´ë»ó ÇÁ·Î±×·¥À» ÁöÁ¤ÇÏ´Â ¹æ¹ýÀ» »ý°¢ÇØ º¸¾Æ¾ß °ÚÁÒ? Àú´Â ÁÖ·Î µÎ°¡Áö ¹æ¹ýÀ» »ç¿ëÇϴµ¥, ù¹ø¤Š ¹æ¹ýÀº ¸ðµâÀÇ À̸§À» °¡Áö°í °Ë»öÇÏ´Â ¹æ¹ýÀÔ´Ï´Ù. (½ÇÇà ÆÄÀÏÀ̸§ÀÌ º°·Î ¹Ù²ð¸®´Â ¾ø´Ù´Â Á¡¿¡¼± ÁÁÁÒ) µÎ¹ø¤Š ¹æ¹ýÀº Window NameÀ» °¡Áö°í °Ë»öÇÏ´Â ¹æ¹ýÀÔ´Ï´Ù. (âÀ̸§À» °¡Áö°í ÇÒ°æ¿ì Code°¡ ª¾ÆÁö°í ÁÁÁÒ) ¾î¤Šµç,Àü À̹ø ±Û¿¡¼± ´ëµµ·ÏÀ̸é Code¸¦ ª°Ô ÇϰíÀÚ ÇÏ±â ‹š¹®¿¡, µÎ¹ø¤Š ¹æ¹ýÀÎ Window NameÀ» °¡Áö°í °Ë»öÇÏ´Â ¹æ¹ýÀ» »ç¿ëÇϱâ·Î ÇÏÁÒ. Window NameÀ» °Ë»öÇÏ´Â API´Â? :p ¹Ù·Î FindWindow() ÇÔ¼öÀÌÁÒ :p (³Ê¹« ½¬¿î Áú¹®À̾ú³ª? :p) HWND FindWindow( LPCTSTR lpClassName, LPCTSTR lpWindowName ); À½? ù¹ø¤Š ÀÎÀÚ´Â ClassNameÀÌ°í µÎ¹ø¤Š ÀÎÀÚ´Â WindowNameÀ̱º¿ä :p ClassNameÀ¸·Î ÇÒ°æ¿ì ÀåÁ¡Àº ¿ª½Ã º¯È­¼ºÀÌ Àû´Ù´Â Á¡À̰í, (´Ü ´ÜÁ¡Àº MFC or VB or DELPHI ÇÁ·Î±×·¥ µéÀº ClassNameÀÌ.. =_=;) µÎ¹ø¤Š ÀÎÀÚÀÎ WindowNameÀ¸·Î ÇÒ°æ¿ì ÀåÁ¡Àº WindowNameÀÌ ¹«¾ùÀΰ¡´Â ¾Ë±â°¡ ½±°í, À̸§ÀÌ °ãÄ¥ °¡´É¼ºÀÌ ClassNameº¸´Ù Àû½À´Ï´Ù. (´ÜÁ¡Àº °£´ÜÈ÷ ¿¹¸¦ µé¾î ¹öÁ¯À» Á¦¸ñ Ç¥½ÃÁÙ¿¡ Ç¥½ÃÇÏ´Â ÇÁ·Î±×·¥ÀÇ °æ¿ì ¹öÁ¯¾÷ÀÌ µÉ¶§¸¶´Ù WindowNameÀÌ ´Þ¶ó Áú¼ö À־ =_=;) µÑÁßÀÇ ¾î¶²°É ¾²´ø FindWindow() ÇÔ¼ö¸¦ ´ë»ó ÇÁ·Î±×·¥ÀÇ ÇÚµåÀ» ¾ò¾î¿Ã¼ö ÀÖ½À´Ï´Ù. Ãß°¡ÀûÀ¸·Î Process IDµµ ¾ò¾î µÎ°Ú½À´Ï´Ù. DWORD GetWindowThreadProcessId( HWND hWnd, LPDWORD lpdwProcessId ); ù¹ø¤Š ÀÎÀÚ´Â FindWindow() ÇÔ¼ö¸¦ ÅëÇØ¼­ ¾òÀº â ÇÚµé À̰í, µÎ¹ø¤Š ÀÎÀÚ´Â Process ID¸¦ ÀúÀåÇÒ º¯¼öÀÇ ÁÖ¼Ò ÀÔ´Ï´Ù. ¾î¤Šµç, À§ µÎ ÇÔ¼öµéÀ» Code¿¡ Ãß°¡ ½ÃŰ°Ú½À´Ï´Ù. :p //================================================================================ BOOL CALLBACK MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) { HWND W_hWnd; DWORD Pid; switch(iMessage) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: W_hWnd = FindWindow(NULL,"Dual is My Hero"); //WindowNameÀ¸·Î ´ë»ó ÇÚµéÀ» ¾ò´Â ÇÔ¼ö. if(W_hWnd == 0) return FALSE; GetWindowThreadProcessId(W_hWnd,&Pid); //ProcessID¸¦ ¾ò´Â ÇÔ¼ö. return TRUE; default: return FALSE; } case WM_CLOSE: EndDialog(hDlg,0); return TRUE; default: return FALSE; } return FALSE; } //=========================================================================== ¿¡~~ À§ÀÇ ÄÚµå·Î ´ë»ó ÇÁ·Î±×·¥À» ¾Ë¾Æ ³»´Â ÀÛ¾÷Àº ¿Ï·á µÈ°Ì´Ï´Ù. :p Á¤¸» Simple ÇÏÁÒ? (6ÁÙÀÇ À§·Â?! :p) ´ë»ó ÇÁ·Î±×·¥À» Attach ½ÃŰ´Â API°¡ ¹«¾ùÀÎÁö ¿©·¯ºÐÀº ¾Ë°í °Ô½Ê´Ï±î? :p ¹Ù·Î DebugActiveProcess() ¶ó´Â API ÀÔ´Ï´Ù. :p BOOL DebugActiveProcess( DWORD dwProcessId ); ¿¡~! ÀÎÀÚ¸¦ Çϳª¸¸ ¿øÇÏ´Â ÇÔ¼öÀε¥~ Process ID¸¦ ¿øÇϰí ÀÖ±º¿ä? :p (¿ì¸° ¾Æ±î Process ID¸¦ ¾ò¾ú¾úÁÒ ¾Æ¸¶? :p) ±×·³ ¹Ù·Î Code¿¡ Ãß°¡ ½Ã۵µ·Ï ÇÏÁÒ! //================================================================================ BOOL CALLBACK MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) { HWND W_hWnd; DWORD Pid; BOOL Attach; switch(iMessage) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: W_hWnd = FindWindow(NULL,"Dual is My Hero"); //WindowNameÀ¸·Î ´ë»ó ÇÚµéÀ» ¾ò´Â ÇÔ¼ö. if(W_hWnd == 0) return FALSE; GetWindowThreadProcessId(W_hWnd,&Pid); //ProcessID¸¦ ¾ò´Â ÇÔ¼ö. Attach = DebugActiveProcess(Pid); //´ë»ó ÇÁ·Î±×·¥À» Attach ÇÏ´Â ÇÔ¼ö. if(Attach == 0) return FALSE; return TRUE; default: return FALSE; } case WM_CLOSE: EndDialog(hDlg,0); return TRUE; default: return FALSE; } return FALSE; } //=========================================================================== ¿¡¿¡~~! :p Attach ÇÏ´Â ¹æ¹ý±îÁö ¾Ë°ÔµÇ¾úÁÒ? :p ÀÌÁ¦ AttachµÈ ´ë»ó ÇÁ·Î±×·¥ÀÇ Debug Msg´Â ¿ì¸® ÇÁ·Î±×·¥À¸·Î º¸³»Áö°Ô µË´Ï´Ù. :p (¹ÝÀº ¿Â°Å ¾Æ´Ï°Ú¾î¿ä? :p) ¹°·± Debug Msg¸¦ ¹Þ±â À§Çؼ± Debug MsgLoop¸¦ ¸¸µé¾î ÁÖ¾î¾ß ÇÕ´Ï´Ù. ±×·³ Áö±ÝºÎÅÍ DebugMsg RoutineÀ» ÀÛ¼ºÇÏ¿© º¸µµ·Ï ÇÏÁÒ~ :p Àú´Â DebugMsg Loop´Â º°µµÀÇ ÇÔ¼ö·Î µÎ´Â°Ô ÁÁ´Ù°í »ý°¢Çؼ­ º°µµÀÇ ÇÔ¼ö·Î Á¤ÀÇ ÇÏ¿´½À´Ï´Ù. ¹ØÀº ÇØ´ç Code ÀÔ´Ï´Ù. :p //=========================================================================== void DebugMsgLoop() { DEBUG_EVENT DebugEV; CREATE_PROCESS_DEBUG_INFO CPDI; DWORD dwContinueStatus = DBG_CONTINUE; while(TRUE) { WaitForDebugEvent(&DebugEV,INFINITE); dwContinueStatus = DBG_CONTINUE; switch(DebugEV.dwDebugEventCode) { case CREATE_PROCESS_DEBUG_EVENT: CPDI = DebugEV.u.CreateProcessInfo; break; case EXCEPTION_DEBUG_EVENT: if(DebugEV.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) break; break; case EXIT_PROCESS_DEBUG_EVENT: return; } ContinueDebugEvent(DebugEV.dwProcessId,DebugEV.dwThreadId,dwContinueStatus); } } //=========================================================================== À§ÀÇ Äڵ忡 ´ëÇÏ¿© ¾Ë¾Æ º¼±î¿ä? :p ¹«ÇÑ ·çÇÁ¸¦ µ¹¸é¼­ WaitForDebugEvent()ÇÔ¼ö·Î ¸Þ½ÃÁö¸¦ °¡Á®¿É´Ï´Ù. dwDebugEventCode¸¦ ÅëÇØ¼­ ¾î¶² EventÀÎÁö ±¸º° ÇÏ¿© ³À´Ï´Ù. CREATE_PROCESS..¸Þ½ÃÁö°¡ ¿Ã‹ž CPDI¶õ ±¸Á¶Ã¼¿¡ Á¤º¸¸¦ ÀúÀåÇÕ´Ï´Ù. (Á¤¸» Áß¿äÇÑ Á¤º¸ÁÒ :p) EXIT_PROCESS_..¸Þ½ÃÁö°¡ ¿Ã‹ž ·çÇÁ¿¡¼­ return ÇÔÀ¸·Î½á ÇÁ·Î±×·¥À» Á¾·á ÇÕ´Ï´Ù. ±×¸®°í °¡Àå Áß¿äÇÑ EXCEPTION_DEBUG.. ¸Þ½ÃÁö.. Áï, ¿¹¿Ü ó¸® ¸Þ½ÃÁö°¡ ¿Ã‹š´Â ÇÏÀ§ ±¸Á¶Ã¼¸¦ Á¶»çÇÏ¿© EXCEPTION_BPÀÎÁö ´Ù½Ã Çѹø üũ ÇÑÈÄ ±×·²°æ¿ì ¾î¶² 󸮸¦ ÇÒÁö Áغñ¸¦ ÇØµÐ Äڵ尡 µÇ°Ú½À´Ï´Ù. ContinueDebugEvent()ÇÔ¼ö´Â Debug°¡ °è¼Ó À̾îÁú¼ö ÀÖµµ·Ï ÇØÁÖ´Â ÇÔ¼öÁÒ. WaitForDebugEvent()ÇÔ¼ö¿Í ContinueDebugEvent()ÇÔ¼ö°¡ °è¼Ó ÇÎ±Û ÇÎ±Û µ¹¾Æ °¡´Â °Ì´Ï´Ù. :p What is the Exception Event? ¿¹¿Ü󸮶õ ¹«¾ùÀÌ°í ¾î¶²‹š ÀϾ´Â °ÍÀϱî¿ä? :p ¿¹¿Ü󸮶õ ¸» ±×´ë·Î ÇÁ·Î±×·¥¿¡¼­ ÀϾ´Â ¿¹»óÇÑ ±×¿ÜÀÇ ÀϵéÀ» ó¸® ÇÏ´Â °ÍµéÀ» ¸»ÇÕ´Ï´Ù. Exception EventµéÀº ±×·± ÀϵéÀÌ ¹ú¾îÁ³À»‹š ¿À´Â MessageÀÌÁÒ. :p ¹¹ ¿©·¯Á¾·ù°¡ ÀÖÁö¸¸ ¿ì¸®°¡ °ü½ÉÀִ°ÍÀº EXCEPTION_BREAKPOINT ¶õ ³à¼®ÀÌÁÒ. :p EXCEPTION_BREAKPOINT¿¡¼­µµ ¸î°¡Áö Codeµé·Î ³ª´µ¾î Áý´Ï´Ù~ EXCEPTION_DEBUG_EVENT ;¿¹¿Ü ó¸® ¸Þ½ÃÁö CREATE_THREAD_DEBUG_EVENT ;ÇÁ·Î±×·¥ÀÌ ½ÃÀÛ or Attach µÉ‹šÀÇ ¸Þ½ÃÁö EXIT_THREAD_DEBUG_EVENT ;Thread°¡ Á¾·á µÉ‹šÀÇ ¸Þ½ÃÁö EXIT_PROCESS_DEBUG_EVENT ;Process°¡ Á¾·á µÉ‹šÀÇ ¸Þ½ÃÁö LOAD_DLL_DEBUG_EVENT ;DLLÀÌ ·Îµå µÉ‹šÀÇ ¸Þ½ÃÁö UNLOAD_DEBUG_EVENT ;DLLÀÌ ¾ð·Îµå µÉ‹šÀÇ ¸Þ½ÃÁö ... ' ~ ' ¹Ù·Î À§ÀÇ °ÍµéÀÌÁÒ~~ ÈÄÈÊ ´ëÃæ À§ÀÇ °ÍµéÀÌ ÀÖ´Ù´Â°É ¾Ë¾Æ µÎµµ·Ï ÇÏÁÒ. À̱ۿ¡¼­ ¼³¸íÇÒ Hooking¿¡ ¾²ÀÌ´Â Event´Â EXCEPTION_DEBUG_EVENTÀÔ´Ï´Ù. (¿¹¿Ü µð¹ö±× À̺¥Æ® ¶ó°í ÇØ¼® ÇÏ¸é µÇ·Á³ª? :p) How to can be operating for needed time? ¾î¶»°Ô Çϸé Åë½Å¿¡ ¾²ÀÌ´Â ÇÔ¼ö°¡ ¾²ÀÌ´Â ‹š¿¡ ±×°ÍÀ» °¡·Îç¼ö ÀÖµµ·Ï ÀÛµ¿ÇÒ¼ö ÀÖÀ»±î¿ä? :p À̰ÍÀÌ HookingÀÇ °¡Àå ÇÙ½ÉÁ¡À̶ó°í Àú´Â »ý°¢ÇÕ´Ï´Ù. Àú´Â 3½Ã°£ µ¿¾ÈÀÇ ³·ÀáÀ» ÅëÇØ ´äÀ» ¾òÀ»¼ö ÀÖ¾ú½À´Ï´Ù. Àç°¡ »ý°¢ÇÑ ¹æ¹ýÀº ¹Ù·Î ÀÌ·¸½À´Ï´Ù. ================================================== 1. APIÈ£Ãâ À̶õ°ÍÀº Dll¾È¿¡ ÀÖ´Â ÇÔ¼ö¸¦ È£Ãâ ÇÏ´Â °ÍÀÌ´Ù. 2. DllÀÇ ³»¿ëÀº ¾î´ÀÁ¤µµ Á¶ÀÛÀ» ÅëÇØ¼­ ¹Ù²Ü¼ö ÀÖÀ»°ÍÀÌ´Ù. 3. ¿øÇÏ´Â APIÀÇ ½ÃÀۺκп¡ EXCEPTION_DEBUG_EVENT(0xCC)¸¦ ½É¾î µÎ¸é API°¡ È£Ã⠵Ǵ ¼ø°£¿¡ EXCEPTION_DEBUG_EVENT À̺¥Æ®°¡ ¹ß»ýµÇ¾î µð¹ö±× ºÎ¸ðÀÎ ¿ì¸® ÇÁ·Î±×·¥¿¡°Ô Á¦¾î±ÇÀÌ ³Ñ¾î ¿Ã °ÍÀÌ´Ù. 4. Á¦¾î±ÇÀÌ ³Ñ¾î¿Â ¼ø°£¿¡ µð¹ö±×ÀÇ ´ë»ó ÇÁ·Î±×·¥Àº ÀϽà ÁßÁö »óÅÂÀϰÍÀÓÀ¸·Î ¸Þ¸ð¸®ÀÇ ³»¿ëµµ ¹Ù²îÁö ¾ÊÀº »óÅÂÀϰÍÀÌ´Ù. ¿ì¸®´Â À̵¿¾È ¿øÇÏ´Â ³»¿ëÀ» Àоî¿Ã¼ö ÀÖÀ» °ÍÀÌ´Ù. ================================================== ¾î¶§¿ä? ¾ÆÁÖ °£´ÜÇÑ »ý°¢À̸鼭µµ ¹Ù·Î ¾µ¼ö ÀÖÀ»²¨ °°Àº ±âºÐÀÌ µéÁö ¾Ê³ª¿ä? :p µfµfµf.... ±×·± ±âºÐÀÌ µéÁö ¾Ê¾Æ¾ß Á¤»óÀÔ´Ï´Ù. :p ¿Ö³Ä¸é À§¿¡²« ±×³É ÀÌ·ÐÀÏ »ÓÀÌÁÒ. ¾îµð ½ÃÁ¡¿¡¼­ APIÀÇ ½ÃÀÛ ºÎºÐ¿¡ EXCEPTION_DEBUG_EVENT¸¦ ½É¾î µÑÁöµµ ¾Æ¸¶ Áö±ÝÀº ¸ð¸¦ °ÍÀ̰í. À̺¸´Ù ¸ÕÀú APIÀÇ ½ÃÀۺθ¦ ±¸ÇÏ´Â ¹æ¹ý Á¶Â÷ ¿©·¯ºÐÀº ¾ÆÁ÷Àº ¸ð¸£°í ÀÖÀ» °ÍÀÔ´Ï´Ù. :p (±×·¡¼­ ÀÌ °­Á¸¦ Àаí ÀÖ´Â°Í ¾Æ´Ï°Ú¾î¿ä? ¼³¸¶ À̰ÍÀÌ ´ç½ÅÀ» °Ý¸êÇÏ´Â ¸» Àΰ¡¿ä? Good bye... :p) ÀÚ~! ÀÌÁ¦ À§¿¡¼­ ¸»ÇÑ ÀÌ·ÐÀ» ½ÇÁ¦ Code·Î º¸¿© µå¸®°Ú½À´Ï´Ù~! //============================================================ void DebugMsgLoop() { DEBUG_EVENT DebugEV; CREATE_PROCESS_DEBUG_INFO CPDI; DWORD dwContinueStatus = DBG_CONTINUE; HMODULE Wsock_Handle; //ÈÄÅ·ÇÒ API°¡ Á¸ÀçÇÏ´Â ¸ðµâÀÇ ÇÚµé ÀúÀå º¯¼ö LPVOID Send_Adr; //ÈÄÅ·À» ¿øÇÏ´Â ´ë»ó APIÁÖ¼Ò ÀúÀå º¯¼ö. MEMORY_BASIC_INFORMATION mbi; unsigned long OldProtect,NewProtect; char FirstByte,BreakByte = (char)0xCC; unsigned long cbByte; CONTEXT Org_Context,New_Context; //Context BOOL FirstHit = FALSE; //Attach½Ã¿¡ »ý±â´Â Exception Event üũ º¯¼ö while(TRUE) { WaitForDebugEvent(&DebugEV,INFINITE); //µð¹ö±× À̺¥Æ®¸¦ ±â´Ù¸°´Ù. switch(DebugEV.dwDebugEventCode) { case CREATE_PROCESS_DEBUG_EVENT: //ÇÁ·Î¼¼½º¸¦ óÀ½ Attach ÇßÀ»‹š~ CPDI = DebugEV.u.CreateProcessInfo; Wsock_Handle = GetModuleHandle("WS2_32.DLL"); if(Wsock_Handle == 0) { Wsock_Handle = LoadLibrary("WS2_32.DLL"); if(Wsock_Handle == 0) return; } Send_Adr = GetProcAddress(Wsock_Handle,"send"); if(Send_Adr == 0) return; VirtualQueryEx(CPDI.hProcess,Send_Adr,&mbi,sizeof(mbi)); NewProtect = mbi.Protect; NewProtect &= ~(PAGE_READONLY | PAGE_EXECUTE_READ); NewProtect |= (PAGE_READWRITE); VirtualProtectEx(CPDI.hProcess,Send_Adr, sizeof(char),NewProtect, &OldProtect); ReadProcessMemory(CPDI.hProcess,Send_Adr, &FirstByte,sizeof(FirstByte), &cbByte); WriteProcessMemory(CPDI.hProcess,Send_Adr, &BreakByte,sizeof(BreakByte), &cbByte); break; case EXCEPTION_DEBUG_EVENT: if(DebugEV.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) if(FirstHit == FALSE) FirstHit = TRUE; else { WriteProcessMemory(CPDI.hProcess,Send_Adr, &FirstByte,sizeof(FirstByte), &cbByte); Org_Context.ContextFlags = CONTEXT_FULL; GetThreadContext(CPDI.hThread,&Org_Context); New_Context = Org_Context; New_Context.Eip = (unsigned long)DebugEV.u.Exception.ExceptionRecord.ExceptionAddress; //New_Context.Eip--; SetThreadContext(CPDI.hThread,&New_Context); } break; break; case EXIT_PROCESS_DEBUG_EVENT: return; } ContinueDebugEvent(DebugEV.dwProcessId,DebugEV.dwThreadId,dwContinueStatus); } } //======================================================= ÀÌÁ¦ À§¿¡ Äڵ带 »ìÆì º¸¸é~~~ :p GetModuleHandle()ÇÔ¼ö¸¦ ÅëÇØ WS2_32.DLLÀÇ HMODULE¸¦ ±¸ÇØ ¿À°í,±× HMODULEÀ» °¡Áö°í GetProcAddress()¶ó´Â ÇÔ¼öÀÇ ½ÃÀÛÁÖ¼Ò¸¦ °¡Á®¿À´Â API¸¦ ÀÌ¿ëÇÏ¿© WS2_32.DLL¾È¿¡ ÀÖ´Â send¶ó´Â APIÀÇ ÁÖ¼Ò¸¦ ±¸ÇؿɴϴÙ. ±× ´ÙÀ½ VirtualQueryEx() ¶ó´Â ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© Send_Adr(sendÇÔ¼öÀÇ ÁÖ¼Ò)ÀÇ ¸Þ¸ð¸® ¿µ¿ª¿¡ °üÇÑ Á¤º¸¸¦ ±¸ÇؿɴϴÙ. (¿ì¸®°¡ ÇÊ¿ä·Î Çß´ø°ÍÀº Protect¿´´ä´Ï´Ù. :p) ±×ÈÄ VirtualProtectEx()¶ó´Â ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© ±×ºÎºÐÀÇ Protect¸¦ PAGE_READWRITE·Î ¹Ù²Ù¾î ¹ö¸³´Ï´Ù. (ÀÌ·¡¾ß ¾î´ÀÁ¤µµ ÀÚÀ¯·Ó°Ô Àб⠾²±â°¡ µÇÁÒ~) Áö±Ý ºÎÅÍ Áß¿äÇÑ ÀÛ¾÷Àε¥... ReadProcessMemory()¶ó´Â API¸¦ ÀÌ¿ëÇÏ¿© sendÇÔ¼öÀÇ Ã¹¹ÙÀÌÆ®¸¦ Àоî¿É´Ï´Ù. ±×´ÙÀ½ WriteProcessMemory()¶ó´Â ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© ù¹ÙÀÌÆ®¿¡ EXCEPTION_DEBUG_EVENT(0xCC)¸¦ ±â·ÏÇÕ´Ï´Ù. (À̷νá Hooking Áغñ´Â ¿Ï·á µÈ°ÍÀÌÁÒ~~ :p) VirtualQueryEx() ¹Ù…f´ø Protect¸¦ ¿ø·¡´ë·Î µÇµ¹·Á ³õ½À´Ï´Ù. ÀÌÁ¦ ¿ì¸®°¡ ÇÒÀÏÀº ´ë»ó ÇÁ·Î±×·¥¿¡¼­ sendÇÔ¼ö°¡ ¹ß»ýÇÏ±æ ±â´Ù¸®´ÂÀÏ »ÓÀÔ´Ï´Ù~~! :p WoW~!! Á¤¸» HookingÀ̶ó´Â°Íµµ ±×¸® ¾î·Á¿î°Í¸¸Àº ¾Æ´Ñ°Å °°´Ù´Â »ý°¢µéÁö ¾Ê³ª¿ä? :p (½ÇÁ¦·Îµµ ±×¸® ¾î·Á¿î °ÍÀÌ ¾Æ´Õ´Ï´Ù. º»ÀÎÀÌ ¼³¸íÀ» Àß ¸øÇؼ­ ±×·¸Áö~~;) ) ±×·±µ¥ ¸»ÀÌÁÒ~~ À§ Äڵ忡¼­ ¹º°¡ ÀÌ»óÇϴٴ°Š¹ß°ßÇѺÐ~? º°½á ÀÖÀ»Áöµµ ¸ð¸¨´Ï´Ù. :p ³× ±×·¸½À´Ï´Ù. À§ ÄÚµå´Â Çѹø¹Û¿¡ ÀÛµ¿À» ¾ÈÇÕ´Ï´Ù. ±×·¸´Ù¸é ¾î¶»°Ô ÇØ¾ß °è¼Ó ÀÛµ¿ÇÒ±î¿ä? :p ´ë´äÀº °£´ÜÇÕ´Ï´Ù. À§ ÄÚµåÁß »ìÇ¥º¸Áö ¾ÊÀº ºÎºÐÀ» °è¼Ó º¸¸ç ¼³¸í Çϵµ·Ï ÇÏÁÒ~ DebugLoop¸¦ µ¹¸é¼­ ´ë»ó ÇÁ·Î±×·¥À» óÀ½ AttachÇßÀ»‹š EXCEPTION_DEBUG_EVENT°¡ ¸ÕÀú Çѹø ¹ß»ý µË´Ï´Ù. ±×‹š¸¦ üũÇϱâ À§ÇØ Àú´Â FirstHit¶ó´Â º¯¼ö¸¦ µÎ°í óÀ½ °É·ÈÀ»‹š¸¦ üũ ÇÏ°Ô ÇÏ¿´½À´Ï´Ù. :p ±× ´ÙÀ½ EXCEPTION_DEBUG_EVENT°¡ ¹ß»ýÇߴٴ°ÍÀº sendÇÔ¼ö°¡ ´ë»ó ÇÁ·Î±×·¥¿¡¼­ »ç¿ëµÇ¾ú´Ù´Â ¸»ÀÔ´Ï´Ù. :p Àç°¡ À§¿¡¼­ ÀÛ¼ºÇصРCode´Â WriteProcessMemory()¸¦ ÀÌ¿ëÇÏ¿© ù¹ø¤Š ¹ÙÀÌÆ®¸¦ ¿ø·¡µÇ·Î µ¹·Á ³õ°í~ (º¸Åë ù¹ÙÀÌÆ®´Â 0x55ÀÔ´Ï´Ù.) GetThreadContext()¶ó´Â ÇÔ¼ö·Î ´ë»ó ÇÁ·Î±×·¥ÀÇ Context¸¦ Àоî¿ÂÈÄ Eip(´ÙÀ½ ½ÇÇà¹øÁö ±â¾ï ·¹Áö½ºÅÍ)¸¦ ÀÌÀü EXCEPTION_DEBUG_EVENT°¡ ¹ß»ýÇÑ À§Ä¡·Î µ¹·Á³õ½À´Ï´Ù. ±×ÈÄ SetThreadContext()¶ó´Â ÇÔ¼ö·Î ´ë»ó ÇÁ·Î±×·¥¿¡ Context»óŸ¦ Àû¿ë ½Ãŵ´Ï´Ù. ÀÌ·Î½á ¾ò´Â È¿°ú´Â ´Ù½Ã ´ë»ó ÇÁ·Î±×·¥ÀÇ Code°¡ Á¤»óÀûÀ¸·Î ½ÇÇà µÉ¼ö ÀÖµµ·Ï ÇÏ´Â °ÍÀÔ´Ï´Ù. :p ¿©±â±îÁö ÁøÇàµÇ¸é °¡Àå ù¹ø¤Š SendÇÔ¼ö°¡ ¹ß»ýµÇ¾úÀ»‹š ÀÌ RoutineÀÌ ½ÇÇàµÇ°í ±×´ÙÀ½ ºÎÅÏ ½ÇÇàµÇÁö ¾Ê½À´Ï´Ù. ¿ì¸®´Â sendÇÔ¼öÀÇ Ã¹¹ø¤Š ¹ÙÀÌÆ®¸¦ ¿ø·¡µÇ·Î µÇµ¹·Á ³õ¾Ò±â ‹š¹®¿¡ EXCEPTION_DEBUG_EVENT°¡ ´õÀÌ»ó ¹ß»ýÇÏÁö ¾Ê±â ‹š¹®ÀÔ´Ï´Ù. ´Ù½Ã ¹ß»ý½Ã۱â À§Çؼ± ÀÌ µÞºÎºÐ¿¡ ´Ù½Ã ù¹ø¤Š ¹ÙÀÌÆ®¸¦ 0xCC·Î ¹Ù²Ù´Â Code¸¦ Ãß°¡ ½Ãų Çʿ伺ÀÌ ÀÖ½À´Ï´Ù. :p ±×·¡¼­ º»ÀÎÀº ¹Ø¿¡¿Í °°Àº Code¸¦ Routine¿¡ Ãß°¡ ½ÃŰ¾ú½À´Ï´Ù. :p //============================================================= ContinueDebugEvent(DebugEV.dwProcessId,DebugEV.dwThreadId,dwContinueStatus); /* ReadProcessMemory(CPDI.hProcess,Send_Adr, &FirstByte,sizeof(FirstByte), &cbByte); */ WriteProcessMemory(CPDI.hProcess,Send_Adr, &BreakByte,sizeof(BreakByte), &cbByte); MessageBox(NULL,"sendÇÔ¼ö°¡ ¹ß»ýÇÏ¿´½À´Ï´Ù.","==¾Ë¸²==",MB_OK); //============================================================== À̷νá sendÇÔ¼ö°¡ ¹ß»ý ÇÒ‹š¸¶´Ù ¿ì¸®´Â ¸Þ½ÃÁö ¹Ú½º¸¦ ÅëÇØ ¾Ë¼ö ÀÖ°Ô µÇ¾ú½À´Ï´Ù. (½ÇÁ¦·Î µÇ´ÂÁö Å×½ºÆ®Çϱ⿡ ½Ã°¢ÀûÀÎ ¸Þ½ÃÁö ¹Ú½º ¸¸Å­ ÁÁÀº°Íµµ ¾øÁÒ :p) ±×·³ À§ÀÇ Codeµµ Ãß°¡½ÃŲ Áö±Ý±îÁö ¿ì¸®°¡ ÀÛ¼ºÇÑ RoutineÀ» º¸µµ·Ï ÇÏÁÒ. //============================================================== void DebugMsgLoop() { DEBUG_EVENT DebugEV; CREATE_PROCESS_DEBUG_INFO CPDI; DWORD dwContinueStatus = DBG_CONTINUE; HMODULE Wsock_Handle; //ÈÄÅ·ÇÒ API°¡ Á¸ÀçÇÏ´Â ¸ðµâÀÇ ÇÚµé ÀúÀå º¯¼ö LPVOID Send_Adr; //ÈÄÅ·À» ¿øÇÏ´Â ´ë»ó APIÁÖ¼Ò ÀúÀå º¯¼ö. MEMORY_BASIC_INFORMATION mbi; unsigned long OldProtect,NewProtect; char FirstByte,BreakByte = (char)0xCC; unsigned long cbByte; CONTEXT Org_Context,New_Context; //Context BOOL FirstHit = FALSE; //Attach½Ã¿¡ »ý±â´Â Exception Event üũ º¯¼ö while(TRUE) { WaitForDebugEvent(&DebugEV,INFINITE); //µð¹ö±× À̺¥Æ®¸¦ ±â´Ù¸°´Ù. switch(DebugEV.dwDebugEventCode) { case CREATE_PROCESS_DEBUG_EVENT: //ÇÁ·Î¼¼½º¸¦ óÀ½ Attach ÇßÀ»‹š~ CPDI = DebugEV.u.CreateProcessInfo; //Á¤º¸¸¦ ÀúÀåÇÏ¿© µÐ´Ù. Wsock_Handle = GetModuleHandle("WS2_32.DLL"); //¸ðµâ ÇÚµéÀ» ±¸ÇÑ´Ù. if(Wsock_Handle == 0) { Wsock_Handle = LoadLibrary("WS2_32.DLL"); //¾øÀ» °æ¿ì LoadÇÑ´Ù. if(Wsock_Handle == 0) break; } Send_Adr = GetProcAddress(Wsock_Handle,"send"); //SendÇÔ¼öÀÇ ÁÖ¼Ò¸¦ ±¸ÇÑ´Ù. if(Send_Adr == 0) break; VirtualQueryEx(CPDI.hProcess,Send_Adr,&mbi,sizeof(mbi)); //¸Þ¸ð¸® ÇÁ·ÎÅØÆ®¸¦ ±¸Çؿ´Ù. NewProtect = mbi.Protect; NewProtect &= ~(PAGE_READONLY | PAGE_EXECUTE_READ); //Àç¿Ü ½Ã۰í~ NewProtect |= (PAGE_READWRITE); //Ãß°¡ ½ÃŲ´Ù. VirtualProtectEx(CPDI.hProcess,Send_Adr, //º¸È£ ¸ðµå Á¶Á¤ sizeof(char),NewProtect, &OldProtect); ReadProcessMemory(CPDI.hProcess,Send_Adr, //ù¹ÙÀÌÆ®¸¦ Àоî¿Â´Ù. &FirstByte,sizeof(FirstByte), &cbByte); WriteProcessMemory(CPDI.hProcess,Send_Adr, //EXCEPTION_EVENT(0xCC) ±â·Ï &BreakByte,sizeof(BreakByte), &cbByte); break; case EXCEPTION_DEBUG_EVENT: //¿¹¿Ü µð¹ö±× À̺¥Æ® ¹ß»ý½Ã if(DebugEV.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) //EXCEPTION_BREAKPOINTÀΰ¡? { if(FirstHit == FALSE) FirstHit = TRUE; //ù¹ø¤Š ºêÆ÷ º¯¼ö üũ else { WriteProcessMemory(CPDI.hProcess,Send_Adr, //ù¹ÙÀÌÆ®¸¦ ¿ø·¡ ´ë·Î µ¹¸² &FirstByte,sizeof(FirstByte), &cbByte); Org_Context.ContextFlags = CONTEXT_FULL; //Context Mode GetThreadContext(CPDI.hThread,&Org_Context); //Context¸¦ ±¸Çؿ´Ù. New_Context = Org_Context; //º¹»çº»À» ¸¸µç´Ù. New_Context.Eip = (unsigned long)DebugEV.u.Exception.ExceptionRecord.ExceptionAddress; //New_Context.Eip--; //Eip°ªÀ» -1 ½ÃŲ´Ù. SetThreadContext(CPDI.hThread,&New_Context); //Context¸¦ Àû¿ëÇÑ´Ù. ContinueDebugEvent(DebugEV.dwProcessId,DebugEV.dwThreadId,dwContinueStatus); //´ë»ó ÇÁ·Î±×·¥¿¡ °á°ú ¹Ý¿µ /*ReadProcessMemory(CPDI.hProcess,Send_Adr, //ù ¹ÙÀÌÆ®¸¦ Àоî¿Â´Ù. &FirstByte,sizeof(FirstByte), &cbByte); */ WriteProcessMemory(CPDI.hProcess,Send_Adr, //0xCC¸¦ ±â·Ï &BreakByte,sizeof(BreakByte), &cbByte); MessageBox(NULL,"sendÇÔ¼ö°¡ ¹ß»ýÇÏ¿´½À´Ï´Ù.","==¾Ë¸²==",64); //½Ã°¢Àû È¿°ú } } break; case EXIT_PROCESS_DEBUG_EVENT: //ÇÁ·Î¼¼½º Á¾·á µð¹ö±× À̺¥Æ® ÀÏ‹ž ·çÇÁ ³¡ return; } ContinueDebugEvent(DebugEV.dwProcessId,DebugEV.dwThreadId,dwContinueStatus); } } //================================================================================ À½ Áö±Ý±îÁö ¿ì¸®°¡ ÀÛ¼ºÇÑ RoutineÀ¸·Î ÇÒ¼ö ÀÖ´Â ÀÏÀº ´ë»ó ÇÁ·Î±×·¥¿¡¼­ ¿øÇÏ´Â API°¡ ¹ß»ýµÇ¾úÀ»‹š ¿ì¸® ÇÁ·Î±×·¥ÀÌ ±×°ÍÀ» ¾Ë¾Æ ç¼ö Àִ°¡ ¾ø´Â°¡ ÀÔ´Ï´Ù. À̰͸¸À¸·Ð ¿ì¸®°¡ ¿øÇÏ´Â ±â´ÉÀÌ ¾Æ´ÏÁÒ. :p ¿ì¸®°¡ ¿øÇÏ´Â °¡Àå Áß¿äÇѰÍÀº ¹Ù·Î 'Á¶ÀÛ' ÀϰÍÀÔ´Ï´Ù. :p Áö±ÝºÎÅÍ ±×·¯¸é Á¶ÀÛ¿¡ ´ëÇØ¼­ »ý°¢ÇÏ¿© º¸ÁÒ. ¾î¶»°Ô ÇÏ¸é ´ë»ó ÇÁ·Î±×·¥¿¡¼­ API¸¦ È£ÃâÇÒ‹šÀÇ Parameter¸¦ Á¶ÀÛÇÒ¼ö ÀÖÀ»±î¿ä? :p ¿ì¸®´Â ¹Ù·Î À§ÀÇ Routine¿¡¼­ GetThreadContext()¶ó´Â API¸¦ ÀÌ¿ëÇÏ¿© ´ë»ó ÇÁ·Î±×·¥ÀÇ Context»óŸ¦ ±¸Çؿüö ÀÖ¾ú½À´Ï´Ù. ÀÌ‹š ±¸ÇØ¿Â Context(»óÅÂ)°¡ ¾î¶²‹šÀÇ ContextÀÎÁö »ý°¢ÇÏ¸é ¿ì¸®´Â ÀÌ¹Ì ´äÀ» ¾ò¾ú´Ù´Â °ÍÀ» ¾Ë¼ö ÀÖ½À´Ï´Ù. :p Áö±Ý±îÁö Çß´ø °úÁ¤À» ´Ù½Ã ÁýÀ¸¸ç ¾î¶² »óÅÂÀÎÁö ¾Ë¾Æ º¸µµ·Ï ÇÏÁÒ. ¸ÕÀú ù¹ø¤Š·Î ¿ì¸° ´ë»ó ÇÁ·Î±×·¥ÀÇ ÇÚµéÀ» ±¸ÇÏ°í ´ë»ó ÇÁ·Î±×·¥À» AttachÇÏ¿´°í, ´ë»ó ÇÁ·Î±×·¥ÀÇ ¿øÇÏ´Â APIºÎºÐ¿¡ 0xCC¸¦ ±â·ÏÇÏ¿© µÎ¾ú°í ÀÌ GetThreadContext()°¡ È£Ã⠵Ǵ ¹Ù·Î ÀÌ ½ÃÁ¡Àº ¿ì¸®°¡ ¿øÇÏ´Â API¿¡ ½É¾îµÐ 0xCC°¡ EXCEPTION_DEBUG_EVENT°¡ ¹ß»ýµÇ¾úÀ»‹š ÀÔ´Ï´Ù. ´Ù½Ã ¿ä¾àÇØ ¸»ÇÏÀÚ¸é ´ë»ó ÇÁ·Î±×·¥¿¡¼­ ¿ì¸®°¡ Hooking ÇϰíÀÚ ÇÏ´Â ÇÔ¼ö(send)¸¦ È£ÃâÇÏ¿´´Âµ¥ ¿ì¸®°¡ ¼³Ä¡ÇصР0xCC¿¡ ÀÇÇØ¼­ Áö±Ý ÇØ´ç APIÀÇ Ã¹ºÎºÐ¿¡¼­ ¸ØÃß¾î ÀÖ´Â »óÅ ÀΰÍÀÔ´Ï´Ù. ±×·¸±â ‹š¹®¿¡ ½ºÅÿ¡´Â API¸¦ È£ÃâÇϴµ¥ ÇÊ¿äÇÑ ParameterµéÀÌ °í½º¶õÈ÷ µé¾îÀÖ°ÚÁÒ? :p ±×·¸´Ù¸é ´ë»ó ÇÁ·Î±×·¥ÀÇ ½ºÅÃÀ» ±¸ÇØ¿À´Â ¹æ¹ýÀº??? :p ±×°ÍÀÇ ´ä¿ª½Ã GetThreadContext() ÇÔ¼ö¿¡ ÀÖ½À´Ï´Ù. ÄÄÇ»ÅÍÀÇ ·¹Áö½ºÅÍÁß ESP¶ó´Â ·¹Áö½ºÅͰ¡ ÀÖ½À´Ï´Ù. (½ºÅÃÀÇ ²À´ë±â¸¦ °¡¸£Åµ´Ï´Ù. :P) ¿ì¸®´Â ÀÌ ESP·¹Áö½ºÅÍÀÇ °ªÀ» ¾Ë°í ÀÖ½À´Ï´Ù. :p ¾î¶»°Ô³Ä±¸¿ä? GetThreadContext() ÇÔ¼ö°¡ ±¸ÇØ¿À´Â °ªÁß¿¡ ESPÀÇ °ªµµ Àֱ⠋š¹®ÀÌÁÒ. :p send APIÀÇ »ý±è»õ¸¦ º¾½Ã´Ù. :p ==================================== int send( SOCKET s, const char* buf, int len, int flags ); ==================================== ù¹ø¤Š ÀÎÀÚ s´Â ¼ÒÄÏ ±¸Á¶Ã¼¸¦ ³ªÅ¸³»¸ç, µÎ¹ø¤Š ÀÎÀÚ buf´Â Àü¼ÛÇÒ °ªÀÌ ÀÖ´Â bufÀ§Ä¡¸¦ Æ÷ÀÎÆ® Çϸç,(Áß¿ä Æ÷ÀÎÆ®1) ¼¼¹ø¤Š ÀÎÀÚ lenÀº bufÀÇ °ª¿¡ ±æÀ̸¦ ³ªÅ¸³À´Ï´Ù.(Áß¿ä Æ÷ÀÎÆ®2) ³×¹ø¤Š ÀÎÀÚ flag´Â flag¸¦ ³ªÅ¸³»ÁÒ~ (¼³¸íÀÌ ¹¹ ÀÌ·¸´ã :p) sendÇÔ¼ö¸¦ ÅëÇØ º¸³¾°ªÀº µÎ¹ø¤ŠÀÎÀÚ buf¿¡ ÀÇÇØ Æ÷ÀÎÆ® µÇ¾î ÀÖ°í lenÀº ±× Å©±â¸¦ ³ªÅ¸ ³»°í ÀÖ´Ù´Â »ç½ÇÀº ¾ÆÁÖ Áß¿ä ÇÕ´Ï´Ù~! ReadProcessMemory()ÇÔ¼ö¸¦ ÅëÇÏ¿© buf¿Í len°ª¸¸ Àоî¿Â´Ù¸é ³»¿ë ÈÉÃÄ º¸±â´Â ¹°·± ³»¿ë Á¶ÀÛÇϱ⵵ ´©¿ö¼­ ¶± ¸Ô±â ¶ó´Â »ç½ÇÀÔ´Ï´Ù. :p (¿ª½Ã³ª ¸» º¸´Ù´Â Code·Î º¸´Â°Ô ¸íÈ®ÇÒµí :p) //========================================================== void DebugMsgLoop() { DEBUG_EVENT DebugEV; CREATE_PROCESS_DEBUG_INFO CPDI; DWORD dwContinueStatus = DBG_CONTINUE; HMODULE Wsock_Handle; //ÈÄÅ·ÇÒ API°¡ Á¸ÀçÇÏ´Â ¸ðµâÀÇ ÇÚµé ÀúÀå º¯¼ö LPVOID Send_Adr; //ÈÄÅ·À» ¿øÇÏ´Â ´ë»ó APIÁÖ¼Ò ÀúÀå º¯¼ö. MEMORY_BASIC_INFORMATION mbi; unsigned long OldProtect,NewProtect; char FirstByte,BreakByte = (char)0xCC; unsigned long cbByte; CONTEXT Org_Context,New_Context; //Context DWORD ESP,ESP4 = 0,ESP8 = 0,ESPC = 0,ESP10 = 0; DWORD BufAdr,Len; LPVOID buffer; BOOL FirstHit = FALSE; //Attach½Ã¿¡ »ý±â´Â Exception Event üũ º¯¼ö while(TRUE) { WaitForDebugEvent(&DebugEV,INFINITE); //µð¹ö±× À̺¥Æ®¸¦ ±â´Ù¸°´Ù. switch(DebugEV.dwDebugEventCode) { case CREATE_PROCESS_DEBUG_EVENT: //ÇÁ·Î¼¼½º¸¦ óÀ½ Attach ÇßÀ»‹š~ CPDI = DebugEV.u.CreateProcessInfo; //Á¤º¸¸¦ ÀúÀåÇÏ¿© µÐ´Ù. Wsock_Handle = GetModuleHandle("WS2_32.DLL"); //¸ðµâ ÇÚµéÀ» ±¸ÇÑ´Ù. if(Wsock_Handle == 0) { Wsock_Handle = LoadLibrary("WS2_32.DLL"); //¾øÀ» °æ¿ì LoadÇÑ´Ù. if(Wsock_Handle == 0) break; } Send_Adr = GetProcAddress(Wsock_Handle,"send"); //SendÇÔ¼öÀÇ ÁÖ¼Ò¸¦ ±¸ÇÑ´Ù. if(Send_Adr == 0) break; VirtualQueryEx(CPDI.hProcess,Send_Adr,&mbi,sizeof(mbi)); //¸Þ¸ð¸® ÇÁ·ÎÅØÆ®¸¦ ±¸Çؿ´Ù. NewProtect = mbi.Protect; NewProtect &= ~(PAGE_READONLY | PAGE_EXECUTE_READ); //Àç¿Ü ½Ã۰í~ NewProtect |= (PAGE_READWRITE); //Ãß°¡ ½ÃŲ´Ù. VirtualProtectEx(CPDI.hProcess,Send_Adr, //º¸È£ ¸ðµå Á¶Á¤ sizeof(char),NewProtect, &OldProtect); ReadProcessMemory(CPDI.hProcess,Send_Adr, //ù¹ÙÀÌÆ®¸¦ Àоî¿Â´Ù. &FirstByte,sizeof(FirstByte), &cbByte); WriteProcessMemory(CPDI.hProcess,Send_Adr, //EXCEPTION_EVENT(0xCC) ±â·Ï &BreakByte,sizeof(BreakByte), &cbByte); break; case EXCEPTION_DEBUG_EVENT: //¿¹¿Ü µð¹ö±× À̺¥Æ® ¹ß»ý½Ã if(DebugEV.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) //EXCEPTION_BREAKPOINTÀΰ¡? { if(FirstHit == FALSE) FirstHit = TRUE; //ù¹ø¤Š ºêÆ÷ º¯¼ö üũ else { WriteProcessMemory(CPDI.hProcess,Send_Adr, //ù¹ÙÀÌÆ®¸¦ ¿ø·¡ ´ë·Î µ¹¸² &FirstByte,sizeof(FirstByte), &cbByte); Org_Context.ContextFlags = CONTEXT_FULL; //Context Mode GetThreadContext(CPDI.hThread,&Org_Context); //Context¸¦ ±¸Çؿ´Ù. ESP = Org_Context.Esp; //API°¡ ³¡³ª°í ¸®ÅÏ(µ¹¾Æ°¥) ÁÖ¼Ò ESP4 = ESP + 4; //S ESP8 = ESP + 8; //buf Adr ESPC = ESP + 0xC; //len ESP10 = ESP + 0x10; //flag ReadProcessMemory(CPDI.hProcess,(void *)ESPC, //lenÀоî¿È &Len,sizeof(DWORD), &cbByte); buffer = malloc(Len); //±æÀÌ ¸¸Å­ ¸Þ¸ð¸® ÇÒ´ç ReadProcessMemory(CPDI.hProcess,(void *)ESP8, //Buffer ÁÖ¼Ò Àоî¿È &BufAdr,sizeof(DWORD), &cbByte); ReadProcessMemory(CPDI.hProcess,(void *)BufAdr, //Buffer Àоî¿È buffer,Len, &cbByte); New_Context = Org_Context; //º¹»çº»À» ¸¸µç´Ù. New_Context.Eip = (unsigned long)DebugEV.u.Exception.ExceptionRecord.ExceptionAddress; //New_Context.Eip--; //Eip°ªÀ» -1 ½ÃŲ´Ù. SetThreadContext(CPDI.hThread,&New_Context); //Context¸¦ Àû¿ëÇÑ´Ù. ContinueDebugEvent(DebugEV.dwProcessId,DebugEV.dwThreadId,dwContinueStatus); //´ë»ó ÇÁ·Î±×·¥¿¡ °á°ú ¹Ý¿µ /* ReadProcessMemory(CPDI.hProcess,Send_Adr, //ù ¹ÙÀÌÆ®¸¦ Àоî¿Â´Ù. &FirstByte,sizeof(FirstByte), &cbByte); */ WriteProcessMemory(CPDI.hProcess,Send_Adr, //0xCC¸¦ ±â·Ï &BreakByte,sizeof(BreakByte), &cbByte); free(buffer); //µ¿Àû ÇÒ´çÇÑ ¸Þ¸ð¸®¸¦ ³õ¾ÆÁØ´Ù. MessageBox(NULL,"sendÇÔ¼ö°¡ ¹ß»ýÇÏ¿´½À´Ï´Ù.","==¾Ë¸²==",64); //½Ã°¢Àû È¿°ú } } break; case EXIT_PROCESS_DEBUG_EVENT: //ÇÁ·Î¼¼½º Á¾·á µð¹ö±× À̺¥Æ® ÀÏ‹ž ·çÇÁ ³¡ return; } ContinueDebugEvent(DebugEV.dwProcessId,DebugEV.dwThreadId,dwContinueStatus); } } //================================================= ¿¡¿¡~ À§¿¡ »õ·Ó°Ô Ãß°¡ ½ÃŲ CodeµéÀ» »ìÆì º¸¸é~ :p Context ½ºÆ®·°ÃÄÀÇ Espº¯¼öÀÇ °ªÀ» ESP¶ó´Â º¯¼ö¿¡ ÀúÀå½Ã۰í~ ³ª¸ÓÁö »ó´ë À§Ä¡µéµµ ¼¼ÆÃ ½ÃŲÈÄ :p ReadProcessMemory()ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© len(±æÀÌ)¸¦ Àоî¿ÂÈÄ malloc()¸¦ ÀÌ¿ëÇÏ¿© Len¸¸Å­ Å©±âÀÇ ¸Þ¸ð¸®¸¦ ÇÒ´çÇϰí, ReadProcessMemory()ÇÔ¼ö·Î BufferÀÇ ÁÖ¼Ò¸¦ Àоî¿ÂÈÄ ReadProcessMemory()ÇÔ¼öÀÇ ÀÎÀÚ·Î BufferÀÇ ÁÖ¼Ò¿¡¼­ Len(±æÀÌ)¸¸Å­ Àоî¿Í¼­ malloc()À¸·Î ÇÒ´çÇÑ ¸Þ¸ð¸®¿¡ ÀúÀå ½ÃŰ´Â ±¸Á¶°¡ µÇ°Ú½À´Ï´Ù. :p ¿©±â±îÁö°¡ Parameter¸¦ ¸ô·¡ Àоî¿À´Â SniffingÀÔ´Ï´Ù. :p »ý°¢º¸´Ù Parameter¸¦ ¸ô·¡ Àоî¿ÈÀ¸·Î½á Åë½ÅÀÇ ³»¿ëÀ» °¨Ã»ÇÏ´Â °Íµµ ½±´Ù°í ´À²¸ÁöÁö ¾Ê³ª¿ä? :p (Áö±Ý buffe¿¡ ÀúÀå ½ÃŲ°ªÀ» ¹®ÀÚ¿­·Î º¯È¯ ½ÃŲÈÄ txt ÆÄÀÏ¿¡ ÀúÀå½ÃŰ´Â ±¸Á¶¸¦ ÅÃÇÑ´Ù¸é Åë½ÅÇÑ ³»¿ëÀ» ¸ô·¡ ÀúÀå ½ÃŰ´Â Logger Á¾·ùÀÇ ÇÁ·Î±×·¥ÀÌ µÇ°Ú±º¿ä? :p) ´ÙÀ½ ³»¿ëÀÎ ³»¿ëÀ» Á¶ÀÛÇϱâÀü¿¡ ¸î°¡Áö Áý°í ³Ñ¾î °¡µµ·Ï ÇϰڽÀ´Ï´Ù~ :p ¿Ö Àú´Â ÀϹÝÀûÀ¸·Î ¾²ÀÌ´Â ¹æ¹ýÀÎ ÀÓÆ÷Æ® Å×À̺íÀÇ Á¡ÇÁ À§Ä¡¸¦ ¹Ù²Ù°Å³ª ¿¢½ºÆ÷Æ® Å×À̺íÀ» Á¶ÀÛÇϰųª Code overwriting(ÄÚµå µ¤¾î¾²±â)¸¦ ÅëÇÑ ¹æ¹ýÀ» ¾²Áö ¾Ê¾ÒÀ» ±î¿ä? :p ±×°Ç ¹Ù·Î À§ÀÇ ¹æ¹ý ¸ðµÎ Dll InjectionÀÌ ÇÊ¿äÇϱ⠋š¹®ÀÔ´Ï´Ù. (¹Ýµå½Ã Dll InjectionÀÌ ÇÊ¿äÇѰÍÀº ¾Æ´ÏÁö¸¸ WriteProcessMemory()ÇÔ¼ö·Î Á÷Á¢ RoutineÀ» »ðÀÔÇÏ·Á ÇÒ °æ¿ì ¾î¼Àºí¸®¾î¿¡ ´ëÇÑ Áö½ÄÀÌ ÇÊ¿ä·Î µË´Ï´Ù. :p º»ÀÎ °°Àº °æ¿ì´Â C¾ð¾î¸¦ Á¢Çϱâ Àü¿¡ ¾î¼Àºí¸®¾î¸¦ ¸ÕÀú Á¢Ç߱⠶§¹®¿¡ »ó°ü ¾øÁö¸¸ °ÅÀÇ ´ëºÎºÐÀÇ ºÐµéÀÌ C¾ð¾î¸¦ ¸ÕÀú Á¢ÇÏ°í ¾î¼Àºí¸®¾î¿¡ ´ëÇØ ¹«³úÇϱ⠶§¹®¿¡ °ñ¶õÇÏ´Ù°í ÇÒ¼ö ÀÖ½À´Ï´Ù. ±×·¯³ª ¿¢½ºÆ÷Æ® Å×À̺í(Export Table)À» Á¶ÀÛÇÏ´Â ¹æ¹ýÀº º»ÀÎÀÌ °¡Àå ÃßõÇÏ´Â ¹æ¹ýÀÔ´Ï´Ù. ¶ÇÇÑ °¡Àå ÁÁ¾ÆÇÏ´Â ¹æ¹ýÀ̱⵵ Çϱ¸¿ä :p) ÀÓÆ÷Æ® Å×À̺íÀ» Á¶ÀÛÇÏ´Â °æ¿ì´Â ¹®Á¦°¡ ÀÖ½À´Ï´Ù~! ±×°ÍÀº? ´ë»ó ÇÁ·Î±×·¥ÀÌ Packing À̳ª Encrypting µÇ¾î ÀÖÀ» °æ¿ì ÀÓÆ÷Æ® Å×À̺íÀ» Áö¿ì°í LoadLibrary(), GetProcAddress()¸¦ ÀÌ¿ëÇÑ µ¿Àû ·çƾÀ» ±¸ÇöÇØ¼­ »ç¿ëÇÏ±â ‹š¹®¿¡ ÀÓÆ÷Æ® Å×À̺íÀ» Á¶ÀÛÇÏ´Â ¹æ¹ýÀ¸·Ð Çê¶¥¸¸ Ä¡°Ô µË´Ï´Ù. :p (º»ÀÎÀÇ exe¾Ïȣȭ±â 1.1b Äڵ带 Âü°í ÇϽþ µË´Ï´Ù~ °Å±â¿¡ µ¿Àû ·çƾÀ» ´ã¾Æ³ùÁÒ :p) ¿¢½ºÆ÷Æ® Å×À̺íÀ» Á¶ÀÛÇÏ´Â ¹æ¹ýÀº Åë½ÅÇÔ¼ö ÈÄÅ·¿¡ À־ Á¤¸» ÁÁÀº ¹æ¹ýÀ̶ó°í »ý°¢ÇÕ´Ï´Ù. ¿Ö³ÄÇϸé WS2_32.DLL °ú WSOCK32.DLL °£¿¡ Export¸¦ ÇØÁÖ°í ÀÖ±â ‹š¹®¿¡ µÑÁßÀÇ ÇÑ DLLÀÇ ¿¢½ºÆ÷Æ® Å×À̺íÀ» Á¶ÀÛÇÏ¿© µÎ¸é =_= b ÁÁÀº(?) È¿°ú¸¦ ÁÙ¼ö ÀÖ½À´Ï´Ù. ±×·¯³ª ¹¹ º»ÀÎÀÇ ÇöÀç ±ÛÀº SimpleÀ» ¸ñÀûÀ¸·Î Çϱ⿡ ¿¢½ºÆ÷Æ® Å×À̺í Á¶ÀÛÀº Àû´çÇÏÁö ¾Ê´Ù°í »ý°¢ÇÏ¿© ¾²Áö ¾Ê¾Ò½À´Ï´Ù. :p µÎ¹ø¤Š Áý°í ³Ñ¾î°¥ Á¡Àº º»ÀÎÀÇ ±Û¿¡¼­ ÇöÀç±îÁö ¼Ò°³µÈ ÄÚµåÀÇ °æ¿ì, ´ë»ó ÇÁ·Î±×·¥À» ÈÄÅ·Çϰí ÀÖ´Â µ¿¾È ³» ÇÁ·Î±×·¥ ÀÚ½ÅÀº Á¤ÁöµÈ »óÅ·Πº¸ÀÌ°Ô µË´Ï´Ù. (ÀÀ´ä¾øÀ½ »óŶó°í ÇÏÁÒ ÈçÈ÷~ :p) ¹¹, DebugLoop¸¦ µ¹°í ÀÖ±â ‹š¹®¿¡ ´ç¿¬ÇÑ Çö»óÀ̶ó°íµµ º¼¼ö ÀÖ½À´Ï´Ù. À̸¦ ÇØ°áÇÏ´Â ¾ÆÁÖ °£´ÜÇÑ ¹æ¹ýÀ» ¾Ë·Á µå¸®°Ú½À´Ï´Ù. :p ÀÌ ¹æ¹ýÀ» »ý°¢ÇÏ°Ô µÈ°Ç 1³âÀü ¾î´À °Ü¿ï³¯ À̾ú´øµí ½Í±º¿ä :p ¹æ¹ýÀ̶õ ¹«¾ùÀΰ¡ Çϸé...? CreateThread() ¶ó´Â API¸¦ ÀÌ¿ëÇÏ´Â °ÍÀÔ´Ï´Ù. :p (CreateRemoteThread¶ó´Â ´ë»ó ÇÁ·Î±×·¥¿¡ Thread¸¦ »ý¼º ½ÃŰ´Â APIµµ ÀÖ½À´Ï´Ù. :p ÀÌ API¿ª½Ã API Hooking¿¡ ¸¹ÀÌ ¾²ÀÌ´Â ÇÔ¼öÀε¥~ :p º»ÀÎÀÇ ±Û¿¡¼± ´Ù·ç¾îÁöÁö ¾Ê´Â±º¿ä~ T.T ´Ù¸¥ ºÐµéÀÇ ¸¹Àº ±Û¿¡¼­ ¾ó¸¶µçÁö º¼¼ö ÀÖÀ»Å×´Ï ½½ÆÛÇÏÁö´Â ¸¶¼¼¿ä~ :p) ============================================ HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, //Security SIZE_T dwStackSize, //½ºÅà ũ±â LPTHREAD_START_ROUTINE lpStartAddress, //ÇÔ¼ö ½ÃÀÛ ÁÖ¼Ò LPVOID lpParameter, //Æä·¯¹ÌÅÍ(ÀÎÀÚ) DWORD dwCreationFlags, //»ý¼º Ç÷¹±× LPDWORD lpThreadId //°ª ); ============================================= ÀÌ API¸¦ ÀÌ¿ëÇÏ¸é ´ÙÁß ¾²·¹µå ÇÁ·Î±×·¡¹ÖÀ» ÇÒ¼ö Àִµ¥, DebugMsgLoop()¸¦ ÇÔ¼ö½ÃÀÛ ÁÖ¼Ò·Î ÁÖ¸é ´ë»ó ÇÁ·Î±×·¥À» ÈÄÅ·ÇÏ´Â µ¿¾È¿¡µµ º»ÀÎÀÇ ÇÁ·Î±×·¥µµ ÀÀ´ä¾øÀ½ »óŰ¡ ¾Æ´Ñ =_=b Á¤»óÀû ÀÛµ¿ »óŸ¦ À¯Áö ÇÒ¼ö ÀÖÀ½À» º¸½Ç¼ö ÀÖÀ»°Ì´Ï´Ù. (ÀÌ¿¡ ÇØ´çÇÏ´Â ³»¿ëÀº ±¸Áö º»ÀÎÀÇ Äڵ忡 ³Ö°í ½ÍÁöµµ ¾Ê°í, ¿©·¯ºÐµéµµ ¾ó¸¶µçÁö ÀÛ¼ºÇÒ¼ö ÀÖÀ» °Ì´Ï´Ù. :p ¿Ö³Ä±¸¿ä? ÀϹÝÀûÀÎ Windows ProgrammingÃ¥¿¡¼­ ¸¹ÀÌ ¼Ò°³µÇ´Â ³»¿ëÀ̱⠶§¹®ÀÌÁÒ. :p »ç½Ç ÀÌ°Ç º¯¸íÀÌ°í ³»ºÎÀûÀÎ ½ÇÁ¦¿äÀÎÀº Äڵ带 ¼öÁ¤ÇϱⰡ ±ÍÂú¾Æ¼­ ÀÔ´Ï´Ù. :p) ÀÌÁ¦ ¿ì¸®´Â Parameter¸¦ Àоî¿À´Â°Í,Áï ÆÐŶÀÇ ³»¿ëÀ» Àоî¿À´Â°Í ±îÁö ÇÒ¼ö ÀÖ°Ô µÇ¾ú½À´Ï´Ù. ÀÌÁ¦ Áö±ÝºÎÅÍ À̰ÍÀ» Á¶ÀÛÇÏ´Â ¹æ¹ýÀ» ¾Ë¾Æ º¸µµ·Ï ÇϰڽÀ´Ï´Ù. ³»¿ëÀ» Á¶ÀÛÇϴ°ÍÀº ³»¿ëÀ» Àоî¿À´Â°Í ¸¸Å­À̳ª ½±½À´Ï´Ù. :p ¸»·Î Çϴ°ͺ¸´Ü Code¸¦ ¸ÕÀú º¸´Â°Ô ÁÁÀ»°Ì´Ï´Ù. (Code¸¦ ºÁ¾ß ¼³¸í°¡´É :p) //========================================================== void DebugMsgLoop() { DEBUG_EVENT DebugEV; CREATE_PROCESS_DEBUG_INFO CPDI; DWORD dwContinueStatus = DBG_CONTINUE; HMODULE Wsock_Handle; //ÈÄÅ·ÇÒ API°¡ Á¸ÀçÇÏ´Â ¸ðµâÀÇ ÇÚµé ÀúÀå º¯¼ö LPVOID Send_Adr; //ÈÄÅ·À» ¿øÇÏ´Â ´ë»ó APIÁÖ¼Ò ÀúÀå º¯¼ö. MEMORY_BASIC_INFORMATION mbi; unsigned long OldProtect,NewProtect; char FirstByte,BreakByte = (char)0xCC; unsigned long cbByte; CONTEXT Org_Context,New_Context; //Context DWORD ESP,ESP4 = 0,ESP8 = 0,ESPC = 0,ESP10 = 0; DWORD BufAdr,Len; LPVOID buffer; BOOL FirstHit = FALSE; //Attach½Ã¿¡ »ý±â´Â Exception Event üũ º¯¼ö while(TRUE) { WaitForDebugEvent(&DebugEV,INFINITE); //µð¹ö±× À̺¥Æ®¸¦ ±â´Ù¸°´Ù. switch(DebugEV.dwDebugEventCode) { case CREATE_PROCESS_DEBUG_EVENT: //ÇÁ·Î¼¼½º¸¦ óÀ½ Attach ÇßÀ»‹š~ CPDI = DebugEV.u.CreateProcessInfo; //Á¤º¸¸¦ ÀúÀåÇÏ¿© µÐ´Ù. Wsock_Handle = GetModuleHandle("WS2_32.DLL"); //¸ðµâ ÇÚµéÀ» ±¸ÇÑ´Ù. if(Wsock_Handle == 0) { Wsock_Handle = LoadLibrary("WS2_32.DLL"); //¾øÀ» °æ¿ì LoadÇÑ´Ù. if(Wsock_Handle == 0) break; } Send_Adr = GetProcAddress(Wsock_Handle,"send"); //SendÇÔ¼öÀÇ ÁÖ¼Ò¸¦ ±¸ÇÑ´Ù. if(Send_Adr == 0) break; VirtualQueryEx(CPDI.hProcess,Send_Adr,&mbi,sizeof(mbi)); //¸Þ¸ð¸® ÇÁ·ÎÅØÆ®¸¦ ±¸Çؿ´Ù. NewProtect = mbi.Protect; NewProtect &= ~(PAGE_READONLY | PAGE_EXECUTE_READ); //Àç¿Ü ½Ã۰í~ NewProtect |= (PAGE_READWRITE); //Ãß°¡ ½ÃŲ´Ù. VirtualProtectEx(CPDI.hProcess,Send_Adr, //º¸È£ ¸ðµå Á¶Á¤ sizeof(char),NewProtect, &OldProtect); ReadProcessMemory(CPDI.hProcess,Send_Adr, //ù¹ÙÀÌÆ®¸¦ Àоî¿Â´Ù. &FirstByte,sizeof(FirstByte), &cbByte); WriteProcessMemory(CPDI.hProcess,Send_Adr, //EXCEPTION_EVENT(0xCC) ±â·Ï &BreakByte,sizeof(BreakByte), &cbByte); break; case EXCEPTION_DEBUG_EVENT: //¿¹¿Ü µð¹ö±× À̺¥Æ® ¹ß»ý½Ã if(DebugEV.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) //EXCEPTION_BREAKPOINTÀΰ¡? { if(FirstHit == FALSE) FirstHit = TRUE; //ù¹ø¤Š ºêÆ÷ º¯¼ö üũ else { WriteProcessMemory(CPDI.hProcess,Send_Adr, //ù¹ÙÀÌÆ®¸¦ ¿ø·¡ ´ë·Î µ¹¸² &FirstByte,sizeof(FirstByte), &cbByte); Org_Context.ContextFlags = CONTEXT_FULL; //Context Mode GetThreadContext(CPDI.hThread,&Org_Context); //Context¸¦ ±¸Çؿ´Ù. ESP = Org_Context.Esp; //API°¡ ³¡³ª°í ¸®ÅÏ(µ¹¾Æ°¥) ÁÖ¼Ò ESP4 = ESP + 4; //S ESP8 = ESP + 8; //buf Adr ESPC = ESP + 0xC; //len ESP10 = ESP + 0x10; //flag ReadProcessMemory(CPDI.hProcess,(void *)ESPC, //lenÀоî¿È &Len,sizeof(DWORD), &cbByte); buffer = malloc(Len); //±æÀÌ ¸¸Å­ ¸Þ¸ð¸® ÇÒ´ç ReadProcessMemory(CPDI.hProcess,(void *)ESP8, //Buffer ÁÖ¼Ò Àоî¿È &BufAdr,sizeof(DWORD), &cbByte) /*ReadProcessMemory(CPDI.hProcess,(void *)BufAdr, //Buffer Àоî¿È buffer,Len, &cbByte); */ memset(buffer,0x90,Len); WriteProcessMemory(CPDI.hProcess,(void *)BufAdr, buffer,Len, &cbByte); New_Context = Org_Context; //º¹»çº»À» ¸¸µç´Ù. New_Context.Eip = (unsigned long)DebugEV.u.Exception.ExceptionRecord.ExceptionAddress; //New_Context.Eip--; //Eip°ªÀ» -1 ½ÃŲ´Ù. SetThreadContext(CPDI.hThread,&New_Context); //Context¸¦ Àû¿ëÇÑ´Ù. ContinueDebugEvent(DebugEV.dwProcessId,DebugEV.dwThreadId,dwContinueStatus); //´ë»ó ÇÁ·Î±×·¥¿¡ °á°ú ¹Ý¿µ /* ReadProcessMemory(CPDI.hProcess,Send_Adr, //ù ¹ÙÀÌÆ®¸¦ Àоî¿Â´Ù. &FirstByte,sizeof(FirstByte), &cbByte); */ WriteProcessMemory(CPDI.hProcess,Send_Adr, //0xCC¸¦ ±â·Ï &BreakByte,sizeof(BreakByte), &cbByte); free(buffer); //µ¿Àû ÇÒ´çÇÑ ¸Þ¸ð¸®¸¦ ³õ¾ÆÁØ´Ù. MessageBox(NULL,"sendÇÔ¼ö°¡ ¹ß»ýÇÏ¿´½À´Ï´Ù.","==¾Ë¸²==",64); //½Ã°¢Àû È¿°ú } } break; case EXIT_PROCESS_DEBUG_EVENT: //ÇÁ·Î¼¼½º Á¾·á µð¹ö±× À̺¥Æ® ÀÏ‹ž ·çÇÁ ³¡ return; } ContinueDebugEvent(DebugEV.dwProcessId,DebugEV.dwThreadId,dwContinueStatus); } } //================================================= À§ÀÇ Code¿¡¼­ º¯°æµÈ°ÍÀ̶ó°ï ReadProcessMemory()ÇÔ¼ö·Î bufferÀ̸§ÀÇ ¹öÆÛ(Len ¸¸Å­ÀÇ ±æÀÌ)¿¡ Parameter(ÆÐŶÀÇ ³»¿ë)À» Àоî¿À°Ô Çß´ø°ÍÀ» ÁÖ¼®Ã³¸® Çϰí, memset()ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© bufferº¯¼ö¸¦ 0x90·Î ä¿ì°í, WriteProcessMemory()ÇÔ¼ö·Î ´ë»ó ÇÁ·Î±×·¥¿¡ À̰ªÀ» ½á³Ö¾ú½À´Ï´Ù. ½ÇÁ¦·Î ÆÐŶÀÇ ³»¿ëÀÌ º¯°æµÇ´ÂÁö È®ÀÎÇϱâ À§Çؼ­ ´Ù¸¥ ÆÐŶ ½º´ÏÇÎ ÇÁ·Î±×·¥À» ÀÌ¿ëÇÏ¿©¼­ È®ÀÎÇÑ °á°ú ¹Ø°ú °°Àº °á°ú¸¦ ¾òÀ»¼ö ÀÖ¾ú½À´Ï´Ù. //===================================================== 0000 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................ 0010 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................ 0020 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ................ 0030 90 90 90 90 90 90 90 90 ........ //===================================================== Áï ¼º°øÀûÀ¸·Î ParameterÀÇ ³»¿ë(ÆÐŶÀÇ ³»¿ë)À» º¯°æ½Ãų¼ö ÀÖ´Ù´Â °ÍÀ» ¾Ë¼ö ÀÖ¾ú½À´Ï´Ù. À̰ÍÀº ¾î¶² ÆÐŶÀÌµç ¹«Á¶°Ç Á¶ÀÛÇÏ´Â °ÍÀÌÁö¸¸, memcmpÇÔ¼ö·Î ÆÐŶÀÇ °íÁ¤ÀûÀÎ ºÎºÐÀ» ºñ±³ÇÏ¿©, ¿øÇÏ´Â ÆÐŶÀ̸é ó¸®ÇÏ°Ô º¯°æÇÒ¼öµµ ÀÖ°Ú½À´Ï´Ù. :p ÇÏÁö¸¸ À§¿¡¼­ Àç°¡ ¾´ ¹æ¹ý´ë·Î ¶ó¸é, ºÐ¸í ¹º°¡¸¦ Set(Write)ÇÏ´Â ÇÔ¼öÀÇ ³»¿ëÀ» Á¶ÀÛÇÏ¿´À» °æ¿ì ¼º°ú¸¦ ¹ßÈÖÇÒ¼ö ÀÖÁö¸¸, ¹º°¡ Get(Read)ÇÏ´Â ÇÔ¼öÀÇ ³»¿ëÀ» Á¶ÀÛÇϰíÀÚ ÇÑ´Ù¸é À§ÀÇ ³»¿ë°ú´Â ¾à°£ ¹æ¹ýÀÌ ´Þ¶óÁú Çʿ䰡 ÀÖ½À´Ï´Ù. À§ÀÇ ¹æ¹ý¿¡¼± HookingÇϰíÀÚ ÇÏ´Â ÇÔ¼öÀÇ ÀÛ¾÷ÀÌ ½ÃÀ۵DZâ Àü¿¡ ³»¿ëÀ» ¹Ù²Ù´Â ¹æ¹ýÀ̾úÁö¸¸, ¹º°¡¸¦ Get(Read)ÇÏ´Â ÇÔ¼öÀÇ Parameter¸¦ Àоî¿À°íÀÚ ÇÔÀº HookingÀÇ ´ë»ó ÇÔ¼ö°¡ ½ÇÇàµÇ°í ³ª¼­ ÇØ¾ß ¿øÇÏ´Â °ªÀ» ¾ò¾î¿Ã¼ö ÀÖÀ»°ÍÀÔ´Ï´Ù. :p À̰ÍÀÇ ÇØ°á¹ýÀº »ý°¢¿Ü·Î ¾ÆÁÖ °£´ÜÇÕ´Ï´Ù. :p À§¿¡¼­ Àú´Â ESP¿¡ Hooking ÇϰíÀÚ ÇÏ´Â ÇÔ¼ö°¡ ½ÇÇàÇÑ´ÙÀ½ µ¹¾Æ°¥ Return Address°¡ µé¾îÀÖ´Ù´Â ¸»À» ÇÑÀûÀÌ ÀÖ½À´Ï´Ù. (¹«½¼ ¶æÀÎÁö ¸Ó¸® ÁÁÀº ºÐµéÀº ¹ú½á ¾Ë¾ÆÂ÷¸®¼Ì°ÚÁÒ?) Return Address¿¡ 0xCC¸¦ Àû¾î³õ°í ±â´Ù¸®¸é HookingÇϰíÀÚ ÇÏ´Â ÇÔ¼öÀÇ ÀÛ¾÷ÀÌ ¸ðµÎ ³¡³­ÈÄ ¿Ã¹Ù¸¥ ³»¿ëÀ» Àоî¿Ã¼ö ÀÖÀ»°ÍÀÔ´Ï´Ù. À̰ÍÀÌ ¹Ù·Î recvÇÔ¼öÀÇ Parameter HookingÀÇ ¹æ¹ýÀÔ´Ï´Ù. Àç°¡ Àû°íÀÚ Çß´ø ³»¿ëÀº ¸ðµÎ ³¡ÀÌ ³µ½À´Ï´Ù. ±ÛÀÇ ³¡ºÎºÐÀÌ ÈåÁöºÎÁö ÇØ¼­ Á˼ÛÇÕ´Ï´Ù. °³ÀÎÀûÀÎ »çÁ¤À¸·Î ÀÚ¼¼È÷ ¾µ¼ö ¾ø°ÔµÇ¾î¼­~ T.T ¾î¤Šµç ÀüüÀûÀÎ ³»¿ëÀº Àü´ÞµÇ¾úÀ¸¸®¶ó º¾´Ï´Ù. ±×·¡µµ ³¡ºÎºÐÀÎ ¸¸Å­ Áö±Ý±îÁö ÇÑ ³»¿ëÀ» Á¤¸®ÇÒ Çʿ伺ÀÌ ÀÖ´Ù°í »ý°¢Çؼ­ ¸¶Áö¸·À¸·Î Á¤¸®ÇÏ¿© º¸¸é, //======================================= ¨çHooking ÇϰíÀÚ ÇÏ´Â ´ë»ó ÇÁ·Î±×·¥(Remote_Server) ÁöÁ¤ ¨èµð¹ö±× ¸Þ½ÃÁö ·çÇÁ¸¦ µ¹¸² ¨éÇÁ·Î¼¼½º »ý¼º µð¹ö±× À̺¥Æ®°¡ ¹ß»ýÇÏ¿´À»‹š ±¸Á¶Ã¼¸¦ ä¿ì°í Hooking ÇϰíÀÚ ÇÏ´Â ÇÔ¼öÀÇ Ã¹¹ÙÀÌÆ®¸¦ ´ëÇÇ ½ÃÄÑ µÎ°í ±×ÀÚ¸®¿¡ 0xCC¸¦ Àû¾îµÒ. ¨êHookingÀÇ ´ë»ó(Remote_Server)ÀÌ HookingÇÒ ´ë»ó ÇÔ¼ö¸¦ ½ÇÇàÇѼø°£ Á¦¾î±ÇÀÌ ¿ì¸® ÇÁ·Î¼¼½º(Remote_Host)·Î Á¦¾î±ÇÀÌ ³Ñ¾î¿Â´Ù. ¨ë¿øÇϴ ó¸®¸¦ ÇÏ¿© ÁØ´Ù. (³»¿ë Àоî¿À±â,³»¿ë Á¶ÀÛÇϱâ) ¨ìHooking ´ë»ó ÇÔ¼öÀÇ Ã¹¹ÙÀÌÆ®¸¦ ¿ø·¡´ë·Î µÇµ¹·Á ³õ´Â´Ù. ¨í´ë»ó(Remote_Host)¿¡°Ô ÇÔ¼ö¸¦ Á¤»óÀûÀ¸·Î ½ÇÇàÇÏ°Ô ÇÑ´Ù. ¨î´Ù½Ã HookingÀÇ ´ë»ó ÇÔ¼öÀÇ Ã¹¹ÙÀÌÆ®¿¡ 0xCC¸¦ ½É¾îµÐ´Ù. //========================================= Á¤¸®ÇÏ¿© º¸´Ï ¾î¶² ¹æ¹ýÀÎÁö ´ëÃæ ¾Æ½Ã°Ú³ª¿ä? :p ÀÌ ±ÛÀ» Àаí ÀÖ´Â ºÐÀº ºÐ¸í ÀڽŸ¸ÀÇ ¹æ¹ýÀ» ¸¸µé¾î ³¾°ÍÀÔ´Ï´Ù. Àç°¡ À̱ۿ¡¼­ ›§´ø ¹æ¹ýº¸´Ù ÈξÀ ÁÁÀº ¹æ¹ýÀ» ¸»ÀÌÁÒ~! :p ³»¿ëÀº ¹ÌÈíÇßÁö¸¸ ½Ã°£À» Á¶±Ý¾¿ ºñ¿ö¼­ ¾´±ÛÀθ¸Å­ ÈåÁöºÎÁö ÇÏ°Ô ³¡³»´Â º»ÀÎÀÇ ¸¶À½ÀÌ ¾ÆÇÁ±º¿ä T.T ±×·¯³ª ¹¹ º¸´Ù ÁÁÀº ³»¿ëÀ» À§Çؼ­ À̹ø ±ÛÀº ¿©±â¼­ ¸¶Ä¡µµ·Ï ÇϰڽÀ´Ï´Ù. ´ÙÀ½¿¡ ½áº¼ ±ÛÀº PEÆÄÀÏÀÇ Resource¸¦ Á¶ÀÛÇÏ´Â ¹æ¹ý¿¡ ´ëÇØ¼­ ½áº¸°íÀÚ ÇÕ´Ï´Ù. ¾ðÁ¦Âë ±ÛÀ» ´Ù½Ã ¾²°Ô µÉÁö´Â ºÒÈ®½Ç ÇÏÁö¸¸ ¸»ÀÌÁÒ :P ´ÙÀ½ ±Ûµµ Àд ºÐ¿¡°Ô ÃÖ´ëÇÑ ÀÌÇØÇϱ⠽±µµ·Ï ½áº¸µµ·Ï ÇϰڽÀ´Ï´Ù. :p ÀÌ ±Û¿¡¼­ À߸øµÈ ³»¿ëÀÌ ÀÖ´Â °æ¿ì Dual5651@hotmail.com À¸·Î ¾Ë·Á ÁÖ½Ã¸é °í¸¿°Ú´Ù´Â ¸»À» ³²±â¸ç À̸¸ ±ÛÀ» ¸¶Ä¡°Ú½À´Ï´Ù. ±×·³ Good Byte ~ :p P.S: BPM(Break Point at Memory)¶ó´Â °ÍÀ» ¾Ë°í °Ô½Ê´Ï±î? °£´ÜÈ÷ Á¤ÀÇÇÏ¿© º¸¸é ¸Þ¸ð¸®ÀÇ ³»¿ëÀÌ º¯°æµÇ¾úÀ»‹š ¾îµð¿¡¼­ º¯°æÇÏ¿´´ÂÁö ¾Ë¼ö ÀÖ´Â ±â¼úÀ̶ó°í ÇϰڽÀ´Ï´Ù. ¿¹¸¦ µé¸é, main(){ int a; a = 11; //---(1) } ¶ó´Â Code°¡ ÀÖÀ»‹š aÀÇ °ªÀ» º¯°æ½ÃŰ´Â ¸í·ÉÀÇ À§Ä¡´Â (1)ÀÌ µË´Ï´Ù. À̰ÍÀ» ¿ÜºÎ ÇÁ·Î±×·¥¿¡¼­ ¾Ë¾Æ³»´Â ¹æ¹ýÀÌ ÀÖ½À´Ï´Ù. ±×°ÍÀÌ ¹Ù·Î BPMÀÌÁÒ. :p ¾²ÀÌ´Â API´Â.. VirtualProtectEx() ÇÔ¼ö·Î aÀÇ ¸Þ¸ð¸® ¼Ó¼ºÀ» READ_ONLY·Î ¹Ù²Ù¾î ³õ½À´Ï´Ù. ±×·¸´Ù¸é (1)¿¡¼­ a¿¡ °ªÀ» ½á³ÖÀ¸·Á ÇßÀ»‹š EXCEPTION_DEBUG_EVENT°¡ ¹ß»ýÇÒ°ÍÀÔ´Ï´Ù. ÀÌ‹šÀÇ, DebugEV.u.Exception.ExceptionRecord.ExceptionAddress´Â (1)ÀÌ µÇ´Â °ÍÀÔ´Ï´Ù. ¹«½¼ ¸»ÀÎÁö ¾Æ½Ã°Ú³ª¿ä? :p ¹Ý´ë·Î aÀÇ °ªÀ» Àо´Â °æ¿ìµµ ¸Þ¸ð¸® ¼Ó¼ºÀ» WRITE_ONLYµûÀ§·Î ¹Ù²Ù¾î µÐ´Ù¸é 󸮰¡ °¡´ÉÇÒ°ÍÀÔ´Ï´Ù. (¹°·± ¿øÇÏ´Â °á°ú¸¦ ¾òÀºÈÄ¿£ ¸Þ¸ð¸® ¼Ó¼ºÀ» ¿ø·¡µÇ·Î µ¹·Á³õ´Â ¼¾½º°¡ ÇÊ¿äÇÕ´Ï´Ù. :p)