Как сделать, чтобы прога не получала сооб-я, посланные др. процессом?

Тема в разделе "WASM.WIN32", создана пользователем AndreyMust19, 12 май 2009.

  1. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    Итак, в одной теме я высказался что решил потренироваться в Visual C с окошками и пишу программу, посылающую чужим окнам сообщения, такие как Minimize и Close.
    Любой элемент интерфейса не защищен от влияния со стороны чужого процесса. Поэтому возникает вопрос - как защитить свою программу от SendMessage из другого процесса? А именно - хотелось бы защитить интерфейс моего отладчика от получения сообщений типа WM_CLOSE и WM_HIDE из другого процесса (н-р, отлаживаемого).
    Надо каким-то образом определить - кто послал нам сообщение и если это не мы, то игнорируем его. У меня есть несколько вариантов.

    1
    Для изменения интерфейса подавать сигналы с помощью семафоров или событий. Второй поток ждет сообщения с помощью WaitMessage. Главный поток поднимает "флаг", посылает сообщение интерфейсу и ждет снятия флага. Второй поток - дождался, и если флаг установлен, то обрабатывает сообщение и сбрасывает флаг. Главный поток узнал, что флаг опустили и продолжает работу.

    2
    Можно каждое событие реализовывать как отдельное сообщение. Но тогда будет очень много потоков, каждый из к-х будет ждать изменение состояния своего события.

    3
    В некоторых сообщениях можно передавать в аргументах магическое число или изменять особым образом значение переменной. А при обработке сообщения - проверять это магическое число или значение переменной.

    Какие ваши предложения? Только, пожалуйста, без ядерных вариантов.
    И возможно ли вообще определить источника сообщения или нет?
     
  2. RET

    RET Well-Known Member

    Публикаций:
    17
    Регистрация:
    5 янв 2008
    Сообщения:
    789
    Адрес:
    Jabber: darksys@sj.ms
    Странный вопрос. В оконной процедуре всегда первый параметр - хендл окна, если конечно чистый API использовать.
     
  3. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    InSendMessage возвращает true, если сообщение было послано из другого потока (своего или чужого процесса)
     
  4. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    InSendMessageEx интереснее :)
     
  5. mrcrown

    mrcrown Member

    Публикаций:
    0
    Регистрация:
    18 янв 2008
    Сообщения:
    227
    Зачем велосипед изобретать, ведь, как уже сказал RET, первый параметр хендл окна, по нему проверять можно.
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Интересно, каким образом можно по хэндлу собственного окна узнать кем послано сообщение ?!
     
  7. onSide

    onSide New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2008
    Сообщения:
    476
    Помоему InSendMessageEx не пойдет, потому что сообщения могут приходить и из других потоков данного процесса.
    Можешь похукать SendMessage в своем процессе при старте, и там допустим засовывать в UINT Msg какое-то магическое число, а в WPARAM wParam передавать указатель на структуру с оригинальными Msg,wParam,lParam.
    А в оконной процедуре в самом начале
    Код (Text):
    1. BOOL DecodeMessage(...)
    2. {
    3. if(*Msg!= MAGIC_NUM) return FALSE;//не наше
    4.  
    5. //Наше
    6. ....;//Восстанавливаем оригинальные Msg,wParam,lParam из структуры, указатель на кот. в wParam
    7. return TRUE;
    8. }
    Код (Text):
    1. if(!DecodeMessage(&Msg,&wParam,&wParam)) return TRUE; //не обрабатываем левые сообщения
    2. switch(uMsg)
    3. {
    4. case WM_COMMAND:
    5. ...;//обработка твоих сообщений
    6. }
    Вот примерно так, но я это не проверял, чистая теория :)
     
  8. mrcrown

    mrcrown Member

    Публикаций:
    0
    Регистрация:
    18 янв 2008
    Сообщения:
    227
    Да действительно! Как? Вот пишут сами не знают что! :))
    Да затупил! Мой пост ффтопку! :)
     
  9. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    onSide
    Не думаю, что часто возникает необходимость закрывать из потока окна других потоков (своей проги). А если возникает, то для данной задачки как раз и можно ввести доп.спец.сообщение MAGIC_NUM для закрытия окна другого потока
     
  10. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    onSide
    Про магические числа.
    Не всегда их можно будет передавать через само сообщение. В некоторых сообщениях wParam и lParam используются, а сообщение типа WM_COMMAND содержит в младшем слове wParam (помоему?) ID элемента управления, которому послано сообщение.
    Короче, передавать магическое число в аргументах сообщения - подходит не для всех сообщений.

    Получается что единственный вариант - перед посылом сообщения записать в переменную магическое значение, а после получения сообщения - проверить ее значение и обнулить. Можно вместо переменной использовать семафоры / события, но это будет медленнее.

    Но вот как спастись от WM_CLOSE / WM_HIDE / WM_MINIMIZE, посланного другим приложением?
    Вспомнил что с Windows NT есть задания (Jobs), одним из аттрибутов которых может быть "запрет на сообщения". Все процессы, находящиеся в таком задании не могут посылать сообщения чужим окнам. Жалко, а мне надо наоборот - чтобы мне чужие процессы не могли посылать сообщения! Собирать все чужие процессы в задание - не выход, во-первых могут отсутствовать права, во-вторых, в задание можно поместить только новый процесс (а может и нет?).

    Хм... если ли способ решения проблемы через WinAPI-функции?
    Может при посыле сообщения моему процессу у посыльника возникает что-то, по чему этого посыльника можно узнать?
    И интересно, когда ПОЛЬЗОВАТЕЛЬ нажимает на клавиши или двигает мышью, то какой системный процесс посылает сообщения? Может его похукать?
     
  11. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    leo
    Закрывать то не надо, а вод добавлять строки в ListBox, изменять строки в ComboBox может потребоваться.
    InSendMessage для этих целей поможет (чтобы только главный поток мог модифицировать строки и надписи) а вот от WM_CLOSE или WM_MINIMIZE это не защищает.
     
  12. onSide

    onSide New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2008
    Сообщения:
    476
    Ты не понял схемы) Системе пофигу (но надо проверить) какие числа ты отправляешь через SendMessage, они имеют значение только для оконной процедуры и DefWindowProc. Соответственно в процедуре DecodeMessage() восстанавливаются оригинальные значения Msg wParam и lParam, которые идут дальше к твоей процедуре и DefWindowProc. А если это сообщение не содержит магич. число, мы просто возвращаем TRUE типа мы "обработали" это сообщение.

    leo ну не уверен, например когда ты делаешь "Файл-Открыть..." этот диалог создается помоему в отдельном потоке, и вместе с ним еще несколько потоков создается, и закрывается он тоже неизвестно откуда, может ты и прав, это надо делать и смотреть на конкретном примере:)
     
  13. RET

    RET Well-Known Member

    Публикаций:
    17
    Регистрация:
    5 янв 2008
    Сообщения:
    789
    Адрес:
    Jabber: darksys@sj.ms
    Да я тож чегото сразу не допонял.
    Тут не только интерфейс защищать нужно...
    Но факт остается фактом:
    Раз уж пишешь отладчик изучи сначала как работают другие отладчики и плагины к ним.
    P.S: Смотри в сторону сорцов фантика и ему подобных к ольке.
     
  14. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    onSide
    В том то и дело, что не пофигу, надо проверить. При определенных типах сообщений используются параметры (н-р, при сообщении типа "Клик" через lParam и wParam передаются координаты от левого верхнего угла окна / рабочего стола, на к-х надо выполнить клик. Вот я и говорю что не во всех сообщениях можно приватизировать параметры. Важно сделать чтобы сообщения работы с интерфейсом могли посылать только мы и обезопасить себя от убийственных CLOSE и HIDE (чтобы кроме нас их могла посылать система).

    RET
    Я не пишу отладчик, а тренируюсь в системных функциях отладки. В результате получается отладчик :) .
     
  15. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    SetMessageExtraInfo/GetMessageExtraInfo
    Наверное как альтернатива передачи МЧ через переменную и городить ещё очередь для привязки переменных к сообщениям
     
  16. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    Гуд, dag, то что надо. Завтра проверю.
     
  17. onSide

    onSide New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2008
    Сообщения:
    476
    Я знаю, они в очень многих сообщениях юзаются.
    Только сначала это сообщение приходит в твою процедуру, где ты восстановишь эти координаты или что там надо будет, и продолжишь обработку вызвав DefWindowProc с новыми(восстановленными) параметрами )

    Хотя мне все больше начинает казаться, что это сильно затрудненный метод и должно быть что-то попроще..
     
  18. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    Делать рандомное имя класса и заголовок окна.
    В RkU 3.0 например заголовок рандомный (как и имя процесса), а в RkU 3.8 надпись заголовока вобще отрисовывается вручную.
     
  19. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    AndreyMust19
    Ничего не понял. Раз "закрывать то не надо", то соотв-но в WindowProc можно обрабатывать WM_CLOSE, WM_SYSCOMMAND и т.п. только по InSendMessage == false, т.е. при закрытии окна только из своего потока. Если есть необходимость закрыть окно из другого (своего) потока, то можно предусмотреть вариант с передачей и контролем доп.параметров wParam,lParam = magic_number, например, 0xDEADBEEF и т.п.
    По сути это развитие твоего вариант №3, учитывающее возможность закрытия, минимизации и т.п. окна по WM_SYSCOMMAND, которые генерятся виндой при нажатии на кнопки в заголовке окна и соотв-но вмешаться в них ты просто так не можешь (если только отслеживать мышиные клики и взводить флаги или же перехватывать SendMessage\CallWindowProc по совету onSide). А по InSendMessage легко определить пришло ли SC_CLOSE от твоей кнопки или было послано другой прогой

    onSide
    Тут дело не в потоках, а в том, что у стандартных диалогов свои циклы выборки сообщений и свои WindowProc, и поэтому влезть в них со своим IsSendMessage ес-но нельзя и соотв-но защитить их от закрытия извне таким способом тоже нельзя. Но и не думаю, что ТС хочет защищать все окна подряд, включая стандартные диалоги типа открытия файлов. Тем более с точки зрения защиты диалога, видимо важнее контролировать нажатие кнопок и подмену данных извне, нежели простое закрытие
     
  20. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    AndreyMust19
    Судя по описанию это совсем не то, что надо ;)
    SetMessageExtraInfo устанавливает некоторое значение не для конкретного сообщения, а одно общее для всех сообщений, обрабатываемых в текущем потоке, т.е. это просто некий упрощенный аналог TlsSetValue\TlsGetValue. Поэтому GetMessageExtraInfo будет выдавать одно и то же ранее установленное в данном потоке значение независимо от того откуда пришло сообщение из своего потока или из чужого