Что нового

Обмен данными между процессами

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Kaster
Я переводил уже на translate.google.ru. После фразы
Если установить скрипт работает в потоке будет Pack1Creator объекта доступны через имен Творца.
надолго задумался... :smile:
 
Автор
kaster

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
madmasles
на самом деле в этом предложении и на английском каша ;D
ну в смысле запятые утеряны. вот правильный перевод
AddCreator Логический: Если установлен (полагаю, равен 1), то запушенный скрипт в треде будет доступен из пространства имен Creator посредством объекта Pack1Creator
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Kaster
Если честно, то я и из правильного перевода мало что понял, азов не хватает... :'(
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Yashied [?]
доступ к памяти первого процесса, второй процесс не получит и, соответственно, структуру прочесть не сможет.
А вот интересно, по сути указатель это же адресс в памяти процесса, неужели нельзя прочитать участок памяти (имея адрес) во внешнем процессе?
Кажется ботоводы это успешно делают...
 

VladUs

Скриптер
Сообщения
621
Репутация
182
CreatoR [?]
А вот интересно
Честно говоря мне тоже это интересно...
Существуют же функции для работы с памятью, в том числе и чужого процесса,
Я говорю о _WinAPI_WriteProcessMemory() и _WinAPI_ReadProcessMemory()
Есть даже библиотека "NomadMemory.au3", которая облегчает процесс считывания и записи данных в память чужего процесса.
Да и к тому же, как тогда работает OLLYDBG, она ведь захватывает полностью код процесса в памяти.... :scratch:
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
VladUs [?]
Существуют же функции для работы с памятью, в том числе и чужого процесса
Пробовал сделать так:

Sender.au3
Код:
#include <Container.au3>

$oContainer = _Container_Open("storage", 1)

$st = DllStructCreate("float var;")
DllStructSetData($st, "var", 5)
$ptr = DllStructGetPtr($st)

_Container_PutProperty($oContainer, "ptr", Hex($ptr))
_Container_PutProperty($oContainer, "pid", @AutoItPID)

MsgBox(64, "", "Значения установлены. Теперь, не закрывая это сообщение, запустите 2.au3")


Reciever.au3
Код:
#include <Container.au3>
#include <WinAPI.au3>
#Include <ProcessConstants.au3>

$oContainer = _Container_Open("storage", 0)

$ptr = _Container_GetProperty($oContainer, "ptr")
$iPID = _Container_GetProperty($oContainer, "pid")
$stBuffer = DllStructCreate("float")
$iRead = 0
$hProc = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, True, Int($iPID)); get access to read/write/anything the process memory
_WinAPI_ReadProcessMemory($hProc, Ptr($ptr), DllStructGetPtr($stBuffer), 8, $iRead)

ConsoleWrite(DllStructGetData($stBuffer, 1) & ":" & $iRead & @LF)

для запуска требуется Container.au3 ;)

