-
Уважаемые, существует ли альтернатива использованию конструкции SendMessage() для передачи сообщения объекту тестируемого приложения.
Дело в том, что данная конструкция не работает на практике, применительно к объектам следующих классов: TreeView и DateTimePicker (В тестируемом приложении используются модификации этих классов. SysTreeView32, SysDateTimePick32). Всевозможные варианты использования SendMessage() уже перебрал и не добился результатов. Неделя потраченного времени и нервов. Возможно существует другой способ отправки сообщений? Существует ли возможность изменения значения (к примеру даты в DateTimePicker) через адреса памяти текущего процесса? Заранее благодарен.
-
СендМессджу глубоко фиолетово, что там было модифицировано. Он как посылал сообщение окну, так и посылает.
-
> Дело в том, что данная конструкция не работает на практике
работает. применительно к объектам любых классов, лишь бы HWND был
-
Игорь, я пробовал следующие конструкции: 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), но формат устанавливается "неправильный".
-
Э...тебе в другое приложение надо указатель передать через SendMessage ?
Так точно не получится, надо в другое приложение DLL внедрять
-
Да, именно, к внешнему процессу. И sendMessage() работает в большенстве случаев. (Применительно к объектам ComboBox и EditText например). И если это единственное решение, не мог бы поподробне рассказать (в контексте решаймой задачи)? А теорию я уже сам нарою.
-
Игорь404 (07.04.09 11:56) [5]
> Да, именно, к внешнему процессу. > И sendMessage() работает в большенстве случаев. (Применительно > к объектам ComboBox и EditText например).
Строки Windows умеет передавать между приложениями, а вот структуры - не умеет.
> И если это единственное решение, не мог бы поподробне рассказать > (в контексте решаймой задачи)?
Подробнее в книге Рихтера "Windows для профессионалов", четвертое издание, глава 22.
-
Игорь, спасибо за столь точную ссылку. :) Иду читать...
-
> Игорь Шевченко © (07.04.09 12:46) [6]
> Строки Windows умеет передавать между приложениями, а вот > структуры - не умеет.
WM_COPYDATA умеет
-
DVM © (07.04.09 16:03) [8]
К сожалению оконные классы, указанные в первом посте ветки на WM_COPYDATA не реагируют так, как хотелось бы автору.
-
Вот люди а, передают в чужой процесс указатель и ждут, что там появится его структура.
-
Что delphi делает с человеком ?!!!
-
> Вот люди а, передают в чужой процесс указатель и ждут, что > там появится его структура.
И вам читать Рихтера :-)
-
Кстати, к сожалению из издания "Windows via C/C++" 2008 года убрана глава про сообщения.
-
guav © (08.04.09 00:07) [13]
У меня есть третье издание Windows для профессионалов (95-го года), так в четвертое тоже не все вошло и тоже выброшена часть по User (правда, сейчас не вспомню, какая), и выброшен хороший пример по синхронизации (Supermarket). Это к тому, что в очередном издании появится что-нибудь про особенности 128-разрядной Windows как там борятся с DLL Hell, но будет убрана например глава про Memory-mapped files...
-
Кстати, ещё момент. В Висте ж появилось Address space layout randomization. В издании 2008 года оно упоминается. Но пример внедрения с CreateRemoteThread тоже имеется, и описание rebase тоже. Тема влияния ASLR на CreateRemoteThread не раскрыта.
-
>guav © (08.04.09 00:02) [12] >И вам читать Рихтера :-) Что именно ?
-
> guav © (08.04.09 00:58) [15] > Кстати, ещё момент. В Висте ж появилось Address space layout > randomization. В издании 2008 года оно упоминается. Но пример > внедрения > с CreateRemoteThread тоже имеется, и описание rebase тоже. > > Тема влияния ASLR на CreateRemoteThread не раскрыта. >
А должно быть влияние ?
-
> И вам читать Рихтера :-)
Мало читать плохо, и много читать тоже вредно, начинает мерещиться всякое, всякое страшное и не возможное
-
аноним (08.04.09 08:23) [16]
> Что именно ?
Про маршаллинг сообщений. Некоторые структуры таки оказываются "чудом" в чужом процессе. Все структуры сообщений, что меньше WM_USER.
Человек (08.04.09 08:56) [17]
> А должно быть влияние ?
Нет, но это ж неочевидно ;-)
-
> Так точно не получится, надо в другое приложение DLL внедрять
Библиотеку то зачем?
-
> Про маршаллинг сообщений.Некоторые структуры таки оказываются > "чудом" в чужом процессе. Все структуры сообщений, что меньше > WM_USER
Тут как раз таки никакого волшебства, система про эти сообщения знает, знает размер структуры или строки и копирует в адресное пространство все это. В данном случае надо это делать самому, без магии все ручками ИМХО тут WM_COPYDATA лучший вариант
-
Никак не могу понять, чем WM_COPYDATA (будучи упомянутой уже дважды в данной ветке) может помочь при отправке того-же DTM_SETSYSTEMTIME?
-
Rouse_ © (08.04.09 22:31) [22]
> Никак не могу понять, чем WM_COPYDATA (будучи упомянутой > уже дважды в данной ветке) может помочь при отправке того- > же DTM_SETSYSTEMTIME?
ну если DTM_SETSYSTEMTIME не получается, может DateTimePicker на WM_COPYDATA согласится...
-
С WM_COPYDATA у меня таки ничего не получилось. Да даже еслиб и получилось, то как в этом случае быть с TreeView?
-
> даже еслиб и получилось, то как в этом случае быть с TreeView?
а почему тривью должно вдруг обрабатывать wm_copydata?
-
> как в этом случае быть с TreeView?
Вот тебе старый пример работы с CommCtrl окнами в удаленном процессе, делай по аналогии:
program RemoteSysListView32;
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
hwndRemoteSysListView := GetFirstChild(GetFirstChild(FindWindow('ProgMan', nil)));
if hwndRemoteSysListView = 0 then ExitProcess(GetLastError);
nItemCount := ListView_GetItemCount(hwndRemoteSysListView);
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);
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);
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
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.
-
Дело в том, что элементов управления очень много и придется адаптировать код к каждому отдельно (или адаптировать ко всем сразу). Но вот на что я наткнулся "Внедрение библиотеки через CreateRemoteThread" http://delphisite.ru/faq/vnedrenie-biblioteki-cherez-createremotethreadВыполнение собственного кода в чужом процессе. Осталось только взвесить эти два варианта на предмет трудоемкости и выбрать наиболее гибкое и легкореализуемое...
-
-
Наверное много времени бы потратил на отладку :)
К счастью человек эволюционирует и на смену рогаткам, с чрезвычайно узким спектром применения, приходят мелкокалиберные винтовки, с ненамного большим, но однако же большим. И все это я к тому, что не факт что только по "воробьям", если ты меня понимаешь. :) В мое случае приложение должно быть достаточно гибким, чтобы в перспективе была возможноть оперативно изменять его согласно новым требованиям. Мне кажется в случае с DLL injection приложение будет обладать достаточной гибкостью и масштабируюмостью.
-
> Никак не могу понять, чем WM_COPYDATA (будучи упомянутой > уже дважды в данной ветке) может помочь при отправке того- > же DTM_SETSYSTEMTIME?
Привилегий хватит писать в память чужого процесса ? Как Виста на такое отреагирует и Вин7 (я точно не знаю)? Лучше переписать прогу чтобы она принимала WM_COPYDATA и не волноваться за будующее
-
> Лучше переписать прогу чтобы она принимала WM_COPYDATA и > не волноваться за будующее
DateTimePicker переписать или TreeView ?
-
> DateTimePicker переписать или TreeView ?
Такие откровенные глупости писать не надо. Хорошо ? Я понимаю делфи и все такое, но есть же предел в конце концов.
-
> Такие откровенные глупости писать не надо. Хорошо ?
Хорошо, не будем - только и ты плз глупости не пиши о переписывании программы и читай внимательней, желательно с самого начала. Приложение чужое, поэтому у тебя и спрашивают, что именно в чужом приложении стоит переписать?
-
Возможно я ввел кого-то в заблуждение, но к коду тестируемого приложения доступа нет.
-
> Хорошо, не будем - только и ты плз глупости не пиши о переписывании > программы и читай внимательней, желательно с самого начала. > Приложение чужое, поэтому у тебя и спрашивают, что именно > в чужом приложении стоит переписать?
Где там сказано, что код чужой ? Там сказано, что процесс другой.
-
Задача решена. Я внедрил DLL в процесс тестируемого приложения и передал ему SendMessage(handle, DTM_SETSYSTEMTIME, GDT_VALID, Longint(@dateTime)); теперь все работает, не тестировал еще с TreView, но думаю и здесь проблем не будет. Осталось решить проблему с адаптированием DLLки к разным элементам управления, но это уже другая история.
p.s. Ради таких минут мы и живем друзья, спасибо! :)
-
Удалено модератором
|