Всем известна утилита SPYXX. С помощью нее можно делать много чего интересного. В числе ее возможностей - просмотр сообщений отправленных окну и результаты их обработки. Я решил сделать что-то подобное только на VB6 (не в качестве создания программы типа SPYXX, а в качестве демонстрации возможности внедрения кода из VB6, так что функционал проги очень маленький). Как известно SPYXX делает это с помощью глобальных хуков, но мне была интересна идея внедрения без DLL (c DLL все гораздо проще можно сделать, у Рихтера описано как можно несколькими функциями внедрится в чужой код с помощью DLL) и я решил сделать немного по другому. В моем примере код вместе с оконной процедурой непосредственно копируется в АП нужного процесса и там запускается (работает только с 32 разрядными приложениями). Там я размещаю код, который устанавливает новую процедуру обработки сообщений, для окна и усыпляю поток. В новой процедуре, я всего лиш передаю параметры, которые получило чужое окно, моему окну (frmSpy), далее вызывается оригинальная процедура окна. Скажу сразу - передача осуществляется не самым эффективным способом, можно было сделать гораздо эффективнее напрямую работая с FileMapping'ом, либо асинхронно передавать 2 сообщения подряд. Но я не стал заморачиваться лишним кодом, т.к. моя конечная цель не эффективность. Отмена инъекции осуществляеться пробуждением потока и завершению его естественным образом, после чего из своей программы я освобождаю ресурсы. Работу я проверял в отладчике все работает, как и задумывалось.
При работе в другом процессе, вообще не используется рантайм, хотя можно его загрузить и использовать (про инициализацию контекста потока отдельно) его функции, массивы строки и т.п. Также возникает проблема работы с переменными, т.к. глобальных переменных "не существует", и соответственно обращение к любым таким переменным может оказаться фатальным для всего процесса. Для вызова API я использую сплайсинг "псевдофункций API", заменяю вызов на безусловный переход к нужной функции. Работа с переменными осуществляеться в выделенной для этого области. Для того чтобы ее сохранить я использую SetProp, т.к. из WindowProc я могу что-то идентифицировать только через hWnd. Если надо добавить еще какие-либо глобальные переменные, то можно в этой области выделить место под строки и т.п. (например для вызова LoadLibrary с нужным параметром). Если бы в VB была непосредственная работа с указателями (без VarPtr, GetMem и т.п. функций), то было намного проще. Можно делать сразу ассемблерный переходник и в нем можно узнать значения переменных переданных в поток без SetProp и CopyMemory, но это детали, кто захочет - тот сделает.
PS Работает все только в скомпилированном (native) виде.