Mejoras en general

This commit is contained in:
Matias Fernandez
2019-07-29 22:54:48 -04:00
parent 57623a6933
commit a6327060f9
16 changed files with 738 additions and 393 deletions

260
lib/bgr233_palette.py Normal file
View File

@@ -0,0 +1,260 @@
# BGR233 palette
palette = [
0, 0, 0,
36, 0, 0,
73, 0, 0,
109, 0, 0,
146, 0, 0,
182, 0, 0,
219, 0, 0,
255, 0, 0,
0, 36, 0,
36, 36, 0,
73, 36, 0,
109, 36, 0,
146, 36, 0,
182, 36, 0,
219, 36, 0,
255, 36, 0,
0, 73, 0,
36, 73, 0,
73, 73, 0,
109, 73, 0,
146, 73, 0,
182, 73, 0,
219, 73, 0,
255, 73, 0,
0, 109, 0,
36, 109, 0,
73, 109, 0,
109, 109, 0,
146, 109, 0,
182, 109, 0,
219, 109, 0,
255, 109, 0,
0, 146, 0,
36, 146, 0,
73, 146, 0,
109, 146, 0,
146, 146, 0,
182, 146, 0,
219, 146, 0,
255, 146, 0,
0, 182, 0,
36, 182, 0,
73, 182, 0,
109, 182, 0,
146, 182, 0,
182, 182, 0,
219, 182, 0,
255, 182, 0,
0, 219, 0,
36, 219, 0,
73, 219, 0,
109, 219, 0,
146, 219, 0,
182, 219, 0,
219, 219, 0,
255, 219, 0,
0, 255, 0,
36, 255, 0,
73, 255, 0,
109, 255, 0,
146, 255, 0,
182, 255, 0,
219, 255, 0,
255, 255, 0,
0, 0, 85,
36, 0, 85,
73, 0, 85,
109, 0, 85,
146, 0, 85,
182, 0, 85,
219, 0, 85,
255, 0, 85,
0, 36, 85,
36, 36, 85,
73, 36, 85,
109, 36, 85,
146, 36, 85,
182, 36, 85,
219, 36, 85,
255, 36, 85,
0, 73, 85,
36, 73, 85,
73, 73, 85,
109, 73, 85,
146, 73, 85,
182, 73, 85,
219, 73, 85,
255, 73, 85,
0, 109, 85,
36, 109, 85,
73, 109, 85,
109, 109, 85,
146, 109, 85,
182, 109, 85,
219, 109, 85,
255, 109, 85,
0, 146, 85,
36, 146, 85,
73, 146, 85,
109, 146, 85,
146, 146, 85,
182, 146, 85,
219, 146, 85,
255, 146, 85,
0, 182, 85,
36, 182, 85,
73, 182, 85,
109, 182, 85,
146, 182, 85,
182, 182, 85,
219, 182, 85,
255, 182, 85,
0, 219, 85,
36, 219, 85,
73, 219, 85,
109, 219, 85,
146, 219, 85,
182, 219, 85,
219, 219, 85,
255, 219, 85,
0, 255, 85,
36, 255, 85,
73, 255, 85,
109, 255, 85,
146, 255, 85,
182, 255, 85,
219, 255, 85,
255, 255, 85,
0, 0, 170,
36, 0, 170,
73, 0, 170,
109, 0, 170,
146, 0, 170,
182, 0, 170,
219, 0, 170,
255, 0, 170,
0, 36, 170,
36, 36, 170,
73, 36, 170,
109, 36, 170,
146, 36, 170,
182, 36, 170,
219, 36, 170,
255, 36, 170,
0, 73, 170,
36, 73, 170,
73, 73, 170,
109, 73, 170,
146, 73, 170,
182, 73, 170,
219, 73, 170,
255, 73, 170,
0, 109, 170,
36, 109, 170,
73, 109, 170,
109, 109, 170,
146, 109, 170,
182, 109, 170,
219, 109, 170,
255, 109, 170,
0, 146, 170,
36, 146, 170,
73, 146, 170,
109, 146, 170,
146, 146, 170,
182, 146, 170,
219, 146, 170,
255, 146, 170,
0, 182, 170,
36, 182, 170,
73, 182, 170,
109, 182, 170,
146, 182, 170,
182, 182, 170,
219, 182, 170,
255, 182, 170,
0, 219, 170,
36, 219, 170,
73, 219, 170,
109, 219, 170,
146, 219, 170,
182, 219, 170,
219, 219, 170,
255, 219, 170,
0, 255, 170,
36, 255, 170,
73, 255, 170,
109, 255, 170,
146, 255, 170,
182, 255, 170,
219, 255, 170,
255, 255, 170,
0, 0, 255,
36, 0, 255,
73, 0, 255,
109, 0, 255,
146, 0, 255,
182, 0, 255,
219, 0, 255,
255, 0, 255,
0, 36, 255,
36, 36, 255,
73, 36, 255,
109, 36, 255,
146, 36, 255,
182, 36, 255,
219, 36, 255,
255, 36, 255,
0, 73, 255,
36, 73, 255,
73, 73, 255,
109, 73, 255,
146, 73, 255,
182, 73, 255,
219, 73, 255,
255, 73, 255,
0, 109, 255,
36, 109, 255,
73, 109, 255,
109, 109, 255,
146, 109, 255,
182, 109, 255,
219, 109, 255,
255, 109, 255,
0, 146, 255,
36, 146, 255,
73, 146, 255,
109, 146, 255,
146, 146, 255,
182, 146, 255,
219, 146, 255,
255, 146, 255,
0, 182, 255,
36, 182, 255,
73, 182, 255,
109, 182, 255,
146, 182, 255,
182, 182, 255,
219, 182, 255,
255, 182, 255,
0, 219, 255,
36, 219, 255,
73, 219, 255,
109, 219, 255,
146, 219, 255,
182, 219, 255,
219, 219, 255,
255, 219, 255,
0, 255, 255,
36, 255, 255,
73, 255, 255,
109, 255, 255,
146, 255, 255,
182, 255, 255,
219, 255, 255,
255, 255, 255
]

