Текущий архив: 2003.05.08;
Скачать: CL | DM;
Вниз
форму нельза закрыть? Найти похожие ветки
← →
Zew (2003-04-27 11:04) [0]Подскажите пожалуйста как сделать так чтобы форму нельзя было закрыть не по alt-F4 ни по ctrl-alt-delete.
← →
Слесарь Матерящийся (2003-04-27 11:06) [1]Никак. На самом серьёзе.
← →
Fenik (2003-04-27 11:11) [2]А зачем тебе это?
← →
Anatoly Podgoretsky (2003-04-27 11:12) [3]А выключать клавишей Reset
← →
TButton (2003-04-27 18:09) [4]onClose
...
Exit;
...
или
onCloseQuery
...
CanClose:=false;
...
"...используй силу..."
← →
aldor (2003-04-27 21:28) [5]от Alt-F4 поможет совет TButton. Практически исчерпывающе.
Только можно добавить:
onClose:
Action := caNone;
а Exit просто прекратит обработку события, но оно все равно произойдет! (т.е. написание Exit аналогично вообще пустой процедуре)
от Ctrl-Alt-Del в Win9x программу можно спрятать (см. RegisterServiceProcess), но все равно можно убить сам процесс.
Смиритесь с тем, что способа полностью защитить программу не существует.
← →
NightAngel (2003-04-28 01:40) [6]> от Ctrl-Alt-Del в Win9x программу можно спрятать (см. RegisterServiceProcess), но все равно можно убить сам процесс.
А что мешает перехватить ту-же TerminateProcess()?
В системах Win9x Kernel32.dll загружается в адресное пространство выше 2Gb, которое проецируется на все контексты, присутствующие в системе, то есть ее содержимое одинаково для всех процессов. Для перехвата вызова производится изменение кода уже загруженного в память модуля. Изменяются первые 5 байт перехватываемой функции (вставляется jmp hook).
Сложности здесь такие:
Надо учитывать спроецированность памяти >2Gb, ведь если некоторый регион будет разрешен для записи, а потом его память будет изменена, то эти изменения произойдут одновременно во всех контекстах. Таким образом, если удастся изменить ядро для передачи управления некоторых функций другим обработчикам, расположенным в памяти >2Gb (память пользовательского процесса), то при вызове перехваченной функции процессом другого контекста произойдёт сбой - по указанному адресу не окажется соответствующего кода обработчика. Следовательно, код глобальных обработчиков функций ядра необходимо располагать также в памяти >2Gb. В системах Win9x невозможно перезаписать память в диапазоне адресов от 0x80000000 до 0xBFFFFFFF. Решается вызовом VxDCall (всегда первая экспортируемая функция в Kernel32.dll) _PageModifyPermissions или прямой записью из Ring0 (через CallGate).
Так как заранее не известно, по каким адресам расположится код ловушки, в ней не следует использовать абсолютных адресов. Код должен быть базонезависимым.
Чтобы не нарушить работу программы, функция ловушки должна перед возвратом восстановить регистры (все регистры общего назначения, кроме eax, ecx) и очистить стек от адреса возврата и аргументов.
Для вызова перехваченой функции сначала необходимо вернуть на место старые 5 байт, чтобы избежать повторных вызовов ловушки из самой себя и зацикливания. После возврата из перехваченой функции 5 байт должны быть опять переписаны, чтобы при следующих вызовах управление передавалось в функцию-ловушку. Как вариант - можно обойтись без вырезания фиксированого кол-ва байт, вырезав несколько инструкций (там скорее всего будут: push,pop,mov), и разместив их за своим обработчиком, а затем jmp на перехватываемую функцию.
Где размещать код:
1. Можно в DOS части заголовка Kernel32.dll. В структуре IMAGE_DOS_HEADER (располагается непосредственно по адресу image base, который для exe-файлов обычно равен 0x400000) для Windows важны только поля e_magic (первое) и e_lfanew (последнее). Соответственно всё, что между ними (58 байт), может использоваться ловушкой. Ещё одна неиспользуемая область - dos stub (код, который работает при запуске программы в режиме DOS и выдаёт сообщение "This program can’t be run in DOS mode."). Эта область начинается сразу после IMAGE_DOS_HEADER и заканчивается там, где начинается IMAGE_NT_HEADERS. Обычно её размер составляет около 200 байт.
2. В Relocation table. Область данных, на которую ссылается IMAGE_DIRECTORY_ENTRY_BASERELOC. После загрузки модуля она не нужна. Её размер обычно достигает нескольких килобайт.
3. Неиспользуемые области, выравнивающие секции на соответствующие границы. Их не трудно найти, просмотрев все структуры IMAGE_SECTION_HEADER.
4. Можно выделить память под объект - проекцию файла, например, из своп-файла. Содержимое подобного объекта будет расположено системой >2Gb, все выделенные страницы могут быть помечены атрибутом "исполняемые" (всё равно Ваш процесс не завершиться).
Теперь, как это сделать:
а) Определить базовый адресс по которому загружен Kernel32.dll GetModuleHandle().
б) Определить адресс перехватываемой функции GetProcAddress().
в) Записать код обработчика (в область где Вы его решили разместить).
г) Заменить первые 5 байт перехватываемой функции на вызов Вашего обработчика (предварительно сохранив эти 5 байт, в эту же область).
← →
TButton (2003-04-28 09:53) [7]2 aldor ©
а помоему всетаки Exit в onClose очень хорошо работал, помнится я в одной проге диалог Save changes (yes, no, cancel) поставил в onClose вместо onCloseQuery и помнится она очень хорошо висла когда я тыкал Cancel ;)
Страницы: 1 вся ветка
Текущий архив: 2003.05.08;
Скачать: CL | DM;
Память: 0.47 MB
Время: 0.009 c