class Android::Dex
parsed dex object @see source.android.com/devices/tech/dalvik/dex-format.html @attr_reader strings [Array<String>] strings in dex file.
Constants
- TYPE_DESCRIPTOR
@private
Attributes
@return [Array<Dex::ClassInfo>] array of class information
@return [String] dex binary data
@return [Dex::Header] dex header information
@return [Dex::Header] dex header information
Public Class Methods
@param [String] data dex binary data
# File lib/android/dex.rb, line 24 def initialize(data) @data = data @data.force_encoding(Encoding::ASCII_8BIT) @classes = [] parse() end
parse sleb128(signed integer) data @param [String] data target byte data @param [Integer] offset @return [Integer, Integer] parsed value and parsed byte length
# File lib/android/dex/utils.rb, line 34 def sleb128(data, offset=0) result = 0 shift = 0 d = data[offset...data.size] (0..4).each do |i| byte = d.getbyte(i) result |=((byte & 0x7F) << shift) return (0 == (byte & 0x40) ? result : result - (1 << (shift+7))), i+1 if ((byte & 0x80) == 0) shift += 7 end end
parse uleb128(unsigned integer) data @param [String] data target byte data @param [Integer] offset @return [Integer, Integer] parsed value and parsed byte length @see en.wikipedia.org/wiki/LEB128
# File lib/android/dex/utils.rb, line 11 def uleb128(data, offset=0) result = 0 shift = 0 d = data[offset...data.size] (0..4).each do |i| byte = d.getbyte(i) result |= ((byte & 0x7f) << shift) return result, i+1 if ((byte & 0x80) == 0) shift += 7 end end
parse uleb128 + 1 data @param [String] data target byte data @param [Integer] offset @return [Integer, Integer] parsed value and parsed byte length
# File lib/android/dex/utils.rb, line 26 def uleb128p1(data, offset=0) ret, len = self.uleb128(data, offset) return (ret - 1), len end
Public Instance Methods
# File lib/android/dex.rb, line 35 def inspect "<Android::Dex @classes => #{@classes.size}, datasize => #{@data.size}>" end
# File lib/android/dex.rb, line 31 def strings @strings ||= @string_data_items.map{|item| item.to_s } end
# File lib/android/dex.rb, line 54 def type_resolve(typeid) type = strings[@type_ids[typeid]] if type.start_with? '[' type = type[1..type.size] return TYPE_DESCRIPTOR.fetch(type, type) + "[]" # TODO: recursive else return TYPE_DESCRIPTOR.fetch(type, type) end end
Private Instance Methods
# File lib/android/dex.rb, line 87 def ids_list_array(cls, offset, size) ret_array = [] size.times { |i| ret_array << cls.new(@data, offset + cls.size * i) } ret_array end
# File lib/android/dex.rb, line 66 def parse @header = DexObject::Header.new(@data) @map_list = DexObject::MapList.new(@data, h[:map_off]) # parse strings @string_ids = DexObject::StringIdItem.new(@data, h[:string_ids_off], h[:string_ids_size]) @string_data_items = [] @string_ids[:string_data_off].each { |off| @string_data_items << DexObject::StringDataItem.new(@data, off) } @type_ids = DexObject::TypeIdItem.new(@data, h[:type_ids_off], h[:type_ids_size]) @proto_ids = ids_list_array(DexObject::ProtoIdItem, h[:proto_ids_off], h[:proto_ids_size]) @field_ids = ids_list_array(DexObject::FieldIdItem, h[:field_ids_off], h[:field_ids_size]) @method_ids = ids_list_array(DexObject::MethodIdItem, h[:method_ids_off], h[:method_ids_size]) @class_defs = ids_list_array(DexObject::ClassDefItem, h[:class_defs_off], h[:class_defs_size]) @classes = [] @class_defs.each do |cls_def| @classes << ClassInfo.new(cls_def, self) end end