基本适应win7,win10,win server 08,win server 12,win server 16的截图

This commit is contained in:
2025-01-03 23:00:47 +08:00
parent 909b89dfce
commit 84362607c2
77 changed files with 69638 additions and 1 deletions

138
grdp/core/io.go Normal file
View File

@@ -0,0 +1,138 @@
package core
import (
"encoding/binary"
"io"
)
type ReadBytesComplete func(result []byte, err error)
func StartReadBytes(len int, r io.Reader, cb ReadBytesComplete) {
b := make([]byte, len)
go func() {
_, err := io.ReadFull(r, b)
//glog.Debug("StartReadBytes Get", n, "Bytes:", hex.EncodeToString(b))
cb(b, err)
}()
}
func ReadBytes(len int, r io.Reader) ([]byte, error) {
b := make([]byte, len)
length, err := io.ReadFull(r, b)
return b[:length], err
}
func ReadByte(r io.Reader) (byte, error) {
b, err := ReadBytes(1, r)
return b[0], err
}
func ReadUInt8(r io.Reader) (uint8, error) {
b, err := ReadBytes(1, r)
return uint8(b[0]), err
}
func ReadUint16LE(r io.Reader) (uint16, error) {
b := make([]byte, 2)
_, err := io.ReadFull(r, b)
if err != nil {
return 0, nil
}
return binary.LittleEndian.Uint16(b), nil
}
func ReadUint16BE(r io.Reader) (uint16, error) {
b := make([]byte, 2)
_, err := io.ReadFull(r, b)
if err != nil {
return 0, nil
}
return binary.BigEndian.Uint16(b), nil
}
func ReadUInt32LE(r io.Reader) (uint32, error) {
b := make([]byte, 4)
_, err := io.ReadFull(r, b)
if err != nil {
return 0, nil
}
return binary.LittleEndian.Uint32(b), nil
}
func ReadUInt32BE(r io.Reader) (uint32, error) {
b := make([]byte, 4)
_, err := io.ReadFull(r, b)
if err != nil {
return 0, nil
}
return binary.BigEndian.Uint32(b), nil
}
func WriteByte(data byte, w io.Writer) (int, error) {
b := make([]byte, 1)
b[0] = byte(data)
return w.Write(b)
}
func WriteBytes(data []byte, w io.Writer) (int, error) {
return w.Write(data)
}
func WriteUInt8(data uint8, w io.Writer) (int, error) {
b := make([]byte, 1)
b[0] = byte(data)
return w.Write(b)
}
func WriteUInt16BE(data uint16, w io.Writer) (int, error) {
b := make([]byte, 2)
binary.BigEndian.PutUint16(b, data)
return w.Write(b)
}
func WriteUInt16LE(data uint16, w io.Writer) (int, error) {
b := make([]byte, 2)
binary.LittleEndian.PutUint16(b, data)
return w.Write(b)
}
func WriteUInt32LE(data uint32, w io.Writer) (int, error) {
b := make([]byte, 4)
binary.LittleEndian.PutUint32(b, data)
return w.Write(b)
}
func WriteUInt32BE(data uint32, w io.Writer) (int, error) {
b := make([]byte, 4)
binary.BigEndian.PutUint32(b, data)
return w.Write(b)
}
func PutUint16BE(data uint16) (uint8, uint8) {
b := make([]byte, 2)
binary.BigEndian.PutUint16(b, data)
return uint8(b[0]), uint8(b[1])
}
func Uint16BE(d0, d1 uint8) uint16 {
b := make([]byte, 2)
b[0] = d0
b[1] = d1
return binary.BigEndian.Uint16(b)
}
func RGB565ToRGB(data uint16) (r, g, b uint8) {
r = uint8(data & 0xF800 >> 8)
g = uint8(data & 0x07E0 >> 3)
b = uint8(data & 0x001F << 3)
return
}
func RGB555ToRGB(data uint16) (r, g, b uint8) {
r = uint8(data & 0x7C00 >> 7)
g = uint8(data & 0x03E0 >> 2)
b = uint8(data & 0x001F << 3)
return
}

17
grdp/core/io_test.go Normal file
View File

