Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2011.04.17;
Скачать: [xml.tar.bz2];

Вниз

Альтернатива 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 вся ветка

Форум: "WinAPI";
Текущий архив: 2011.04.17;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.006 c
2-1295246151
NUser
2011-01-17 09:35
2011.04.17
Показать сообщение "недопустимый символ"


15-1293912187
NewUserWin7
2011-01-01 23:03
2011.04.17
Win 7 - параметры папки


15-1293447297
GanibalLector
2010-12-27 13:54
2011.04.17
Распознавания рукописных символов (FlexiCapture + Delphi)


2-1295269594
Евгений07
2011-01-17 16:06
2011.04.17
дельфи игнорирует файл источник


15-1293597688
Curse
2010-12-29 07:41
2011.04.17
Профсоюз IT





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский