Автор Тема: Выполнение API без приостановки скрипта  (Прочитано 2490 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн firex [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 943
  • Репутация: 203
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.x.x
Очередная вариация на тему потоков. Простая концепция, все возможности не раскрыты. Присутствует возможность получения результата.

Код: AutoIt [Выделить]
#Include <WinAPI.au3>
#Include <Memory.au3>

$tData = DllStructCreate( "wchar Title[50]; wchar Text[50]" )
$tData.Title = "Title"
$tData.Text = "Text"

$tThread = _AsmThread( 'user32.dll', 'int', 'MessageBoxW', 65, DllStructGetPtr( $tData, 'Title' ), DllStructGetPtr( $tData, 'Text' ), 0 )
If IsDllStruct( $tThread ) Then
    While Sleep( 1000 )
        If $tThread.Return Then
            ConsoleWrite( $tThread.Return & @CRLF)
            ExitLoop
        EndIf
        ConsoleWrite( "Main thread..." & @CRLF)
    WEnd
EndIf

;sModule - Module name
;sRetType - Return type( 4 BYTE, like dword, ptr32, int ... )
;sFunc - Function name
;ArgN - Argument( 4 BYTE )
; -----
;Return:
;$tRet.Id - InternalThreadId ( ___THREADi )
;$tRet.Thread - hThread
;$tRet.Mem - pAllocatedVirtualMemory
;$tRet.Ptr - Ptr to tRet
;$tRet.Return - Return value
Func _AsmThread( $sModule, $sRetType, $sFunc, $Arg1 = 0, $Arg2 = 0, $Arg3 = 0, $Arg4 = 0, $Arg5 = 0, $Arg6 = 0 )
    Local $Idx, $hModule, $pFunc, $tRet, $pMem, $aRes, _
        $tOpCode, $iOpCode_sz, $vOpCode = "0x", _
        $aArgs[6] = [ $Arg1, $Arg2, $Arg3, $Arg4, $Arg5, $Arg6 ]
    ; *
    ReDim $aArgs[@NumParams-2]
    ; ---
    $tRet = DllStructCreate( $sRetType & " Return; ptr Ptr; ptr Mem; handle Thread; ulong Id" )
        $tRet.Ptr = DllStructGetPtr( $tRet )

    For $Idx = 0 To @NumParams - 4 Step 1
        $vOpCode &= "68" & _AsmSwap( $aArgs[$Idx] ) ;PUSH Arg
    Next
    Do
        $hModule = _WinAPI_GetModuleHandle( $sModule )
        If Not $hModule Then ExitLoop

        $pFunc =  _WinAPI_GetProcAddress( $hModule, $sFunc )
        If Not $pFunc Then ExitLoop
        ; -
        $vOpCode &= _
            "B8" & _AsmSwap( $pFunc ) & _       ;MOV EAX,pFunc
            "FFD0" & _                          ;CALL EAX
            "A3" & _AsmSwap( $tRet.Ptr ) & _    ;MOV DWORD PTR[pRet],EAX
            "C3"                                ;RET

        $vOpCode = Binary( $vOpCode )
        $iOpCode_sz = BinaryLen( $vOpCode )
        ; -
        $pMem = _MemVirtualAlloc( 0, $iOpCode_sz, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE )
        If Not $pMem Then ExitLoop

        $tOpCode = DllStructCreate( "byte OpCode[" & $iOpCode_sz & "]", $pMem )
        $tOpCode.OpCode = $vOpCode

        $aRes = DllCall( 'kernel32.dll', 'ptr', 'CreateThread', 'ptr', 0, 'dword_ptr', 0, 'ptr', $pMem, 'ptr', 0, 'dword', 0, 'dword*', 0)
        If @Error Or Not $aRes[0] Then ExitLoop

        ; - < Anti-crash region ( save allocated memory for struct's )
        $Idx = 0
        While IsDeclared( "___THREAD" & $Idx )
            $Idx += 1
        WEnd
        Assign( "___THREAD" & $Idx, $tRet, 2 )

        $tRet.Mem = $pMem
        $tRet.Thread = $aRes[0]
        $tRet.Id = $Idx

        Sleep( 10 )
        Return $tRet
    Until True
    ; ---
    Return 0
EndFunc

Func _AsmSwap( $vData )
    Return Hex( Binary( $vData ) )
EndFunc

« Последнее редактирование: Февраль 06, 2015, 15:31:09 от firex »

Русское сообщество AutoIt

Выполнение API без приостановки скрипта
« Отправлен: Февраль 06, 2015, 15:22:12 »

Оффлайн Yashied [?]

  • AutoIt MVP
  • Глобальный модератор
  • *
  • Сообщений: 5379
  • Репутация: 2695
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Выполнение API без приостановки скрипта
« Ответ #1, Отправлен: Февраль 06, 2015, 16:40:16 »
А какой интерес запускать самодостаточную MessageBox(), и зачем здесь нужен opcode? Кстати, давно я уже что-то похожее писал.


Думай, прежде чем говорить.

Оффлайн firex [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 943

  • Автор темы
  • Репутация: 203
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Выполнение API без приостановки скрипта
« Ответ #2, Отправлен: Февраль 06, 2015, 16:43:48 »
Yashied
1. MessageBox я привел в кач-ве примера, а цели у меня были иные, как и в целом их реализация.
2. С опкодом я облегчаю получение результата, хотя перспективы все же иные.

Оффлайн Prog [?]

  • Осваивающий
  • **
  • Сообщений: 292
  • Репутация: 29
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
Re: Выполнение API без приостановки скрипта
« Ответ #3, Отправлен: Февраль 06, 2015, 17:40:32 »
1. Формат ThreadProc. https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms686736(v=vs.85).aspx
Асм. вставка не чистит стек от аргумента.

2. Не освобождается память выделенная MemVirtualAlloc.

3. Проще и безопаснее написать dll в которой реализовать многопоточность.

Русское сообщество AutoIt

Re: Выполнение API без приостановки скрипта
« Ответ #3 Отправлен: Февраль 06, 2015, 17:40:32 »

Оффлайн firex [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 943

  • Автор темы
  • Репутация: 203
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Выполнение API без приостановки скрипта
« Ответ #4, Отправлен: Февраль 06, 2015, 17:44:09 »
Prog
Если вы присмотритесь, то увидите следующее:
Код: AutoIt [Выделить]
;Return:
;$tRet.Id - InternalThreadId ( ___THREADi )
;$tRet.Thread - hThread
;$tRet.Mem - pAllocatedVirtualMemory
;$tRet.Ptr - Ptr to tRet
;$tRet.Return - Return value


Цитировать
Асм. вставка не чистит стек от аргумента.
В данном опкоде в этом нет необходимости.

Цитировать
2. Не освобождается память выделенная MemVirtualAlloc
Это концепция, а следовательно если это будет интересно, то подобные операции должен будет производить интересующийся.
1. Отслеживать ( GetThreadExitCode )
2. Чистить ( VirtualFree )

Цитировать
3. Проще и безопаснее написать dll в которой реализовать многопоточность.
Ну вы разогнались... Речь идет о частных вызовах DLL функций в потоке, а не полноценной реализации потоков.
« Последнее редактирование: Февраль 06, 2015, 18:14:13 от firex »

Оффлайн Yashied [?]

  • AutoIt MVP
  • Глобальный модератор
  • *
  • Сообщений: 5379
  • Репутация: 2695
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Выполнение API без приостановки скрипта
« Ответ #5, Отправлен: Февраль 06, 2015, 18:01:56 »
Проще и безопаснее написать dll в которой реализовать многопоточность.

Я, собственно, так и делаю. В данном контексте больше представляет интерес запуск AutoIt - DllCallback() - процедуры, а не функции из DLL. ASM, VirtualAlloc() и все прочие плюшки в этом примере нафиг не нужны. Достаточно просто создать глобальную или static AutoIt структуру для передачи параметров и отпустить MessageBox() в свободное плавание.

Русское сообщество AutoIt

Re: Выполнение API без приостановки скрипта
« Ответ #5 Отправлен: Февраль 06, 2015, 18:01:56 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
15 Ответов
12511 Просмотров
Последний ответ Март 30, 2013, 01:03:23
от La2Angel
9 Ответов
7025 Просмотров
Последний ответ Апрель 03, 2011, 04:03:53
от WasonAl
0 Ответов
2675 Просмотров
Последний ответ Апрель 02, 2011, 12:09:28
от madmasles
15 Ответов
4683 Просмотров
Последний ответ Июль 27, 2011, 19:11:14
от Yashied
3 Ответов
5124 Просмотров
Последний ответ Август 01, 2011, 15:47:34
от snoitaleR
4 Ответов
3637 Просмотров
Последний ответ Июль 06, 2012, 22:59:40
от AZJIO
6 Ответов
3426 Просмотров
Последний ответ Февраль 28, 2013, 02:55:33
от Arikurinkuto
2 Ответов
2683 Просмотров
Последний ответ Март 15, 2013, 07:20:37
от Trans
6 Ответов
3030 Просмотров
Последний ответ Май 15, 2014, 00:27:19
от InnI
3 Ответов
1202 Просмотров
Последний ответ Апрель 15, 2015, 08:23:06
от neversaymoo