Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.04.17;
Скачать: CL | DM;

Вниз

Альтернатива SendMessage   Найти похожие ветки 

 
Игорь404   (2009-04-07 09:40) [0]

Уважаемые, существует ли альтернатива использованию конструкции SendMessage() для передачи сообщения объекту тестируемого приложения.

Дело в том, что данная конструкция не работает на практике, применительно к объектам следующих классов: TreeView и DateTimePicker (В тестируемом приложении используются модификации этих классов. SysTreeView32, SysDateTimePick32). Всевозможные варианты использования SendMessage() уже перебрал и не добился результатов. Неделя потраченного времени и нервов. Возможно существует другой способ отправки сообщений?
Существует ли возможность изменения значения (к примеру даты в DateTimePicker) через адреса памяти текущего процесса?
Заранее благодарен.


 
Медвежонок Пятачок ©   (2009-04-07 10:04) [1]

СендМессджу глубоко фиолетово, что там было модифицировано. Он как посылал сообщение окну, так и посылает.


 
Игорь Шевченко ©   (2009-04-07 10:54) [2]


> Дело в том, что данная конструкция не работает на практике


работает. применительно к объектам любых классов, лишь бы HWND был


 
Игорь404   (2009-04-07 11:40) [3]

Игорь, я пробовал следующие конструкции:
SendMessage(Win_Handle ,DTM_SETSYSTEMTIME, GDT_VALID, Longint(@stF) );где
stF: SYSTEMTIME;

 stF.wYear:= 2009;
 stF.wMonth:= 1;
 stF.wDay:= 11;
 stF.wHour:= 12;
 stF.wMinute:= 30;
 stF.wSecond:= 12;
 stF.wMilliseconds:= 0;

Применительно к приложению, они не работают.

Но вот, что интересно: конструкция
SendMessage(a,DTM_SETFORMAT,0, Longint(PChar(Edit1.Text)));отрабатывает и возвращает (1), но формат устанавливается "неправильный".


 
Игорь Шевченко ©   (2009-04-07 11:47) [4]

Э...тебе в другое приложение надо указатель передать через SendMessage ?

Так точно не получится, надо в другое приложение DLL внедрять


 
Игорь404   (2009-04-07 11:56) [5]

Да, именно, к внешнему процессу.
И sendMessage() работает в большенстве случаев. (Применительно к объектам ComboBox и EditText например).
И если это единственное решение, не мог бы поподробне рассказать (в контексте решаймой задачи)? А теорию я уже сам нарою.


 
Игорь Шевченко ©   (2009-04-07 12:46) [6]

Игорь404   (07.04.09 11:56) [5]


> Да, именно, к внешнему процессу.
> И sendMessage() работает в большенстве случаев. (Применительно
> к объектам ComboBox и EditText например).


Строки Windows умеет передавать между приложениями, а вот структуры - не умеет.


> И если это единственное решение, не мог бы поподробне рассказать
> (в контексте решаймой задачи)?


Подробнее в книге Рихтера "Windows для профессионалов", четвертое издание, глава 22.


 
Игорь404   (2009-04-07 12:50) [7]

Игорь, спасибо за столь точную ссылку. :) Иду читать...


 
DVM ©   (2009-04-07 16:03) [8]


> Игорь Шевченко ©   (07.04.09 12:46) [6]


> Строки Windows умеет передавать между приложениями, а вот
> структуры - не умеет.

WM_COPYDATA умеет


 
Игорь Шевченко ©   (2009-04-07 16:08) [9]

DVM ©   (07.04.09 16:03) [8]

К сожалению оконные классы, указанные в первом посте ветки на WM_COPYDATA не реагируют так, как хотелось бы автору.


 
аноним   (2009-04-07 21:26) [10]

Вот люди а, передают в чужой процесс указатель и ждут, что там появится его структура.


 
аноним   (2009-04-07 21:28) [11]

Что delphi делает с человеком ?!!!


 
guav ©   (2009-04-08 00:02) [12]


> Вот люди а, передают в чужой процесс указатель и ждут, что
> там появится его структура.

И вам читать Рихтера :-)


 
guav ©   (2009-04-08 00:07) [13]

Кстати, к сожалению из издания "Windows via C/C++" 2008 года убрана глава про сообщения.


 
Игорь Шевченко ©   (2009-04-08 00:26) [14]

guav ©   (08.04.09 00:07) [13]