@@ -0,0 +1,17 @@
package core
import (
"bytes"
"encoding/hex"
"testing"
)
func TestWriteUInt16LE(t *testing.T) {
buff := &bytes.Buffer{}
WriteUInt32LE(66538, buff)
result := hex.EncodeToString(buff.Bytes())
expected := "ea030100"
if result != expected {
t.Error(result, "not equals to", expected)
}
}

865
grdp/core/rle.go Normal file
View File

@@ -0,0 +1,865 @@
package core
import (
"fmt"
"unsafe"
)
func CVAL(p *[]uint8) int {
a := int((*p)[0])
*p = (*p)[1:]
return a
}
func CVAL2(p *[]uint8, v *uint16) {
*v = *((*uint16)(unsafe.Pointer(&(*p)[0])))
*p = (*p)[2:]
}
func CVAL3(p *[]uint8, v *[3]uint8) {
(*v)[0] = (*p)[0]
(*v)[1] = (*p)[1]
(*v)[2] = (*p)[2]
*p = (*p)[3:]
}
func REPEAT(f func(), count *int, x *int, width int) {
for (*count & ^0x7) != 0 && ((*x + 8) < width) {
for i := 0; i < 8; i++ {
f()
*count = *count - 1
*x = *x + 1
}
}
for (*count > 0) && (*x < width) {
f()
*count = *count - 1
*x = *x + 1
}
}
/* 1 byte bitmap decompress */
func decompress1(output *[]uint8, width, height int, input []uint8, size int) bool {
var (
prevline, line, count int
offset, code int
x int = width
opcode int
lastopcode int8 = -1
insertmix, bicolour, isfillormix bool
mixmask, mask uint8
colour1, colour2 uint8
mix uint8 = 0xff
fom_mask uint8
)
out := *output
for len(input) != 0 {
fom_mask = 0
code = CVAL(&input)
opcode = code >> 4
/* Handle different opcode forms */
switch opcode {
case 0xc, 0xd, 0xe:
opcode -= 6
count = int(code & 0xf)
offset = 16
break
case 0xf:
opcode = code & 0xf
if opcode < 9 {
count = int(CVAL(&input))
count |= int(CVAL(&input) << 8)
} else {
count = 1
if opcode < 0xb {
count = 8
}
}
offset = 0
break
default:
opcode >>= 1
count = int(code & 0x1f)
offset = 32
break
}
/* Handle strange cases for counts */
if offset != 0 {
isfillormix = ((opcode == 2) || (opcode == 7))
if count == 0 {
if isfillormix {
count = int(CVAL(&input)) + 1
} else {
count = int(CVAL(&input) + offset)
}
} else if isfillormix {
count <<= 3
}
}
/* Read preliminary data */
switch opcode {
case 0: /* Fill */
if (lastopcode == int8(opcode)) && !((x == width) && (prevline == 0)) {
insertmix = true
}
break
case 8: /* Bicolour */
colour1 = uint8(CVAL(&input))
colour2 = uint8(CVAL(&input))
break
case 3: /* Colour */
colour2 = uint8(CVAL(&input))
break
case 6: /* SetMix/Mix */
fallthrough
case 7: /* SetMix/FillOrMix */
mix = uint8(CVAL(&input))
opcode -= 5
break
case 9: /* FillOrMix_1 */
mask = 0x03
opcode = 0x02
fom_mask = 3
break
case 0x0a: /* FillOrMix_2 */
mask = 0x05
opcode = 0x02
fom_mask = 5
break
}
lastopcode = int8(opcode)
mixmask = 0
/* Output body */
for count > 0 {
if x >= width {
if height <= 0 {
return false
}
x = 0
height--
prevline = line
line = height * width
}
switch opcode {
case 0: /* Fill */
if insertmix {
if prevline == 0 {
out[x+line] = mix
} else {
out[x+line] = out[prevline+x] ^ mix
}
insertmix = false
count--
x++
}
if prevline == 0 {
REPEAT(func() {
out[x+line] = 0
}, &count, &x, width)
} else {
REPEAT(func() {
out[x+line] = out[prevline+x]
}, &count, &x, width)
}
break
case 1: /* Mix */
if prevline == 0 {
REPEAT(func() {
out[x+line] = mix
}, &count, &x, width)
} else {
REPEAT(func() {
out[x+line] = out[prevline+x] ^ mix
}, &count, &x, width)
}
break
case 2: /* Fill or Mix */
if prevline == 0 {
REPEAT(func() {
mixmask <<= 1
if mixmask == 0 {
mask = fom_mask
if fom_mask == 0 {
mask = uint8(CVAL(&input))
mixmask = 1
}
}
if mask&mixmask != 0 {
out[x+line] = mix
} else {
out[x+line] = 0
}
}, &count, &x, width)
} else {
REPEAT(func() {
mixmask = mixmask << 1
if mixmask == 0 {
mask = fom_mask
if fom_mask == 0 {
mask = uint8(CVAL(&input))
mixmask = 1
}
}
if mask&mixmask != 0 {
out[x+line] = out[prevline+x] ^ mix
} else {
out[x+line] = out[prevline+x]
}
}, &count, &x, width)
}
break
case 3: /* Colour */
REPEAT(func() {
out[x+line] = colour2
}, &count, &x, width)
break
case 4: /* Copy */
REPEAT(func() {
out[x+line] = uint8(CVAL(&input))
}, &count, &x, width)
break
case 8: /* Bicolour */
REPEAT(func() {
if bicolour {
out[x+line] = colour2
bicolour = false
} else {
out[x+line] = colour1
bicolour = true
count++
}
}, &count, &x, width)
break
case 0xd: /* White */
REPEAT(func() {
out[x+line] = 0xff
}, &count, &x, width)
break
case 0xe: /* Black */
REPEAT(func() {
out[x+line] = 0
}, &count, &x, width)
break
default:
fmt.Printf("bitmap opcode 0x%x\n", opcode)
return false
}
}
}
return true
}
/* 2 byte bitmap decompress */
func decompress2(output *[]uint8, width, height int, input []uint8, size int) bool {
var (
prevline, line, count int
offset, code int
x int = width
opcode int
lastopcode int = -1
insertmix, bicolour, isfillormix bool
mixmask, mask uint8
colour1, colour2 uint16
mix uint16 = 0xffff
fom_mask uint8
)
out := make([]uint16, width*height)
for len(input) != 0 {
fom_mask = 0
code = CVAL(&input)
opcode = code >> 4
/* Handle different opcode forms */
switch opcode {
case 0xc, 0xd, 0xe:
opcode -= 6
count = code & 0xf
offset = 16
break
case 0xf:
opcode = code & 0xf
if opcode < 9 {
count = CVAL(&input)
count |= CVAL(&input) << 8
} else {
count = 1
if opcode < 0xb {
count = 8
}
}
offset = 0
break
default:
opcode >>= 1
count = code & 0x1f
offset = 32
break
}
/* Handle strange cases for counts */
if offset != 0 {
isfillormix = ((opcode == 2) || (opcode == 7))
if count == 0 {
if isfillormix {
count = CVAL(&input) + 1
} else {
count = CVAL(&input) + offset
}
} else if isfillormix {
count <<= 3
}
}
/* Read preliminary data */
switch opcode {
case 0: /* Fill */
if (lastopcode == opcode) && !((x == width) && (prevline == 0)) {
insertmix = true
}
break
case 8: /* Bicolour */
CVAL2(&input, &colour1)
CVAL2(&input, &colour2)
break
case 3: /* Colour */
CVAL2(&input, &colour2)
break
case 6: /* SetMix/Mix */
fallthrough
case 7: /* SetMix/FillOrMix */
CVAL2(&input, &mix)
opcode -= 5
break
case 9: /* FillOrMix_1 */
mask = 0x03
opcode = 0x02
fom_mask = 3
break
case 0x0a: /* FillOrMix_2 */
mask = 0x05
opcode = 0x02
fom_mask = 5
break
}
lastopcode = opcode
mixmask = 0
/* Output body */
for count > 0 {
if x >= width {
if height <= 0 {
return false
}
x = 0
height--
prevline = line
line = height * width
}
switch opcode {
case 0: /* Fill */
if insertmix {
if prevline == 0 {
out[x+line] = mix
} else {
out[x+line] = out[prevline+x] ^ mix
}
insertmix = false
count--
x++
}
if prevline == 0 {
REPEAT(func() {
out[x+line] = 0
}, &count, &x, width)
} else {
REPEAT(func() {
out[x+line] = out[prevline+x]
}, &count, &x, width)
}
break
case 1: /* Mix */
if prevline == 0 {
REPEAT(func() {
out[x+line] = mix
}, &count, &x, width)
} else {
REPEAT(func() {
out[x+line] = out[prevline+x] ^ mix
}, &count, &x, width)
}
break
case 2: /* Fill or Mix */
if prevline == 0 {
REPEAT(func() {
mixmask <<= 1
if mixmask == 0 {
mask = fom_mask
if fom_mask == 0 {
mask = uint8(CVAL(&input))
mixmask = 1
}
}
if mask&mixmask != 0 {
out[x+line] = mix
} else {
out[x+line] = 0
}
}, &count, &x, width)
} else {
REPEAT(func() {
mixmask = mixmask << 1
if mixmask == 0 {
mask = fom_mask
if fom_mask == 0 {
mask = uint8(CVAL(&input))
mixmask = 1
}
}
if mask&mixmask != 0 {
out[x+line] = out[prevline+x] ^ mix
} else {
out[x+line] = out[prevline+x]
}
}, &count, &x, width)
}
break
case 3: /* Colour */
REPEAT(func() {
out[x+line] = colour2
}, &count, &x, width)
break
case 4: /* Copy */
REPEAT(func() {
var a uint16
CVAL2(&input, &a)
out[x+line] = a
}, &count, &x, width)
break
case 8: /* Bicolour */
REPEAT(func() {
if bicolour {
out[x+line] = colour2
bicolour = false
} else {
out[x+line] = colour1
bicolour = true
count++
}
}, &count, &x, width)
break
case 0xd: /* White */
REPEAT(func() {
out[x+line] = 0xffff
}, &count, &x, width)
break
case 0xe: /* Black */
REPEAT(func() {
out[x+line] = 0
}, &count, &x, width)
break
default:
fmt.Printf("bitmap opcode 0x%x\n", opcode)
return false
}
}
}
j := 0
for _, v := range out {
(*output)[j], (*output)[j+1] = PutUint16BE(v)
j += 2
}
return true
}
// /* 3 byte bitmap decompress */
func decompress3(output *[]uint8, width, height int, input []uint8, size int) bool {
var (
prevline, line, count int
opcode, offset, code int
x int = width
lastopcode int = -1
insertmix, bicolour, isfillormix bool
mixmask, mask uint8
colour1 = [3]uint8{0, 0, 0}
colour2 = [3]uint8{0, 0, 0}
mix = [3]uint8{0xff, 0xff, 0xff}
fom_mask uint8
)
out := *output
for len(input) != 0 {
fom_mask = 0
code = CVAL(&input)
opcode = code >> 4
/* Handle different opcode forms */
switch opcode {
case 0xc, 0xd, 0xe:
opcode -= 6
count = code & 0xf
offset = 16
break
case 0xf:
opcode = code & 0xf
if opcode < 9 {
count = CVAL(&input)
count |= CVAL(&input) << 8
} else {
count = 1
if opcode < 0xb {
count = 8
}
}
offset = 0
break
default:
opcode >>= 1
count = code & 0x1f
offset = 32
break
}
/* Handle strange cases for counts */
if offset != 0 {
isfillormix = ((opcode == 2) || (opcode == 7))
if count == 0 {
if isfillormix {
count = CVAL(&input) + 1
} else {
count = CVAL(&input) + offset
}
} else if isfillormix {
count <<= 3
}
}
/* Read preliminary data */
switch opcode {
case 0: /* Fill */
if (lastopcode == opcode) && !((x == width) && (prevline == 0)) {
insertmix = true
}
break
case 8: /* Bicolour */
CVAL3(&input, &colour1)
CVAL3(&input, &colour2)
break
case 3: /* Colour */
CVAL3(&input, &colour2)
break
case 6: /* SetMix/Mix */
fallthrough
case 7: /* SetMix/FillOrMix */
CVAL3(&input, &mix)
opcode -= 5
break
case 9: /* FillOrMix_1 */
mask = 0x03
opcode = 0x02
fom_mask = 3
break
case 0x0a: /* FillOrMix_2 */
mask = 0x05
opcode = 0x02
fom_mask = 5
break
}
lastopcode = opcode
mixmask = 0
/* Output body */
for count > 0 {
if x >= width {
if height <= 0 {
return false
}
x = 0
height--
prevline = line
line = height * width * 3
}
switch opcode {
case 0: /* Fill */
if insertmix {
if prevline == 0 {
out[3*x+line] = mix[0]
out[3*x+line+1] = mix[1]
out[3*x+line+2] = mix[2]
} else {
out[3*x+line] = out[prevline+3*x] ^ mix[0]
out[3*x+line+1] = out[prevline+3*x+1] ^ mix[1]
out[3*x+line+2] = out[prevline+3*x+2] ^ mix[2]
}
insertmix = false
count--
x++
}
if prevline == 0 {
REPEAT(func() {
out[3*x+line] = 0
out[3*x+line+1] = 0
out[3*x+line+2] = 0
}, &count, &x, width)
} else {
REPEAT(func() {
out[3*x+line] = out[prevline+3*x]
out[3*x+line+1] = out[prevline+3*x+1]
out[3*x+line+2] = out[prevline+3*x+2]
}, &count, &x, width)
}
break
case 1: /* Mix */
if prevline == 0 {
REPEAT(func() {
out[3*x+line] = mix[0]
out[3*x+line+1] = mix[1]
out[3*x+line+2] = mix[2]
}, &count, &x, width)
} else {
REPEAT(func() {
out[3*x+line] = out[prevline+3*x] ^ mix[0]
out[3*x+line+1] = out[prevline+3*x+1] ^ mix[1]
out[3*x+line+2] = out[prevline+3*x+2] ^ mix[2]
}, &count, &x, width)
}
break
case 2: /* Fill or Mix */
if prevline == 0 {
REPEAT(func() {
mixmask = mixmask << 1
if mixmask == 0 {
mask = fom_mask
if fom_mask == 0 {
mask = uint8(CVAL(&input))
mixmask = 1
}
}
if mask&mixmask != 0 {
out[3*x+line] = mix[0]
out[3*x+line+1] = mix[1]
out[3*x+line+2] = mix[2]
} else {
out[3*x+line] = 0
out[3*x+line+1] = 0
out[3*x+line+2] = 0
}
}, &count, &x, width)
} else {
REPEAT(func() {
mixmask = mixmask << 1
if mixmask == 0 {
mask = fom_mask
if fom_mask == 0 {
mask = uint8(CVAL(&input))
mixmask = 1
}
}
if mask&mixmask != 0 {
out[3*x+line] = out[prevline+3*x] ^ mix[0]
out[3*x+line+1] = out[prevline+3*x+1] ^ mix[1]
out[3*x+line+2] = out[prevline+3*x+2] ^ mix[2]
} else {
out[3*x+line] = out[prevline+3*x]
out[3*x+line+1] = out[prevline+3*x+1]
out[3*x+line+2] = out[prevline+3*x+2]
}
}, &count, &x, width)
}
break
case 3: /* Colour */
REPEAT(func() {
out[3*x+line] = colour2[0]
out[3*x+line+1] = colour2[1]
out[3*x+line+2] = colour2[2]
}, &count, &x, width)
break
case 4: /* Copy */
REPEAT(func() {
out[3*x+line] = uint8(CVAL(&input))
out[3*x+line+1] = uint8(CVAL(&input))
out[3*x+line+2] = uint8(CVAL(&input))
}, &count, &x, width)
break
case 8: /* Bicolour */
REPEAT(func() {
if bicolour {
out[3*x+line] = colour2[0]
out[3*x+line+1] = colour2[1]
out[3*x+line+2] = colour2[2]
bicolour = false
} else {
out[3*x+line] = colour1[0]
out[3*x+line+1] = colour1[1]
out[3*x+line+2] = colour1[2]
bicolour = true
count++
}
}, &count, &x, width)
break
case 0xd: /* White */
REPEAT(func() {
out[3*x+line] = 0xff
out[3*x+line+1] = 0xff
out[3*x+line+2] = 0xff
}, &count, &x, width)
break
case 0xe: /* Black */
REPEAT(func() {
out[3*x+line] = 0
out[3*x+line+1] = 0
out[3*x+line+2] = 0
}, &count, &x, width)
break
default:
fmt.Printf("bitmap opcode 0x%x\n", opcode)
return false
}
}
}
return true
}
/* decompress a colour plane */
func processPlane(in *[]uint8, width, height int, output *[]uint8, j int) int {
var (
indexw int
indexh int
code int
collen int
replen int
color uint8
x uint8
revcode int
lastline int
thisline int
)
ln := len(*in)
lastline = 0
indexh = 0
i := 0
for indexh < height {
thisline = j + (width * height * 4) - ((indexh + 1) * width * 4)
color = 0
indexw = 0
i = thisline
if lastline == 0 {
for indexw < width {
code = CVAL(in)
replen = int(code & 0xf)
collen = int((code >> 4) & 0xf)
revcode = (replen << 4) | collen
if (revcode <= 47) && (revcode >= 16) {
replen = revcode
collen = 0
}
for collen > 0 {
color = uint8(CVAL(in))
(*output)[i] = uint8(color)
i += 4
indexw++
collen--
}
for replen > 0 {
(*output)[i] = uint8(color)
i += 4
indexw++
replen--
}
}
} else {
for indexw < width {
code = CVAL(in)
replen = int(code & 0xf)
collen = int((code >> 4) & 0xf)
revcode = (replen << 4) | collen
if (revcode <= 47) && (revcode >= 16) {
replen = revcode
collen = 0
}
for collen > 0 {
x = uint8(CVAL(in))
if x&1 != 0 {
x = x >> 1
x = x + 1
color = -x
} else {
x = x >> 1
color = x
}
x = (*output)[indexw*4+lastline] + color
(*output)[i] = uint8(x)
i += 4
indexw++
collen--
}
for replen > 0 {
x = (*output)[indexw*4+lastline] + color
(*output)[i] = uint8(x)
i += 4
indexw++
replen--
}
}
}
indexh++
lastline = thisline
}
return ln - len(*in)
}
/* 4 byte bitmap decompress */
func decompress4(output *[]uint8, width, height int, input []uint8, size int) bool {
var (
code int
onceBytes, total int
)
code = CVAL(&input)
if code != 0x10 {
return false
}
total = 1
onceBytes = processPlane(&input, width, height, output, 3)
total += onceBytes
onceBytes = processPlane(&input, width, height, output, 2)
total += onceBytes
onceBytes = processPlane(&input, width, height, output, 1)
total += onceBytes
onceBytes = processPlane(&input, width, height, output, 0)
total += onceBytes
return size == total
}
/* main decompress function */
func Decompress(input []uint8, width, height int, Bpp int) []uint8 {
size := width * height * Bpp
output := make([]uint8, size)
switch Bpp {
case 1:
decompress1(&output, width, height, input, size)
case 2:
decompress2(&output, width, height, input, size)
case 3:
decompress3(&output, width, height, input, size)
case 4:
decompress4(&output, width, height, input, size)
default:
fmt.Printf("Bpp %d\n", Bpp)
}
return output
}

