|
|
|
@ -3,8 +3,11 @@
|
|
|
|
|
package process
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"C"
|
|
|
|
|
"bytes"
|
|
|
|
|
"context"
|
|
|
|
|
"encoding/binary"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
|
|
|
|
"os/exec"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"strconv"
|
|
|
|
@ -78,19 +81,49 @@ func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
argc := 0
|
|
|
|
|
argvp := unsafe.Pointer(&buf[0])
|
|
|
|
|
argv := *(**C.char)(unsafe.Pointer(argvp))
|
|
|
|
|
size := unsafe.Sizeof(argv)
|
|
|
|
|
/* From man sysctl(2):
|
|
|
|
|
The buffer pointed to by oldp is filled with an array of char
|
|
|
|
|
pointers followed by the strings themselves. The last char
|
|
|
|
|
pointer is a NULL pointer. */
|
|
|
|
|
var strParts []string
|
|
|
|
|
r := bytes.NewReader(buf)
|
|
|
|
|
baseAddr := uintptr(unsafe.Pointer(&buf[0]))
|
|
|
|
|
for {
|
|
|
|
|
argvp, err := readPtr(r)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if argvp == 0 { // check for a NULL pointer
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
offset := argvp - baseAddr
|
|
|
|
|
length := uintptr(bytes.IndexByte(buf[offset:], 0))
|
|
|
|
|
str := string(buf[offset : offset+length])
|
|
|
|
|
strParts = append(strParts, str)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for argv != nil {
|
|
|
|
|
strParts = append(strParts, C.GoString(argv))
|
|
|
|
|
return strParts, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
argc++
|
|
|
|
|
argv = *(**C.char)(unsafe.Pointer(uintptr(argvp) + uintptr(argc)*size))
|
|
|
|
|
// readPtr reads a pointer data from a given reader. WARNING: only little
|
|
|
|
|
// endian architectures are supported.
|
|
|
|
|
func readPtr(r io.Reader) (uintptr, error) {
|
|
|
|
|
switch sizeofPtr {
|
|
|
|
|
case 4:
|
|
|
|
|
var p uint32
|
|
|
|
|
if err := binary.Read(r, binary.LittleEndian, &p); err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
return uintptr(p), nil
|
|
|
|
|
case 8:
|
|
|
|
|
var p uint64
|
|
|
|
|
if err := binary.Read(r, binary.LittleEndian, &p); err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
return uintptr(p), nil
|
|
|
|
|
default:
|
|
|
|
|
return 0, fmt.Errorf("unsupported pointer size")
|
|
|
|
|
}
|
|
|
|
|
return strParts, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
|
|
|
|
|