如何获取子进程的句柄 uintptr?

huangapple go评论83阅读模式
英文:

How do I get a handle uintptr of a child process?

问题

我想启动一个子进程(我在Windows 10上),并且希望能够随时挂起和恢复该进程。

我找到了一个很好的未记录的Windows函数NtSuspendProcess,它来自于ntdll.dll,应该可以完成这个任务,但是现在我需要获取进程的句柄来发出挂起命令。

这是一个示例:

modntdll := syscall.NewLazyDLL("ntdll.dll")
procNtSuspendProcess := modntdll.NewProc("NtSuspendProcess")
procNtResumeProcess := modntdll.NewProc("NtResumeProcess")
_, _, err := procNtSuspendProcess.Call(uintptr(handle))
_, _, err := procNtResumeProcess.Call(uintptr(handle))

通常,我会使用exec.Command函数来启动进程,但是我找不到一种方法来检索进程的句柄。

在启动进程时有办法获取句柄吗?
如果不能使用exec.Command,那么我应该使用哪个库来启动一个返回进程句柄的进程?

另外一件事:
我已经研究了syscall.StartProcess,但它是相当底层的,我不太能够处理这样的原始实现。

_, handle, err := syscall.StartProcess("C:\\WINDOWS\\system32\\cmd.exe", []string{}, procAttr)
英文:

I want to start a child process (i'm on windows 10) and I would like to be able to suspend and resume the process at will.

I found this neat undocumented windows function NtSuspendProcess from ntdll.dll that should do the job but now I need to get the handle of the process to issue the suspend command.

this is an example:

modntdll = syscall.NewLazyDLL("ntdll.dll")
procNtSuspendProcess = modntdll.NewProc("NtSuspendProcess")
procNtResumeProcess  = modntdll.NewProc("NtResumeProcess")
_, _, err = procNtSuspendProcess.Call(uintptr(handle))
_, _, err = procNtResumeProcess.Call(uintptr(handle))

To start the process I would normally use the exec.Command function but I can't find a way to retrieve the handle of the process.

Is there a way to get the handle when starting a process?
If not with exec.Command, what other library should I use to start a process that returns also the process handle?

As a side note:
I've looked into syscall.StartProcess but it's quite low level and I don't feel able to handle such a raw implementation.

_, handle, err := syscall.StartProcess("C:\\WINDOWS\\system32\\cmd.exe", []string{}, procAttr)

答案1

得分: 1

Go在exec.Command中不公开暴露句柄,你可以通过以下方式访问它:

反射

cmd := exec.Command("cmd.exe")
cmd.Start()
handle := uintptr(reflect.ValueOf(cmd.Process).Elem().FieldByName("handle").Uint())

或者通过创建一个相同的Process类型,并将Cmd.Process强制转换为你自己的类型来访问私有字段。

type Process struct {
   Pid int
   handle uintptr
   isdone uint32
   sigMu sync.RWMutex
}
cmd := exec.Command("cmd.exe")
cmd.Start()
proc := (*Process)(unsafe.Pointer(cmd.Process))
println(proc.handle)
英文:

Go does not publicly expose the handle in exec.Command, you will have to access it either by.

Reflection

cmd := exec.Command("cmd.exe")
cmd.Start()
handle := uintptr(reflect.ValueOf(cmd.Process).Elem().FieldByName("handle").Uint())

or by creating an identical Process type and casting the Cmd.Process to your own type to access the private fields.

type Process struct {
   Pid int
   handle uintptr
   isdone uint32
   sigMu sync.RWMutex
}
cmd := exec.Command("cmd.exe")
cmd.Start()
proc := (*Process)(unsafe.Pointer(cmd.Process))
println(proc.handle)

答案2

得分: 0

"Make that 4"的答案无可挑剔,简洁明了。

我只想补充一个我找到的额外方法,以保证完整性(需要导入golang.org/x/sys/windows
更新:显然,这种方法可能会导致错误/bug,最好不要实现它(请查看评论)

cmd := exec.Command("cmd.exe")
cmd.Start()

// 使用PROCESS_SUSPEND_RESUME,因为我想调用NtSuspendProcess函数
handle, _ := windows.OpenProcess(windows.PROCESS_SUSPEND_RESUME, false, uint32(cmd.Process.Pid))
defer windows.CloseHandle(handle)

fmt.Println(handle)
英文:

The answer by "Make that 4" were both flawless, being simple and well explained.

I would just add an additional method that I found, just for completeness (requires the import of golang.org/x/sys/windows)
Update: apparently this method might lead to bugs/errors and it's probably better not to implement it (check the comments)

cmd := exec.Command("cmd.exe")
cmd.Start()

// using PROCESS_SUSPEND_RESUME since I want to call NtSuspendProcess function
handle, _ := windows.OpenProcess(windows.PROCESS_SUSPEND_RESUME, false, uint32(cmd.Process.Pid))
defer windows.CloseHandle(handle)

fmt.Println(handle)

huangapple
  • 本文由 发表于 2021年6月9日 06:43:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/67895434.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定