15
grdp/core/rle_test.go Normal file
View File

@@ -0,0 +1,15 @@
// rle_test.go
package core
import (
"fmt"
"testing"
)
func TestSum(t *testing.T) {
input := []byte{
192, 44, 200, 8, 132, 200, 8, 200, 8, 200, 8, 200, 8, 0, 19, 132, 232, 8, 12, 50, 142, 66, 77, 58, 208, 59, 225, 25, 1, 0, 0, 0, 0, 0, 0, 0, 132, 139, 33, 142, 66, 142, 66, 142, 66, 208, 59, 4, 43, 1, 0, 0, 0, 0, 0, 0, 0, 132, 203, 41, 142, 66, 142, 66, 142, 66, 208, 59, 96, 0, 1, 0, 0, 0, 0, 0, 0, 0, 132, 9, 17, 142, 66, 142, 66, 142, 66, 208, 59, 230, 27, 1, 0, 0, 0, 0, 0, 0, 0, 132, 200, 8, 9, 17, 139, 33, 74, 25, 243, 133, 14, 200, 8, 132, 200, 8, 200, 8, 200, 8, 200, 8,
}
out := Decompress(input, 64, 64, 3)
fmt.Println(out)
}

74
grdp/core/socket.go Normal file
View File

@@ -0,0 +1,74 @@
package core
import (
"crypto/rsa"
"math/big"
"github.com/huin/asn1ber"
//"crypto/tls"
"errors"
"net"
"github.com/icodeface/tls"
)
type SocketLayer struct {
conn net.Conn
tlsConn *tls.Conn
}
func NewSocketLayer(conn net.Conn) *SocketLayer {
l := &SocketLayer{
conn: conn,
tlsConn: nil,
}
return l
}
func (s *SocketLayer) Read(b []byte) (n int, err error) {
if s.tlsConn != nil {
return s.tlsConn.Read(b)
}
return s.conn.Read(b)
}
func (s *SocketLayer) Write(b []byte) (n int, err error) {
if s.tlsConn != nil {
return s.tlsConn.Write(b)
}
return s.conn.Write(b)
}
func (s *SocketLayer) Close() error {
if s.tlsConn != nil {
err := s.tlsConn.Close()
if err != nil {
return err
}
}
return s.conn.Close()
}
func (s *SocketLayer) StartTLS() error {
config := &tls.Config{
InsecureSkipVerify: true,
MinVersion: tls.VersionTLS10,
MaxVersion: tls.VersionTLS13,
PreferServerCipherSuites: true,
}
s.tlsConn = tls.Client(s.conn, config)
return s.tlsConn.Handshake()
}
type PublicKey struct {
N *big.Int `asn1:"explicit,tag:0"` // modulus
E int `asn1:"explicit,tag:1"` // public exponent
}
func (s *SocketLayer) TlsPubKey() ([]byte, error) {
if s.tlsConn == nil {
return nil, errors.New("TLS conn does not exist")
}
pub := s.tlsConn.ConnectionState().PeerCertificates[0].PublicKey.(*rsa.PublicKey)
return asn1ber.Marshal(*pub)
}

