mirror of
https://github.com/yv1ing/ShotRDP.git
synced 2025-09-16 15:10:57 +08:00
新增动态链接库调用
This commit is contained in:
187
client/rdpClient.go
Normal file
187
client/rdpClient.go
Normal 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
22
client/rdpClient_test.go
Normal 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))
|
||||
}
|
||||
Reference in New Issue
Block a user