Class: Rex::Proto::ADB::Message

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/proto/adb/message.rb

Overview

A Message for the ADB protocol. For documentation see: android.googlesource.com/platform/system/core/+/master/adb/protocol.txt

Direct Known Subclasses

Auth, Close, Connect, Open, Ready, Sync, Write

Defined Under Namespace

Classes: Auth, Close, Connect, Open, Ready, Sync, Write

Constant Summary collapse

WORD_WIDTH =

bytes

4
WORD_PACK =
'L<'
MESSAGE_TYPES =

Avoid a dependency on Rails's nice Class#subclasses

[Connect, Auth, Open, Ready, Write, Close, Sync]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(arg0, arg1, data) ⇒ Message

Returns a new instance of Message.


23
24
25
26
27
28
# File 'lib/rex/proto/adb/message.rb', line 23

def initialize(arg0, arg1, data)
  self.command = self.class::COMMAND if defined?(self.class::COMMAND)
  self.arg0 = arg0
  self.arg1 = arg1
  self.data = data + "\0"
end

Instance Attribute Details

#arg0Object

Returns the value of attribute arg0


19
20
21
# File 'lib/rex/proto/adb/message.rb', line 19

def arg0
  @arg0
end

#arg1Object

Returns the value of attribute arg1


20
21
22
# File 'lib/rex/proto/adb/message.rb', line 20

def arg1
  @arg1
end

#commandObject

Returns the value of attribute command


18
19
20
# File 'lib/rex/proto/adb/message.rb', line 18

def command
  @command
end

#dataObject

Returns the value of attribute data


21
22
23
# File 'lib/rex/proto/adb/message.rb', line 21

def data
  @data
end

Class Method Details

.read(socket) ⇒ Object


69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/rex/proto/adb/message.rb', line 69

def self.read(socket)
  header = socket.recvfrom(6 * WORD_WIDTH)[0]
  command = header[0, WORD_WIDTH]
  arg0 = header[WORD_WIDTH, WORD_WIDTH].unpack(WORD_PACK)[0]
  arg1 = header[WORD_WIDTH*2, WORD_WIDTH].unpack(WORD_PACK)[0]
  payload_len = header[WORD_WIDTH*3, WORD_WIDTH].unpack(WORD_PACK)[0]
  payload = socket.recvfrom(payload_len)[0]

  klass = MESSAGE_TYPES.find { |klass| klass::COMMAND == command }
  if klass.nil?
    raise "Invalid adb command: #{command}"
  end

  message = klass.allocate
  message.command = command
  message.arg0 = arg0
  message.arg1 = arg1
  message.data = payload
  message
end

Instance Method Details

#command_wordObject


40
41
42
# File 'lib/rex/proto/adb/message.rb', line 40

def command_word
  command.unpack(WORD_PACK)[0]
end

#data_checkObject


30
31
32
33
34
# File 'lib/rex/proto/adb/message.rb', line 30

def data_check
  # this check is implemented in adb/transport.cpp, in the send_packet method.
  # it is not crc32 as the docs make it appear, it is just a 32bit sum.
  data.bytes.inject(&:+) & 0xffffffff
end

#magicObject


36
37
38
# File 'lib/rex/proto/adb/message.rb', line 36

def magic
  command_word ^ 0xffffffff
end

#send_recv(socket) ⇒ Object


44
45
46
47
# File 'lib/rex/proto/adb/message.rb', line 44

def send_recv(socket)
  socket.print self.serialize
  Message.read socket
end

#serializeObject


49
50
51
52
53
54
55
56
57
58
# File 'lib/rex/proto/adb/message.rb', line 49

def serialize
  [
    command_word,
    arg0,
    arg1,
    data.bytes.length,
    data_check,
    magic
  ].pack(WORD_PACK+'*') + data
end

#to_sObject


60
61
62
63
64
65
66
67
# File 'lib/rex/proto/adb/message.rb', line 60

def to_s
  [
    "command=#{command}",
    "arg0=0x#{arg0.to_s(16)}",
    "arg1=0x#{arg1.to_s(16)}",
    "data=#{data}"
  ].join("\n")
end