Проблема с хуком (WH_CALLWNDPROCRET)

Тема в разделе "WASM.BEGINNERS", создана пользователем XshStasX, 12 авг 2008.

  1. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    вот есть ловушка в она должна записывать все окна которые активировались в файл.
    но при ее роботе выскакивает целая куча ошибок в других программах вот пример кода этой ловушки

    Library Hook;
    Uses
    Windows,Messages,sysutils;

    var
    H,h1: THandle;
    msg:PMSG;
    wn:PCBTCreateWnd;
    buf,cap:PansiChar;
    send:PCWPRETSTRUCT;
    Edit:HWND;
    S:PAnsiChar;
    Function HookProc1(Code:Integer;Wparam:Word;Lparam:Cardinal):Integer;stdcall;
    begin
    Result:=CallNextHookEx(h1,code,Wparam,Lparam);
    end;

    Function HookProc(Code:Integer;Wparam:Word;Lparam:Cardinal):Integer;stdcall;
    var
    F:textfile;
    cap:PAnsiChar;
    str:String;
    begin
    if Code=HC_ACTION then
    send:=PCWPRetStruct(Lparam);
    Result:=CallNextHookEx(h,code,Wparam,Lparam);
    if send.message=WM_ACTIVATEAPP then
    begin
    Assign(f,'c:\log.txt');
    if not FileExists('c:\log.txt') then
    Rewrite(f);
    Append(f);
    cap:=pansichar(AllocMem(255));
    getWindowText(GetAncestor(send.hwnd,GA_ROOT),cap,255);
    str:=cap;
    Writeln(F,str);
    CloseFile(f);
    FreeMem(cap);
    end;
    end;

    procedure SetHook(g:HWND);stdcall;
    begin
    h:=SetWindowsHookEx(WH_CALLWNDPROCRET,@hookproc,HInstance,0);
    end;

    Procedure DelHook;stdcall;
    begin
    UnhookWindowsHookEx(H);
    end;
    exports
    SetHook,DelHook;
    begin
    end.

    Может подскажите в чем проблема???
    мне вообще надо узнавать какие окна были создание и записывать ихней заголовок в файл.Пробивал использовать хук на WH_CBT... но при этом у меня все окна зависают(такое чувство что моя программа не отправляет им сообщения дальше потомушто ни одно окна ни начто не реагирует и не создаться новие от этого помогает токо RESET )
    буду очень благодарен за помощь
     
  2. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    1. Для оформления кода нужно использовать тег\кнопочку Code
    2. Что это за финт ушами:
    А если Code <> HC_ACTION, то send = Nil или инвалидному указателю из предыдущего lParam. Нужно объявить send локальной переменной в HookProc и условие записать так:
    Код (Text):
    1. if Code=HC_ACTION then
    2.   Result:=0
    3. else
    4.   Result:=CallNextHookEx(h,code,Wparam,Lparam);
    5. send:=PCWPRetStruct(Lparam);
    PS: str:=cap совершенно ни к чему, т.к. Writeln и cap нормально скушает. Возиться с Alloc\FreeMem тоже незачем, лучше объявить cap:array[0..255] of AnsiChar;

    PPS: Открывать\закрывать файл на каждый вызов wndproc это (видимо) страшные тормоза. Наверное лучше писать данные в буфер и сбрасывать его в файл только при переполнении и при снятии хука
     
  3. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Вот есть кусок кода ловушки он толком не работает и ошибки видаються при его работе
    мож подскажете что здесь не так?

    Library Hook;
    Uses
    Windows,Messages,sysutils,sharemem;

    var
    H,h1: THandle;
    msg:PMSG;
    wn:PCBTCreateWnd;
    buf,cap:PansiChar;
    send:PCWPRETSTRUCT;
    Edit:HWND;
    S:PAnsiChar;
    Function HookProc1(Code:Integer;Wparam:Word;Lparam:Cardinal):Integer;stdcall;
    begin
    Result:=CallNextHookEx(h1,code,Wparam,Lparam);
    end;


    Function HookProc(Code:Integer;Wparam:Word;Lparam:Cardinal):Integer;stdcall;
    var
    F:textfile;
    cap:String;
    begin
    if Code=HC_ACTION then
    Result:=0
    else
    Result:=CallNextHookEx(h,code,Wparam,Lparam);
    send:=PCWPRetStruct(Lparam);
    if (send.message=WM_CREATE)and(send<>nil) then
    begin
    Assign(f,'c:\log.txt');
    if not FileExists('c:\log.txt') then
    Rewrite(f);
    Append(f);
    getWindowText(GetAncestor(send.hwnd,GA_ROOT),PansiChar(cap),255);
    Writeln(F,cap);
    CloseFile(f);
    end;
    end;

    procedure SetHook(g:HWND);stdcall;
    begin
    h:=SetWindowsHookEx(WH_CBT,@hookproc,HInstance,0);
    end;

    Procedure DelHook;stdcall;
    begin
    UnhookWindowsHookEx(H);
    end;
    exports
    SetHook,DelHook;
    begin
    end.
     
  4. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Во-первых, WParam - это не WORD а DWORD. Во-вторых, лучше столь длинный листинг кода не выкладывать прямо в пост, а присоединять файл, благо форум wasm это позволяет (ну или хотябы юзать bb-код не , а [cоde]).
     
  5. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    XshStasX
    Это тебе для кейлоггера, я так понимаю. Нафига тебе кроме хука на клаву, еще и хук на окна.
    Сделай проще: при начале ввода с клавиатуры, вызывай GetForegroundWindow && GetWindowText
    и будет тебе счастье без лишних хуков.
     
  6. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Хук на окна это для общего развития=)
    И я буду очень рад если поможите с етим хуком разобраться
     
  7. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    XshStasX
    Слушай, кончай валять дурака - если не понимаешь как работают паскалевские String, то и нечего их юзать. Я ж тебе сказал - юзай array
    Код (Text):
    1. var
    2.   cap:array[0..255] of char;
    3. begin
    4.   ...
    5.   getWindowText(GetAncestor(send.hwnd,GA_ROOT),@cap,255); //в дельфи можно и без @
    6.   Writeln(F,cap);
    7.   ...
    8. end;
    PS: в дельфях string - указатель на динамическую строку, поэтому если ты своему cap ничего не присвоил, то cap = '' и pointer(cap) = Nil, но при приведении pAnsiChar(cap) компилятор из соображений совместимости выдает не Nil, а реальный указатель на 0-символ в секции кода. Поэтому когда GetWindowText пытается в него писать получается AV
     
  8. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Кому не сложно помощь с хуками на окна???
     
  9. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    leo
    Похоже у ТС твои разъяснения вызывают полный коллапс :)
     
  10. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    что то я не понял.... всмысле???
     
  11. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    XshStasX
    Да в том смысле, что его разъяснения похоже полностью Вами игнорируются.
     
  12. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Нет почему я обратил внимание на его разъяснения...
    но это токо тестовой пример и в нем мне главное чтоб я мог узнать какие окна создаются в системе...а потом уже все остальное...
     
  13. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    XshStasX
    Повторюсь.
    Во-первых, вы должны провести замену строки "Wparam:Word" на "WParam:lol: WORD", "WParam:WPARAM" или же на "WParam:Cardinal".
    Во-вторых, уяснить, что хук CBT принимает в парам code не HC_ACTION, а одну из констант HCBT_###. Именно поэтому в вашем коде, там где нужно было выдать в результат нуль, в нём в результате неверной проверки оказывалось рандомное ненулевое число, блокировавшее приход окнам сообщений.
     
  14. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Фу ты, еще и WH_CALLWNDPROCRET на WH_CBT в тихушечку поменял...

    PS: WParam конечно нужно заменить для порядка на dword, хотя дельфя сама в stdcall блюдет выравнивание стека на 4 и делает ret 0Ch
     
  15. z_x_spectrum

    z_x_spectrum New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2007
    Сообщения:
    145
    Ты нормальный или нет?
    Тебе уже сказали:
    HookProc(Code:Integer;Wparam:Word;Lparam:Cardinal):Integer;stdcall
    - это бред.
    getWindowText(GetAncestor(send.hwnd,GA_ROOT),PansiChar(cap),255
    - тоже бред
    И вобще все это бред, потому что send:PCWPRETSTRUCT; - это указатель на TCWPRetStruct;
    Код (Text):
    1.  
    2. PCWPRetStruct = ^TCWPRetStruct;
    3.   tagCWPRETSTRUCT = packed record
    4.     lResult: LRESULT;
    5.     lParam: LPARAM;
    6.     wParam: WPARAM;
    7.     message: UINT;
    8.     hwnd: HWND;
    9.   end;
    10.   TCWPRetStruct = tagCWPRETSTRUCT;
    11.   CWPRETSTRUCT = tagCWPRETSTRUCT;
    Попробуй хотя бы так
    var
    Buf: Array[0..255] of AnsiChar;
    ...
    Len:=GetWindowText(send^.hwnd, @Buf[0], SizeOf(Buf));
    SetString(cap, Buf, Len);
    ...

    А вообще - это не те вещи, которые надо спрашивать на форумах...
     
  16. shurik

    shurik Александр

    Публикаций:
    0
    Регистрация:
    27 авг 2006
    Сообщения:
    52
    Адрес:
    Украина
    XshStasX
    Я бы поставил хук на WH_GETMESSAGE и обрабатывал сообщения WM_CREATE.
    Попробуй
    Код (Text):
    1. procedure SetHook(g:HWND);stdcall;
    2. begin
    3. h:=SetWindowsHookEx(WH_GETMESSAGE,@hookproc,HInstance,0);
    4. end;
    У тебя код процедуры хука как раз для WH_GETMESSAGE.

    Ну и конечно учти все вышеприведенные замечания :)
     
  17. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    И не только порядка для!
    Когда ещё моя учился юзать чистый API в Делфях, меня очень бесил тот факт, что в Win98 окно моей проги рисовалось на ура, а в WinXP постоянно пёрли глюки с перерисовкой. Я долго не мог понять в чём дело, пока однажды не сравнил тот DC окна, что выдавал мне GetDC, и тот, что передавался через WParam, который я, подобно топикстартеру (и прочитав об этом в литературе!!) проставил как Word. WParam содержал только младшее слово (что неудивительно!). Как известно, в Win98 стоит на кол-во хендлов жёсткое ограничение в 0FFFFh штук, чего в ХР нет. И DC это ещё не самое важное, что может быть в этом параме передано.

    Так что, граждане!
    SIZEOF WParam = 4
     
  18. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    А ни кто не знает где можна скачать учебники по Win API в Дельфи на руском?
    если такие есть конечно:)
    а то учебников по Win API в С++ много в интеренете а вот по на Дельфи я еще ги одной не нашол :dntknw:(
     
  19. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494