├── Func ├── PPID Spoofing │ └── ppid.go └── go-netstat │ ├── LICENSE │ ├── README.md │ ├── go.mod │ ├── main.go │ └── netstat │ ├── netstat.go │ ├── netstat_darwin.go │ ├── netstat_linux.go │ ├── netstat_types_darwin.go │ ├── netstat_windows.go │ └── types_darwin.go └── README.md /Func/PPID Spoofing/ppid.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "os/exec" 6 | "syscall" 7 | 8 | "golang.org/x/sys/windows" 9 | 10 | "log" 11 | ) 12 | 13 | func main() { 14 | 15 | startProcess("C:\\windows\\system32\\notepad.exe", "C:\\windows\\system32", nil, 9700, nil, nil, false) 16 | 17 | } 18 | 19 | func startProcess(proc string, currentDir string, args []string, ppid uint32, stdout *bytes.Buffer, stderr *bytes.Buffer, suspended bool) (*exec.Cmd, error) { 20 | var CurrentToken windows.Token 21 | var cmd *exec.Cmd 22 | if len(args) > 0 { 23 | cmd = exec.Command(proc, args...) 24 | } else { 25 | cmd = exec.Command(proc) 26 | } 27 | cmd.SysProcAttr = &windows.SysProcAttr{ 28 | Token: syscall.Token(CurrentToken), 29 | HideWindow: true, 30 | } 31 | err := SpoofParent(ppid, cmd, currentDir) 32 | if err != nil { 33 | log.Printf("could not spoof parent PID: %v\n", err) 34 | } 35 | cmd.Stdout = stdout 36 | cmd.Stderr = stderr 37 | if suspended { 38 | cmd.SysProcAttr.CreationFlags = windows.CREATE_SUSPENDED 39 | } 40 | err = cmd.Start() 41 | if err != nil { 42 | log.Println("Could not start process:", proc) 43 | return nil, err 44 | } 45 | return cmd, nil 46 | } 47 | 48 | func SpoofParent(ppid uint32, cmd *exec.Cmd, currentDir string) error { 49 | parentHandle, err := windows.OpenProcess(windows.PROCESS_CREATE_PROCESS|windows.PROCESS_DUP_HANDLE|windows.PROCESS_QUERY_INFORMATION, false, ppid) 50 | if err != nil { 51 | log.Printf("OpenProcess failed: %v\n", err) 52 | return err 53 | } 54 | if cmd.SysProcAttr == nil { 55 | cmd.SysProcAttr = &windows.SysProcAttr{} 56 | } 57 | cmd.SysProcAttr.ParentProcess = syscall.Handle(parentHandle) 58 | cmd.Dir = currentDir 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /Func/go-netstat/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Cihangir Akturk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Func/go-netstat/README.md: -------------------------------------------------------------------------------- 1 | ### Usage: 2 | 3 | ``` 4 | Usage of ./go-netstat: 5 | -4 display only IPv4 sockets 6 | -6 display only IPv6 sockets 7 | -all 8 | display both listening and non-listening sockets 9 | -help 10 | display this help screen 11 | -lis 12 | display only listening sockets 13 | -res 14 | lookup symbolic names for host addresses 15 | -tcp 16 | display TCP sockets 17 | -udp 18 | display UDP sockets 19 | ``` 20 | ### Installation: 21 | 22 | ``` 23 | $ go get github.com/cakturk/go-netstat 24 | ``` 25 | 26 | ### Using as a library 27 | #### [Godoc](https://godoc.org/github.com/cakturk/go-netstat/netstat) 28 | #### Getting the package 29 | ``` 30 | $ go get github.com/cakturk/go-netstat/netstat 31 | ``` 32 | 33 | ```go 34 | import ( 35 | "fmt" 36 | 37 | "github.com/cakturk/go-netstat/netstat" 38 | ) 39 | 40 | func displaySocks() error { 41 | // UDP sockets 42 | socks, err := netstat.UDPSocks(netstat.NoopFilter) 43 | if err != nil { 44 | return err 45 | } 46 | for _, e := range socks { 47 | fmt.Printf("%v\n", e) 48 | } 49 | 50 | // TCP sockets 51 | socks, err = netstat.TCPSocks(netstat.NoopFilter) 52 | if err != nil { 53 | return err 54 | } 55 | for _, e := range socks { 56 | fmt.Printf("%v\n", e) 57 | } 58 | 59 | // get only listening TCP sockets 60 | tabs, err := netstat.TCPSocks(func(s *netstat.SockTabEntry) bool { 61 | return s.State == netstat.Listen 62 | }) 63 | if err != nil { 64 | return err 65 | } 66 | for _, e := range tabs { 67 | fmt.Printf("%v\n", e) 68 | } 69 | 70 | // list all the TCP sockets in state FIN_WAIT_1 for your HTTP server 71 | tabs, err = netstat.TCPSocks(func(s *netstat.SockTabEntry) bool { 72 | return s.State == netstat.FinWait1 && s.LocalAddr.Port == 80 73 | }) 74 | // error handling, etc. 75 | 76 | return nil 77 | } 78 | ``` 79 | -------------------------------------------------------------------------------- /Func/go-netstat/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/cakturk/go-netstat 2 | 3 | go 1.13 4 | -------------------------------------------------------------------------------- /Func/go-netstat/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "net" 7 | "os" 8 | 9 | "github.com/cakturk/go-netstat/netstat" 10 | ) 11 | 12 | var ( 13 | udp = flag.Bool("udp", false, "display UDP sockets") 14 | tcp = flag.Bool("tcp", false, "display TCP sockets") 15 | listening = flag.Bool("lis", false, "display only listening sockets") 16 | all = flag.Bool("all", false, "display both listening and non-listening sockets") 17 | resolve = flag.Bool("res", false, "lookup symbolic names for host addresses") 18 | ipv4 = flag.Bool("4", false, "display only IPv4 sockets") 19 | ipv6 = flag.Bool("6", false, "display only IPv6 sockets") 20 | help = flag.Bool("help", false, "display this help screen") 21 | ) 22 | 23 | const ( 24 | protoIPv4 = 0x01 25 | protoIPv6 = 0x02 26 | ) 27 | 28 | func main() { 29 | flag.Parse() 30 | 31 | if *help { 32 | flag.Usage() 33 | os.Exit(0) 34 | } 35 | 36 | var proto uint 37 | if *ipv4 { 38 | proto |= protoIPv4 39 | } 40 | if *ipv6 { 41 | proto |= protoIPv6 42 | } 43 | if proto == 0x00 { 44 | proto = protoIPv4 | protoIPv6 45 | } 46 | 47 | if os.Geteuid() != 0 { 48 | fmt.Println("Not all processes could be identified, you would have to be root to see it all.") 49 | } 50 | fmt.Printf("Proto %-23s %-23s %-12s %-16s\n", "Local Addr", "Foreign Addr", "State", "PID/Program name") 51 | 52 | if *udp { 53 | if proto&protoIPv4 == protoIPv4 { 54 | tabs, err := netstat.UDPSocks(netstat.NoopFilter) 55 | if err == nil { 56 | displaySockInfo("udp", tabs) 57 | } 58 | } 59 | if proto&protoIPv6 == protoIPv6 { 60 | tabs, err := netstat.UDP6Socks(netstat.NoopFilter) 61 | if err == nil { 62 | displaySockInfo("udp6", tabs) 63 | } 64 | } 65 | } else { 66 | *tcp = true 67 | } 68 | 69 | if *tcp { 70 | var fn netstat.AcceptFn 71 | 72 | switch { 73 | case *all: 74 | fn = func(*netstat.SockTabEntry) bool { return true } 75 | case *listening: 76 | fn = func(s *netstat.SockTabEntry) bool { 77 | return s.State == netstat.Listen 78 | } 79 | default: 80 | fn = func(s *netstat.SockTabEntry) bool { 81 | return s.State != netstat.Listen 82 | } 83 | } 84 | 85 | if proto&protoIPv4 == protoIPv4 { 86 | tabs, err := netstat.TCPSocks(fn) 87 | if err == nil { 88 | displaySockInfo("tcp", tabs) 89 | } 90 | } 91 | if proto&protoIPv6 == protoIPv6 { 92 | tabs, err := netstat.TCP6Socks(fn) 93 | if err == nil { 94 | displaySockInfo("tcp6", tabs) 95 | } 96 | } 97 | } 98 | } 99 | 100 | func displaySockInfo(proto string, s []netstat.SockTabEntry) { 101 | lookup := func(skaddr *netstat.SockAddr) string { 102 | const IPv4Strlen = 17 103 | addr := skaddr.IP.String() 104 | if *resolve { 105 | names, err := net.LookupAddr(addr) 106 | if err == nil && len(names) > 0 { 107 | addr = names[0] 108 | } 109 | } 110 | if len(addr) > IPv4Strlen { 111 | addr = addr[:IPv4Strlen] 112 | } 113 | return fmt.Sprintf("%s:%d", addr, skaddr.Port) 114 | } 115 | 116 | for _, e := range s { 117 | p := "" 118 | if e.Process != nil { 119 | p = e.Process.String() 120 | } 121 | saddr := lookup(e.LocalAddr) 122 | daddr := lookup(e.RemoteAddr) 123 | fmt.Printf("%-5s %-23.23s %-23.23s %-12s %-16s\n", proto, saddr, daddr, e.State, p) 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /Func/go-netstat/netstat/netstat.go: -------------------------------------------------------------------------------- 1 | package netstat 2 | 3 | /* 4 | MIT License 5 | Copyright (c) 2018 Cihangir Akturk 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | import ( 24 | "fmt" 25 | "net" 26 | ) 27 | 28 | // SockAddr represents an ip:port pair 29 | type SockAddr struct { 30 | IP net.IP 31 | Port uint16 32 | } 33 | 34 | func (s *SockAddr) String() string { 35 | return fmt.Sprintf("%v:%d", s.IP, s.Port) 36 | } 37 | 38 | // SockTabEntry type represents each line of the /proc/net/[tcp|udp] 39 | type SockTabEntry struct { 40 | ino string 41 | LocalAddr *SockAddr 42 | RemoteAddr *SockAddr 43 | State SkState 44 | UID uint32 45 | Process *Process 46 | } 47 | 48 | // Process holds the PID and process name to which each socket belongs 49 | type Process struct { 50 | Pid int 51 | Name string 52 | } 53 | 54 | func (p *Process) String() string { 55 | return fmt.Sprintf("%d/%s", p.Pid, p.Name) 56 | } 57 | 58 | // SkState type represents socket connection state 59 | type SkState uint8 60 | 61 | func (s SkState) String() string { 62 | return skStates[s] 63 | } 64 | 65 | // AcceptFn is used to filter socket entries. The value returned indicates 66 | // whether the element is to be appended to the socket list. 67 | type AcceptFn func(*SockTabEntry) bool 68 | 69 | // NoopFilter - a test function returning true for all elements 70 | func NoopFilter(*SockTabEntry) bool { return true } 71 | 72 | // TCPSocks returns a slice of active TCP sockets containing only those 73 | // elements that satisfy the accept function 74 | func TCPSocks(accept AcceptFn) ([]SockTabEntry, error) { 75 | return osTCPSocks(accept) 76 | } 77 | 78 | // TCP6Socks returns a slice of active TCP IPv4 sockets containing only those 79 | // elements that satisfy the accept function 80 | func TCP6Socks(accept AcceptFn) ([]SockTabEntry, error) { 81 | return osTCP6Socks(accept) 82 | } 83 | 84 | // UDPSocks returns a slice of active UDP sockets containing only those 85 | // elements that satisfy the accept function 86 | func UDPSocks(accept AcceptFn) ([]SockTabEntry, error) { 87 | return osUDPSocks(accept) 88 | } 89 | 90 | // UDP6Socks returns a slice of active UDP IPv6 sockets containing only those 91 | // elements that satisfy the accept function 92 | func UDP6Socks(accept AcceptFn) ([]SockTabEntry, error) { 93 | return osUDP6Socks(accept) 94 | } -------------------------------------------------------------------------------- /Func/go-netstat/netstat/netstat_darwin.go: -------------------------------------------------------------------------------- 1 | package netstat 2 | 3 | import ( 4 | "encoding/binary" 5 | "net" 6 | "unsafe" 7 | 8 | "golang.org/x/sys/unix" 9 | ) 10 | 11 | var skStates = [...]string{ 12 | "CLOSED", 13 | "LISTEN", 14 | "SYN_SENT", 15 | "SYN_RCVD", 16 | "ESTABLISHED", 17 | "CLOSE_WAIT", 18 | "FIN_WAIT_1", 19 | "CLOSING", 20 | "LAST_ACK", 21 | "FIN_WAIT_2", 22 | "TIME_WAIT", 23 | } 24 | 25 | // Socket states 26 | const ( 27 | Closed SkState = 0 << iota 28 | Listen 29 | SynSent 30 | SynRecvd 31 | Established 32 | CloseWait 33 | FinWait1 34 | Closing 35 | LastAck 36 | FinWait2 37 | TimeWait 38 | ) 39 | 40 | const ( 41 | TCP = 1 << iota 42 | UDP 43 | ) 44 | 45 | func osTCPSocks(accept AcceptFn) ([]SockTabEntry, error) { 46 | return parseTCP(INP_IPV4) 47 | } 48 | 49 | func osTCP6Socks(accept AcceptFn) ([]SockTabEntry, error) { 50 | return parseTCP(INP_IPV6) 51 | } 52 | 53 | func osUDPSocks(accept AcceptFn) ([]SockTabEntry, error) { 54 | return parseUDP(INP_IPV4) 55 | } 56 | 57 | func osUDP6Socks(accept AcceptFn) ([]SockTabEntry, error) { 58 | return parseUDP(INP_IPV6) 59 | } 60 | 61 | const ( 62 | INP_IPV4 = 1 << iota 63 | INP_IPV6 64 | ) 65 | 66 | func ntohs(v uint16) uint16 { 67 | bs := make([]byte, 2) 68 | binary.LittleEndian.PutUint16(bs, v) 69 | return binary.BigEndian.Uint16(bs) 70 | } 71 | 72 | func getIP(data [16]byte, family int) net.IP { 73 | var ip net.IP 74 | switch family { 75 | case INP_IPV4: 76 | in4addr := (*InAddr4in6)(unsafe.Pointer(&data[0])) 77 | ip = net.IP(in4addr.Addr4[:]).To4() 78 | case INP_IPV6: 79 | in6addr := (*In6Addr)(unsafe.Pointer(&data[0])) 80 | ip = net.IP(in6addr.X__u6_addr[:]) 81 | } 82 | return ip 83 | } 84 | 85 | func parseTCP(version uint8) ([]SockTabEntry, error) { 86 | entries := make([]SockTabEntry, 0) 87 | buf, err := unix.SysctlRaw("net.inet.tcp.pcblist64") 88 | if err != nil { 89 | return nil, err 90 | } 91 | xinpgen := (*Xinpgen)(unsafe.Pointer(&buf[0])) 92 | current := xinpgen 93 | for i := 1; i < int(xinpgen.Count); i++ { 94 | xig := (*XTCPcb64)(unsafe.Pointer(current)) 95 | inp := (*Xinpcb64)(unsafe.Pointer(&xig.Pad_cgo_0)) 96 | if inp.Inp_vflag&version != 0 { 97 | entry := parseXinpcb64(inp, TCP, version, xig) 98 | entries = append(entries, entry) 99 | } 100 | current = (*Xinpgen)(unsafe.Pointer(uintptr(unsafe.Pointer(current)) + uintptr(current.Len))) 101 | } 102 | return entries, nil 103 | } 104 | 105 | func parseUDP(version uint8) ([]SockTabEntry, error) { 106 | entries := make([]SockTabEntry, 0) 107 | buf, err := unix.SysctlRaw("net.inet.udp.pcblist64") 108 | if err != nil { 109 | return nil, err 110 | } 111 | xinpgen := (*Xinpgen)(unsafe.Pointer(&buf[0])) 112 | current := xinpgen 113 | for i := 1; i < int(xinpgen.Count); i++ { 114 | inp := (*Xinpcb64)(unsafe.Pointer(current)) 115 | if inp.Inp_vflag&version != 0 { 116 | entry := parseXinpcb64(inp, UDP, version, nil) 117 | entries = append(entries, entry) 118 | } 119 | current = (*Xinpgen)(unsafe.Pointer(uintptr(unsafe.Pointer(current)) + uintptr(current.Len))) 120 | } 121 | return entries, nil 122 | } 123 | 124 | func parseXinpcb64(inp *Xinpcb64, transport int, ipVersion uint8, xig *XTCPcb64) SockTabEntry { 125 | var result SockTabEntry 126 | 127 | lport := ntohs(inp.Inp_lport) 128 | fport := ntohs(inp.Inp_fport) 129 | 130 | switch ipVersion { 131 | case INP_IPV4: 132 | result.LocalAddr = &SockAddr{ 133 | IP: getIP(inp.Inp_dependladdr, INP_IPV4), 134 | Port: lport, 135 | } 136 | result.RemoteAddr = &SockAddr{ 137 | IP: getIP(inp.Inp_dependfaddr, INP_IPV4), 138 | Port: fport, 139 | } 140 | case INP_IPV6: 141 | result.LocalAddr = &SockAddr{ 142 | IP: getIP(inp.Inp_dependladdr, INP_IPV6), 143 | Port: lport, 144 | } 145 | result.RemoteAddr = &SockAddr{ 146 | IP: getIP(inp.Inp_dependfaddr, INP_IPV6), 147 | Port: fport, 148 | } 149 | } 150 | if xig != nil { 151 | result.State = SkState(xig.T_state) 152 | } 153 | return result 154 | } -------------------------------------------------------------------------------- /Func/go-netstat/netstat/netstat_linux.go: -------------------------------------------------------------------------------- 1 | package netstat 2 | 3 | /* 4 | Package netstat provides primitives for getting socket information on a 5 | Linux based operating system. 6 | MIT License 7 | Copyright (c) 2018 Cihangir Akturk 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | import ( 26 | "bufio" 27 | "bytes" 28 | "encoding/binary" 29 | "errors" 30 | "fmt" 31 | "io" 32 | "io/ioutil" 33 | "net" 34 | "os" 35 | "path" 36 | "strconv" 37 | "strings" 38 | ) 39 | 40 | const ( 41 | pathTCPTab = "/proc/net/tcp" 42 | pathTCP6Tab = "/proc/net/tcp6" 43 | pathUDPTab = "/proc/net/udp" 44 | pathUDP6Tab = "/proc/net/udp6" 45 | 46 | ipv4StrLen = 8 47 | ipv6StrLen = 32 48 | ) 49 | 50 | // Socket states 51 | const ( 52 | Established SkState = 0x01 53 | SynSent = 0x02 54 | SynRecv = 0x03 55 | FinWait1 = 0x04 56 | FinWait2 = 0x05 57 | TimeWait = 0x06 58 | Close = 0x07 59 | CloseWait = 0x08 60 | LastAck = 0x09 61 | Listen = 0x0a 62 | Closing = 0x0b 63 | ) 64 | 65 | var skStates = [...]string{ 66 | "UNKNOWN", 67 | "ESTABLISHED", 68 | "SYN_SENT", 69 | "SYN_RECV", 70 | "FIN_WAIT1", 71 | "FIN_WAIT2", 72 | "TIME_WAIT", 73 | "", // CLOSE 74 | "CLOSE_WAIT", 75 | "LAST_ACK", 76 | "LISTEN", 77 | "CLOSING", 78 | } 79 | 80 | // Errors returned by gonetstat 81 | var ( 82 | ErrNotEnoughFields = errors.New("gonetstat: not enough fields in the line") 83 | ) 84 | 85 | func parseIPv4(s string) (net.IP, error) { 86 | v, err := strconv.ParseUint(s, 16, 32) 87 | if err != nil { 88 | return nil, err 89 | } 90 | ip := make(net.IP, net.IPv4len) 91 | binary.LittleEndian.PutUint32(ip, uint32(v)) 92 | return ip, nil 93 | } 94 | 95 | func parseIPv6(s string) (net.IP, error) { 96 | ip := make(net.IP, net.IPv6len) 97 | const grpLen = 4 98 | i, j := 0, 4 99 | for len(s) != 0 { 100 | grp := s[0:8] 101 | u, err := strconv.ParseUint(grp, 16, 32) 102 | binary.LittleEndian.PutUint32(ip[i:j], uint32(u)) 103 | if err != nil { 104 | return nil, err 105 | } 106 | i, j = i+grpLen, j+grpLen 107 | s = s[8:] 108 | } 109 | return ip, nil 110 | } 111 | 112 | func parseAddr(s string) (*SockAddr, error) { 113 | fields := strings.Split(s, ":") 114 | if len(fields) < 2 { 115 | return nil, fmt.Errorf("netstat: not enough fields: %v", s) 116 | } 117 | var ip net.IP 118 | var err error 119 | switch len(fields[0]) { 120 | case ipv4StrLen: 121 | ip, err = parseIPv4(fields[0]) 122 | case ipv6StrLen: 123 | ip, err = parseIPv6(fields[0]) 124 | default: 125 | return nil, fmt.Errorf("Bad formatted string") 126 | } 127 | if err != nil { 128 | return nil, err 129 | } 130 | v, err := strconv.ParseUint(fields[1], 16, 16) 131 | if err != nil { 132 | return nil, err 133 | } 134 | return &SockAddr{IP: ip, Port: uint16(v)}, nil 135 | } 136 | 137 | func parseSocktab(r io.Reader, accept AcceptFn) ([]SockTabEntry, error) { 138 | br := bufio.NewScanner(r) 139 | tab := make([]SockTabEntry, 0, 4) 140 | 141 | // Discard title 142 | br.Scan() 143 | 144 | for br.Scan() { 145 | var e SockTabEntry 146 | line := br.Text() 147 | // Skip comments 148 | if i := strings.Index(line, "#"); i >= 0 { 149 | line = line[:i] 150 | } 151 | fields := strings.Fields(line) 152 | if len(fields) < 12 { 153 | return nil, fmt.Errorf("netstat: not enough fields: %v, %v", len(fields), fields) 154 | } 155 | addr, err := parseAddr(fields[1]) 156 | if err != nil { 157 | return nil, err 158 | } 159 | e.LocalAddr = addr 160 | addr, err = parseAddr(fields[2]) 161 | if err != nil { 162 | return nil, err 163 | } 164 | e.RemoteAddr = addr 165 | u, err := strconv.ParseUint(fields[3], 16, 8) 166 | if err != nil { 167 | return nil, err 168 | } 169 | e.State = SkState(u) 170 | u, err = strconv.ParseUint(fields[7], 10, 32) 171 | if err != nil { 172 | return nil, err 173 | } 174 | e.UID = uint32(u) 175 | e.ino = fields[9] 176 | if accept(&e) { 177 | tab = append(tab, e) 178 | } 179 | } 180 | return tab, br.Err() 181 | } 182 | 183 | type procFd struct { 184 | base string 185 | pid int 186 | sktab []SockTabEntry 187 | p *Process 188 | } 189 | 190 | var sockPrefix = "socket:[" 191 | 192 | func getProcName(s []byte) string { 193 | i := bytes.Index(s, []byte("(")) 194 | if i < 0 { 195 | return "" 196 | } 197 | j := bytes.LastIndex(s, []byte(")")) 198 | if i < 0 { 199 | return "" 200 | } 201 | if i > j { 202 | return "" 203 | } 204 | return string(s[i+1 : j]) 205 | } 206 | 207 | func (p *procFd) iterFdDir() { 208 | // link name is of the form socket:[5860846] 209 | fddir := path.Join(p.base, "/fd") 210 | fi, err := ioutil.ReadDir(fddir) 211 | if err != nil { 212 | return 213 | } 214 | var buf [128]byte 215 | 216 | for _, file := range fi { 217 | fd := path.Join(fddir, file.Name()) 218 | lname, err := os.Readlink(fd) 219 | if err != nil { 220 | continue 221 | } 222 | 223 | for i := range p.sktab { 224 | sk := &p.sktab[i] 225 | ss := sockPrefix + sk.ino + "]" 226 | if ss != lname { 227 | continue 228 | } 229 | if p.p == nil { 230 | stat, err := os.Open(path.Join(p.base, "stat")) 231 | if err != nil { 232 | return 233 | } 234 | n, err := stat.Read(buf[:]) 235 | stat.Close() 236 | if err != nil { 237 | return 238 | } 239 | z := bytes.SplitN(buf[:n], []byte(" "), 3) 240 | name := getProcName(z[1]) 241 | p.p = &Process{p.pid, name} 242 | } 243 | sk.Process = p.p 244 | } 245 | } 246 | } 247 | 248 | func extractProcInfo(sktab []SockTabEntry) { 249 | var basedir = "/proc" 250 | fi, err := ioutil.ReadDir(basedir) 251 | if err != nil { 252 | return 253 | } 254 | 255 | for _, file := range fi { 256 | if !file.IsDir() { 257 | continue 258 | } 259 | pid, err := strconv.Atoi(file.Name()) 260 | if err != nil { 261 | continue 262 | } 263 | base := path.Join(basedir, file.Name()) 264 | proc := procFd{base: base, pid: pid, sktab: sktab} 265 | proc.iterFdDir() 266 | } 267 | } 268 | 269 | // doNetstat - collect information about network port status 270 | func doNetstat(path string, fn AcceptFn) ([]SockTabEntry, error) { 271 | f, err := os.Open(path) 272 | if err != nil { 273 | return nil, err 274 | } 275 | tabs, err := parseSocktab(f, fn) 276 | f.Close() 277 | if err != nil { 278 | return nil, err 279 | } 280 | extractProcInfo(tabs) 281 | return tabs, nil 282 | } 283 | 284 | // TCPSocks returns a slice of active TCP sockets containing only those 285 | // elements that satisfy the accept function 286 | func osTCPSocks(accept AcceptFn) ([]SockTabEntry, error) { 287 | return doNetstat(pathTCPTab, accept) 288 | } 289 | 290 | // TCP6Socks returns a slice of active TCP IPv4 sockets containing only those 291 | // elements that satisfy the accept function 292 | func osTCP6Socks(accept AcceptFn) ([]SockTabEntry, error) { 293 | return doNetstat(pathTCP6Tab, accept) 294 | } 295 | 296 | // UDPSocks returns a slice of active UDP sockets containing only those 297 | // elements that satisfy the accept function 298 | func osUDPSocks(accept AcceptFn) ([]SockTabEntry, error) { 299 | return doNetstat(pathUDPTab, accept) 300 | } 301 | 302 | // UDP6Socks returns a slice of active UDP IPv6 sockets containing only those 303 | // elements that satisfy the accept function 304 | func osUDP6Socks(accept AcceptFn) ([]SockTabEntry, error) { 305 | return doNetstat(pathUDP6Tab, accept) 306 | } -------------------------------------------------------------------------------- /Func/go-netstat/netstat/netstat_types_darwin.go: -------------------------------------------------------------------------------- 1 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 2 | // cgo -godefs /Users/lesnuages/code/go/src/github.com/lesnuages/netstat/netstat/types_darwin.go 3 | 4 | package netstat 5 | 6 | const ( 7 | sizeofPtr = 0x8 8 | sizeofShort = 0x2 9 | sizeofInt = 0x4 10 | sizeofLong = 0x8 11 | sizeofLongLong = 0x8 12 | ) 13 | 14 | type ( 15 | _C_short int16 16 | _C_int int32 17 | _C_long int64 18 | _C_long_long int64 19 | ) 20 | 21 | type In6Addr struct { 22 | X__u6_addr [16]byte 23 | } 24 | 25 | type InAddr4in6 struct { 26 | Pad32 [3]uint32 27 | Addr4 [4]byte /* in_addr */ 28 | } 29 | 30 | type XSockbuf struct { 31 | Cc uint32 32 | Hiwat uint32 33 | Mbcnt uint32 34 | Mbmax uint32 35 | Lowat int32 36 | Flags int16 37 | Timeo int16 38 | } 39 | 40 | type XSocket64 struct { 41 | Xso_len uint32 42 | Pad_cgo_0 [8]byte 43 | So_type int16 44 | So_options int16 45 | So_linger int16 46 | So_state int16 47 | Pad_cgo_1 [8]byte 48 | Xso_protocol int32 49 | Xso_family int32 50 | So_qlen int16 51 | So_incqlen int16 52 | So_qlimit int16 53 | So_timeo int16 54 | So_error uint16 55 | So_pgid int32 56 | So_oobmark uint32 57 | So_rcv XSockbuf 58 | So_snd XSockbuf 59 | So_uid uint32 60 | } 61 | 62 | type Xinpgen struct { 63 | Len uint32 64 | Count uint32 65 | Gen uint64 66 | Sogen uint64 67 | } 68 | 69 | type InPCB64ListEntry struct { 70 | Next uint64 71 | Prev uint64 72 | } 73 | 74 | type Xinpcb64 struct { 75 | Xi_len uint64 76 | Xi_inpp uint64 77 | Inp_fport uint16 78 | Inp_lport uint16 79 | Pad_cgo_0 [64]byte 80 | Inp_flags int32 81 | Inp_flow uint32 82 | Inp_vflag uint8 83 | Inp_ip_ttl uint8 84 | Inp_ip_p uint8 85 | Pad_cgo_1 [1]byte 86 | Inp_dependfaddr [16]byte 87 | Inp_dependladdr [16]byte 88 | // Inp_depend4 _Ctype_struct___3 89 | // Inp_depend6 _Ctype_struct___4 90 | Xi_socket XSocket64 91 | Pad_cgo_2 [8]byte 92 | } 93 | 94 | type XTCPcb64 struct { 95 | Xt_len uint32 96 | Pad_cgo_0 [256]byte 97 | T_segq uint64 98 | T_dupacks int32 99 | T_timer [4]int32 100 | T_state int32 101 | T_flags uint32 102 | T_force int32 103 | Snd_una uint32 104 | Snd_max uint32 105 | Snd_nxt uint32 106 | Snd_up uint32 107 | Snd_wl1 uint32 108 | Snd_wl2 uint32 109 | Iss uint32 110 | Irs uint32 111 | Rcv_nxt uint32 112 | Rcv_adv uint32 113 | Rcv_wnd uint32 114 | Rcv_up uint32 115 | Snd_wnd uint32 116 | Snd_cwnd uint32 117 | Snd_ssthresh uint32 118 | T_maxopd uint32 119 | T_rcvtime uint32 120 | T_starttime uint32 121 | T_rtttime int32 122 | T_rtseq uint32 123 | T_rxtcur int32 124 | T_maxseg uint32 125 | T_srtt int32 126 | T_rttvar int32 127 | T_rxtshift int32 128 | T_rttmin uint32 129 | T_rttupdated uint32 130 | Max_sndwnd uint32 131 | T_softerror int32 132 | T_oobflags int8 133 | T_iobc int8 134 | Snd_scale uint8 135 | Rcv_scale uint8 136 | Request_r_scale uint8 137 | Requested_s_scale uint8 138 | Ts_recent uint32 139 | Ts_recent_age uint32 140 | Last_ack_sent uint32 141 | Cc_send uint32 142 | Cc_recv uint32 143 | Snd_recover uint32 144 | Snd_cwnd_prev uint32 145 | Snd_ssthresh_prev uint32 146 | T_badrxtwin uint32 147 | Xt_alignment_hack uint64 148 | } -------------------------------------------------------------------------------- /Func/go-netstat/netstat/netstat_windows.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | Copyright (c) 2018 Cihangir Akturk 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | */ 20 | 21 | package netstat 22 | 23 | import ( 24 | "bytes" 25 | "encoding/binary" 26 | "errors" 27 | "fmt" 28 | "net" 29 | "reflect" 30 | "syscall" 31 | "unsafe" 32 | ) 33 | 34 | const ( 35 | errInsuffBuff = syscall.Errno(122) 36 | 37 | Th32csSnapProcess = uint32(0x00000002) 38 | InvalidHandleValue = ^uintptr(0) 39 | MaxPath = 260 40 | ) 41 | 42 | var ( 43 | errNoMoreFiles = errors.New("no more files have been found") 44 | 45 | modiphlpapi = syscall.NewLazyDLL("Iphlpapi.dll") 46 | modkernel32 = syscall.NewLazyDLL("Kernel32.dll") 47 | 48 | procGetTCPTable2 = modiphlpapi.NewProc("GetTcpTable2") 49 | procGetTCP6Table2 = modiphlpapi.NewProc("GetTcp6Table2") 50 | procGetExtendedUDPTable = modiphlpapi.NewProc("GetExtendedUdpTable") 51 | procCreateSnapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") 52 | procProcess32First = modkernel32.NewProc("Process32First") 53 | procProcess32Next = modkernel32.NewProc("Process32Next") 54 | ) 55 | 56 | // Socket states 57 | const ( 58 | Close SkState = 0x01 59 | Listen = 0x02 60 | SynSent = 0x03 61 | SynRecv = 0x04 62 | Established = 0x05 63 | FinWait1 = 0x06 64 | FinWait2 = 0x07 65 | CloseWait = 0x08 66 | Closing = 0x09 67 | LastAck = 0x0a 68 | TimeWait = 0x0b 69 | DeleteTcb = 0x0c 70 | ) 71 | 72 | var skStates = [...]string{ 73 | "UNKNOWN", 74 | "", // CLOSE 75 | "LISTEN", 76 | "SYN_SENT", 77 | "SYN_RECV", 78 | "ESTABLISHED", 79 | "FIN_WAIT1", 80 | "FIN_WAIT2", 81 | "CLOSE_WAIT", 82 | "CLOSING", 83 | "LAST_ACK", 84 | "TIME_WAIT", 85 | "DELETE_TCB", 86 | } 87 | 88 | func memToIPv4(p unsafe.Pointer) net.IP { 89 | a := (*[net.IPv4len]byte)(p) 90 | ip := make(net.IP, net.IPv4len) 91 | copy(ip, a[:]) 92 | return ip 93 | } 94 | 95 | func memToIPv6(p unsafe.Pointer) net.IP { 96 | a := (*[net.IPv6len]byte)(p) 97 | ip := make(net.IP, net.IPv6len) 98 | copy(ip, a[:]) 99 | return ip 100 | } 101 | 102 | func memtohs(n unsafe.Pointer) uint16 { 103 | return binary.BigEndian.Uint16((*[2]byte)(n)[:]) 104 | } 105 | 106 | type WinSock struct { 107 | Addr uint32 108 | Port uint32 109 | } 110 | 111 | func (w *WinSock) Sock() *SockAddr { 112 | ip := memToIPv4(unsafe.Pointer(&w.Addr)) 113 | port := memtohs(unsafe.Pointer(&w.Port)) 114 | return &SockAddr{IP: ip, Port: port} 115 | } 116 | 117 | type WinSock6 struct { 118 | Addr [net.IPv6len]byte 119 | ScopeID uint32 120 | Port uint32 121 | } 122 | 123 | func (w *WinSock6) Sock() *SockAddr { 124 | ip := memToIPv6(unsafe.Pointer(&w.Addr[0])) 125 | port := memtohs(unsafe.Pointer(&w.Port)) 126 | return &SockAddr{IP: ip, Port: port} 127 | } 128 | 129 | type MibTCPRow2 struct { 130 | State uint32 131 | LocalAddr WinSock 132 | RemoteAddr WinSock 133 | WinPid 134 | OffloadState uint32 135 | } 136 | 137 | type WinPid uint32 138 | 139 | func (pid WinPid) Process(snp ProcessSnapshot) *Process { 140 | if pid < 1 { 141 | return nil 142 | } 143 | return &Process{ 144 | Pid: int(pid), 145 | Name: snp.ProcPIDToName(uint32(pid)), 146 | } 147 | } 148 | 149 | func (m *MibTCPRow2) LocalSock() *SockAddr { return m.LocalAddr.Sock() } 150 | func (m *MibTCPRow2) RemoteSock() *SockAddr { return m.RemoteAddr.Sock() } 151 | func (m *MibTCPRow2) SockState() SkState { return SkState(m.State) } 152 | 153 | type MibTCPTable2 struct { 154 | NumEntries uint32 155 | Table [1]MibTCPRow2 156 | } 157 | 158 | func (t *MibTCPTable2) Rows() []MibTCPRow2 { 159 | var s []MibTCPRow2 160 | hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s)) 161 | hdr.Data = uintptr(unsafe.Pointer(&t.Table[0])) 162 | hdr.Len = int(t.NumEntries) 163 | hdr.Cap = int(t.NumEntries) 164 | return s 165 | } 166 | 167 | // MibTCP6Row2 structure contains information that describes an IPv6 TCP 168 | // connection. 169 | type MibTCP6Row2 struct { 170 | LocalAddr WinSock6 171 | RemoteAddr WinSock6 172 | State uint32 173 | WinPid 174 | OffloadState uint32 175 | } 176 | 177 | func (m *MibTCP6Row2) LocalSock() *SockAddr { return m.LocalAddr.Sock() } 178 | func (m *MibTCP6Row2) RemoteSock() *SockAddr { return m.RemoteAddr.Sock() } 179 | func (m *MibTCP6Row2) SockState() SkState { return SkState(m.State) } 180 | 181 | // MibTCP6Table2 structure contains a table of IPv6 TCP connections on the 182 | // local computer. 183 | type MibTCP6Table2 struct { 184 | NumEntries uint32 185 | Table [1]MibTCP6Row2 186 | } 187 | 188 | func (t *MibTCP6Table2) Rows() []MibTCP6Row2 { 189 | var s []MibTCP6Row2 190 | hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s)) 191 | hdr.Data = uintptr(unsafe.Pointer(&t.Table[0])) 192 | hdr.Len = int(t.NumEntries) 193 | hdr.Cap = int(t.NumEntries) 194 | return s 195 | } 196 | 197 | // MibUDPRowOwnerPID structure contains an entry from the User Datagram 198 | // Protocol (UDP) listener table for IPv4 on the local computer. The entry also 199 | // includes the process ID (PID) that issued the call to the bind function for 200 | // the UDP endpoint 201 | type MibUDPRowOwnerPID struct { 202 | WinSock 203 | WinPid 204 | } 205 | 206 | func (m *MibUDPRowOwnerPID) LocalSock() *SockAddr { return m.Sock() } 207 | func (m *MibUDPRowOwnerPID) RemoteSock() *SockAddr { return &SockAddr{net.IPv4zero, 0} } 208 | func (m *MibUDPRowOwnerPID) SockState() SkState { return Close } 209 | 210 | // MibUDPTableOwnerPID structure contains the User Datagram Protocol (UDP) 211 | // listener table for IPv4 on the local computer. The table also includes the 212 | // process ID (PID) that issued the call to the bind function for each UDP 213 | // endpoint. 214 | type MibUDPTableOwnerPID struct { 215 | NumEntries uint32 216 | Table [1]MibUDPRowOwnerPID 217 | } 218 | 219 | func (t *MibUDPTableOwnerPID) Rows() []MibUDPRowOwnerPID { 220 | var s []MibUDPRowOwnerPID 221 | hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s)) 222 | hdr.Data = uintptr(unsafe.Pointer(&t.Table[0])) 223 | hdr.Len = int(t.NumEntries) 224 | hdr.Cap = int(t.NumEntries) 225 | return s 226 | } 227 | 228 | // MibUDP6RowOwnerPID serves the same purpose as MibUDPRowOwnerPID, except that 229 | // the information in this case is for IPv6. 230 | type MibUDP6RowOwnerPID struct { 231 | WinSock6 232 | WinPid 233 | } 234 | 235 | func (m *MibUDP6RowOwnerPID) LocalSock() *SockAddr { return m.Sock() } 236 | func (m *MibUDP6RowOwnerPID) RemoteSock() *SockAddr { return &SockAddr{net.IPv4zero, 0} } 237 | func (m *MibUDP6RowOwnerPID) SockState() SkState { return Close } 238 | 239 | // MibUDP6TableOwnerPID serves the same purpose as MibUDPTableOwnerPID for IPv6 240 | type MibUDP6TableOwnerPID struct { 241 | NumEntries uint32 242 | Table [1]MibUDP6RowOwnerPID 243 | } 244 | 245 | func (t *MibUDP6TableOwnerPID) Rows() []MibUDP6RowOwnerPID { 246 | var s []MibUDP6RowOwnerPID 247 | hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s)) 248 | hdr.Data = uintptr(unsafe.Pointer(&t.Table[0])) 249 | hdr.Len = int(t.NumEntries) 250 | hdr.Cap = int(t.NumEntries) 251 | return s 252 | } 253 | 254 | // Processentry32 describes an entry from a list of the processes residing in 255 | // the system address space when a snapshot was taken 256 | type Processentry32 struct { 257 | Size uint32 258 | CntUsage uint32 259 | Th32ProcessID uint32 260 | Th32DefaultHeapID uintptr 261 | Th32ModuleID uint32 262 | CntThreads uint32 263 | Th32ParentProcessID uint32 264 | PriClassBase int32 265 | Flags uint32 266 | ExeFile [MaxPath]byte 267 | } 268 | 269 | func rawGetTCPTable2(proc uintptr, tab unsafe.Pointer, size *uint32, order bool) error { 270 | var oint uintptr 271 | if order { 272 | oint = 1 273 | } 274 | r1, _, callErr := syscall.Syscall( 275 | proc, 276 | uintptr(3), 277 | uintptr(tab), 278 | uintptr(unsafe.Pointer(size)), 279 | oint) 280 | if callErr != 0 { 281 | return callErr 282 | } 283 | if r1 != 0 { 284 | return syscall.Errno(r1) 285 | } 286 | return nil 287 | } 288 | 289 | func getTCPTable2(proc uintptr, order bool) ([]byte, error) { 290 | var ( 291 | size uint32 292 | buf []byte 293 | ) 294 | 295 | // determine size 296 | err := rawGetTCPTable2(proc, unsafe.Pointer(nil), &size, false) 297 | if err != nil && err != errInsuffBuff { 298 | return nil, err 299 | } 300 | buf = make([]byte, size) 301 | table := unsafe.Pointer(&buf[0]) 302 | err = rawGetTCPTable2(proc, table, &size, true) 303 | if err != nil { 304 | return nil, err 305 | } 306 | return buf, nil 307 | } 308 | 309 | // GetTCPTable2 function retrieves the IPv4 TCP connection table 310 | func GetTCPTable2(order bool) (*MibTCPTable2, error) { 311 | b, err := getTCPTable2(procGetTCPTable2.Addr(), true) 312 | if err != nil { 313 | return nil, err 314 | } 315 | return (*MibTCPTable2)(unsafe.Pointer(&b[0])), nil 316 | } 317 | 318 | // GetTCP6Table2 function retrieves the IPv6 TCP connection table 319 | func GetTCP6Table2(order bool) (*MibTCP6Table2, error) { 320 | b, err := getTCPTable2(procGetTCP6Table2.Addr(), true) 321 | if err != nil { 322 | return nil, err 323 | } 324 | return (*MibTCP6Table2)(unsafe.Pointer(&b[0])), nil 325 | } 326 | 327 | // The UDPTableClass enumeration defines the set of values used to indicate 328 | // the type of table returned by calls to GetExtendedUDPTable 329 | type UDPTableClass uint 330 | 331 | // Possible table class values 332 | const ( 333 | UDPTableBasic UDPTableClass = iota 334 | UDPTableOwnerPID 335 | UDPTableOwnerModule 336 | ) 337 | 338 | func getExtendedUDPTable(table unsafe.Pointer, size *uint32, order bool, af uint32, cl UDPTableClass) error { 339 | var oint uintptr 340 | if order { 341 | oint = 1 342 | } 343 | r1, _, callErr := syscall.Syscall6( 344 | procGetExtendedUDPTable.Addr(), 345 | uintptr(6), 346 | uintptr(table), 347 | uintptr(unsafe.Pointer(size)), 348 | oint, 349 | uintptr(af), 350 | uintptr(cl), 351 | uintptr(0)) 352 | if callErr != 0 { 353 | return callErr 354 | } 355 | if r1 != 0 { 356 | return syscall.Errno(r1) 357 | } 358 | return nil 359 | } 360 | 361 | // GetExtendedUDPTable function retrieves a table that contains a list of UDP 362 | // endpoints available to the application 363 | func GetExtendedUDPTable(order bool, af uint32, cl UDPTableClass) ([]byte, error) { 364 | var size uint32 365 | err := getExtendedUDPTable(nil, &size, order, af, cl) 366 | if err != nil && err != errInsuffBuff { 367 | return nil, err 368 | } 369 | buf := make([]byte, size) 370 | err = getExtendedUDPTable(unsafe.Pointer(&buf[0]), &size, order, af, cl) 371 | if err != nil { 372 | return nil, err 373 | } 374 | return buf, nil 375 | } 376 | 377 | func GetUDPTableOwnerPID(order bool) (*MibUDPTableOwnerPID, error) { 378 | b, err := GetExtendedUDPTable(true, syscall.AF_INET, UDPTableOwnerPID) 379 | if err != nil { 380 | return nil, err 381 | } 382 | return (*MibUDPTableOwnerPID)(unsafe.Pointer(&b[0])), nil 383 | } 384 | 385 | func GetUDP6TableOwnerPID(order bool) (*MibUDP6TableOwnerPID, error) { 386 | b, err := GetExtendedUDPTable(true, syscall.AF_INET6, UDPTableOwnerPID) 387 | if err != nil { 388 | return nil, err 389 | } 390 | return (*MibUDP6TableOwnerPID)(unsafe.Pointer(&b[0])), nil 391 | } 392 | 393 | // ProcessSnapshot wraps the syscall.Handle, which represents a snapshot of 394 | // the specified processes. 395 | type ProcessSnapshot syscall.Handle 396 | 397 | // CreateToolhelp32Snapshot takes a snapshot of the specified processes, as 398 | // well as the heaps, modules, and threads used by these processes 399 | func CreateToolhelp32Snapshot(flags uint32, pid uint32) (ProcessSnapshot, error) { 400 | r1, _, callErr := syscall.Syscall( 401 | procCreateSnapshot.Addr(), 402 | uintptr(2), 403 | uintptr(flags), 404 | uintptr(pid), 0) 405 | ret := ProcessSnapshot(r1) 406 | if callErr != 0 { 407 | return ret, callErr 408 | } 409 | if r1 == InvalidHandleValue { 410 | return ret, fmt.Errorf("invalid handle value: %#v", r1) 411 | } 412 | return ret, nil 413 | } 414 | 415 | // ProcPIDToName translates PID to a name 416 | func (snp ProcessSnapshot) ProcPIDToName(pid uint32) string { 417 | var processEntry Processentry32 418 | processEntry.Size = uint32(unsafe.Sizeof(processEntry)) 419 | handle := syscall.Handle(snp) 420 | err := Process32First(handle, &processEntry) 421 | if err != nil { 422 | return "" 423 | } 424 | for { 425 | if processEntry.Th32ProcessID == pid { 426 | return StringFromNullTerminated(processEntry.ExeFile[:]) 427 | } 428 | err = Process32Next(handle, &processEntry) 429 | if err != nil { 430 | return "" 431 | } 432 | } 433 | } 434 | 435 | // Close releases underlying win32 handle 436 | func (snp ProcessSnapshot) Close() error { 437 | return syscall.CloseHandle(syscall.Handle(snp)) 438 | } 439 | 440 | // Process32First retrieves information about the first process encountered 441 | // in a system snapshot 442 | func Process32First(handle syscall.Handle, pe *Processentry32) error { 443 | pe.Size = uint32(unsafe.Sizeof(*pe)) 444 | r1, _, callErr := syscall.Syscall( 445 | procProcess32First.Addr(), 446 | uintptr(2), 447 | uintptr(handle), 448 | uintptr(unsafe.Pointer(pe)), 0) 449 | if callErr != 0 { 450 | return callErr 451 | } 452 | if r1 == 0 { 453 | return errNoMoreFiles 454 | } 455 | return nil 456 | } 457 | 458 | // Process32Next retrieves information about the next process 459 | // recorded in a system snapshot 460 | func Process32Next(handle syscall.Handle, pe *Processentry32) error { 461 | pe.Size = uint32(unsafe.Sizeof(*pe)) 462 | r1, _, callErr := syscall.Syscall( 463 | procProcess32Next.Addr(), 464 | uintptr(2), 465 | uintptr(handle), 466 | uintptr(unsafe.Pointer(pe)), 0) 467 | if callErr != 0 { 468 | return callErr 469 | } 470 | if r1 == 0 { 471 | return errNoMoreFiles 472 | } 473 | return nil 474 | } 475 | 476 | // StringFromNullTerminated returns a string from a nul-terminated byte slice 477 | func StringFromNullTerminated(b []byte) string { 478 | n := bytes.IndexByte(b, '\x00') 479 | if n < 1 { 480 | return "" 481 | } 482 | return string(b[:n]) 483 | } 484 | 485 | type winSockEnt interface { 486 | LocalSock() *SockAddr 487 | RemoteSock() *SockAddr 488 | SockState() SkState 489 | Process(snp ProcessSnapshot) *Process 490 | } 491 | 492 | func toSockTabEntry(ws winSockEnt, snp ProcessSnapshot) SockTabEntry { 493 | return SockTabEntry{ 494 | LocalAddr: ws.LocalSock(), 495 | RemoteAddr: ws.RemoteSock(), 496 | State: ws.SockState(), 497 | Process: ws.Process(snp), 498 | } 499 | } 500 | 501 | func osTCPSocks(accept AcceptFn) ([]SockTabEntry, error) { 502 | tbl, err := GetTCPTable2(true) 503 | if err != nil { 504 | return nil, err 505 | } 506 | snp, err := CreateToolhelp32Snapshot(Th32csSnapProcess, 0) 507 | if err != nil { 508 | return nil, err 509 | } 510 | var sktab []SockTabEntry 511 | s := tbl.Rows() 512 | for i := range s { 513 | ent := toSockTabEntry(&s[i], snp) 514 | if accept(&ent) { 515 | sktab = append(sktab, ent) 516 | } 517 | } 518 | snp.Close() 519 | return sktab, nil 520 | } 521 | 522 | func osTCP6Socks(accept AcceptFn) ([]SockTabEntry, error) { 523 | tbl, err := GetTCP6Table2(true) 524 | if err != nil { 525 | return nil, err 526 | } 527 | snp, err := CreateToolhelp32Snapshot(Th32csSnapProcess, 0) 528 | if err != nil { 529 | return nil, err 530 | } 531 | var sktab []SockTabEntry 532 | s := tbl.Rows() 533 | for i := range s { 534 | ent := toSockTabEntry(&s[i], snp) 535 | if accept(&ent) { 536 | sktab = append(sktab, ent) 537 | } 538 | } 539 | snp.Close() 540 | return sktab, nil 541 | } 542 | 543 | func osUDPSocks(accept AcceptFn) ([]SockTabEntry, error) { 544 | tbl, err := GetUDPTableOwnerPID(true) 545 | if err != nil { 546 | return nil, err 547 | } 548 | snp, err := CreateToolhelp32Snapshot(Th32csSnapProcess, 0) 549 | if err != nil { 550 | return nil, err 551 | } 552 | var sktab []SockTabEntry 553 | s := tbl.Rows() 554 | for i := range s { 555 | ent := toSockTabEntry(&s[i], snp) 556 | if accept(&ent) { 557 | sktab = append(sktab, ent) 558 | } 559 | } 560 | snp.Close() 561 | return sktab, nil 562 | } 563 | 564 | func osUDP6Socks(accept AcceptFn) ([]SockTabEntry, error) { 565 | tbl, err := GetUDP6TableOwnerPID(true) 566 | if err != nil { 567 | return nil, err 568 | } 569 | snp, err := CreateToolhelp32Snapshot(Th32csSnapProcess, 0) 570 | if err != nil { 571 | return nil, err 572 | } 573 | var sktab []SockTabEntry 574 | s := tbl.Rows() 575 | for i := range s { 576 | ent := toSockTabEntry(&s[i], snp) 577 | if accept(&ent) { 578 | sktab = append(sktab, ent) 579 | } 580 | } 581 | snp.Close() 582 | return sktab, nil 583 | } -------------------------------------------------------------------------------- /Func/go-netstat/netstat/types_darwin.go: -------------------------------------------------------------------------------- 1 | // +build ignore 2 | 3 | /* 4 | Input to cgo -godefs. 5 | */ 6 | 7 | // +godefs map struct_in_addr [4]byte /* in_addr */ 8 | // +godefs map struct_in6_addr [16]byte /* in6_addr */ 9 | // +godefs map struct_ [16]byte /* in6_addr */ 10 | 11 | package netstat 12 | 13 | /* 14 | #define __DARWIN_UNIX03 0 15 | #define KERNEL 1 16 | #define XNU_TARGET_OS_OSX 1 17 | #define _DARWIN_USE_64_BIT_INODE 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #define TCPSTATES 33 | #include 34 | #include 35 | enum { 36 | sizeofPtr = sizeof(void*), 37 | }; 38 | union sockaddr_all { 39 | struct sockaddr s1; // this one gets used for fields 40 | struct sockaddr_in s2; // these pad it out 41 | struct sockaddr_in6 s3; 42 | struct sockaddr_un s4; 43 | struct sockaddr_dl s5; 44 | }; 45 | struct sockaddr_any { 46 | struct sockaddr addr; 47 | char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; 48 | }; 49 | */ 50 | import "C" 51 | 52 | // Machine characteristics; for internal use. 53 | 54 | const ( 55 | sizeofPtr = C.sizeofPtr 56 | sizeofShort = C.sizeof_short 57 | sizeofInt = C.sizeof_int 58 | sizeofLong = C.sizeof_long 59 | sizeofLongLong = C.sizeof_longlong 60 | ) 61 | 62 | // Basic types 63 | 64 | type ( 65 | _C_short C.short 66 | _C_int C.int 67 | _C_long C.long 68 | _C_long_long C.longlong 69 | ) 70 | 71 | type In6Addr C.struct_in6_addr 72 | 73 | type InAddr4in6 C.struct_in_addr_4in6 74 | 75 | type XSockbuf C.struct_xsockbuf 76 | 77 | type XSocket64 C.struct_xsocket64 78 | 79 | type Xinpgen C.struct_xinpgen 80 | 81 | type InPCB64ListEntry C.struct_inpcb64_list_entry 82 | 83 | type Xinpcb64 C.struct_xinpcb64 84 | 85 | type XTCPcb64 C.struct_xtcpcb64 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iSliver 2 | Learning notes of amazing Sliver C2 project. 3 | 4 | 对令人惊讶的Sliver C2项目的学习与致敬 5 | 6 | iSliver just like iKun 7 | 8 | - iSliver 9 | - Func 10 | - PPID Spoofing 11 | - go-netstat 12 | --------------------------------------------------------------------------------