<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: Чтение переменных окружения из другого процесса]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=9732&amp;type=atom" />
	<updated>2014-06-24T10:33:40Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=9732</id>
		<entry>
			<title type="html"><![CDATA[AHK: Чтение переменных окружения из другого процесса]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=84148#p84148" />
			<content type="html"><![CDATA[<p>Функция PsGetEnv позволяет получить список переменных окружения указанного процесса или одну из переменных. Сочетание битностей (32/64) скрипта и процесса может быть любым.</p><p>Использована информация <a href="http://www.codeproject.com/Articles/25647/Read-Environment-Strings-of-Remote-Process">отсюда</a>, <a href="http://blog.gapotchenko.com/eazfuscator.net/reading-environment-variables">отсюда</a> и <a href="http://www.manhunter.ru/assembler/653_poluchenie_informacii_o_drugom_processe.html">отсюда</a>.<br /></p><div class="codebox"><pre><code>
MsgBox, % PsGetEnv(&quot;AutoHotkey.exe&quot;, &quot;Temp&quot;)    ; Переменная.
MsgBox, % PsGetEnv(&quot;AutoHotkey.exe&quot;)            ; Весь список.

; Переменная процесса активного окна.
F10::
    WinGet, PID, PID, A
    MsgBox, % PsGetEnv(PID, &quot;Path&quot;)
Return


; ============================= Функция ===================================

PsGetEnv(Process, Var = 0)
{
    Static PBI  ; PROCESS_BASIC_INFORMATION
    Static MBI, pMBI, cbMBI := 48  ; MEMORY_BASIC_INFORMATION
    Static PROCESS_VM_READ := 0x10, PROCESS_QUERY_INFORMATION := 0x400
    Static STATUS_SUCCESS := 0, cbPES_max := 0x4000 ; Макс. размер блока переменных.
    If (!PBI) {
        VarSetCapacity(PBI, 48), VarSetCapacity(MBI, cbMBI + 16)
        ; Выравнять по границе 16 байт для NtWow64QueryVirtualMemory64.
        pMBI := ((&amp;MBI + 16) &gt;&gt; 4) &lt;&lt; 4
    }
    Process, Exist, %Process%
    If !(PID := ErrorLevel)
        Return Error(&quot;Процесс не найден&quot;)
    If !(hProcess := DllCall(&quot;OpenProcess&quot;, &quot;uint&quot;, PROCESS_VM_READ | PROCESS_QUERY_INFORMATION
                                          , &quot;int&quot;, 0, &quot;uint&quot;, PID, &quot;ptr&quot;))
        Return Error(&quot;Ошибка OpenProcess&quot;)
    If (A_Is64bitOS)
        DllCall(&quot;IsWow64Process&quot;, &quot;ptr&quot;, hProcess, &quot;int *&quot;, Wow64Process)
    If (!A_Is64bitOS || Wow64Process)   ; Процесс 32-битный.
        PsPtrSize := 4, pptr := &quot;uint *&quot;, OffsetRUPP := 16, OffsetPES := 0x48
    Else                                ; Процесс 64-битный.
        PsPtrSize := 8, pptr := &quot;int64 *&quot;, OffsetRUPP := 32, OffsetPES := 0x80
    If (A_PtrSize &lt; PsPtrSize) {    ; Скрипт х32, процесс х64.
        InfoClass := 0, cbPBI := 48, OffsetPEB := 8
        ;;; PROCESS_BASIC_INFORMATION (PBI)
        If (DllCall(&quot;ntdll.dll\NtWow64QueryInformationProcess64&quot;
                , &quot;ptr&quot;, hProcess, &quot;int&quot;, InfoClass, &quot;ptr&quot;, &amp;PBI, &quot;uint&quot;, cbPBI
                , &quot;int64 *&quot;, ReturnLength) &lt;&gt; STATUS_SUCCESS)
            Return Error(&quot;Ошибка NtWow64QueryInformationProcess64&quot;, hProcess)
        ;;; Process Environment Block (PEB)
        pPEB := NumGet(PBI, OffsetPEB, &quot;int64&quot;)
        ;;; RTL_USER_PROCESS_PARAMETERS (RUPP)
        If (DllCall(&quot;ntdll.dll\NtWow64ReadVirtualMemory64&quot;
                , &quot;ptr&quot;, hProcess, &quot;int64&quot;, pPEB + OffsetRUPP, &quot;int64 *&quot;, pRUPP
                , &quot;int64&quot;, 8, &quot;int64 *&quot;, BytesRead) &lt;&gt; STATUS_SUCCESS)
            Return Error(&quot;Ошибка NtWow64ReadVirtualMemory64: pRUPP&quot;, hProcess)
        ;;; Process Environment Strings (PES)
        If (DllCall(&quot;ntdll.dll\NtWow64ReadVirtualMemory64&quot;
                , &quot;ptr&quot;, hProcess, &quot;int64&quot;, pRUPP + OffsetPES, &quot;int64 *&quot;, pPES
                , &quot;int64&quot;, 8, &quot;int64 *&quot;, BytesRead) &lt;&gt; STATUS_SUCCESS)
            Return Error(&quot;Ошибка NtWow64ReadVirtualMemory64: pPES&quot;, hProcess)
        ;;; Размер региона памяти, где находится PES.
        If (DllCall(&quot;ntdll.dll\NtWow64QueryVirtualMemory64&quot;
                , &quot;ptr&quot;, hProcess, &quot;int64&quot;, pPES, &quot;uint&quot;, 0, &quot;ptr&quot;, pMBI
                , &quot;int64&quot;, cbMBI, &quot;int64 *&quot;, ReturnLength) &lt;&gt; STATUS_SUCCESS)
            Return Error(&quot;Ошибка NtWow64QueryVirtualMemory64&quot;, hProcess)
        cbRegion := NumGet(pMBI+0, 24, &quot;int64&quot;)
    }
    Else {
        If (A_PtrSize &gt; PsPtrSize)  ; Скрипт х64, процесс х32.
            InfoClass := 26, cbPBI := 8, OffsetPEB := 0
        Else
            InfoClass := 0, cbPBI := A_PtrSize * 6, OffsetPEB := A_PtrSize
        ;;; PROCESS_BASIC_INFORMATION (PEB)
        If (DllCall(&quot;ntdll.dll\NtQueryInformationProcess&quot;
                , &quot;ptr&quot;, hProcess, &quot;int&quot;, InfoClass, &quot;ptr&quot;, &amp;PBI, &quot;uint&quot;, cbPBI
                , &quot;uint *&quot;, ReturnLength) &lt;&gt; STATUS_SUCCESS)
        Return Error(&quot;Ошибка NtQueryInformationProcess&quot;, hProcess)
        ;;; Process Environment Block (PEB)
        pPEB := NumGet(PBI, OffsetPEB, &quot;ptr&quot;)
        ;;; RTL_USER_PROCESS_PARAMETERS (RUPP)
        If !DllCall(&quot;ReadProcessMemory&quot;, &quot;ptr&quot;, hProcess, &quot;ptr&quot;, pPEB + OffsetRUPP
                                       , pptr, pRUPP, &quot;ptr&quot;, PsPtrSize, &quot;ptr *&quot;, BytesRead)
            Return Error(&quot;Ошибка ReadProcessMemory: pRUPP&quot;, hProcess)
        ;;; Process Environment Strings (PES)
        If !DllCall(&quot;ReadProcessMemory&quot;, &quot;ptr&quot;, hProcess, &quot;ptr&quot;, pRUPP + OffsetPES
                                       , pptr, pPES, &quot;ptr&quot;, PsPtrSize, &quot;ptr *&quot;, BytesRead)
            Return Error(&quot;Ошибка ReadProcessMemory: pPES&quot;, hProcess)
        ;;; Размер региона памяти, где находится PES.
        If !DllCall(&quot;VirtualQueryEx&quot;, &quot;ptr&quot;, hProcess, &quot;ptr&quot;, pPES, &quot;ptr&quot;, pMBI
                                    , &quot;ptr&quot;, cbMBI, &quot;int64&quot;)
            Return Error(&quot;Ошибка VirtualQueryEx&quot;, hProcess)
        cbRegion := NumGet(pMBI+0, A_PtrSize * 3, &quot;ptr&quot;)
    }
    ;;; Размер от начала блока PES до конца региона.
    cbPES := (((pPES + cbRegion) &gt;&gt; 12) &lt;&lt; 12) - pPES
    If (cbPES &gt; cbPES_max) ; Если размер большой, ограничить разумной величиной.
        cbPES := cbPES_max
    VarSetCapacity(PES, cbPES, 0)
    If (A_PtrSize &lt; PsPtrSize) {
        If (DllCall(&quot;ntdll.dll\NtWow64ReadVirtualMemory64&quot;
                , &quot;ptr&quot;, hProcess, &quot;int64&quot;, pPES, &quot;ptr&quot;, &amp;PES
                , &quot;int64&quot;, cbPES, &quot;int64 *&quot;, ReturnLength, &quot;uint&quot;) &lt;&gt; STATUS_SUCCESS)
            Return Error(&quot;Ошибка NtWow64ReadVirtualMemory64: PES&quot;, hProcess)
    }
    Else {
        If !DllCall(&quot;ReadProcessMemory&quot;
                , &quot;ptr&quot;, hProcess, &quot;ptr&quot;, pPES, &quot;ptr&quot;, &amp;PES
                , &quot;ptr&quot;, cbPES, &quot;ptr *&quot;, BytesRead)
            Return Error(&quot;Ошибка ReadProcessMemory: PES&quot;, hProcess)
    }
    DllCall(&quot;CloseHandle&quot;, &quot;ptr&quot;, hProcess)

    Loop, % cbPES // 2  ; Строки в блоке разделены нулями, на конце два нуля.
    {                   ; Заменяем нули на переводы строки, кроме последних.
        If ((char := NumGet(PES, (A_Index - 1) * 2, &quot;uchar&quot;)) = 0) {
            If (prev = 0)
                Break
            NumPut(0xA, PES, (A_Index - 1) * 2, &quot;uchar&quot;)
        }
        prev := char
    }
    EnvList := StrGet(&amp;PES, &quot;utf-16&quot;)
    If (!Var)
        Return EnvList
    RegExMatch(EnvList, &quot;im`n)^&quot; Var &quot;=([^\n]+)$&quot;, Found)
    Return Found1
}

Error(Msg, hProcess = 0)
{
    If (hProcess)
        DllCall(&quot;CloseHandle&quot;, &quot;ptr&quot;, hProcess)
    MsgBox, %Msg%
    Return False
}
</code></pre></div>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2014-06-24T10:33:40Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=84148#p84148</id>
		</entry>
</feed>
