external process: get working directory (current directory)
external process: get working directory (current directory)
Can somebody help me get this to work? I.e. if possible so that x64/x32 AHK can get the working directory from x64/x32 external processes. Thanks.
I tried it with AHK x32, on Notepad x64/x32, but it didn't work.
[SOLVED]get other process's working dir - Page 2 - Ask for Help - AutoHotkey Community
https://autohotkey.com/board/topic/8530 ... ntry544320
I used this MCode function:
Machine code functions: Bit Wizardry - Scripts and Functions - AutoHotkey Community
https://autohotkey.com/board/topic/1948 ... dry/page-1
There is an alternative MCode function here. I'm not sure if there is a newer version.
MCode function + onlinegenerator (x86 and x64) - Scripts and Functions - AutoHotkey Community
https://autohotkey.com/board/topic/8928 ... 6-and-x64/
I tried it with AHK x32, on Notepad x64/x32, but it didn't work.
[SOLVED]get other process's working dir - Page 2 - Ask for Help - AutoHotkey Community
https://autohotkey.com/board/topic/8530 ... ntry544320
I used this MCode function:
Machine code functions: Bit Wizardry - Scripts and Functions - AutoHotkey Community
https://autohotkey.com/board/topic/1948 ... dry/page-1
There is an alternative MCode function here. I'm not sure if there is a newer version.
MCode function + onlinegenerator (x86 and x64) - Scripts and Functions - AutoHotkey Community
https://autohotkey.com/board/topic/8928 ... 6-and-x64/
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
-
- Posts: 4309
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: external process: get working directory (current directory)
Sometime I wrote the function to get process' comandline. It reads CommandLine from RTL_USER_PROCESS_PARAMETERS structure. Also RUPP contains process' current directory.
Code: Select all
IsAdminChecking(), SetDebugPrivilege() ; only for system processes on Windows 10 (and on Windows 8, maybe), else may by commented out
Process, Exist, winlogon.exe
PID := ErrorLevel
MsgBox, % GetProcessCurrentDirectory(PID)
GetProcessCurrentDirectory(PID) {
static PROCESS_QUERY_INFORMATION := 0x400, PROCESS_VM_READ := 0x10, STATUS_SUCCESS := 0
hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
(A_Is64bitOS && DllCall("IsWow64Process", Ptr, hProc, UIntP, IsWow64))
if (!A_Is64bitOS || IsWow64)
PtrSize := 4, PtrType := "UInt", pPtr := "UIntP"
else
PtrSize := 8, PtrType := "Int64", pPtr := "Int64P"
offsetCURDIR := 4*4 + PtrSize*5
hModule := DllCall("GetModuleHandle", "str", "Ntdll", Ptr)
if (A_PtrSize < PtrSize) { ; <<—— script 32, target process 64
if !QueryInformationProcess := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtWow64QueryInformationProcess64", Ptr)
failed := "NtWow64QueryInformationProcess64"
if !ReadProcessMemory := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtWow64ReadVirtualMemory64", Ptr)
failed := "NtWow64ReadVirtualMemory64"
info := 0, szPBI := 48, offsetPEB := 8
}
else {
if !QueryInformationProcess := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtQueryInformationProcess", Ptr)
failed := "NtQueryInformationProcess"
ReadProcessMemory := "ReadProcessMemory"
if (A_PtrSize > PtrSize) ; <<—— script 64, target process 32
info := 26, szPBI := 8, offsetPEB := 0
else ; <<—— script and target process have the same bitness
info := 0, szPBI := PtrSize * 6, offsetPEB := PtrSize
}
if failed {
DllCall("CloseHandle", Ptr, hProc)
MsgBox, Failed to get pointer to %failed%
Return
}
VarSetCapacity(PBI, 48, 0)
if DllCall(QueryInformationProcess, Ptr, hProc, UInt, info, Ptr, &PBI, UInt, szPBI, UIntP, bytes) != STATUS_SUCCESS {
DllCall("CloseHandle", Ptr, hProc)
Return
}
pPEB := NumGet(&PBI + offsetPEB, PtrType)
DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pPEB + PtrSize * 4, pPtr, pRUPP, PtrType, PtrSize, UIntP, bytes)
DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pRUPP + offsetCURDIR, UShortP, szBuff, PtrType, 2, UIntP, bytes)
DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pRUPP + offsetCURDIR + PtrSize, pPtr, pCURDIR, PtrType, PtrSize, UIntP, bytes)
VarSetCapacity(buff, szBuff, 0)
DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pCURDIR, Ptr, &buff, PtrType, szBuff, UIntP, bytes)
DllCall("CloseHandle", Ptr, hProc)
Return currentDirPath := StrGet(&buff, "UTF-16")
}
IsAdminChecking() {
if !( A_IsAdmin || RegExMatch( DllCall("GetCommandLine", "str"), " /restart(?!\S)" ) ) {
try {
if A_IsCompiled
Run *RunAs "%A_ScriptFullPath%" /restart
else
Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%"
}
ExitApp
}
}
SetDebugPrivilege() {
static PROCESS_QUERY_INFORMATION := 0x400, TOKEN_ADJUST_PRIVILEGES := 0x20, SE_PRIVILEGE_ENABLED := 0x2
hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION, Int, false, UInt, DllCall("GetCurrentProcessId"), Ptr)
DllCall("Advapi32\OpenProcessToken", Ptr, hProc, UInt, TOKEN_ADJUST_PRIVILEGES, PtrP, token)
DllCall("Advapi32\LookupPrivilegeValue", Ptr, 0, Str, "SeDebugPrivilege", Int64P, luid)
VarSetCapacity(TOKEN_PRIVILEGES, 16, 0)
NumPut(1, TOKEN_PRIVILEGES, "UInt")
NumPut(luid, TOKEN_PRIVILEGES, 4, "Int64")
NumPut(SE_PRIVILEGE_ENABLED, TOKEN_PRIVILEGES, 12, "UInt")
DllCall("Advapi32\AdjustTokenPrivileges", Ptr, token, Int, false, Ptr, &TOKEN_PRIVILEGES, UInt, 0, Ptr, 0, Ptr, 0)
res := A_LastError
DllCall("CloseHandle", Ptr, token)
DllCall("CloseHandle", Ptr, hProc)
Return res ; success 0
}
Re: external process: get working directory (current directory)
This is really great, many thanks, and it doesn't need a machine code function.
You've been posting a lot of good stuff the last few months.
You've been posting a lot of good stuff the last few months.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
-
- Posts: 4309
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: external process: get working directory (current directory)
Actually I'm hear to practice my English.
Re: external process: get working directory (current directory)
Haha you're here to practise your English, classic.
Hmm, the comment about system processes, reminded me, I wanted a way to get the user name for a process. I've started a new thread here:
process: get user name (like Task Manager) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=38546
Hmm, the comment about system processes, reminded me, I wanted a way to get the user name for a process. I've started a new thread here:
process: get user name (like Task Manager) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=38546
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: external process: get working directory (current directory)
could you point out how to also get the command line?teadrinker wrote: ↑18 Oct 2017, 19:15Sometime I wrote the function to get process' comandline. It reads CommandLine from RTL_USER_PROCESS_PARAMETERS structure. Also RUPP contains process' current directory.
IsAdminChecking(), SetDebugPrivilege() ; only for system processes on Windows 10 (and on Windows 8, maybe), else may by commented out
all this info is possible to read with your previous function?
Spoiler
the struct above isn't this one?https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-rtl_user_process_parameters
-
- Posts: 4309
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: external process: get working directory (current directory)
Yep, but most items are undocumented.
Of course.
Like this:
Code: Select all
Process, Exist, svchost.exe
PID := ErrorLevel
cmd := GetCommandLine(PID, true, imagePath)
MsgBox, % cmd . "`n" . imagePath
GetCommandLine(PID, setDebugPrivilege := false, ByRef imagePath := "") {
static PROCESS_QUERY_INFORMATION := 0x400, PROCESS_VM_READ := 0x10, STATUS_SUCCESS := 0
, TOKEN_ADJUST_PRIVILEGES := 0x20, SE_PRIVILEGE_ENABLED := 0x2, setDebug := 0
if (setDebugPrivilege && !setDebug) {
RunAsAdmin()
if SetPrivilege("SeDebugPrivilege") != 0
MsgBox, Failed to set debug privelege
}
hProc := DllCall("OpenProcess", "UInt", PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, "Int", 0, "UInt", PID, "Ptr")
(A_Is64bitOS && DllCall("IsWow64Process", "Ptr", hProc, "UIntP", IsWow64))
if (!A_Is64bitOS || IsWow64)
PtrSize := 4, PtrType := "UInt", pPtr := "UIntP", offsetCMD := 0x40
else
PtrSize := 8, PtrType := "Int64", pPtr := "Int64P", offsetCMD := 0x70
hModule := DllCall("GetModuleHandle", "str", "Ntdll", "Ptr")
if (A_PtrSize < PtrSize) { ; script 32, dest proc 64
if !QueryInformationProcess := DllCall("GetProcAddress", "Ptr", hModule, "AStr", "NtWow64QueryInformationProcess64", "Ptr")
failed := "NtWow64QueryInformationProcess64"
if !ReadProcessMemory := DllCall("GetProcAddress", "Ptr", hModule, "AStr", "NtWow64ReadVirtualMemory64", "Ptr")
failed := "NtWow64ReadVirtualMemory64"
info := 0, szPBI := 48, offsetPEB := 8
}
else {
if !QueryInformationProcess := DllCall("GetProcAddress", "Ptr", hModule, "AStr", "NtQueryInformationProcess", "Ptr")
failed := "NtQueryInformationProcess"
ReadProcessMemory := "ReadProcessMemory"
if (A_PtrSize > PtrSize) ; script 64, dest proc 32
info := 26, szPBI := 8, offsetPEB := 0
else ; script and dest proc the same bitness
info := 0, szPBI := PtrSize * 6, offsetPEB := PtrSize
}
if failed {
DllCall("CloseHandle", "Ptr", hProc)
MsgBox, Failed to get pointer to %failed%
Return
}
VarSetCapacity(PBI, 48, 0)
if DllCall(QueryInformationProcess, "Ptr", hProc, "UInt", info, "Ptr", &PBI, "UInt", szPBI, "UIntP", bytes) != STATUS_SUCCESS {
DllCall("CloseHandle", "Ptr", hProc)
Return
}
pPEB := NumGet(&PBI + offsetPEB, PtrType)
DllCall(ReadProcessMemory, "Ptr", hProc, PtrType, pPEB + PtrSize * 4, pPtr, pRUPP, PtrType, PtrSize, "UIntP", bytes)
DllCall(ReadProcessMemory, "Ptr", hProc, PtrType, pRUPP + offsetCMD, "UShortP", szCMD, PtrType, 2, "UIntP", bytes)
DllCall(ReadProcessMemory, "Ptr", hProc, PtrType, pRUPP + offsetCMD + PtrSize, pPtr, pCMD, PtrType, PtrSize, "UIntP", bytes)
VarSetCapacity(buff, szCMD, 0)
DllCall(ReadProcessMemory, "Ptr", hProc, PtrType, pCMD, "Ptr", &buff, PtrType, szCMD, "UIntP", bytes)
CMD := StrGet(&buff, "UTF-16")
if IsByRef(imagePath) {
DllCall(ReadProcessMemory, "Ptr", hProc, PtrType, pRUPP + offsetCMD - PtrSize*2, "UShortP", szPATH, PtrType, 2, "UIntP", bytes)
DllCall(ReadProcessMemory, "Ptr", hProc, PtrType, pRUPP + offsetCMD - PtrSize, pPtr, pPATH, PtrType, PtrSize, "UIntP", bytes)
VarSetCapacity(buff, szPATH, 0)
DllCall(ReadProcessMemory, "Ptr", hProc, PtrType, pPATH, "Ptr", &buff, PtrType, szPATH, "UIntP", bytes)
imagePath := StrGet(&buff, "UTF-16") . (IsWow64 ? " *32" : "")
}
DllCall("CloseHandle", "Ptr", hProc)
Return CMD
}
RunAsAdmin(exitIfNotAdmin := false) {
commandLine := DllCall("GetCommandLine", "str")
isRestarted := !!RegExMatch(commandLine, " /restart(?!\S)")
while !( A_IsAdmin || isRestarted ) {
try Run, % "*RunAs " . (A_IsCompiled ? """" . A_ScriptFullPath . """ /restart"
: """" . A_AhkPath . """ /restart """ . A_ScriptFullPath . """")
catch
break
ExitApp
}
if !A_IsAdmin {
MsgBox, Failed to run the script as admin!
if exitIfNotAdmin
ExitApp
}
}
SetPrivilege(privilege, enable := true) {
static TOKEN_ADJUST_PRIVILEGES := 0x20, SE_PRIVILEGE_ENABLED := 0x2, SE_PRIVILEGE_REMOVED := 0x4
DllCall("Advapi32\OpenProcessToken", "Ptr", -1, "UInt", TOKEN_ADJUST_PRIVILEGES, "PtrP", token)
DllCall("Advapi32\LookupPrivilegeValue", "Ptr", 0, "Str", privilege, "Int64P", luid)
VarSetCapacity(TOKEN_PRIVILEGES, 16, 0)
NumPut(1, TOKEN_PRIVILEGES, "UInt")
NumPut(luid, TOKEN_PRIVILEGES, 4, "Int64")
NumPut(enable ? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED, TOKEN_PRIVILEGES, 12, "UInt")
DllCall("Advapi32\AdjustTokenPrivileges", "Ptr", token, "Int", !enable, "Ptr", &TOKEN_PRIVILEGES, "UInt", 0, "Ptr", 0, "Ptr", 0)
res := A_LastError
DllCall("CloseHandle", "Ptr", token)
DllCall("CloseHandle", "Ptr", hProc)
Return res ; success — 0
}
Re: external process: get working directory (current directory)
your code is a bit hard for me to understand, I thought I would need just to increment a count in some of these ReadProcessMemory call
to get the values of these next items
UNICODE_STRING WindowTitle; is the same title you get by calling ahk "Wingettitle"?
if so, could you also point out how to get it?
-
- Posts: 4309
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: external process: get working directory (current directory)
This is all in one:
Code: Select all
WinGet, PID, PID, ahk_exe explorer.exe
Info := GetProcessInfo(PID)
MsgBox, % "Current Directory: " . Info.currentDir . "`n`n"
. "Dll Path: " . Info.DllPath . "`n`n"
. "Image Path: " . Info.ImagePath . "`n"
. "Command Line: " . Info.CMD . "`n"
. "Window Title: " . Info.WindowTitle . "`n"
. "Desktop Info: " . Info.DesktopInfo . "`n"
. "Shell Info: " . Info.ShellInfo . "`n"
. "Runtime Data: " . Info.RuntimeData
GetProcessInfo(PID, setDebugPrivilege := false) {
static PROCESS_QUERY_INFORMATION := 0x400, PROCESS_VM_READ := 0x10, STATUS_SUCCESS := 0, setDebug := 0
if (setDebugPrivilege && !setDebug) {
RunAsAdmin()
if SetPrivilege("SeDebugPrivilege") != 0
throw "Failed to set debug privelege"
}
hProc := DllCall("OpenProcess", "UInt", PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, "Int", 0, "UInt", PID, "Ptr")
(A_Is64bitOS && DllCall("IsWow64Process", "Ptr", hProc, "UIntP", IsWow64))
if (!A_Is64bitOS || IsWow64)
PtrSize := 4, PtrType := "UInt", pPtr := "UIntP", offsetCMD := 0x40
else
PtrSize := 8, PtrType := "Int64", pPtr := "Int64P", offsetCMD := 0x70
hModule := DllCall("GetModuleHandle", "str", "Ntdll", "Ptr")
if (A_PtrSize < PtrSize) { ; script 32, dest proc 64
if !QueryInformationProcess := DllCall("GetProcAddress", "Ptr", hModule, "AStr", "NtWow64QueryInformationProcess64", "Ptr")
failed := "NtWow64QueryInformationProcess64"
if !ReadProcessMemory := DllCall("GetProcAddress", "Ptr", hModule, "AStr", "NtWow64ReadVirtualMemory64", "Ptr")
failed := "NtWow64ReadVirtualMemory64"
info := 0, szPBI := 48, offsetPEB := 8
}
else {
if !QueryInformationProcess := DllCall("GetProcAddress", "Ptr", hModule, "AStr", "NtQueryInformationProcess", "Ptr")
failed := "NtQueryInformationProcess"
ReadProcessMemory := "ReadProcessMemory"
if (A_PtrSize > PtrSize) ; script 64, dest proc 32
info := 26, szPBI := 8, offsetPEB := 0
else ; script and dest proc the same bitness
info := 0, szPBI := PtrSize * 6, offsetPEB := PtrSize
}
if failed {
DllCall("CloseHandle", "Ptr", hProc)
MsgBox, Failed to get pointer to %failed%
Return
}
VarSetCapacity(PBI, 48, 0)
if DllCall(QueryInformationProcess, "Ptr", hProc, "UInt", info, "Ptr", &PBI, "UInt", szPBI, "UIntP", bytes) != STATUS_SUCCESS {
DllCall("CloseHandle", "Ptr", hProc)
Return
}
pPEB := NumGet(&PBI + offsetPEB, PtrType)
DllCall(ReadProcessMemory, "Ptr", hProc, PtrType, pPEB + PtrSize * 4, pPtr, pRUPP, PtrType, PtrSize, "UIntP", bytes)
Info := {}
BoundFunc := Func("DllCall").Bind(ReadProcessMemory, "Ptr", hProc, PtrType), params := [pPtr, PtrType, PtrSize]
Info.currentDir := ReadUnicodeString(BoundFunc, pRUPP + 16 + PtrSize* 5, params*)
Info.DllPath := ReadUnicodeString(BoundFunc, pRUPP + 16 + PtrSize* 8, params*)
Info.ImagePath := ReadUnicodeString(BoundFunc, pRUPP + 16 + PtrSize*10, params*)
Info.CMD := ReadUnicodeString(BoundFunc, pRUPP + 16 + PtrSize*12, params*)
Info.WindowTitle := ReadUnicodeString(BoundFunc, pRUPP + 52 + PtrSize*15, params*)
Info.DesktopInfo := ReadUnicodeString(BoundFunc, pRUPP + 52 + PtrSize*17, params*)
Info.ShellInfo := ReadUnicodeString(BoundFunc, pRUPP + 52 + PtrSize*19, params*)
Info.RuntimeData := ReadUnicodeString(BoundFunc, pRUPP + 52 + PtrSize*21, params*)
DllCall("CloseHandle", "Ptr", hProc)
Return Info
}
ReadUnicodeString(BoundFunc, addr, pPtr, PtrType, PtrSize) {
BoundFunc.Call(addr, "UShortP", stringSize, PtrType, 2, "UIntP", bytes)
BoundFunc.Call(addr + PtrSize, pPtr, pString, PtrType, PtrSize, "UIntP", bytes)
VarSetCapacity(buff, stringSize, 0)
BoundFunc.Call(pString, "Ptr", &buff, PtrType, stringSize, "UIntP", bytes)
Return StrGet(&buff, "UTF-16")
}
RunAsAdmin(exitIfNotAdmin := false) {
commandLine := DllCall("GetCommandLine", "str")
isRestarted := !!RegExMatch(commandLine, " /restart(?!\S)")
while !( A_IsAdmin || isRestarted ) {
try Run, % "*RunAs " . (A_IsCompiled ? """" . A_ScriptFullPath . """ /restart"
: """" . A_AhkPath . """ /restart """ . A_ScriptFullPath . """")
catch
break
ExitApp
}
if !A_IsAdmin {
MsgBox, Failed to run the script as admin!
if exitIfNotAdmin
ExitApp
}
}
SetPrivilege(privilege, enable := true) {
static TOKEN_ADJUST_PRIVILEGES := 0x20, SE_PRIVILEGE_ENABLED := 0x2, SE_PRIVILEGE_REMOVED := 0x4
DllCall("Advapi32\OpenProcessToken", "Ptr", -1, "UInt", TOKEN_ADJUST_PRIVILEGES, "PtrP", token)
DllCall("Advapi32\LookupPrivilegeValue", "Ptr", 0, "Str", privilege, "Int64P", luid)
VarSetCapacity(TOKEN_PRIVILEGES, 16, 0)
NumPut(1, TOKEN_PRIVILEGES, "UInt")
NumPut(luid, TOKEN_PRIVILEGES, 4, "Int64")
NumPut(enable ? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED, TOKEN_PRIVILEGES, 12, "UInt")
DllCall("Advapi32\AdjustTokenPrivileges", "Ptr", token, "Int", !enable, "Ptr", &TOKEN_PRIVILEGES, "UInt", 0, "Ptr", 0, "Ptr", 0)
res := A_LastError
DllCall("CloseHandle", "Ptr", token)
DllCall("CloseHandle", "Ptr", hProc)
Return res ; success — 0
}
Re: external process: get working directory (current directory)
thank you!! when the process contains multiple windows, with this API is possible to get the wintitle of all windows?
iirc using wingettitle, If you script contain multiple guis, it get the title of the last active/focused window
iirc using wingettitle, If you script contain multiple guis, it get the title of the last active/focused window
Re: external process: get working directory (current directory)
@teadrinker - typo?
if SetPrivilege("SeDebugPrivilege") != 0
vs.
if SetPrivilege("SetDebugPrivilege") != 0
if SetPrivilege("SeDebugPrivilege") != 0
vs.
if SetPrivilege("SetDebugPrivilege") != 0
-
- Posts: 4309
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: external process: get working directory (current directory)
I think this code returns the title of the very first window wihch the process was created with.
Nope.
SE_DEBUG_NAME
Re: external process: get working directory (current directory)
I tested with some different processes, only Current Directory, ImagePath, Command Line has a value all others are blankteadrinker wrote: ↑28 May 2022, 11:00This is all in one:Code: Select all
WinGet, PID, PID, ahk_exe explorer.exe Info := GetProcessInfo(PID) MsgBox, % "Current Directory: " . Info.currentDir . "`n`n" . "Dll Path: " . Info.DllPath . "`n`n" . "Image Path: " . Info.ImagePath . "`n" . "Command Line: " . Info.CMD . "`n" . "Window Title: " . Info.WindowTitle . "`n" . "Desktop Info: " . Info.DesktopInfo . "`n" . "Shell Info: " . Info.ShellInfo . "`n" . "Runtime Data: " . Info.RuntimeData GetProcessInfo(PID, setDebugPrivilege := false) { static PROCESS_QUERY_INFORMATION := 0x400, PROCESS_VM_READ := 0x10, STATUS_SUCCESS := 0, setDebug := 0 if (setDebugPrivilege && !setDebug) { RunAsAdmin() if SetPrivilege("SeDebugPrivilege") != 0 throw "Failed to set debug privelege" } hProc := DllCall("OpenProcess", "UInt", PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, "Int", 0, "UInt", PID, "Ptr") (A_Is64bitOS && DllCall("IsWow64Process", "Ptr", hProc, "UIntP", IsWow64)) if (!A_Is64bitOS || IsWow64) PtrSize := 4, PtrType := "UInt", pPtr := "UIntP", offsetCMD := 0x40 else PtrSize := 8, PtrType := "Int64", pPtr := "Int64P", offsetCMD := 0x70 hModule := DllCall("GetModuleHandle", "str", "Ntdll", "Ptr") if (A_PtrSize < PtrSize) { ; script 32, dest proc 64 if !QueryInformationProcess := DllCall("GetProcAddress", "Ptr", hModule, "AStr", "NtWow64QueryInformationProcess64", "Ptr") failed := "NtWow64QueryInformationProcess64" if !ReadProcessMemory := DllCall("GetProcAddress", "Ptr", hModule, "AStr", "NtWow64ReadVirtualMemory64", "Ptr") failed := "NtWow64ReadVirtualMemory64" info := 0, szPBI := 48, offsetPEB := 8 } else { if !QueryInformationProcess := DllCall("GetProcAddress", "Ptr", hModule, "AStr", "NtQueryInformationProcess", "Ptr") failed := "NtQueryInformationProcess" ReadProcessMemory := "ReadProcessMemory" if (A_PtrSize > PtrSize) ; script 64, dest proc 32 info := 26, szPBI := 8, offsetPEB := 0 else ; script and dest proc the same bitness info := 0, szPBI := PtrSize * 6, offsetPEB := PtrSize } if failed { DllCall("CloseHandle", "Ptr", hProc) MsgBox, Failed to get pointer to %failed% Return } VarSetCapacity(PBI, 48, 0) if DllCall(QueryInformationProcess, "Ptr", hProc, "UInt", info, "Ptr", &PBI, "UInt", szPBI, "UIntP", bytes) != STATUS_SUCCESS { DllCall("CloseHandle", "Ptr", hProc) Return } pPEB := NumGet(&PBI + offsetPEB, PtrType) DllCall(ReadProcessMemory, "Ptr", hProc, PtrType, pPEB + PtrSize * 4, pPtr, pRUPP, PtrType, PtrSize, "UIntP", bytes) Info := {} BoundFunc := Func("DllCall").Bind(ReadProcessMemory, "Ptr", hProc, PtrType), params := [pPtr, PtrType, PtrSize] Info.currentDir := ReadUnicodeString(BoundFunc, pRUPP + 16 + PtrSize* 5, params*) Info.DllPath := ReadUnicodeString(BoundFunc, pRUPP + 16 + PtrSize* 8, params*) Info.ImagePath := ReadUnicodeString(BoundFunc, pRUPP + 16 + PtrSize*10, params*) Info.CMD := ReadUnicodeString(BoundFunc, pRUPP + 16 + PtrSize*12, params*) Info.WindowTitle := ReadUnicodeString(BoundFunc, pRUPP + 52 + PtrSize*15, params*) Info.DesktopInfo := ReadUnicodeString(BoundFunc, pRUPP + 52 + PtrSize*17, params*) Info.ShellInfo := ReadUnicodeString(BoundFunc, pRUPP + 52 + PtrSize*19, params*) Info.RuntimeData := ReadUnicodeString(BoundFunc, pRUPP + 52 + PtrSize*21, params*) DllCall("CloseHandle", "Ptr", hProc) Return Info } ReadUnicodeString(BoundFunc, addr, pPtr, PtrType, PtrSize) { BoundFunc.Call(addr, "UShortP", stringSize, PtrType, 2, "UIntP", bytes) BoundFunc.Call(addr + PtrSize, pPtr, pString, PtrType, PtrSize, "UIntP", bytes) VarSetCapacity(buff, stringSize, 0) BoundFunc.Call(pString, "Ptr", &buff, PtrType, stringSize, "UIntP", bytes) Return StrGet(&buff, "UTF-16") } RunAsAdmin(exitIfNotAdmin := false) { commandLine := DllCall("GetCommandLine", "str") isRestarted := !!RegExMatch(commandLine, " /restart(?!\S)") while !( A_IsAdmin || isRestarted ) { try Run, % "*RunAs " . (A_IsCompiled ? """" . A_ScriptFullPath . """ /restart" : """" . A_AhkPath . """ /restart """ . A_ScriptFullPath . """") catch break ExitApp } if !A_IsAdmin { MsgBox, Failed to run the script as admin! if exitIfNotAdmin ExitApp } } SetPrivilege(privilege, enable := true) { static TOKEN_ADJUST_PRIVILEGES := 0x20, SE_PRIVILEGE_ENABLED := 0x2, SE_PRIVILEGE_REMOVED := 0x4 DllCall("Advapi32\OpenProcessToken", "Ptr", -1, "UInt", TOKEN_ADJUST_PRIVILEGES, "PtrP", token) DllCall("Advapi32\LookupPrivilegeValue", "Ptr", 0, "Str", privilege, "Int64P", luid) VarSetCapacity(TOKEN_PRIVILEGES, 16, 0) NumPut(1, TOKEN_PRIVILEGES, "UInt") NumPut(luid, TOKEN_PRIVILEGES, 4, "Int64") NumPut(enable ? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED, TOKEN_PRIVILEGES, 12, "UInt") DllCall("Advapi32\AdjustTokenPrivileges", "Ptr", token, "Int", !enable, "Ptr", &TOKEN_PRIVILEGES, "UInt", 0, "Ptr", 0, "Ptr", 0) res := A_LastError DllCall("CloseHandle", "Ptr", token) DllCall("CloseHandle", "Ptr", hProc) Return res ; success — 0 }
I'm on win10, I also tried running the script as admin, and setting setDebugPrivilege to true
the processes tested were not running with admin privilege
-
- Posts: 4309
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: external process: get working directory (current directory)
For me it returns for the Skype window on Windows 10:
Re: external process: get working directory (current directory)
What's your win version?
I don't have skype, could you try with Microsoft edge?
C:\Program Files (x86)\Microsoft\Edge\Application
I don't have skype, could you try with Microsoft edge?
C:\Program Files (x86)\Microsoft\Edge\Application
Spoiler
Last edited by logan9 on 28 May 2022, 16:12, edited 1 time in total.
-
- Posts: 4309
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: external process: get working directory (current directory)
For the Calculator.exe process:
Current Directory: C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_10.2103.8.0_x64__8wekyb3d8bbwe\
Dll Path: C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_10.2103.8.0_x64__8wekyb3d8bbwe;C:\Program Files\WindowsApps\Microsoft.UI.Xaml.2.4_2.42007.9001.0_x64__8wekyb3d8bbwe;C:\Program Files\WindowsApps\Microsoft.VCLibs.140.00_14.0.30704.0_x64__8wekyb3d8bbwe;
Image Path: C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_10.2103.8.0_x64__8wekyb3d8bbwe\Calculator.exe
Command Line: "C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_10.2103.8.0_x64__8wekyb3d8bbwe\Calculator.exe" -ServerName:App.AppXsm3pg4n7er43kdh1qp4e79f1j7am68r8.mca
Window Title:
Desktop Info:
Shell Info:
Runtime Data:
-
- Posts: 4309
- Joined: 29 Mar 2015, 09:41
- Contact:
-
- Posts: 4309
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: external process: get working directory (current directory)
For msedge the same result.
Re: external process: get working directory (current directory)
the window title is blank, is it not a script error?teadrinker wrote: ↑28 May 2022, 15:58For the Calculator.exe process:Current Directory: C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_10.2103.8.0_x64__8wekyb3d8bbwe\
Dll Path: C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_10.2103.8.0_x64__8wekyb3d8bbwe;C:\Program Files\WindowsApps\Microsoft.UI.Xaml.2.4_2.42007.9001.0_x64__8wekyb3d8bbwe;C:\Program Files\WindowsApps\Microsoft.VCLibs.140.00_14.0.30704.0_x64__8wekyb3d8bbwe;
Image Path: C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_10.2103.8.0_x64__8wekyb3d8bbwe\Calculator.exe
Command Line: "C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_10.2103.8.0_x64__8wekyb3d8bbwe\Calculator.exe" -ServerName:App.AppXsm3pg4n7er43kdh1qp4e79f1j7am68r8.mca
Window Title:
Desktop Info:
Shell Info:
Runtime Data:
-
- Posts: 4309
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: external process: get working directory (current directory)
No, just no info.