У меня есть третье издание Windows для профессионалов (95-го года), так в четвертое тоже не все вошло и тоже выброшена часть по User (правда, сейчас не вспомню, какая), и выброшен хороший пример по синхронизации (Supermarket). Это к тому, что в очередном издании появится что-нибудь про особенности 128-разрядной Windows как там борятся с DLL Hell, но будет убрана например глава про Memory-mapped files...


 
guav ©   (2009-04-08 00:58) [15]

Кстати, ещё момент. В Висте ж появилось Address space layout randomization. В издании 2008 года оно упоминается. Но пример внедрения с CreateRemoteThread тоже имеется, и описание rebase тоже. Тема влияния ASLR на CreateRemoteThread не раскрыта.


 
аноним   (2009-04-08 08:23) [16]

>guav ©   (08.04.09 00:02) [12]
>И вам читать Рихтера :-)
Что именно ?


 
Человек   (2009-04-08 08:56) [17]


> guav ©   (08.04.09 00:58) [15]
> Кстати, ещё момент. В Висте ж появилось Address space layout
> randomization. В издании 2008 года оно упоминается. Но пример
> внедрения
> с CreateRemoteThread тоже имеется, и описание rebase тоже.
>
> Тема влияния ASLR на CreateRemoteThread не раскрыта.
>

А должно быть влияние ?


 
аноним   (2009-04-08 12:09) [18]


> И вам читать Рихтера :-)

Мало читать плохо, и много читать тоже вредно, начинает мерещиться всякое, всякое страшное и не возможное


 
guav ©   (2009-04-08 15:53) [19]

аноним   (08.04.09 08:23) [16]

> Что именно ?


Про маршаллинг сообщений.
Некоторые структуры таки оказываются "чудом" в чужом процессе. Все структуры сообщений, что меньше WM_USER.

Человек   (08.04.09 08:56) [17]

> А должно быть влияние ?

Нет, но это ж неочевидно ;-)


 
Rouse_ ©   (2009-04-08 15:57) [20]


> Так точно не получится, надо в другое приложение DLL внедрять

Библиотеку то зачем?


 
аноним   (2009-04-08 19:00) [21]


> Про маршаллинг сообщений.Некоторые структуры таки оказываются
> "чудом" в чужом процессе. Все структуры сообщений, что меньше
> WM_USER

Тут как раз таки никакого волшебства, система про эти сообщения знает, знает размер структуры или строки и копирует в адресное пространство все это.
В данном случае надо это делать самому, без магии все ручками
ИМХО тут WM_COPYDATA лучший вариант


 
Rouse_ ©   (2009-04-08 22:31) [22]

Никак не могу понять, чем WM_COPYDATA (будучи упомянутой уже дважды в данной ветке) может помочь при отправке того-же DTM_SETSYSTEMTIME?


 
Игорь Шевченко ©   (2009-04-08 22:51) [23]

Rouse_ ©   (08.04.09 22:31) [22]


> Никак не могу понять, чем WM_COPYDATA (будучи упомянутой
> уже дважды в данной ветке) может помочь при отправке того-
> же DTM_SETSYSTEMTIME?


ну если DTM_SETSYSTEMTIME не получается, может DateTimePicker на WM_COPYDATA согласится...


 
Игорь404   (2009-04-09 07:24) [24]

С WM_COPYDATA у меня таки ничего не получилось. Да даже еслиб и получилось, то как в этом случае быть с TreeView?


 
clickmaker ©   (2009-04-09 10:00) [25]

> даже еслиб и получилось, то как в этом случае быть с TreeView?

а почему тривью должно вдруг обрабатывать wm_copydata?


 
Rouse_ ©   (2009-04-09 10:10) [26]


> как в этом случае быть с TreeView?

Вот тебе старый пример работы с CommCtrl окнами в удаленном процессе, делай по аналогии:

////////////////////////////////////////////////////////////////////////////////
//
//  ****************************************************************************
//  * Unit Name : RemoteSysListView32
//  * Purpose   : Демо работы с удаленным SysListView32
//  * Author    : Александр (Rouse_) Багель
//  * Copyright : © Fangorn Wizards Lab 1998 - 2007
//  * Version   : 1.01
//  * Home Page : http://rouse.drkb.ru
//  ****************************************************************************
//

program RemoteSysListView32;

{$APPTYPE CONSOLE}

uses
 Windows,
 SysUtils,
 CommCtrl;

