新增动态链接库调用

This commit is contained in:
2025-03-21 22:33:07 +08:00
parent ded0148ba6
commit e3490fa5b1
4 changed files with 34 additions and 4 deletions

187
client/rdpClient.go Normal file
View File

@@ -0,0 +1,187 @@
package client
import (
"ShotRDP/common"
"ShotRDP/grdp/core"
"ShotRDP/grdp/glog"
"ShotRDP/grdp/plugin"
"ShotRDP/grdp/protocol/nla"
"ShotRDP/grdp/protocol/pdu"
"ShotRDP/grdp/protocol/sec"
"ShotRDP/grdp/protocol/t125"
"ShotRDP/grdp/protocol/tpkt"
"ShotRDP/grdp/protocol/x224"
"context"
"log"
"net"
"os"
"strings"
"sync"
"time"
)
type RdpClient struct {
Host string // 服务地址(ip:port)
tpkt *tpkt.TPKT // TPKT协议层
x224 *x224.X224 // X224协议层
mcs *t125.MCSClient // MCS协议层
sec *sec.Client // 安全层
pdu *pdu.Client // PDU协议层
channels *plugin.Channels
}
type Position struct {
Top int
Left int
Right int
Bottom int
}
var (
modifyMux = sync.Mutex{}
positionMap = make(map[Position]*common.Bitmap)
)
func Newclient(host string, logLevel glog.LEVEL) *RdpClient {
_logger := log.New(os.Stdout, "", 0)
glog.SetLogger(_logger)
glog.SetLevel(logLevel)
return &RdpClient{Host: host}
}
func (client *RdpClient) Login(domain, username, password string) ([]byte, error) {
conn, err := net.DialTimeout("tcp", client.Host, 3*time.Second)
if err != nil {
return nil, err
}
// 初始化协议栈
client.initProtocolStack(conn, domain, username, password)
// 建立X224连接
err = client.x224.Connect()
if err != nil {
return nil, err
}
// 设置事件处理
client.setEventHandler()
// 合并登录界面位图
wg := &sync.WaitGroup{}
wg.Add(1)
var buff []byte
surfaceflingerCtx, _ := context.WithCancel(context.Background())
go func(ctx context.Context, c *RdpClient) {
outputName := strings.ReplaceAll(client.Host, ":", "_")
//for common.Opened(ctx) {}
// TODO: 寻找合适的截图时机
time.Sleep(5 * time.Second)
modifyMux.Lock()
var bitmapList = make([]*common.Bitmap, 0)
for _, bitmap := range positionMap {
//common.DrawOneBitmap(bitmap, fmt.Sprintf("%d-%d-%d-%d.png", pos.Left, pos.Top, pos.Right, pos.Bottom))
bitmapList = append(bitmapList, bitmap)
}
buff = common.DrawFullImage(outputName, bitmapList)
modifyMux.Unlock()
wg.Done()
}(surfaceflingerCtx, client)
wg.Wait()
return buff, nil
}
// initProtocolStack 初始化RDP协议栈
func (client *RdpClient) initProtocolStack(conn net.Conn, domain, username, password string) {
// 创建协议层实例
client.tpkt = tpkt.New(core.NewSocketLayer(conn), nla.NewNTLMv2(domain, username, password))
client.x224 = x224.New(client.tpkt)
client.mcs = t125.NewMCSClient(client.x224)
client.sec = sec.NewClient(client.mcs)
client.pdu = pdu.NewClient(client.sec)
// 配置桌面信息
client.channels = plugin.NewChannels(client.sec)
client.mcs.SetClientDesktop(uint16(1920), uint16(1080))
// 设置认证信息
client.sec.SetDomain(domain)
client.sec.SetUsername(username)
client.sec.SetPassword(password)
// 配置协议层关联
client.tpkt.SetFastPathListener(client.sec)
client.sec.SetFastPathListener(client.pdu)
client.sec.SetChannelSender(client.mcs)
}
// setEventHandler 设置PDU事件处理器
func (client *RdpClient) setEventHandler() {
client.pdu.On("ready", func() {
})
client.pdu.On("success", func() {
})
client.pdu.On("close", func() {
})
client.pdu.On("done", func() {
})
client.pdu.On("error", func(err error) {
client.pdu.Emit("done")
})
client.pdu.On("bitmap", func(rectangles []pdu.BitmapData) {
modifyMux.Lock()
for _, rectangle := range rectangles {
pos := Position{Left: int(rectangle.DestLeft / rectangle.Width), Top: int(rectangle.DestTop / rectangle.Height), Right: int(rectangle.DestRight / rectangle.Width), Bottom: int(rectangle.DestBottom / rectangle.Height)}
isCompress := rectangle.IsCompress()
data := rectangle.BitmapDataStream
if isCompress {
data = common.BitmapDecompress(&rectangle)
isCompress = false
}
bitmap := &common.Bitmap{
DestLeft: int(rectangle.DestLeft),
DestTop: int(rectangle.DestTop),
DestRight: int(rectangle.DestRight),
DestBottom: int(rectangle.DestBottom),
Width: int(rectangle.Width),
Height: int(rectangle.Height),
BitsPerPixel: common.Bpp(rectangle.BitsPerPixel),
IsCompress: isCompress,
Data: data,
}
positionMap[pos] = bitmap
}
modifyMux.Unlock()
})
}
/*
修改部分grdp/protocol/x224/x224.go#New()
去除requestedProtocol中的PROTOCOL_HYBRID避免使用NLA
*/
func RealGetScreen(host string) ([]byte, error) {
client := Newclient(host, glog.INFO)
return client.Login("", "", "")
}

22
client/rdpClient_test.go Normal file
View File

@@ -0,0 +1,22 @@
package client
import (
"testing"
)
func TestGetScreen(t *testing.T) {
/* 测试成功版本:
Windows Server 2008 ✔
Windows Server 2012 ✔
Windows Server 2016 ✔
Windows 7 ✔
Windows 10 ✔
*/
imgBytes, err := getScreen("192.168.250.128:3389")
if err != nil {
t.Fatal(err)
}
t.Logf("Length of imgBytes: %v", len(imgBytes))
}