View File

@@ -16,5 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# at least, raw encoding is needed by the rfb protocol
from . import common as enc
from . import common
from . import raw
from . import zlib
from . import cursor

View File

@@ -15,5 +15,15 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
encodings = {}
class ENCODINGS:
pass
raw = 0
zlib = 6
# supported pseudo-encodings
cursor = -239
encodings_priority = [
ENCODINGS.zlib,
ENCODINGS.raw
]

View File

@@ -16,5 +16,21 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . import common
from struct import *
from lib import log
import zlib
common.ENCODINGS.cursor = -239
class Encoding:
name = 'Cursor'
id = -239
description = 'Cursor pseudo encoding'
enabled = True
pseudoEncoding = True
cursor_sent = False
def __init__(self):
log.debug("Initialized", __name__)
common.encodings[common.ENCODINGS.cursor] = Encoding
log.debug("Loaded encoding: %s (%s)" % (__name__, Encoding.id))

View File

@@ -17,16 +17,30 @@
from . import common
from struct import *
from lib import log
def send_image(x, y, w, h, image):
_buff = bytearray()
rectangles = 1
_buff.extend(pack("!BxH", 0, rectangles))
_buff.extend(pack("!HHHH", x, y, w, h))
_buff.extend(pack(">i", common.ENCODINGS.raw))
_buff.extend( image.tobytes() )
class Encoding:
_buff = None
return _buff
name = 'raw'
id = 0
description = 'Raw VNC encoding'
enabled = True
firstUpdateSent = False
common.ENCODINGS.raw = 0
common.ENCODINGS.raw_send_image = send_image
def __init__(self):
log.debug("Initialized", __name__)
def send_image(self, x, y, w, h, image):
self._buff = bytearray()
rectangles = 1
self._buff.extend(pack("!BxH", 0, rectangles)) # message type 0 == FramebufferUpdate
self._buff.extend(pack("!HHHH", x, y, w, h))
self._buff.extend(pack(">i", self.id))
self._buff.extend( image.tobytes() )
return self._buff
common.encodings[common.ENCODINGS.raw] = Encoding
log.debug("Loaded encoding: %s (%s)" % (__name__, Encoding.id))