var
 hwndRemoteSysListView: HWND = 0;
 hProcess: THandle = 0;
 dwProcessID: DWORD = 0;
 dwBytesWriten: DWORD;
 nItemCount: Integer = 0;
 I, nTextLength: Integer;
 cchTextMax: Integer = 255;
 plviRemoteLVItem: PLVItem = nil;
 lviRemoteLVItem: LV_ITEM;
 pszText: PChar = nil;
 svText: ShortString;
 ARect: TRect;
 pRemoteRect: Pointer = nil;

 function GetFirstChild(hwndValue: HWND): HWND;
 begin
   Result := GetWindow(hwndValue, GW_CHILD);
 end;

 function Translate(Value: String): String;
 begin
   SetLength(Result, Length(Value));
   AnsiToOem(@Value[1], @Result[1]);
 end;

begin
 // Ищем SysListView32 рабочего стола
 hwndRemoteSysListView := GetFirstChild(GetFirstChild(FindWindow("ProgMan", nil)));
 if hwndRemoteSysListView = 0 then ExitProcess(GetLastError);

 // Получаем количество элементов (ярлыков на рабочем столе)
 nItemCount := ListView_GetItemCount(hwndRemoteSysListView);

 // Получаем ID процесса, которому принадлежит найденное окно
 GetWindowThreadProcessId(hwndRemoteSysListView, @dwProcessID);
 if dwProcessID = 0 then ExitProcess(GetLastError);

 // Открываем процесс
 hProcess := OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwProcessID);
 if hProcess = 0 then ExitProcess(GetLastError);

 // Выделяем в нем память под текстовый буффер
 pszText := VirtualAllocEx(hProcess, nil, cchTextMax,
  MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
 if GetLastError <> 0 then ExitProcess(GetLastError);

 // Выделяем в нем память под структуру LVITEM
 plviRemoteLVItem := VirtualAllocEx(hProcess, nil, SizeOf(LV_ITEM),
  MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
 if GetLastError <> 0 then ExitProcess(GetLastError);

 // Заполняем структуру
 ZeroMemory(@lviRemoteLVItem, SizeOf(LV_ITEM));
 lviRemoteLVItem.mask := LVIF_TEXT;
 lviRemoteLVItem.pszText := pszText;
 lviRemoteLVItem.cchTextMax := cchTextMax;

 // Пишем ее в память удаленного процесса
 if not WriteProcessMemory(hProcess, plviRemoteLVItem, @lviRemoteLVItem,
   SizeOf(LV_ITEM), dwBytesWriten) then ExitProcess(GetLastError);

 // Выделяем в нем память под структуру TRect
 pRemoteRect := VirtualAllocEx(hProcess, nil, SizeOf(TRect),
  MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
 if GetLastError <> 0 then ExitProcess(GetLastError);

 // Получаем текст со всех элементов
 for I := 0 to nItemCount - 1 do
 begin
   // Отправляем сообщение с указателем на выделенный буффер под LVITEM
   nTextLength := SendMessage(hwndRemoteSysListView, LVM_GETITEMTEXT,
     I, Integer(plviRemoteLVItem));

   // Читаем результат
   ZeroMemory(@svText, cchTextMax);
   ReadProcessMemory(hProcess, lviRemoteLVItem.pszText,
     @svText[1], nTextLength, dwBytesWriten);

   // Чтобы получить координаты каждого элемента нужно подготовить структуру
   ZeroMemory(@ARect, SizeOf(TRect));
   ARect.Left := LVIR_ICON;
   if not WriteProcessMemory(hProcess, pRemoteRect, @ARect,
     SizeOf(TRect), dwBytesWriten) then ExitProcess(GetLastError);

   // Посылаем сообщение для получения координат каждого элемента
   SendMessage(hwndRemoteSysListView, LVM_GETITEMRECT,
     I, Integer(pRemoteRect));

   // Читаем результат
   ReadProcessMemory(hProcess, pRemoteRect,
     @ARect, SizeOf(TRect), dwBytesWriten);

   Writeln(Translate(PChar(@svText[1])));
   Writeln(Translate(
     Format("- координаты: Left = %d, Top = %d, Right = %d, Bottom = %d",
       [ARect.Left, ARect.Top, ARect.Right, ARect.Bottom])));

 end;

 // Освобождаем ранее выделенную память
 VirtualFreeEx(hProcess, pszText, 0, MEM_RELEASE);
 VirtualFreeEx(hProcess, plviRemoteLVItem, 0, MEM_RELEASE);

 // Закрываем описатель процесса
 CloseHandle(hProcess);

 Readln;
end.


 
Игорь404   (2009-04-09 13:26) [27]

Дело в том, что элементов управления очень много и придется адаптировать код к каждому отдельно (или адаптировать ко всем сразу).

Но вот на что я наткнулся
"Внедрение библиотеки через CreateRemoteThread"
http://delphisite.ru/faq/vnedrenie-biblioteki-cherez-createremotethread
Выполнение собственного кода в чужом процессе.

Осталось только взвесить эти два варианта на предмет трудоемкости и выбрать наиболее гибкое и легкореализуемое...


 
Rouse_ ©   (2009-04-09 13:32) [28]

Из пушки по воробьям :) Хотя... хозяин барин.

ЗЫ: Если что - то этот пример (по ссылке) нормально выгружается только из своего собственного процесса, более полный вариант этой демки можешь взять тут: http://forum.sources.ru/index.php?showtopic=248156&st=0&#entry2057057


 
Игорь404   (2009-04-09 14:19) [29]

Наверное много времени бы потратил на отладку :)

К счастью человек эволюционирует и на смену рогаткам, с чрезвычайно узким спектром применения, приходят мелкокалиберные винтовки, с ненамного большим, но однако же большим. И все это я к тому, что не факт что только по "воробьям", если ты меня понимаешь. :) В мое случае приложение должно быть достаточно гибким, чтобы в перспективе была возможноть оперативно изменять его согласно новым требованиям. Мне кажется в случае с DLL injection приложение будет обладать достаточной гибкостью и масштабируюмостью.


 
аноним   (2009-04-09 15:29) [30]


