если установлена настройка для IE запускаться в нескольких процессах, то после запуска IE со стартовой страничкой стартует GUI процесс IE(c IEUI.dll) и далее он создаёт процесс для стартовой странички и т д. у меня задача предотвратить выгрузку данных из IE(печать,просмотр печати,просмотр кода страницы,сохранение в файл содержимого страницы). я внедряюсь в каждый процесс где обрабатывается страничка. собственно обработка страницы происходит в процессе запускаемом для каждой новой вкладки, там я и делаю нужную работу, перехватываю команды на печать, сохранение и т д, запрещаю их и всё хорошо. скажу что всё работает в ХП, а вот на WIN 7 есть проблемы с этим самым процессом iexplore, создаваемом для каждой вкладки, незнаю может он сделан как protected process in vista, но мою длл я в него закидываю через CreateRemoteThread без ошибок, проблема в том что после загрузки моей dll в адресное пространство iexplore, не происходит вызова DllMain моей dll, ну и соответвенно dll висит в процессе c счётчиком 1 и молчит). ладно, может я неправ в чём, взял для эксперимента вот эту тулзу http://www.securityxploded.com/remotedll.php, сделал простейшую dll без никто, даже отвязался от рантайма для чистоты эксперимента, в DllMain моей dll просто вывожу строку в outputdebugview. В результате таже самая картина что и у меня...dll грузится но DllMain не вызывается, причём GUI процесс iexplore всё работает и DllMain вызывается как обычно. Видится мне что это какой то заговор от мелкомягких). Ну и вопрос в том что с этим делать, внедряться то надо. Точнее хотелось бы обойти эту проблему ибо не сильно охота менять щас механизм внедрения, надо этот оставить как есть, только заставить выполняться DllMain. Причём у меня тута не поделка какая а коммерч продукт и интересно более менее документированный путь, без сильных извратов. Ещё мне подумалось, что раз мелкомягкие такую поставили бяку, значит могли и ещё както защитить этот процесс от API Hooking или ещё каких техник перехвата функциональности, что кто думает по сабж?
а вы думаете чем я уже 2 дня занимаюсь? да, этот форум прошерстил, гугл тоже насколько смог. ну конкретно этой проблемы не видел. видел проблемы с CreateRemoteThread, но чтобы не вызывалось DllMain, но библиотека корректно грузилилась в процесс - нема такой инфы. создание удалённого потока - без ошибок загрузка dll в процесс, смотрю в оповещении в ядре - без ошибок а вызов DllMain - ни фига не происходит эксепшены тоже не кидаются, просто молчание и всё. неужто никто не фиксил ИМЕННО такое поведение? киньте что ли ссылкой, если уже где то было и я пропустил...
да, всё действие происходит на x86, причём всё работает с первый GUI процессом iexplore, а вот со вторым такая вот проблема...и причём на ХП работает ведь. проверить можно очень просто, берём тулзу http://www.securityxploded.com/remotedll.php делаем длл типа Код (Text): extern "C" __declspec(dllexport) BOOL WINAPI DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { wchar_t str[MAX_PATH]; wsprintf(str,L"DllMain[%d] ul_reason_for_call %d\n",GetCurrentProcessId(),ul_reason_for_call); OutputDebugString(str); return TRUE; } и пробуем грузить эту длл в процессы iexplore смотреть логи в DebugView
вот рабочий код который занимается непосредственно внедрением в процесс известным способом от Рихтера. отрабатывает без ошибок, но DllMain подгруженной dll не вызывается на Windows 7, если внедряемся в iexplore.exe соответвующего вкладке IE. Код (Text): int load_dll(const DWORD dwProcessId, const std::wstring& dllPath) { int result = -1; // Assume that the function fails HANDLE hProcess = NULL, hThread = NULL; PWSTR pszLibFileRemote = NULL; do { // Get a handle for the target process. hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | // Required by Alpha PROCESS_CREATE_THREAD | // For CreateRemoteThread PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx PROCESS_VM_WRITE | // For WriteProcessMemory PROCESS_VM_READ, FALSE, dwProcessId); if (hProcess == NULL) { result = GetLastError(); #ifdef _LOG_OUTPUT TCHAR str[MAX_PATH]; swprintf_s(str,MAX_PATH,L"load_dll OpenProcess id %d error:%d\n",dwProcessId,result); OutputDebugString(str); #endif break; } // Calculate the number of bytes needed for the DLL's pathname int cch = 1 + (int)dllPath.size(); int cb = cch * sizeof(std::wstring::value_type); // Allocate space in the remote process for the pathname pszLibFileRemote = (PWSTR) VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE); if (pszLibFileRemote == NULL) { result = GetLastError(); #ifdef _LOG_OUTPUT TCHAR str[MAX_PATH]; swprintf_s(str,MAX_PATH,L"load_dll VirtualAllocEx cb %d error:%d\n",cb,result); OutputDebugString(str); #endif break; } // Copy the DLL's pathname to the remote process's address space if (!WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID) dllPath.c_str(), cb, NULL)) { result = GetLastError(); #ifdef _LOG_OUTPUT TCHAR str[MAX_PATH]; swprintf_s(str,MAX_PATH,L"load_dll WriteProcessMemory dllPath %s cb %d error:%d\n",dllPath.c_str(),cb,result); OutputDebugString(str); #endif break; } // Get the real address of LoadLibraryW in Kernel32.dll PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle(L"Kernel32"), "LoadLibraryW"); if (pfnThreadRtn == NULL) { result = GetLastError(); break; } // initialize security attributes SECURITY_DESCRIPTOR sd = {0}; SECURITY_ATTRIBUTES sa = {0}; if(!InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION)) { result = GetLastError(); break; } if(!SetSecurityDescriptorDacl(&sd, true, NULL, false)) { result = GetLastError(); break; } sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = true; sa.lpSecurityDescriptor = &sd; // Create a remote thread that calls LoadLibraryW(DLLPathname) hThread = CreateRemoteThread(hProcess, &sa, 0, pfnThreadRtn, pszLibFileRemote, 0, NULL); if (hThread == NULL) { result = GetLastError(); #ifdef _LOG_OUTPUT TCHAR str[MAX_PATH]; swprintf_s(str,MAX_PATH,L"load_dll CreateRemoteThread error:%d\n",result); OutputDebugString(str); #endif break; } // Wait for the remote thread to terminate DWORD ret = WaitForSingleObject(hThread, INFINITE); if(ret != WAIT_OBJECT_0) { result = ret; break; } result = ERROR_SUCCESS; // Everything executed successfully } while (false); // Free the remote memory that contained the DLL's pathname if (pszLibFileRemote != NULL) VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE); if (hThread != NULL) CloseHandle(hThread); if (hProcess != NULL) CloseHandle(hProcess); return result; }
нашёл похожую проблему с внедрением в IE на Windows 7 http://wasm.ru/forum/viewtopic.php?id=39948 похоже дело в Internet Explorer protected mode, отключил его в браузере, проверил - да, при выключенном всё прекрасно внедряется. соответвенно вопрос по преодолению Internet Explorer protected mode, может кто решал подобные вопросы?
как вариант надо будет попробовать, но боюсь что результат будет отрицательный в силу того что в данном случае таки проблема в protected mode в IE на Windows 7, вкратце суть в том что из за того что IE запускает нужный мне процесс с integrity level меньше чем мой(iexplore.exe - low integrity level, мой процесс делающий инжект - medium(если юзер) или high(если админ)) низя преодолеть границы процессов. Сделано для того чтобы BHO работающие в данном iexplore процессе получили ограничение по работе с файловой системой и причими ресурсами компа. По ходу некая песочница. Ну и пока что я накопал что для решения вопроса может подойти понижение integrity level у процесса внедряющего модуль в iexplore до integrity level у iexplore, что при включённом protected mode будет low. Соответвенно алгоритм внедрения может быть такой: - открываем процесс IE - определяем integrity level процесса IE и сравниваем со своим. - если надо делаем integrity level у нас аналогичным процессу IE. - внедряемся ну и тут есть 2 вопроса: - кажется всё подозрительно простым - попав в процесс IE сможем ли сделать подмену API вызовов или ещё что нить касаемо данного процесса или low integrity делает любые действия запрещёнными?
Варианты: 1. Хук в explorer.exe на создание процессов, изнего инжектится в ИЕ ? 2. Закрыть ИЕ, после занового создать внедрив в него свой код? 3. Если можешь писать в память ИЕ то перезапиши указатель по адрессу FS:[C0](для вин 7 и возможно Vista) или 7FFE0300 для ХР на свой код. Постарайся их как можно быстрее вернуть обратно, чтоб ИЕ не упал.
знать бы где и как задаётся protected mode для создаваемого процесса в IE... можно попробовать так: - внедряемся в gui процесс IE и перехватываем ф-цию создания процессов, допустим это CreateProcessW(в импорте iexplore.exe видно что эта ф-ция используется). - при вызове данной функции смотрим что можно сделать, может поменять integrity level или ешё чего, чтобы процесс создался не в protected mode. предлагаю набрать вариантов и потом решить что лучше)
sumson У Verizon есть такая статейка "Escaping from Microsoft's Protected Mode Internet Explorer", гуглится легко. Не уверен, что это именно то, что тебе нужно, но там есть пару любопытных вещей, авось поможет.
вот про внедрение dll в процессы с разными integrity levels http://blog.didierstevens.com/2010/09/07/integrity-levels-and-dll-injection/