Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/rex/proto/adb/message.rb
Views: 11704
# -*- coding: binary -*-12##3# ADB protocol support4##56module Rex7module Proto8module ADB910# A Message for the ADB protocol. For documentation see:11# https://android.googlesource.com/platform/system/core/+/master/adb/protocol.txt12class Message1314WORD_WIDTH = 4 # bytes15WORD_PACK = 'L<'1617attr_accessor :command18attr_accessor :arg019attr_accessor :arg120attr_accessor :data2122def initialize(arg0, arg1, data)23self.command = self.class::COMMAND if defined?(self.class::COMMAND)24self.arg0 = arg025self.arg1 = arg126self.data = data + "\0"27end2829def data_check30# this check is implemented in adb/transport.cpp, in the send_packet method.31# it is not crc32 as the docs make it appear, it is just a 32bit sum.32data.bytes.inject(&:+) & 0xffffffff33end3435def magic36command_word ^ 0xffffffff37end3839def command_word40command.unpack(WORD_PACK)[0]41end4243def send_recv(socket)44socket.print self.serialize45Message.read socket46end4748def serialize49[50command_word,51arg0,52arg1,53data.bytes.length,54data_check,55magic56].pack(WORD_PACK+'*') + data57end5859def to_s60[61"command=#{command}",62"arg0=0x#{arg0.to_s(16)}",63"arg1=0x#{arg1.to_s(16)}",64"data=#{data}"65].join("\n")66end6768def self.read(socket)69header = socket.recvfrom(6 * WORD_WIDTH)[0]70command = header[0, WORD_WIDTH]71arg0 = header[WORD_WIDTH, WORD_WIDTH].unpack(WORD_PACK)[0]72arg1 = header[WORD_WIDTH*2, WORD_WIDTH].unpack(WORD_PACK)[0]73payload_len = header[WORD_WIDTH*3, WORD_WIDTH].unpack(WORD_PACK)[0]74payload = socket.recvfrom(payload_len)[0]7576klass = MESSAGE_TYPES.find { |klass| klass::COMMAND == command }77if klass.nil?78raise "Invalid adb command: #{command}"79end8081message = klass.allocate82message.command = command83message.arg0 = arg084message.arg1 = arg185message.data = payload86message87end8889#90# Subclasses inside Message:: namespace for specific message types91#9293class Connect < Message94COMMAND = "CNXN"95DEFAULT_VERSION = 0x0100000096DEFAULT_MAXDATA = 409697DEFAULT_IDENTITY = "host::"9899def initialize(version=DEFAULT_VERSION,100maxdata=DEFAULT_MAXDATA,101system_identity_string=DEFAULT_IDENTITY)102super103end104end105106class Auth < Message107COMMAND = "AUTH"108TYPE_TOKEN = 1109TYPE_SIGNATURE = 2110111def initialize(type, data)112super(type, 0, data)113end114end115116class Open < Message117COMMAND = "OPEN"118119def initialize(local_id, destination)120super(local_id, 0, destination)121end122end123124class Ready < Message125COMMAND = "OKAY"126127def initialize(local_id, remote_id)128super(local_id, remote_id, "")129end130end131132class Write < Message133COMMAND = "WRTE"134135def initialize(local_id, remote_id, data)136super137end138end139140class Close < Message141COMMAND = "CLSE"142143def initialize(local_id, remote_id)144super(local_id, remote_id, "")145end146end147148class Sync < Message149COMMAND = "SYNC"150151def initialize(online, sequence)152super(online, sequence, "")153end154end155156# Avoid a dependency on Rails's nice Class#subclasses157MESSAGE_TYPES = [Connect, Auth, Open, Ready, Write, Close, Sync]158159end # Message160161end # ADB162end # Proto163end # Rex164165166