介绍
Winpty 模块专门用于处理 Windows 平台上的伪终端(PTY)。伪终端是在 Unix 系统中用于创建一个终端设备并将其连接到另一个进程的机制。Winpty 模块通过在 Windows 上实现类似功能。
vshell中的交互式shell落地了两个文件,一个是winpty.dll,一个是winpty-agent.exe。
想要实现交互shell的可以参考这个项目。https://github.com/NHAS/reverse_ssh/pkg/winpty
主要功能
Winpty 模块提供了以下核心功能:
•创建和管理伪终端•处理终端输入和输出•处理 Windows 特有的终端特性
代码结构
Winpty 模块的代码结构主要包括以下部分:
1.初始化部分:用于设置伪终端的环境,并初始化相关资源。2.输入处理部分:用于处理从用户输入的命令,并将其传递给伪终端。3.输出处理部分:用于处理伪终端的输出,并将其显示给用户。4.清理部分:用于释放伪终端相关的资源,确保程序正常退出。
核心代码解析
以下是pkg/winpty/syscalls.go
文件的部分代码解析:
//go:build windows
// +build windows
package winpty
import(
"errors"
"log"
"os"
"path"
"runtime"
"syscall"
)
.......
.......
// loadWinPty 初始化并加载 WinPTY DLL 和相关函数
func loadWinPty() error {
if modWinPTY !=nil{
returnnil
}
switch runtime.GOARCH {
case"amd64","arm64","386":
default:
return errors.New("unsupported winpty platform "+ runtime.GOARCH)
}
var(
winptyDllName ="winpty.dll"
winptyAgentName ="winpty-agent.exe"
)
cacheDir, err := os.UserCacheDir()
if err !=nil{
log.Println("unable to get cache directory for writing winpty pe's writing may fail if directory is read only")
}
if err ==nil{
winptyDllName = path.Join(cacheDir, winptyDllName)
winptyAgentName = path.Join(cacheDir, winptyAgentName)
}
err = writeBinaries(winptyDllName, winptyAgentName)
if err !=nil{
return errors.New("writing PEs to disk failed: "+ err.Error())
}
modWinPTY = syscall.NewLazyDLL(winptyDllName)
if modWinPTY ==nil{
return errors.New("creating lazy dll failed")
}
// Error handling...
winpty_error_code = modWinPTY.NewProc("winpty_error_code")
winpty_error_msg = modWinPTY.NewProc("winpty_error_msg")
winpty_error_free = modWinPTY.NewProc("winpty_error_free")
// Configuration of a new agent.
winpty_config_new = modWinPTY.NewProc("winpty_config_new")
winpty_config_free = modWinPTY.NewProc("winpty_config_free")
winpty_config_set_initial_size = modWinPTY.NewProc("winpty_config_set_initial_size")
winpty_config_set_mouse_mode = modWinPTY.NewProc("winpty_config_set_mouse_mode")
winpty_config_set_agent_timeout = modWinPTY.NewProc("winpty_config_set_agent_timeout")
// Start the agent.
winpty_open = modWinPTY.NewProc("winpty_open")
winpty_agent_process = modWinPTY.NewProc("winpty_agent_process")
// I/O Pipes
winpty_conin_name = modWinPTY.NewProc("winpty_conin_name")
winpty_conout_name = modWinPTY.NewProc("winpty_conout_name")
winpty_conerr_name = modWinPTY.NewProc("winpty_conerr_name")
// Agent RPC Calls
winpty_spawn_config_new = modWinPTY.NewProc("winpty_spawn_config_new")
winpty_spawn_config_free = modWinPTY.NewProc("winpty_spawn_config_free")
winpty_spawn = modWinPTY.NewProc("winpty_spawn")
winpty_set_size = modWinPTY.NewProc("winpty_set_size")
winpty_free = modWinPTY.NewProc("winpty_free")
returnnil
}
功能解析
1.常量定义:•WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN
和WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION
是用于配置 WinPTY 的标志。2.变量定义:•modWinPTY
是指向 WinPTY DLL 的指针,使用syscall.LazyDLL
加载。•多个syscall.LazyProc
变量用于指向 WinPTY DLL 中的具体函数。3.loadWinPty 函数:•该函数负责初始化并加载 WinPTY DLL 及其相关函数。•首先检查modWinPTY
是否已经加载,如果加载则直接返回。•根据运行时架构检查是否支持当前平台。•获取用户缓存目录并设置 DLL 和 Agent 的路径。•调用writeBinaries
函数将 DLL 和 Agent 写入磁盘。•使用syscall.NewLazyDLL
和NewProc
加载 DLL 和函数指针。
Winpty 模块是 Reverse SSH 项目的一个关键组件,通过在 Windows 平台的伪终端功能,使得该项目能够跨平台运行。
仅限交流学习使用,如您在使用本工具或代码的过程中存在任何非法行为,您需自行承担相应后果,我们将不承担任何法律及连带责任。“如侵权请私聊公众号删文”。
原文始发于微信公众号(柠檬赏金猎人):vshell中的交互式shell
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论