github.com/iDigitalFlame/xmt@v0.5.4/device/xy_nix_crypt.go (about)

     1  //go:build !windows && !js && crypt
     2  // +build !windows,!js,crypt
     3  
     4  // Copyright (C) 2020 - 2023 iDigitalFlame
     5  //
     6  // This program is free software: you can redistribute it and/or modify
     7  // it under the terms of the GNU General Public License as published by
     8  // the Free Software Foundation, either version 3 of the License, or
     9  // any later version.
    10  //
    11  // This program is distributed in the hope that it will be useful,
    12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  // GNU General Public License for more details.
    15  //
    16  // You should have received a copy of the GNU General Public License
    17  // along with this program.  If not, see <https://www.gnu.org/licenses/>.
    18  //
    19  
    20  package device
    21  
    22  import (
    23  	"io"
    24  	"os"
    25  	"runtime"
    26  	"strings"
    27  
    28  	"github.com/iDigitalFlame/xmt/cmd/filter"
    29  	"github.com/iDigitalFlame/xmt/data"
    30  	"github.com/iDigitalFlame/xmt/util"
    31  	"github.com/iDigitalFlame/xmt/util/crypt"
    32  	"github.com/iDigitalFlame/xmt/util/xerr"
    33  )
    34  
    35  var (
    36  	// Shell is the default machine specific command shell.
    37  	Shell = crypt.Get(32) // /bin/sh
    38  	// ShellArgs is the default machine specific command shell arguments to run
    39  	// commands.
    40  	ShellArgs = "-c"
    41  	// PowerShell is the path to the PowerShell binary, which is based on the
    42  	// underlying OS type.
    43  	PowerShell = crypt.Get(33) // pwsh
    44  )
    45  
    46  // IsDebugged returns true if the current process is attached by a debugger.
    47  func IsDebugged() bool {
    48  	for _, e := range data.ReadSplit(crypt.Get(34), "\n") { // /proc/self/status
    49  		if len(e) <= 9 {
    50  			continue
    51  		}
    52  		if e[9] == ':' && e[8] == 'd' && e[0] == 'T' && e[1] == 'r' && e[5] == 'r' {
    53  			return e[len(e)-1] != '0' && e[len(e)-2] != ' ' && e[len(e)-2] != 9 && e[len(e)-2] != '\t'
    54  		}
    55  	}
    56  	return false
    57  }
    58  
    59  // UserHomeDir returns the current user's home directory.
    60  //
    61  // On Unix, including macOS, it returns the $HOME environment variable.
    62  // On Windows, it returns %USERPROFILE%.
    63  // On Plan 9, it returns the $home environment variable.
    64  // On JS/WASM it returns and empty string.
    65  //
    66  // Golang compatibility helper function.
    67  func UserHomeDir() string {
    68  	if OS == Plan9 {
    69  		return os.Getenv(strings.ToLower(crypt.Get(35))) // HOME
    70  	}
    71  	if v := os.Getenv(crypt.Get(35)); len(v) > 0 { // HOME
    72  		return v
    73  	}
    74  	switch OS {
    75  	case IOS:
    76  		return "/"
    77  	case Android:
    78  		return os.Getenv(crypt.Get(36)) // /sdcard
    79  	}
    80  	return ""
    81  }
    82  
    83  // Logins returns an array that contains information about current logged
    84  // in users.
    85  //
    86  // This call is OS-independent but many contain invalid session types.
    87  //
    88  // Always returns an EINVAL on WSAM/JS.
    89  func Logins() ([]Login, error) {
    90  	b, err := data.ReadFile(crypt.Get(37)) // /var/run/utmp
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  	return readWhoEntries(b), nil
    95  }
    96  
    97  // Mounts attempts to get the mount points on the local device.
    98  //
    99  // On Windows devices, this is the drive letters available, otherwise on nix*
   100  // systems, this will be the mount points on the system.
   101  //
   102  // The return result (if no errors occurred) will be a string list of all the
   103  // mount points (or Windows drive letters).
   104  func Mounts() ([]string, error) {
   105  	// 0 - READONLY
   106  	f, err := os.OpenFile(crypt.Get(38), 0, 0) // /proc/self/mounts
   107  	if err != nil {
   108  		// 0 - READONLY
   109  		if f, err = os.OpenFile(crypt.Get(39), 0, 0); err != nil { // /etc/mtab
   110  			return nil, xerr.Wrap("cannot find mounts", err)
   111  		}
   112  	}
   113  	b, err := data.ReadAll(f)
   114  	if f.Close(); err != nil {
   115  		return nil, err
   116  	}
   117  	var (
   118  		e = strings.Split(string(b), "\n")
   119  		m = make([]string, 0, len(e))
   120  	)
   121  	for _, v := range e {
   122  		x, l := 0, 0
   123  		for s := 0; s < 2; s++ {
   124  			for l = x; x < len(v)-1 && v[x] != ' ' && v[x] != 9; x++ {
   125  			}
   126  			if x < len(v)-1 && s == 0 {
   127  				x++
   128  			}
   129  		}
   130  		if l == x {
   131  			continue
   132  		}
   133  		m = append(m, v[l:x])
   134  	}
   135  	return m, nil
   136  }
   137  
   138  // DumpProcess will attempt to copy the memory of the targeted Filter to the
   139  // supplied Writer. This fill select the first process that matches the Filter.
   140  //
   141  // If the Filter is nil or empty or if an error occurs during reading/writing
   142  // an error will be returned.
   143  //
   144  // This function may fail if attempting to dump a process that is a different CPU
   145  // architecture that the host process.
   146  func DumpProcess(f *filter.Filter, w io.Writer) error {
   147  	if f.Empty() {
   148  		return filter.ErrNoProcessFound
   149  	}
   150  	p, err := f.SelectFunc(nil)
   151  	if err != nil {
   152  		return err
   153  	}
   154  	v := crypt.Get(11) + util.Uitoa(uint64(p)) // /proc/
   155  	b, err := data.ReadFile(v + crypt.Get(40)) // /maps
   156  	if err != nil {
   157  		return err
   158  	}
   159  	// 0 - READONLY
   160  	d, err := os.OpenFile(v+crypt.Get(41), 0, 0) // /mem
   161  	if err != nil {
   162  		return err
   163  	}
   164  	for _, e := range strings.Split(string(b), "\n") {
   165  		if err = parseLine(e, d, w); err != nil {
   166  			break
   167  		}
   168  	}
   169  	d.Close()
   170  	runtime.GC()
   171  	FreeOSMemory()
   172  	return err
   173  }