54
lib/encodings/zlib.py Normal file
View File

@@ -0,0 +1,54 @@
from . import common
from struct import *
from lib import log
import zlib
class Encoding:
name = 'zlib'
id = 6
description = 'zlib VNC encoding'
enabled = True
firstUpdateSent = False
_compressObj = None
def __init__(self):
log.debug("Initialized", __name__)
self._compressObj = zlib.compressobj(
zlib.Z_DEFAULT_COMPRESSION, # level: 0-9
zlib.DEFLATED, # method: must be DEFLATED
zlib.MAX_WBITS, # window size in bits:
# -15..-8: negate, suppress header
# 8..15: normal
# 16..30: subtract 16, gzip header
zlib.DEF_MEM_LEVEL, # mem level: 1..8/9
zlib.Z_DEFAULT_STRATEGY # strategy:
# 0 = Z_DEFAULT_STRATEGY
# 1 = Z_FILTERED
# 2 = Z_HUFFMAN_ONLY
# 3 = Z_RLE
# 4 = Z_FIXED
)
def send_image(self, x, y, w, h, image):
sendbuff = bytearray()
rectangles = 1
sendbuff.extend(pack("!BxH", 0, rectangles)) # message type 0 == FramebufferUpdate
sendbuff.extend(pack("!HHHH", x, y, w, h))
sendbuff.extend(pack(">i", self.id))
#log.debug("Compressing...")
zlibdata = self._compressObj.compress( image.tobytes() )
zlibdata += self._compressObj.flush(zlib.Z_FULL_FLUSH)
#log.debug("LEN", len(zlibdata))
l = pack("!I", len(zlibdata) )
sendbuff.extend( l ) # send length
sendbuff.extend( zlibdata ) # send compressed data
return sendbuff
common.encodings[common.ENCODINGS.zlib] = Encoding
log.debug("Loaded encoding: %s (%s)" % (__name__, Encoding.id))

41
lib/imagegrab.py Normal file
View File

@@ -0,0 +1,41 @@
import sys
from PIL import Image
from lib import log
if sys.platform == "linux" or sys.platform == "linux2":
log.debug("ImageGrab: running on Linux")
from Xlib import display, X
# take screen images, that's not the best way, so here
# we use directly use xlib to take the screenshot.
class ImageGrab():
def grab():
dsp = display.Display()
root = dsp.screen().root
geom = root.get_geometry()
w = geom.width
h = geom.height
raw = root.get_image(0, 0, w ,h, X.ZPixmap, 0xffffffff)
image = Image.frombytes("RGB", (w, h), raw.data, "raw", "BGRX")
return image
elif sys.platform == "darwin":
log.debug("ImageGrab: running on darwin")
import Quartz.CoreGraphics as CG
class ImageGrab():
def grab():
screenshot = CG.CGWindowListCreateImage(CG.CGRectInfinite, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault)
width = CG.CGImageGetWidth(screenshot)
height = CG.CGImageGetHeight(screenshot)
bytesperrow = CG.CGImageGetBytesPerRow(screenshot)
pixeldata = CG.CGDataProviderCopyData(CG.CGImageGetDataProvider(screenshot))
i = Image.frombytes("RGBA", (width, height), pixeldata)
(b, g, r, x) = i.split()
i = Image.merge("RGBX", (r, g, b, x))
return i
else:
log.debug("ImageGrab: running on Unknown!")
from PIL import ImageGrab

47
lib/kbdctrl.py Normal file
View File