> Никак не могу понять, чем WM_COPYDATA (будучи упомянутой
> уже дважды в данной ветке) может помочь при отправке того-
> же DTM_SETSYSTEMTIME?

Привилегий хватит писать в память чужого процесса ? Как Виста на такое отреагирует и Вин7 (я точно не знаю)?
Лучше переписать прогу чтобы она принимала WM_COPYDATA и не волноваться за будующее


 
Игорь Шевченко ©   (2009-04-09 20:30) [31]


> Лучше переписать прогу чтобы она принимала WM_COPYDATA и
> не волноваться за будующее


DateTimePicker переписать или TreeView ?


 
аноним   (2009-04-10 04:15) [32]


> DateTimePicker переписать или TreeView ?

Такие откровенные глупости писать не надо. Хорошо ?
Я понимаю делфи и все такое, но есть же предел в конце концов.


 
Rouse_ ©   (2009-04-10 09:11) [33]


> Такие откровенные глупости писать не надо. Хорошо ?

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


 
Игорь404   (2009-04-10 11:41) [34]

Возможно я ввел кого-то в заблуждение, но к коду тестируемого приложения доступа нет.


 
аноним   (2009-04-10 13:36) [35]


> Хорошо, не будем - только и ты плз глупости не пиши о переписывании
> программы и читай внимательней, желательно с самого начала.
>  Приложение чужое, поэтому у тебя и спрашивают, что именно
> в чужом приложении стоит переписать?

Где там сказано, что код чужой ? Там сказано, что процесс другой.


 
Игорь404   (2009-04-10 15:11) [36]

Задача решена. Я внедрил DLL в процесс тестируемого приложения и передал ему
SendMessage(handle, DTM_SETSYSTEMTIME, GDT_VALID, Longint(@dateTime));
теперь все работает, не тестировал еще с TreView, но думаю и здесь проблем не будет.
Осталось решить проблему с адаптированием DLLки к разным элементам управления, но это уже другая история.

p.s. Ради таких минут мы и живем друзья, спасибо! :)


 
имя   (2009-07-13 13:10) [37]

Удалено модератором



Страницы: 1 вся ветка

Текущий архив: 2011.04.17;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.01 c
15-1294009604
Германн
2011-01-03 02:06
2011.04.17
Бред и I/O Error 1784


15-1293744604
Юрий
2010-12-31 00:30
2011.04.17
С днем рождения ! 31 декабря 2010 пятница


15-1293565837
TUser
2010-12-28 22:50
2011.04.17
Почему эбонит электризуется при натерании об шерсть?


2-1295254611
RUu
2011-01-17 11:56
2011.04.17
initialization и finalization в модуле


15-1293831003
Юрий
2011-01-01 00:30
2011.04.17
С днем рождения ! 1 января 2011 суббота