mirror of
https://github.com/sairson/Yasso.git
synced 2026-11-03 06:04:58 +08:00
Yasso更新大改动,更新扫描方式,去除不常用功能,增加指纹和协议识别,修补bug等
This commit is contained in:
131
pkg/grdp/core/io.go
Normal file
131
pkg/grdp/core/io.go
Normal file
@@ -0,0 +1,131 @@
|
||||
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(uint32(data&0xF800)>>11) << 3
|
||||
g = uint8(uint32(data&0x07E0)>>5) << 2
|
||||
b = uint8(uint32(data&0x001F)) << 3
|
||||
|
||||
return
|
||||
}
|
||||
19
pkg/grdp/core/io_test.go
Normal file
19
pkg/grdp/core/io_test.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package core_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"Yasso/pkg/grdp/core"
|
||||
)
|
||||
|
||||
func TestWriteUInt16LE(t *testing.T) {
|
||||
buff := &bytes.Buffer{}
|
||||
core.WriteUInt32LE(66538, buff)
|
||||
result := hex.EncodeToString(buff.Bytes())
|
||||
expected := "ea030100"
|
||||
if result != expected {
|
||||
t.Error(result, "not equals to", expected)
|
||||
}
|
||||
}
|
||||
854
pkg/grdp/core/rle.go
Normal file
854
pkg/grdp/core/rle.go
Normal file
@@ -0,0 +1,854 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"Yasso/pkg/grdp/glog"
|
||||
"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])))
|
||||
//*v = binary.BigEndian.Uint16((*p)[0:2])
|
||||
//fmt.Println("*v:", *v)
|
||||
*p = (*p)[2:]
|
||||
}
|
||||
|
||||
func REPEAT(f func(), count, 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 bitmap_decompress1(uint8 * output, int width, int height, uint8 * input, int size) bool{
|
||||
// uint8 *end = input + size;
|
||||
// uint8 *prevline = NULL, *line = NULL;
|
||||
// int opcode, count, offset, isfillormix, x = width;
|
||||
// int lastopcode = -1, insertmix = false, bicolour = false;
|
||||
// uint8 code;
|
||||
// uint8 colour1 = 0, colour2 = 0;
|
||||
// uint8 mixmask, mask = 0;
|
||||
// uint8 mix = 0xff;
|
||||
// int fom_mask = 0;
|
||||
|
||||
// for (input < end){
|
||||
// fom_mask = 0;
|
||||
// code = CVAL(input);
|
||||
// opcode = code >> 4;
|
||||
// /* Handle different opcode forms */
|
||||
// switch (opcode){
|
||||
// case 0xc:
|
||||
// case 0xd:
|
||||
// case 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 = (opcode < 0xb) ? 8 : 1;
|
||||
// }
|
||||
// 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 == NULL))){
|
||||
// insertmix = true;
|
||||
// }
|
||||
// break;
|
||||
// case 8: /* Bicolour */
|
||||
// colour1 = CVAL(input);
|
||||
// case 3: /* Colour */
|
||||
// colour2 = CVAL(input);
|
||||
// break;
|
||||
// case 6: /* SetMix/Mix */
|
||||
// case 7: /* SetMix/FillOrMix */
|
||||
// mix = 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 = opcode;
|
||||
// mixmask = 0;
|
||||
// /* Output body */
|
||||
// for (count > 0){
|
||||
// if (x >= width){
|
||||
// if (height <= 0)
|
||||
// return false;
|
||||
// x = 0;
|
||||
// height--;
|
||||
// prevline = line;
|
||||
// line = output + height * width;
|
||||
// }
|
||||
// switch (opcode){
|
||||
// case 0: /* Fill */
|
||||
// if (insertmix){
|
||||
// if (prevline == NULL)
|
||||
// line[x] = mix;
|
||||
// else
|
||||
// line[x] = prevline[x] ^ mix;
|
||||
// insertmix = false;
|
||||
// count--;
|
||||
// x++;
|
||||
// }
|
||||
// if (prevline == NULL){
|
||||
// REPEAT(line[x] = 0)
|
||||
// }else{
|
||||
// REPEAT(line[x] = prevline[x])
|
||||
// }
|
||||
// break;
|
||||
// case 1: /* Mix */
|
||||
// if (prevline == NULL){
|
||||
// REPEAT(line[x] = mix)
|
||||
// }else{
|
||||
// REPEAT(line[x] = prevline[x] ^ mix)
|
||||
// }
|
||||
// break;
|
||||
// case 2: /* Fill or Mix */
|
||||
// if (prevline == NULL){
|
||||
// REPEAT
|
||||
// (
|
||||
// MASK_UPDATE();
|
||||
// if (mask & mixmask)
|
||||
// line[x] = mix;
|
||||
// else
|
||||
// line[x] = 0;
|
||||
// )
|
||||
// }else{
|
||||
// REPEAT
|
||||
// (
|
||||
// MASK_UPDATE();
|
||||
// if (mask & mixmask)
|
||||
// line[x] = prevline[x] ^ mix;
|
||||
// else
|
||||
// line[x] = prevline[x];
|
||||
// )
|
||||
// }
|
||||
// break;
|
||||
// case 3: /* Colour */
|
||||
// REPEAT(line[x] = colour2)
|
||||
// break;
|
||||
// case 4: /* Copy */
|
||||
// REPEAT(line[x] = CVAL(input))
|
||||
// break;
|
||||
// case 8: /* Bicolour */
|
||||
// REPEAT
|
||||
// (
|
||||
// if (bicolour)
|
||||
// {
|
||||
// line[x] = colour2;
|
||||
// bicolour = false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// line[x] = colour1;
|
||||
// bicolour = true; count++;
|
||||
// }
|
||||
// )
|
||||
// break;
|
||||
// case 0xd: /* White */
|
||||
// REPEAT(line[x] = 0xff)
|
||||
// break;
|
||||
// case 0xe: /* Black */
|
||||
// REPEAT(line[x] = 0)
|
||||
// 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 int
|
||||
opcode, count, offset, code int
|
||||
x int = width
|
||||
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:
|
||||
glog.Infof("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 bitmap_decompress3(uint8 * output, int width, int height, uint8 * input, int size)bool{
|
||||
// uint8 *end = input + size;
|
||||
// uint8 *prevline = NULL, *line = NULL;
|
||||
// int opcode, count, offset, isfillormix, x = width;
|
||||
// int lastopcode = -1, insertmix = false, bicolour = false;
|
||||
// uint8 code;
|
||||
// uint8 colour1[3] = {0, 0, 0}, colour2[3] = {0, 0, 0};
|
||||
// uint8 mixmask, mask = 0;
|
||||
// uint8 mix[3] = {0xff, 0xff, 0xff};
|
||||
// int fom_mask = 0;
|
||||
|
||||
// while (input < end)
|
||||
// {
|
||||
// fom_mask = 0;
|
||||
// code = CVAL(input);
|
||||
// opcode = code >> 4;
|
||||
// /* Handle different opcode forms */
|
||||
// switch (opcode)
|
||||
// {
|
||||
// case 0xc:
|
||||
// case 0xd:
|
||||
// case 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 = (opcode <
|
||||
// 0xb) ? 8 : 1;
|
||||
// }
|
||||
// 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 == NULL)))
|
||||
// insertmix = true;
|
||||
// break;
|
||||
// case 8: /* Bicolour */
|
||||
// colour1[0] = CVAL(input);
|
||||
// colour1[1] = CVAL(input);
|
||||
// colour1[2] = CVAL(input);
|
||||
// case 3: /* Colour */
|
||||
// colour2[0] = CVAL(input);
|
||||
// colour2[1] = CVAL(input);
|
||||
// colour2[2] = CVAL(input);
|
||||
// break;
|
||||
// case 6: /* SetMix/Mix */
|
||||
// case 7: /* SetMix/FillOrMix */
|
||||
// mix[0] = CVAL(input);
|
||||
// mix[1] = CVAL(input);
|
||||
// mix[2] = 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 = opcode;
|
||||
// mixmask = 0;
|
||||
// /* Output body */
|
||||
// while (count > 0)
|
||||
// {
|
||||
// if (x >= width)
|
||||
// {
|
||||
// if (height <= 0)
|
||||
// return false;
|
||||
// x = 0;
|
||||
// height--;
|
||||
// prevline = line;
|
||||
// line = output + height * (width * 3);
|
||||
// }
|
||||
// switch (opcode)
|
||||
// {
|
||||
// case 0: /* Fill */
|
||||
// if (insertmix)
|
||||
// {
|
||||
// if (prevline == NULL)
|
||||
// {
|
||||
// line[x * 3] = mix[0];
|
||||
// line[x * 3 + 1] = mix[1];
|
||||
// line[x * 3 + 2] = mix[2];
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// line[x * 3] =
|
||||
// prevline[x * 3] ^ mix[0];
|
||||
// line[x * 3 + 1] =
|
||||
// prevline[x * 3 + 1] ^ mix[1];
|
||||
// line[x * 3 + 2] =
|
||||
// prevline[x * 3 + 2] ^ mix[2];
|
||||
// }
|
||||
// insertmix = false;
|
||||
// count--;
|
||||
// x++;
|
||||
// }
|
||||
// if (prevline == NULL)
|
||||
// {
|
||||
// REPEAT
|
||||
// (
|
||||
// line[x * 3] = 0;
|
||||
// line[x * 3 + 1] = 0;
|
||||
// line[x * 3 + 2] = 0;
|
||||
// )
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// REPEAT
|
||||
// (
|
||||
// line[x * 3] = prevline[x * 3];
|
||||
// line[x * 3 + 1] = prevline[x * 3 + 1];
|
||||
// line[x * 3 + 2] = prevline[x * 3 + 2];
|
||||
// )
|
||||
// }
|
||||
// break;
|
||||
// case 1: /* Mix */
|
||||
// if (prevline == NULL)
|
||||
// {
|
||||
// REPEAT
|
||||
// (
|
||||
// line[x * 3] = mix[0];
|
||||
// line[x * 3 + 1] = mix[1];
|
||||
// line[x * 3 + 2] = mix[2];
|
||||
// )
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// REPEAT
|
||||
// (
|
||||
// line[x * 3] =
|
||||
// prevline[x * 3] ^ mix[0];
|
||||
// line[x * 3 + 1] =
|
||||
// prevline[x * 3 + 1] ^ mix[1];
|
||||
// line[x * 3 + 2] =
|
||||
// prevline[x * 3 + 2] ^ mix[2];
|
||||
// )
|
||||
// }
|
||||
// break;
|
||||
// case 2: /* Fill or Mix */
|
||||
// if (prevline == NULL)
|
||||
// {
|
||||
// REPEAT
|
||||
// (
|
||||
// MASK_UPDATE();
|
||||
// if (mask & mixmask)
|
||||
// {
|
||||
// line[x * 3] = mix[0];
|
||||
// line[x * 3 + 1] = mix[1];
|
||||
// line[x * 3 + 2] = mix[2];
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// line[x * 3] = 0;
|
||||
// line[x * 3 + 1] = 0;
|
||||
// line[x * 3 + 2] = 0;
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// REPEAT
|
||||
// (
|
||||
// MASK_UPDATE();
|
||||
// if (mask & mixmask)
|
||||
// {
|
||||
// line[x * 3] =
|
||||
// prevline[x * 3] ^ mix [0];
|
||||
// line[x * 3 + 1] =
|
||||
// prevline[x * 3 + 1] ^ mix [1];
|
||||
// line[x * 3 + 2] =
|
||||
// prevline[x * 3 + 2] ^ mix [2];
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// line[x * 3] =
|
||||
// prevline[x * 3];
|
||||
// line[x * 3 + 1] =
|
||||
// prevline[x * 3 + 1];
|
||||
// line[x * 3 + 2] =
|
||||
// prevline[x * 3 + 2];
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
// break;
|
||||
// case 3: /* Colour */
|
||||
// REPEAT
|
||||
// (
|
||||
// line[x * 3] = colour2 [0];
|
||||
// line[x * 3 + 1] = colour2 [1];
|
||||
// line[x * 3 + 2] = colour2 [2];
|
||||
// )
|
||||
// break;
|
||||
// case 4: /* Copy */
|
||||
// REPEAT
|
||||
// (
|
||||
// line[x * 3] = CVAL(input);
|
||||
// line[x * 3 + 1] = CVAL(input);
|
||||
// line[x * 3 + 2] = CVAL(input);
|
||||
// )
|
||||
// break;
|
||||
// case 8: /* Bicolour */
|
||||
// REPEAT
|
||||
// (
|
||||
// if (bicolour)
|
||||
// {
|
||||
// line[x * 3] = colour2[0];
|
||||
// line[x * 3 + 1] = colour2[1];
|
||||
// line[x * 3 + 2] = colour2[2];
|
||||
// bicolour = false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// line[x * 3] = colour1[0];
|
||||
// line[x * 3 + 1] = colour1[1];
|
||||
// line[x * 3 + 2] = colour1[2];
|
||||
// bicolour = true;
|
||||
// count++;
|
||||
// }
|
||||
// )
|
||||
// break;
|
||||
// case 0xd: /* White */
|
||||
// REPEAT
|
||||
// (
|
||||
// line[x * 3] = 0xff;
|
||||
// line[x * 3 + 1] = 0xff;
|
||||
// line[x * 3 + 2] = 0xff;
|
||||
// )
|
||||
// break;
|
||||
// case 0xe: /* Black */
|
||||
// REPEAT
|
||||
// (
|
||||
// line[x * 3] = 0;
|
||||
// line[x * 3 + 1] = 0;
|
||||
// line[x * 3 + 2] = 0;
|
||||
// )
|
||||
// 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 int
|
||||
x int
|
||||
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 = code & 0xf
|
||||
collen = (code >> 4) & 0xf
|
||||
revcode = (replen << 4) | collen
|
||||
if (revcode <= 47) && (revcode >= 16) {
|
||||
replen = revcode
|
||||
collen = 0
|
||||
}
|
||||
for collen > 0 {
|
||||
color = 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 = code & 0xf
|
||||
collen = (code >> 4) & 0xf
|
||||
revcode = (replen << 4) | collen
|
||||
if (revcode <= 47) && (revcode >= 16) {
|
||||
replen = revcode
|
||||
collen = 0
|
||||
}
|
||||
for collen > 0 {
|
||||
x = CVAL(in)
|
||||
if x&1 != 0 {
|
||||
x = x >> 1
|
||||
x = x + 1
|
||||
color = -x
|
||||
} else {
|
||||
x = x >> 1
|
||||
color = x
|
||||
}
|
||||
x = int((*output)[indexw*4+lastline]) + color
|
||||
(*output)[i] = uint8(x)
|
||||
i += 4
|
||||
indexw++
|
||||
collen--
|
||||
}
|
||||
for replen > 0 {
|
||||
x = int((*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:
|
||||
glog.Infof("Bpp %d\n", Bpp)
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
10
pkg/grdp/core/rle_test.go
Normal file
10
pkg/grdp/core/rle_test.go
Normal file
@@ -0,0 +1,10 @@
|
||||
// rle_test.go
|
||||
package core
|
||||
|
||||
//func TestSum() {
|
||||
// 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, 2)
|
||||
// fmt.Println(out)
|
||||
//}
|
||||
75
pkg/grdp/core/socket.go
Normal file
75
pkg/grdp/core/socket.go
Normal file
@@ -0,0 +1,75 @@
|
||||
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)
|
||||
}
|
||||
21
pkg/grdp/core/types.go
Normal file
21
pkg/grdp/core/types.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package core
|
||||
|
||||
import "Yasso/pkg/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)
|
||||
}
|
||||
52
pkg/grdp/core/util.go
Normal file
52
pkg/grdp/core/util.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"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 convertUTF16ToLittleEndianBytes(u []uint16) []byte {
|
||||
b := make([]byte, 2*len(u))
|
||||
for index, value := range u {
|
||||
binary.LittleEndian.PutUint16(b[index*2:], value)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// s.encode('utf-16le')
|
||||
func UnicodeEncode(p string) []byte {
|
||||
return convertUTF16ToLittleEndianBytes(utf16.Encode([]rune(p)))
|
||||
}
|
||||
|
||||
func UnicodeDecode(p []byte) string {
|
||||
b := make([]byte, 2)
|
||||
n := make([]uint16, 0, len(p)/2)
|
||||
for i, v := range p {
|
||||
if i%2 == 0 {
|
||||
b[0] = v
|
||||
} else {
|
||||
b[1] = v
|
||||
a := binary.LittleEndian.Uint16(b)
|
||||
n = append(n, a)
|
||||
}
|
||||
}
|
||||
return string(utf16.Decode(n))
|
||||
}
|
||||
Reference in New Issue
Block a user