@@ -0,0 +1,47 @@
import sys
from struct import pack, unpack
from pynput import keyboard
from lib import log
from lib.kbdmap import *
class KeyboardController:
kbdmap = kbdmap
kbdkey = ''
downflag = None
key = None
controller = None
kbd = None
def __init__(self):
self.kbd = keyboard
self.controller = self.kbd.Controller()
def process_event(self, data):
# B = U8, L = U32
(self.downflag, self.key) = unpack("!BxxL", data)
log.debug("KeyEvent", self.downflag, hex(self.key))
# special key
if self.key in self.kbdmap:
self.kbdkey = self.kbdmap[self.key]
log.debug("SPECIAL KEY", self.kbdkey)
else: # normal key
try:
self.kbdkey = self.kbd.KeyCode.from_char(chr(self.key))
except:
self.kbdkey = None
# debug keypress to stdout
try:
log.debug("KEY:", self.kbdkey)
except:
log.debug("KEY: (unprintable)")
# send the actual keyboard event
try:
if self.downflag:
self.controller.press(self.kbdkey)
else:
self.controller.release(self.kbdkey)
except:
log.debug("Error sending key")

79
lib/kbdmap.py Normal file
View File

@@ -0,0 +1,79 @@
import sys
from pynput import keyboard
__all__ = ['kbdmap']
kbdmap = {
0xff08: keyboard.Key.backspace,
0xff09: keyboard.Key.tab,
0xff0d: keyboard.Key.enter,
0xff1b: keyboard.Key.esc,
0xff63: keyboard.Key.insert if hasattr(keyboard.Key, "insert") else None,
0xffff: keyboard.Key.delete,
0xff50: keyboard.Key.home,
0xff57: keyboard.Key.end,
0xff55: keyboard.Key.page_up,
0xff56: keyboard.Key.page_down,
0xff51: keyboard.Key.left,
0xff52: keyboard.Key.up,
0xff53: keyboard.Key.right,
0xff54: keyboard.Key.down,
0xffbe: keyboard.Key.f1,
0xffbf: keyboard.Key.f2,
0xffc0: keyboard.Key.f3,
0xffc1: keyboard.Key.f4,
0xffc2: keyboard.Key.f5,
0xffc3: keyboard.Key.f6,
0xffc4: keyboard.Key.f7,
0xffc5: keyboard.Key.f8,
0xffc6: keyboard.Key.f9,
0xffc7: keyboard.Key.f10,
0xffc8: keyboard.Key.f11,
0xffc9: keyboard.Key.f12,
0xffca: keyboard.Key.f13,
0xffcb: keyboard.Key.f14,
0xffcc: keyboard.Key.f15,
0xffcd: keyboard.Key.f16,
0xffce: keyboard.Key.f17,
0xffcf: keyboard.Key.f18,
0xffd0: keyboard.Key.f19,
0xffd1: keyboard.Key.f20,
0xffe1: keyboard.Key.shift_l,
0xffe2: keyboard.Key.shift_r,
0xffe3: keyboard.Key.ctrl_l,
0xffe4: keyboard.Key.ctrl_r,
0xffe7: None, # "KEY_MetaLeft"
0xffe8: None, # "KEY_MetaRight"
#0xffe9: keyboard.Key.cmd_l,
0xffe9: keyboard.Key.alt,
0xffea: keyboard.Key.alt_gr, # "KEY_AltRight"
0xff14: keyboard.Key.scroll_lock if hasattr(keyboard.Key, "scroll_lock") else None,
0xff15: keyboard.Key.print_screen if hasattr(keyboard.Key, "print_screen") else None, # "KEY_Sys_Req"
0xff7f: keyboard.Key.num_lock if hasattr(keyboard.Key, "num_lock") else None,
0xffe5: keyboard.Key.caps_lock,
0xff13: keyboard.Key.pause if hasattr(keyboard.Key, "pause") else None,
0xffeb: keyboard.Key.cmd_r, # "KEY_Super_L"
0xffec: keyboard.Key.cmd_r, # "KEY_Super_R"
0xffed: None, # "KEY_Hyper_L"
0xffee: None, # "KEY_Hyper_R"
0xffb0: None, # "KEY_KP_0"
0xffb1: None, # "KEY_KP_1"
0xffb2: None, # "KEY_KP_2"
0xffb3: None, # "KEY_KP_3"
0xffb4: None, # "KEY_KP_4"
0xffb5: None, # "KEY_KP_5"
0xffb6: None, # "KEY_KP_6"
0xffb7: None, # "KEY_KP_7"
0xffb8: None, # "KEY_KP_8"
0xffb9: None, # "KEY_KP_9"
0xff8d: None, # "KEY_KP_Enter"
0x002f: "/", # KEY_ForwardSlash
0x005c: "\\", # KEY_BackSlash
0x0020: keyboard.Key.space, # "KEY_SpaceBar"
0xff7e: keyboard.Key.alt_gr, # altgr, at least on a mac (?)
#0xfe03: keyboard.Key.alt_l,
0xfe03: keyboard.Key.cmd_l,
}
if sys.platform == "darwin":
kbdmap[0xffe2] = keyboard.Key.shift

