26

Re: AHK: Получить переменные окружения процесса, зная его PID

Ага, спасибо за информацию, надо иметь в виду.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

27 (изменено: teadrinker, 2017-01-09 23:35:38)

Re: AHK: Получить переменные окружения процесса, зная его PID

YMP, а можешь ntdll 32-bit из win 10 запостить?

YMP пишет:

Кстати, в Win10 функция ntdll.dll\NtWow64QueryVirtualMemory64 не существует

Тут путаница, она должна называться NtWow64ReadVirtualMemory64. Точно ли нету? Так не пробовал (из 32-битного скрипта):

hModule := DllCall("GetModuleHandle", "str", "Ntdll", Ptr)
ReadProcessMemory := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtWow64ReadVirtualMemory64", Ptr)

?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

28

Re: AHK: Получить переменные окружения процесса, зная его PID

Нет, я именно про Query, я её использую в моём скрипте, чтобы узнать размер региона памяти. А Read и Write пока есть. Вот полный список экспорта: https://yadi.sk/d/iJ-rTrsD387dkM.

29

Re: AHK: Получить переменные окружения процесса, зная его PID

YMP пишет:

я её использую в моём скрипте, чтобы узнать размер региона памяти

Так зачем его узнавать, просто ставь 0x4000. Хотя бы только для данной ситуации (32 — 64). По моим оценкам достаточно с большим запасом и 0x3000. А в крайнем случае просто функция чтения упадёт.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

30

Re: AHK: Получить переменные окружения процесса, зная его PID

Аполитично рассуждаешь. Раз была такая функция, то зачем было гаданиями заниматься и до крайнего случая доводить? Сейчас, конечно, можно и так сделать.

31

Re: AHK: Получить переменные окружения процесса, зная его PID

Да я из практического опыта. Пробовал просто подставлять максимальное значение — проблем не разу не возникло. Ещё так можно:

$F10::
   WinGet, PID, PID, A
   MsgBox % GetEnv(PID)
;  MsgBox % GetEnv(PID, "PATH")
   Return
   
GetEnv(PID, Var := "")  {
   Is32bitProc := true
   if A_Is64bitOS  {
      hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION := 0x400, Int, 0, UInt, PID, Ptr)
      DllCall("IsWow64Process", Ptr, hProc, UIntP, Is32bitProc)
      DllCall("CloseHandle", Ptr, hProc)
   }
   SplitPath, A_AhkPath,, Dir
   if !FileExist(AhkPath := Dir . "\AutoHotkeyU" . (Is32bitProc ? "32" : "64") . ".exe")  {
      MsgBox, Исполнимый файл %AhkPath% не найден!`nДля работы скрипта установите AutoHotkey!
      Return
   }
   Return ExecScript( GetScript(PID, Var), AhkPath )
}

ExecScript(script, AhkPath)  {
   shell := ComObjCreate("WScript.Shell")
   exec := shell.Exec(AhkPath . " /ErrorStdOut *")
   exec.StdIn.Write(script)
   exec.StdIn.Close()
   return exec.StdOut.ReadAll()
}

GetScript(PID, Var := "")  {
   script =
   (
      #NoTrayIcon
      PID := %PID%, Var := "%Var%"
      PROCESS_QUERY_INFORMATION := 0x400, PROCESS_VM_READ := 0x10, cbPES_max := 0x3000
      info := STATUS_SUCCESS := 0, OffsetPES := A_PtrSize = 4 ? 0x48 : 0x80, sbMBI := A_PtrSize * 5 + 4 * 2
      
      hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
      VarSetCapacity(PBI, szPBI := A_PtrSize * 6, 0)
      if DllCall("Ntdll\NtQueryInformationProcess", Ptr, hProc, UInt, info, Ptr, &PBI, UInt, szPBI, UIntP, bytes) != STATUS_SUCCESS  {
         DllCall("CloseHandle", Ptr, hProc)
         Return
      }
      pPEB := NumGet(&PBI + A_PtrSize, "Ptr")
      DllCall("ReadProcessMemory", Ptr, hProc, Ptr, pPEB + A_PtrSize * 4, PtrP, pRUPP, Ptr, A_PtrSize, UIntP, bytes)
      DllCall("ReadProcessMemory", Ptr, hProc, Ptr, pRUPP + OffsetPES, PtrP, pPES, Ptr, A_PtrSize, UIntP, bytes)
      
      VarSetCapacity(MBI, sbMBI, 0)
      DllCall("VirtualQueryEx", Ptr, hProc, Ptr, pPES, Ptr, &MBI, Ptr, sbMBI)
      cbRegion := NumGet(&MBI + A_PtrSize * 3)
      cbPES := (((pPES + cbRegion) >> 12) << 12) - pPES
      (cbPES > cbPES_max && cbPES := cbPES_max)
      
      VarSetCapacity(PES, cbPES, 0)
      DllCall("ReadProcessMemory", Ptr, hProc, Ptr, pPES, Ptr, &PES, Ptr, cbPES, UIntP, bytes)
      DllCall("CloseHandle", Ptr, hProc)
      
      CurrPtr := &PES, len := -1
      while len := DllCall("lstrlenW", Ptr, CurrPtr += len*2 + 2)
         env .= (A_Index = 1 ? "" : "``r``n") . StrGet(CurrPtr)

      if Var  {
         RegExMatch(env, "im``n)^" Var "=([^\n]+)$", Found)
         env := Found1
      }
      FileAppend, `% env, *
   )
   Return script
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

32

Re: AHK: Получить переменные окружения процесса, зная его PID

Т.е. запускать версию АНК с нужной разрядностью? Интересная мысль.