From 11a5bfd4b4e00ae644bc46c014439b82bf31757a Mon Sep 17 00:00:00 2001 From: "alexey.min" Date: Mon, 13 Feb 2012 11:01:22 +0000 Subject: [PATCH] Fixed window finding (may be not complete) Added more hooks checks on ws2_32.dll functions --- l2detect/DebugDlg.cpp | 21 +++++++++++++++++++- l2detect/RadarDllWnd.cpp | 43 ++++++++++++++++++++++++++++++++++------ l2detect/net_hook.h | 6 ++++++ l2detect/net_hook_my.cpp | 19 +++++++++++++++++- 4 files changed, 81 insertions(+), 8 deletions(-) diff --git a/l2detect/DebugDlg.cpp b/l2detect/DebugDlg.cpp index 36ed0b2..4a22b63 100644 --- a/l2detect/DebugDlg.cpp +++ b/l2detect/DebugDlg.cpp @@ -291,9 +291,28 @@ void DebugDlg_OnBnClickedValidateInterception( HWND hDlg ) hDlg = NULL; Hook_ValidateInterception_my(); Hook_CheckVirtualProtect(); + Hook_check_func_prolog( L"ws2_32.dll", "connect", original_ws2_32_connect_6_bytes ); + Hook_check_func_prolog( L"ws2_32.dll", "recv", original_ws2_32_recv_6_bytes ); + Hook_check_func_prolog( L"ws2_32.dll", "send", original_ws2_32_send_6_bytes ); + Hook_check_func_prolog( L"ws2_32.dll", "listen", original_ws2_32_listen_6_bytes ); + Hook_check_func_prolog( L"ws2_32.dll", "socket", original_ws2_32_socket_6_bytes ); + Hook_check_func_prolog( L"ws2_32.dll", "accept", original_ws2_32_accept_6_bytes ); + Hook_check_func_prolog( L"ws2_32.dll", "WSAConnect", original_ws2_32_WSAConnect_6_bytes ); - Hook_check_func_prolog( L"ws2_32.dll", "WSASend", original_ws2_32_WSASend_6_bytes ); Hook_check_func_prolog( L"ws2_32.dll", "WSARecv", original_ws2_32_WSARecv_6_bytes ); + Hook_check_func_prolog( L"ws2_32.dll", "WSASend", original_ws2_32_WSASend_6_bytes ); + Hook_check_func_prolog( L"ws2_32.dll", "WSAAccept", original_ws2_32_WSAAccept_6_bytes ); + Hook_check_func_prolog( L"ws2_32.dll", "WSASocketA", original_ws2_32_WSASocketA_6_bytes ); + Hook_check_func_prolog( L"ws2_32.dll", "WSASocketW", original_ws2_32_WSASocketW_6_bytes ); + + if( GetModuleHandleW( L"iphlpapi.dll" ) ) + { + log_error( LOG_WARNING, "Iphlpapi.dll loaded\n" ); + } + else + { + log_error( LOG_OK, "Iphlpapi.dll not loaded\n" ); + } } void DebugDlg_OnBnClickedInterceptConnect( HWND hDlg ) diff --git a/l2detect/RadarDllWnd.cpp b/l2detect/RadarDllWnd.cpp index 08e79e6..2c3cdcf 100644 --- a/l2detect/RadarDllWnd.cpp +++ b/l2detect/RadarDllWnd.cpp @@ -114,7 +114,9 @@ BOOL CALLBACK RadarDllWindowThread_EnumWindowsProc( HWND hWnd, LPARAM lParam ) // check window class or name to check is it is main Lineage II window bool isL2Window = false; wchar_t wndTitle[256]; + wchar_t buffer_for_class_name[256] = {0}; memset( wndTitle, 0, sizeof(wndTitle) ); + memset( buffer_for_class_name, 0, sizeof(buffer_for_class_name) ); GetWindowTextW( hWnd, wndTitle, 255 ); log_error( LOG_DEBUGDUMP, ".. got window title [%S]\n", wndTitle ); if( _wcsicmp( wndTitle, L"Lineage II" ) == 0 ) @@ -126,7 +128,6 @@ BOOL CALLBACK RadarDllWindowThread_EnumWindowsProc( HWND hWnd, LPARAM lParam ) if( !isL2Window ) { log_error( LOG_DEBUGDUMP, "... window title doesn't match, trying by class name...\n" ); - wchar_t buffer_for_class_name[256] = {0}; if( GetClassNameW( hWnd, buffer_for_class_name, 255 ) ) { log_error( LOG_DEBUGDUMP, ".... got window class name = [%S]\n", buffer_for_class_name ); @@ -150,13 +151,43 @@ BOOL CALLBACK RadarDllWindowThread_EnumWindowsProc( HWND hWnd, LPARAM lParam ) DWORD nameLen = GetProcessImageFileNameW( hProcess, szFileName, sizeof(szFileName)/sizeof(szFileName[0]) ); if( nameLen > 0 ) { + log_error( LOG_DEBUGDUMP, "..... got process name [%S]\n", szFileName ); const wchar_t *wExe = wcsrchr( szFileName, '\\' ); - if( (_wcsicmp( wExe, L"l2.bin" ) == 0) || (_wcsicmp( wExe, L"l2.exe" ) == 0 ) ) + if( wExe ) { - isL2Window = true; - wchar_t wClassName[256] = {0}; - GetClassNameW( hWnd, wClassName, 255 ); - log_error( LOG_OK, "... found L2 Window by process name (what???) of class [%S]\n", wClassName ); + wExe++; + log_error( LOG_DEBUGDUMP, "..... got EXE name [%S]\n", wExe ); + if( (_wcsicmp( wExe, L"l2.bin" ) == 0) || (_wcsicmp( wExe, L"l2.exe" ) == 0 ) ) + { + std::list wrong_classes; + wrong_classes.push_back( std::wstring(L"IME") ); + wrong_classes.push_back( std::wstring(L"MSCTFIME UI") ); + wrong_classes.push_back( std::wstring(L"DIEmWin") ); + wrong_classes.push_back( std::wstring(L"GFxVideoSoundWindowClass") ); + wrong_classes.push_back( std::wstring(L"NSplashWnd") ); + wchar_t wClassName[256] = {0}; + GetClassNameW( hWnd, wClassName, 255 ); + bool wrong_class = false; // assume class OK + for( std::list::const_iterator iter = wrong_classes.begin(); + iter != wrong_classes.end(); iter++ ) + { + if( wcscmp( wClassName, iter->c_str() ) == 0 ) // wrong class + { + wrong_class = true; // equals to some wrong class + break; + } + if( wClassName[0] == L'#' ) + { + wrong_class = true; // equals to some wrong class // "#32770" for example (dialog) + break; + } + } + if( !wrong_class ) + { + isL2Window = true; + log_error( LOG_DEBUG, ".... found L2 window by exe [%S] of class [%S]!\n", wExe, wClassName ); + } + } } } else diff --git a/l2detect/net_hook.h b/l2detect/net_hook.h index 1144000..55f0718 100644 --- a/l2detect/net_hook.h +++ b/l2detect/net_hook.h @@ -20,6 +20,12 @@ extern const unsigned char original_ws2_32_send_6_bytes[6]; extern const unsigned char original_ws2_32_WSAConnect_6_bytes[6]; extern const unsigned char original_ws2_32_WSARecv_6_bytes[6]; extern const unsigned char original_ws2_32_WSASend_6_bytes[6]; +extern const unsigned char original_ws2_32_listen_6_bytes[6]; +extern const unsigned char original_ws2_32_accept_6_bytes[6]; +extern const unsigned char original_ws2_32_WSAAccept_6_bytes[6]; +extern const unsigned char original_ws2_32_socket_6_bytes[6]; +extern const unsigned char original_ws2_32_WSASocketA_6_bytes[6]; +extern const unsigned char original_ws2_32_WSASocketW_6_bytes[6]; extern const unsigned char original_vpex_6_bytes[6]; extern const unsigned char l2walker_connect_6_bytes[6]; // ^^ orig_bytes diff --git a/l2detect/net_hook_my.cpp b/l2detect/net_hook_my.cpp index 00c254a..066f585 100644 --- a/l2detect/net_hook_my.cpp +++ b/l2detect/net_hook_my.cpp @@ -24,6 +24,15 @@ connect 8B FF 55 8B EC 83 send 8B FF 55 8B EC 83 recv 8B FF 55 8B EC 83 +accept 8B FF 55 8B EC 6A 00 (6A 00 = PUSH 00) ( really calls WSAAccept(1, 2, 3, 0, 0) ) +WSAAccept 8B FF 55 8B EC 51 51 (51 51 = PUSH ECX; PUSH ECX) + +listen 8B FF 55 8B EC 51 81 + +WSASocketA 8B FF 55 8B EC 81 EC (81 EC = SUB ESP, 278) +WSASocketW 6A 20 68 A0 3D AA 75 (PUSH 20; PUSH rel a03daa75) +socket 8B FF 55 8B EC 51 56 (51 = PUSH ECX; 56 = PUSH ESI) (calls WSASocketW) + VirtualProtectEx (from kernelbase.dll) 8B FF 55 8B EC 56 VirtualProtectEx (kernel32) 8B FF 55 8B EC 5D // jump follows, relocate, // rejump/relocate to VirtualProtectEx inside kernelbase.dll @@ -44,6 +53,14 @@ const unsigned char original_ws2_32_send_6_bytes[6] = { 0x8B, 0xFF, 0x55, const unsigned char original_ws2_32_WSAConnect_6_bytes[6] = { 0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x51 }; const unsigned char original_ws2_32_WSARecv_6_bytes[6] = { 0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x51 }; const unsigned char original_ws2_32_WSASend_6_bytes[6] = { 0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x51 }; + +const unsigned char original_ws2_32_listen_6_bytes[6] = { 0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x51 }; +const unsigned char original_ws2_32_accept_6_bytes[6] = { 0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x6A }; +const unsigned char original_ws2_32_WSAAccept_6_bytes[6] = { 0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x51 }; +const unsigned char original_ws2_32_socket_6_bytes[6] = { 0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x51 }; +const unsigned char original_ws2_32_WSASocketA_6_bytes[6] = { 0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x81 }; +const unsigned char original_ws2_32_WSASocketW_6_bytes[6] = { 0x6A, 0x20, 0x68, 0xA0, 0x3D, 0xAA }; + const unsigned char original_vpex_6_bytes[6] = { 0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x56 }; const unsigned char l2walker_connect_6_bytes[6] = { 0xE9, 0xB1, 0x3A, 0xB7, 0x90, 0xC3 }; @@ -299,7 +316,7 @@ bool Hook_ValidateInterception_my() if( !inok ) { logLevel = LOG_WARNING; - log_error( LOG_WARNING, "Not intercepted! Dump will follow...\n" ); + log_error( LOG_WARNING, "ws2_32.dll!connect() Not intercepted! Dump will follow...\n" ); } else log_error( LOG_OK, "ws2_32.dll!connect() Interception OK!\n" );