androidManifest

androidmanifest.xml是一个格式化的xml. 文档结构如图



尝试去读了一下

#encoding:utf-8

require 'zip'
require "rexml/document"

class AndroidManifest
	STEP=4
	MAGIC_VALUE=0x00080003
	STRING_CHUNK=0x001c0001
	RESOURCE_CHUNK=0x00080180
	START_NAMESPACE_CHUNK=0x00100100

	#节点标签
	END_DOC_TAG     =0x00100101
	START_TAG 		=0x00100102
	END_TAG 		=0x00100103
	TEXT_TAG		=0x00100104

	#只分析出了这几种常见的类型
	INT_VALUE_TYPE		=0x10000008
	BOOL_VALUE_TYPE		=0x12000008
	HEX_VALUE_TYPE		=0x11000008
	STRING_VALUE_TYPE	=0x03000008
	DOUBLE_VALUE_TYPE	=0x04000008
	STRING_R_ID			=0x01000008


	def read_number(length=4)
		@seek+=length
		if length==2
			@manifest[@seek-length,length].unpack('S')[0]
		elsif length==4
			@manifest[@seek-length,length].unpack('V')[0]
		else
			raise "未知的数据格式"
		end
	end
	def read_string
		string_length=read_number(2)
		string = @manifest[@seek,string_length*2].force_encoding('UTF-16LE').encode('utf-8')
		@seek+=string_length*2+2
		string
	end

	#第3字节开始是字符串块
	def init_string_table
		#字符串表开始标志
		start_offset=@seek
		raise "string_table?(#{@seek.to_s(16)})" unless STRING_CHUNK == read_number
		#块长度
		chunk_size=read_number
		#字符串数量
		string_count= read_number
		#样式表数量
		style_count =read_number
		#未知
		@seek+=4
		#偏移量
		string_pool_offset=read_number
		style_pool_offset=read_number

		string_offsets=string_count.times.map{|x| read_number }
		style_offsets=style_count.times.map{|x| read_number }
		string_count.times { @strings<<read_string }

		style_count.times { @styles<<read_string }
		#这儿有个问题是补位,如果读完字符串不是正好4的倍数,要补齐
		@seek=start_offset+chunk_size
	end

	#在字符串块之后是资源列表
	def init_resource_table
		raise "resource_table #{@seek.to_s(16)}?" unless RESOURCE_CHUNK == read_number
		chunk_size=read_number
		(chunk_size / 4 -2).times.map{|x| @resource<<read_number}
	end

	def start_name_space
		#24字节
		raise "start_name_space? #{@seek.to_s(16)}?" unless START_NAMESPACE_CHUNK == read_number
		chunk_size=read_number
		line_number=read_number
		read_number
		@prefix=read_number
		@uri=read_number
	end

	def read_xml
		#一共只有4种节点
		begin
			tag=read_number

			if START_TAG == tag
				read_start_tag
			elsif END_TAG == tag
				@seek += 4*4
				name=read_number
				puts "</#{@strings[name]}>"
			elsif END_DOC_TAG ==tag
				puts "文档结束"
				break
			elsif tag==TEXT_TAG
				@seek += 6*4
			else
			     raise "tag at "+@seek.to_s(16)
			end
		end while  true
	end

	def read_start_tag
		chunk_size=read_number
		line =read_number
		@seek+=4 #0xFFFFFFFF
		ns=read_number
		name=read_number
		flag=read_number
		attr_count=read_number
		class_attribute=read_number
		string="<#{@strings[name]}"
		attr_count.times do |index|
			ns=read_number
			name=read_number
			key="#{@strings[@prefix]}:#{@strings[name]}"
			value=read_number
			type=read_number
			data=read_number

			if type == INT_VALUE_TYPE
				value=data
			elsif type == STRING_VALUE_TYPE
				value=@strings[value]
			elsif type == BOOL_VALUE_TYPE
				value=data ? "true" : "false"
			elsif type == STRING_R_ID
				value="0x"+data.to_s(16)
			elsif HEX_VALUE_TYPE == type
				value="0x"+data.to_s(16)
			elsif DOUBLE_VALUE_TYPE == type
				#这儿的精度会缺失错误
				value=[data].pack('L').unpack('e')[0]
			else
				puts "#{key}=\"#{value}\" type #{type.to_s(16)} data:#{data}"
				raise "未知的数据类型"
			end
			string<< " #{key}=\"#{value}\""
			#puts "#{key}=\"#{value}\" type #{type.to_s(16)} data:#{data}"
		end
		string<<">"
		puts string
	end

	def initialize(manifest)
		@manifest=manifest
		@doc = REXML::Document.new('<?xml version="1.0" encoding="utf-8" standalone="no"?>')
		@seek=0
		@strings=[]
		@styles=[]
		@resource=[]
		raise "未知的文件标志符" unless MAGIC_VALUE == read_number
		@file_size=read_number

		init_string_table
		init_resource_table
		start_name_space
		read_xml
	end
end

apk_file="test2.apk"
Zip::File.open(apk_file) do |zip|
	AndroidManifest.new zip.read('AndroidManifest.xml')
end



嗯嗯,好象不错的样子

如果不使用apktool 解压apk包。而直接使用aapt r&a 来修改androidmanifest文件会快好多

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值