60
lib/mousectrl.py Normal file
View File

@@ -0,0 +1,60 @@
from struct import pack, unpack
from pynput import mouse
from lib import log
class MouseController():
def __init__(self):
self.buttonmask = 0
self.buttons = [0, 0, 0, 0, 0, 0, 0, 0]
self.left_pressed = 0
self.right_pressed = 0
self.middle_pressed = 0
def process_event(self, data):
(self.buttonmask, x, y) = unpack("!BHH", data)
self.buttons[0] = self.buttonmask & int("0000001", 2) # left button
self.buttons[1] = self.buttonmask & int("0000010", 2) # middle button
self.buttons[2] = self.buttonmask & int("0000100", 2) # right button
self.buttons[3] = self.buttonmask & int("0001000", 2) # scroll up
self.buttons[4] = self.buttonmask & int("0010000", 2) # scroll down
# set mouse position
mouse.Controller().position = (x, y)
# process mouse button events
if self.buttons[0] and not self.left_pressed:
log.debug("LEFT PRESSED")
mouse.Controller().press(mouse.Button.left)
self.left_pressed = 1
elif not self.buttons[0] and self.left_pressed:
log.debug("LEFT RELEASED")
mouse.Controller().release(mouse.Button.left)
self.left_pressed = 0
if self.buttons[1] and not self.middle_pressed:
log.debug("MIDDLE PRESSED")
mouse.Controller().press(mouse.Button.middle)
self.middle_pressed = 1
elif not self.buttons[1] and self.middle_pressed:
log.debug("MIDDLE RELEASED")
mouse.Controller().release(mouse.Button.middle)
self.middle_pressed = 0
if self.buttons[2] and not self.right_pressed:
log.debug("RIGHT PRESSED")
mouse.Controller().press(mouse.Button.right)
self.right_pressed = 1
elif not self.buttons[2] and self.right_pressed:
log.debug("RIGHT RELEASED")
mouse.Controller().release(mouse.Button.right)
self.right_pressed = 0
if self.buttons[3]:
log.debug("SCROLLUP PRESSED")
mouse.Controller().scroll(0, 2)
if self.buttons[4]:
log.debug("SCROLLDOWN PRESSED")
mouse.Controller().scroll(0, -2)
#log.debug("PointerEvent", buttonmask, x, y)

31
lib/oshelpers/windows.py Normal file
View File

@@ -0,0 +1,31 @@
import ctypes
import sys
from elevate import elevate
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
def run_as_admin_old(argv=None):
shell32 = ctypes.windll.shell32
if argv is None and shell32.IsUserAnAdmin():
return True
if argv is None:
argv = sys.argv
if hasattr(sys, '_MEIPASS'):
# Support pyinstaller wrapped program.
arguments = argv[1:]
else:
arguments = argv
argument_line = u' '.join(arguments)
executable = sys.executable
ret = shell32.ShellExecuteW(None, u"runas", executable, argument_line, None, 1)
if int(ret) <= 32:
return False
return None
def run_as_admin():
elevate()