Ответ 1
Как работает Spy ++ - это некая публичная тайна, вы можете легко сказать, когда вы запускаете Dumpbin.exe /imports
в .exe файле. Для spyxx_amd64.exe(64-разрядная версия) наиболее важными элементами являются:
SPYXXHK_AMD64.DLL
...
3 SpyxxCallWndRetProc
2 SpyxxCallWndProc
4 SpyxxGetMsgProc
USER32.dll
...
320 SetWindowsHookExW
31F SetWindowsHookExA
Другими словами, он использует SetWindowsHookEx() для установки 3 крючков, WH_CALLWNDPROC, WH_CALLWNDPROCRET и WH_GETMESSAGE. Spyxxhk_amd64.dll - это DLL, которая вводится в каждый процесс, содержит обратные вызовы hook.
Обратите внимание, что он использует как Unicode, так и Ansi-версию SetWindowsHookEx(). Один из способов, которым можно легко объяснить, - это когда он использует версию Ansi (SetWindowsHookExA) в вашем окне Unicode. Такой крючок может наблюдать только версию Ansi сообщения WM_CHAR.
Имейте в виду, что Spy ++ не может решить проблему, когда вы запускаете процессы на своем рабочем столе, которые содержат окна Unicode и Ansi, что не является чем-то необычным, и не может сохранить их всех счастливыми. Самое простое предположение состоит в том, что он просто пьет для SetWindowsHookExA как самый низкий общий знаменатель.
Фактически доказательство того, что Spy ++ получает это неправильно, намного сложнее сделать, и я долгое время его откладывал. Любая попытка поймать Spy ++, устанавливая крючки при ее использовании, оказалась бюстом, крючки устанавливаются очень рано при запуске программы. Метод отладки, который я в конце концов обнаружил:
- Сначала я нашел исходную точку входа api
NtUserSetWindowHookEx
, разобрав код для SetWindowsHookExW. На моей машине (Win8.1) она находится на 0x00007FFECC3BA970. - Запущен VS повышенный уровень, необходимый для запуска Spy ++.
- Файл + Открыть + Проект/Решение и выберите Spyxx_amd64.exe.
- Отладка + шаг. Это запускает программу и находит точку выполнения в AfxWinMain (Spy ++ был написан в библиотеке MFC).
- Отладка + Windows + Разборка, вставьте 0x00007FFECC3BA970 в поле адреса
- Установите точку останова по этому адресу. Нажмите F5
Есть два ложных удара, MFC использует SetWindowsHookExW() внутри. Но затем он загорается, три удара, которые выглядят примерно так:
user32.dll!NtUserSetWindowsHookEx()
user32.dll!_SetWindowsHookEx() + 0x5b bytes
user32.dll!SetWindowsHookExAW() + 0x5b bytes
user32.dll!SetWindowsHookExA() + 0x11 bytes
spyxx_amd64.exe!SetMsgHook() + 0x6a bytes
spyxx_amd64.exe!HookMain() + 0x470 bytes
msvcr120.dll!_callthreadstart() Line 257 C
msvcr120.dll!_threadstart(void * ptd) Line 237 + 0x5 bytes C
kernel32.dll!BaseThreadInitThunk() + 0xd bytes
ntdll.dll!RtlUserThreadStart() + 0x34 bytes
Что является доказательством, вы можете видеть, что вызывается SetWindowsHookExA(). Версия Ansi, Spy ++ может отображать только версию Ansi сообщения WM_CHAR.