![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как заставить GUI thread создать нужное мне окно?
Leonid Troyanovsky © (2009-11-24 15:13:00)Хочется, чтобы GUI thread (моего процесса или
чужого) создал нужное мне окно (ThreadID есть).
Это окно буду пользовать для исполнения нужного мне
кода в контексте этого потока путем обработки сообщений,
посланных через SendMessage (отправлять умею).
Доступа к исходникам этого приложения у меня нет,
но мой код не вредоносный (мамой клянусь), бо,
это скины всяки-разны, собс-ручный маршаллинг
и проч. фигня (подробности могу почтой).
Прошу уважаемую общественность пнуть мну
в нужном направлении, бо облазив весь гугль
натыкался лишь на сомнительные варианты с debug API.
Печенкой чую, что искомое где-то рядом,
но, наверное, позабыл как его звать.
--
Regards, LVT.
SPeller (2009-11-25 05:24:00) [21]Немного поправил, сделал перечисление всех окон и в цикле потом слать им сообщения пока окно не создастся. Еще мания у меня какая-то суспендить поток. Тут это сделал для того, чтобы немного снизить шансы изменения списка окон во время перечисления. Может, я опять всё усложняю? :) Наверное, хотябы одно, главное окно в потоке будет и на нем SendMessage отработает.
SPeller (2009-11-25 02:38:00) [22]Спасибо за то, что про хуки напомнили, как же я о них забыл-то? :)
Накидал вот такой код:
function CreateWndInThread(idTarget: Cardinal; WndProc: Pointer): HWND;
implementation
var
HookCS: TRTLCriticalSection;
HHK: HHOOK;
TargetTHreadID: Cardinal;
NewWnd: HWND;
NewWndCreating: Boolean;
function EnumThreadWndProc(hwnd: HWND; lParam: PInteger): BOOL; stdcall;
begin
lParam^ := hwnd;
Result := False;
end;
function HookWndProc(nCode, wParam, lParam: Integer): Integer; stdcall;
begin
if (nCode >= HC_ACTION) then
begin
if (NewWnd = 0) and not NewWndCreating and (GetCurrentThreadId = TargetTHreadID) then
begin
NewWndCreating := True;
NewWnd :=
CreateWindow(
'STATIC', 'Test window', WS_VISIBLE, 0, 0, 200, 200, 0, 0, HInstance, nil);
NewWndCreating := False;
end;
Result := CallNextHookEx(HHK, nCode, wParam, lParam);
end
else
Result := CallNextHookEx(HHK, nCode, wParam, lParam);
end;
function CreateWndInThread(idTarget: Cardinal; WndProc: Pointer): HWND;
var
enumResult: HWND;
hTarget: THandle;
begin
Result := 0;
hTarget := OpenThread(THREAD_ALL_ACCESS, False, idTarget);
HookCS.Enter;
TargetTHreadID := idTarget;
try
try
try
SuspendThread(hTarget);
try
enumResult := 0;
EnumThreadWindows(idTarget, @EnumThreadWndProc, Integer(@enumResult));
if (enumResult = 0) then
raise Exception.Create('No windows in the thread');
HHK := SetWindowsHookEx(WH_CALLWNDPROC, @HookWndProc, HInstance, idTarget);
finally
ResumeThread(hTarget);
end;
SendMessage(enumResult, WM_USER + 1, 0, 0);
if (NewWnd = 0) then
raise Exception.Create('Failed to create window');
Result := NewWnd;
NewWnd := 0;
SetWindowLong(Result, GWL_WNDPROC, Integer(WndProc));
finally
TargetTHreadID := 0;
UnhookWindowsHookEx(HHK);
HHK := 0;
end;
except
DestroyWindow(NewWnd);
NewWnd := 0;
raise;
end;
finally
HookCS.Leave;
CloseHandle(hTarget);
end;
end;
initialization
HookCS.Initialize;
finalization
HookCS.Destroy;
Тут, конечно, если нет еще окон в потоке, то ничего и не выйдет, но и и предыдущий мой вариант тоже оказался бы бессилен. Окно бы он создал, но без цикла выборки очереди сообщений смысл окна теряется.
Eraser (2009-11-25 00:38:00) [23]если интересует готовая реализация на делфи, то вот http://www.wasm.ru/author.php?author=Ms-Rem
Leonid Troyanovsky (2009-11-24 22:51:00) [24]
> Игорь Шевченко © (24.11.09 22:35) [17]
> через хуки, через CreateRemoteThread, но примеры только
> те, что я перечислил :)
Да, давненько я не брал в руки шашки.
Т.е., мелкие тексты - в инете, а крупнее - в ебук.
Как в том анекдоте: мелкую рыбу отпускаем,
а крупную - складываем в майонезную банку.
--
Regards, LVT.
Игорь Шевченко (2009-11-24 22:35:00) [25]Leonid Troyanovsky © (24.11.09 22:29) [16]
Рихтер много рассказывает о путях внедрения, через AppInit_DLL, через хуки, через CreateRemoteThread, но примеры только те, что я перечислил :)
Leonid Troyanovsky (2009-11-24 22:29:00) [26]
> Игорь Шевченко © (24.11.09 22:15) [15]
> Во втором издании гарантировано не было проводника :)
Всё-всё, сдаюсь.
Значит, back orifice only.
Противно.
Хотя, по-крайней мере, знаем, откуда ноги растут :)
--
Regards, LVT.
Игорь Шевченко (2009-11-24 22:15:00) [27]Leonid Troyanovsky © (24.11.09 22:13) [14]
Во втором издании гарантировано не было проводника :) Третье издание относится к Windows 95 и Windows NT 3.5
Leonid Troyanovsky (2009-11-24 22:13:00) [28]
> Игорь Шевченко © (24.11.09 21:47) [13]
> примеров создания окон в проводнике в этой главе (22) нет
Вот, опять :(
Казалось ведь, что хорошо помнилось.
Sorry.
Т.е., ДР тут ни причем.
А может второе издание? :)
--
Regards, LVT.
Игорь Шевченко (2009-11-24 21:47:00) [29]Leonid Troyanovsky © (24.11.09 19:53) [12]
Рихтер описывает внедрение DLL в чужой процесс
При этом он (в четвертом издании):
1. сохраняет позиции икон на рабочем столе.
2. создает список всех DLL загруженных чужим процессом.
примеров создания окон в проводнике в этой главе (22) нет :)
В третьем издании он разворачивает окно Program Manager, когда закрыто последнее пользовательское приложение и тоже создает список DLL чужого процесса.
Leonid Troyanovsky (2009-11-24 19:53:00) [30]
> Игорь Шевченко © (24.11.09 19:27) [11]
> "Внедрение DLL с помощью ловушек", страница 537
Т.е., окна в проводнике он не создавал?
--
Regards, LVT.
Игорь Шевченко (2009-11-24 19:27:00) [31]Leonid Troyanovsky © (24.11.09 18:15) [9]
>
> Игорь, если книга под рукой, посмотри, плиз,
> а то опять буду думать, что напутал.
"Внедрение DLL с помощью ловушек", страница 537
Рихтер, Windows для профессионалов, 4-ое издание
Leonid Troyanovsky (2009-11-24 18:18:00) [32]
> Игорь Шевченко © (24.11.09 17:50) [8]
> Так исходники в сети есть - он не так просто делает, как
> кажется поначалу.
С вертолета, танка - это все неспортивно :)
Ну, ладно, как доделаю, кину сюда, если никто не против.
--
Regards, LVT.
Leonid Troyanovsky (2009-11-24 18:15:00) [33]
> Anatoly Podgoretsky © (24.11.09 16:43) [6]
> И молчит?
Не, он отписался еще в третьем издании.
Но, я ту книгу давно утратил, сейчас где-нибудь поищу.
> Игорь Шевченко © (24.11.09 17:47) [7]
> Не, он сообщения ему отсылал, чтобы иконы упорядочить. Окон
> он не создавал.
Игорь, если книга под рукой, посмотри, плиз,
а то опять буду думать, что напутал.
--
Regards, LVT.
Игорь Шевченко (2009-11-24 17:50:00) [34]Leonid Troyanovsky © (24.11.09 16:25) [3]
> > как делает back orifice ?
>
> Ну, вроде того :)
Так исходники в сети есть - он не так просто делает, как кажется поначалу.
Игорь Шевченко (2009-11-24 17:47:00) [35]Leonid Troyanovsky © (24.11.09 16:25) [3]
> Так и Джеф Рихтер делал, окно в проводнике, ЕМНИП.
Не, он сообщения ему отсылал, чтобы иконы упорядочить. Окон он не создавал.
Anatoly Podgoretsky (2009-11-24 16:43:00) [36]> Leonid Troyanovsky (24.11.2009 16:25:03) [3]
И молчит?
Leonid Troyanovsky (2009-11-24 16:34:00) [37]Всем участникам спасибо!
Проблема решилась:
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1258675071&n=5
Будет время, направлю в фак какой-нить.
--
Regards, LVT.
Leonid Troyanovsky (2009-11-24 16:31:00) [38]
> DVM © (24.11.09 16:16) [2]
> Если коротко, нужно создать окно с требуемыми характеристиками
> в потоке чужого процесса?
Ну, да :)
Я даже стили некоторые знаю, message-only.
Решил, вот, выправить кривой топик.
А то, может, и, впрямь, высокомерен был.
--
Regards, LVT.
Leonid Troyanovsky (2009-11-24 16:25:00) [39]
> Игорь Шевченко © (24.11.09 15:55) [1]
> как делает back orifice ?
Ну, вроде того :)
Так и Джеф Рихтер делал, окно в проводнике, ЕМНИП.
--
Regards, LVT.
DVM (2009-11-24 16:16:00) [40]
> Leonid Troyanovsky ©
Если коротко, нужно создать окно с требуемыми характеристиками в потоке чужого процесса?