25
grdp/core/types.go Normal file
View File

@@ -0,0 +1,25 @@
package core
import "ShotRDP/grdp/emission"
type Transport interface {
Read(b []byte) (n int, err error)
Write(b []byte) (n int, err error)
Close() error
On(event, listener interface{}) *emission.Emitter
Once(event, listener interface{}) *emission.Emitter
Emit(event interface{}, arguments ...interface{}) *emission.Emitter
}
type FastPathListener interface {
RecvFastPath(secFlag byte, s []byte)
}
type FastPathSender interface {
SendFastPath(secFlag byte, s []byte) (int, error)
}
type ChannelSender interface {
SendToChannel(channel string, s []byte) (int, error)
}

67
grdp/core/util.go Normal file
View File

@@ -0,0 +1,67 @@
package core
import (
"bytes"
"crypto/rand"
"encoding/binary"
"unicode/utf16"
)
func Reverse(s []byte) []byte {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
return s
}
func Random(n int) []byte {
const alpha = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
var bytes = make([]byte, n)
rand.Read(bytes)
for i, b := range bytes {
bytes[i] = alpha[b%byte(len(alpha))]
}
return bytes
}
func UTF16ToLittleEndianBytes(u []uint16) []byte {
b := make([]byte, 2*len(u))
for index, value := range u {
binary.LittleEndian.PutUint16(b[index*2:], value)
}
return b
}
func LittleEndianBytesToUTF16(u []byte) []uint16 {
b := make([]uint16, 0, len(u)/2)
n := make([]byte, 2)
for i, v := range u {
if i%2 == 0 {
n[0] = v
} else {
n[1] = v
b = append(b, binary.LittleEndian.Uint16(n))
}
}
return b
}
// s.encode('utf-16le')
func UnicodeEncode(p string) []byte {
return UTF16ToLittleEndianBytes(utf16.Encode([]rune(p)))
}
func UnicodeDecode(p []byte) string {
r := bytes.NewReader(p)
n := make([]uint16, 0, 100)
for r.Len() > 0 {
a, _ := ReadUint16LE(r)
n = append(n, a)
}
//n := LittleEndianBytesToUTF16(p)
return string(utf16.Decode(n))
}
func BytesToUint64(b []byte) uint64 {
return binary.LittleEndian.Uint64(b)
}