Но увы, результат почти никакой :(
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Yashied [?]
Структура - это область выделенной памяти в пределах процесса. Естественно, часть памяти нельзя передать в другой процесс, только данные.
Вот тут есть пример где это успешно делается (передача указателя с посылающего процесса, и чтение памяти по этому указателю из принимающего процесса).

Внимание вопрос (тебе как знатоку WinAPI :smile:):
Как это приспособить к Container UDF?

Пробовал так (по аналогий того примера с офф. сайта):

Sender.au3:
Код:
#include <Container.au3>
#include <WinAPI.au3>

$oContainer = _Container_Open("storage", 1)

$st = DllStructCreate("int var1;uint var2")
DllStructSetData($st, "var1", 1)
$ptr = DllStructGetPtr($st)

_Container_PutProperty($oContainer, "pid", @AutoItPID)
_Container_PutProperty($oContainer, "ptr", Hex($ptr))

MsgBox(64, "", "Значения установлены. Теперь, не закрывая это сообщение, запустите Reciever.au3")


Reciever.au3:
Код:
#include <Container.au3>
#include <WinAPI.au3>

$oContainer = _Container_Open("storage", 0)

$pid = Int(_Container_GetProperty($oContainer, "pid"))
$ptr = Ptr(_Container_GetProperty($oContainer, "ptr"))

$struct = Read_Pointer_FromProcessMemory($pid, $ptr, "int var1;uint var2")

ConsoleWrite(VarGetType($struct) & ":" & @error & ":" & DllStructGetData($struct, "var1") & @LF)

Func Read_Pointer_FromProcessMemory($ProcessID, $Pointer, $StructTag)
	Local $iSYNCHRONIZE = (0x00100000), $iSTANDARD_RIGHTS_REQUIRED = (0x000F0000)
	Local $iPROCESS_ALL_ACCESS = ($iSTANDARD_RIGHTS_REQUIRED + $iSYNCHRONIZE + 0xFFF)
	Local $hProcess, $Struct, $StructPtr, $StructSize, $iRead
	$hProcess = _WinAPI_OpenProcess($iPROCESS_ALL_ACCESS, False, $ProcessID)
	If @error Then Return SetError(@error, 1, $Struct)
	$Struct = DllStructCreate($StructTag)
	$StructSize = DllStructGetSize($Struct)
	$StructPtr = DllStructGetPtr($Struct)
	_WinAPI_ReadProcessMemory($hProcess, $Pointer, $StructPtr, $StructSize, $iRead)
	Return SetError(@error, $iRead, $Struct)
EndFunc


Результат: DllStruct:0:0
:(


P.S
_WinAPI_ReadProcessMemory возвращает 0, как впрочем и $iRead (задаётся в @extended), но вот @error почему то 0.
В чём проблема, как оно там работает, у ткт нет? :scratch:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
CreatoR сказал(а):
В чём проблема...

В преобразовании типов. Int(), Hex() и т.д., зачем все это?

Sender.au3
Код:
_Container_PutProperty($oContainer, "pid", @AutoItPID)
_Container_PutProperty($oContainer, "ptr", Number($ptr))


Reciever.au3
Код:
$pid = _Container_GetProperty($oContainer, "pid")
$ptr = _Container_GetProperty($oContainer, "ptr")


А вот "Ptr" почему-то твой Container UDF не понимает... Баг? А еще я советую проверит этот метод из под учетной записи простого пользователя (не администратора). Ну, и в x64...
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Yashied [?]
В преобразовании типов
Супер, работает!

Потому что...
"Ptr" почему-то твой Container UDF не понимает
;)

Можно правда добавить проверку на Ptr:

Код:
Func _Container_PutProperty($oContainer, $sVarName, $vValue)
	If IsPtr($vValue) Then
		$vValue = Number($vValue)
	EndIf
	
	$oContainer.PutProperty($sVarName, $vValue)
EndFunc
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
CreatoR сказал(а):
Можно правда добавить проверку на Ptr...

Тут дело в другом. Ты говорил, что возможно передавать массивы. Так вот вопрос в том, будет ли передаваться массив, содержащий указатели?

P.S

Кстати, а как передать массив?

Попробывал, указатели в массиве не передаются (COM error...).

:(
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Ты не обновил страницу. Я зачеркнул это.

:smile:

А вот то, что не передает, это очень плохо. Возможно есть еще какие-нибудь подводные камни...
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Yashied [?]
указатели в массиве не передаются
Обошёл пока так:

Код:
Func _Container_PutProperty($oContainer, $sVarName, $vValue, $bCheckPtrVal = False)
	If $bCheckPtrVal Then
		If IsPtr($vValue) Then
			$vValue = Number($vValue)
		ElseIf IsArray($vValue) Then
			Local $iDims = UBound($vValue, 0)
			
			If $iDims > 2 Then
				Return SetError(1)
			EndIf
			
			For $i = 0 To UBound($vValue) - 1
				If $iDims > 1 Then
					For $j = 0 To UBound($vValue, 0) - 1
						If IsPtr($vValue[$i][$j]) Then
							$vValue[$i][$j] = Number($vValue[$i][$j])
						EndIf
					Next
				Else
					If IsPtr($vValue[$i]) Then
						$vValue[$i] = Number($vValue[$i])
					EndIf
				EndIf
			Next
		EndIf
	EndIf
	
	$oContainer.PutProperty($sVarName, $vValue)
EndFunc


Медленно, криво, но вроде работает. Это надеюсь временное решение, пока не найду нормальное описание для методов объекта «InternetExplorer.Application».
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Нашёл, это бага в AutoIt, он не может передавать указатели через COM.

#1410: Bug: Using Pointer type with COM-object throws error. (assigned)

Если спросишь как я нашёл, то довольно просто, я набрал в гугле то что выдаёт ошибка COM-обработчика:
Conversion of parameters failed
и попал в тему на офф. форуме, там trancexx указал на то что это бага AutoIt'а и она известная, тогда я пошёл искать по баг трекеру, и наткнулся на вышеуказанный тикет :smile:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
CreatoR сказал(а):
Медленно, криво, но вроде работает.

Это не выход. Во-первых, принимающая сторона автоматически теряет тип "PTR" (вместо него приходит "INT"). Возможно будет лучше передавать преобразованный тип вместе с сигнатурой, например, если пользователь передает "PTR" (допустим 0x12345678), то фактически передается строка вида

"PTR_SIG0x12345678"

Принимающая сторона, в свою очередь, в случае прихода строкового типа, проверяет наличие сигнатуры:

Код:
If (IsString($Data)) And (StringLeft($Data, 7) = "PTR_SIG") Then
	$Data = Ptr(StringTrimLeft($Data, 7))
EndIf


А во-вторых, я не уверен, что Number() переварит "PTR" в x64 (не проверял). И еще появляется ограничение на размерность массива.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Ох и как же я все-таки не люблю эти COM, там работает, здесь не работает...
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Yashied [?]
Во-первых, принимающая сторона автоматически теряет тип "PTR" (вместо него приходит "INT").
Ну это ведь особо не влияет на работу с ним?

Возможно будет лучше передавать преобразованный тип вместе с сигнатурой
Хорошая идея.

во-вторых, я не уверен, что Number() переварит "PTR" в x64 (не проверял)
Думаю переварит, иначе trancexx не стал бы это рекомендовать не упомянув такое ограничение, он в этом разбирается.

появляется ограничение на размерность массива.
Да, но не думаю что кому то понадобится интеракция с передачей 3-ёх мерного(или более) массива, я считаю это мазохизмом.

[?]
как же я все-таки не люблю эти COM
Да я и сам не большой любитель этого чуда :beer:
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Наконец-то исправили проблему с передачей указателей в COM-объектах.
 

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
CreatoR
использовал твой пример с первой страницы-
http://autoit-script.ru/index.php/topic,4634.msg33451.html#msg33451
на Win 7 x64 ошибок не было. в ХР SP3 через не равные промежутки времени вываливается ошибка
Код:
The requested action with this object has failed.:
Return $oContainer.GetProperty($sName)
Return $oContainer.GetProperty($sName)^ ERROR
я так понял, что работа с объектом невозможна. с объектом к которому идет подключение. почему не сразу появляется ошибка?
пока не перезагрузишь систему скрипт не может работать
можно ли при выходе удалять объект?
 
Верх