Closed cielavenir closed 11 years ago
Thank you for your comment. Resource#query method is not implemented yet. Your suggestion sounds good.
I'll consider to implementing it. But I'm very busy now. If you have a pull requrest, I can merge it. Or please wait a few weeks.
1 month passed... Uh... Although I have little knowledge about resources.arsc, there was a little progress. After reading: http://justanapplication.wordpress.com/tag/androidresources/ http://justanapplication.wordpress.com/2011/09/17/android-internals-resources-part-six-the-typespec-chunk/ I was able to relate keyStrings to ID.
https://gist.github.com/4364699
Using my sample application http://dl.dropbox.com/u/46196585/mondayloader/MondayLoader.apk , apk.resource.keyStrings returns [[], ["ic_launcher"], ["main"], ["app_name", "text1", "text2", "textkey"], ["textView1", "textView2", "progressBar1", "textViewKey"]] So this code successfully points to "app_name".
Zip::ZipFile.open(path){|zip|
xml=Android::AXMLParser.new(zip.read('AndroidManifest.xml')).parse
label_id=xml.get_elements('/manifest/application')[0].attributes['label']
query=label_id[3..-1].to_i(16) #0x7f040000
arsc=Android::Resource.new(zip.read('resources.arsc'))
p arsc.keyStrings
p arsc.keyStrings[((query&0xff0000)>>16)-1][query&0xffff]
}
But I still don't know how to relate this stuff with string pool...
Actually I'd like to add StreamParser to Android::AXMLParser, but that's after...
Another progress... https://gist.github.com/4365521
#!/usr/bin/ruby
require 'ruby_apk'
path='org.connectbot[ConnectBot]-323_1.7.1.apk'
Zip::ZipFile.open(path){|zip|
xml=Android::AXMLParser.new(zip.read('AndroidManifest.xml')).parse
label_id=xml.get_elements('/manifest/application')[0].attributes['label']
query=label_id[3..-1].to_i(16)
arsc=Android::Resource.new(zip.read('resources.arsc'))
p arsc.keyStrings[((query&0xff0000)>>16)-1][query&0xffff]
label_index=arsc.stringpool_relation[((query&0xff0000)>>16)-1][query&0xffff]
p arsc.strings[label_index] #"ConnectBot" success!
}
But unfortunately this code is very dirty and doesn't work for some complex apks. further debug is required. But maybe I'm too tired...
Thank you for your information. I'll try implementing it during this new year holidays.
Hi cielavenir.
I've released v0.5.0. And this version includes Android::Resource#find method. You can get string by using this method with resource id like '@0x7f040000' or '@string/app_name'. This method supports only string resources for now.
I've tested only few cases. I think this version has some bugs. If you find bugs, let me know.
Thanks.
This code isn't working for some apks: http://pastebin.com/GYi86iva
#!/usr/bin/ruby
require 'find'
require 'ruby_apk'
LANG='ja'
DIR='/work/apk/data'
files=Dir.glob(DIR+'/**/*').grep(/\.apk$/)
packages=Hash.new([0,''])
files.each{|path|
Zip::ZipFile.open(path){|zip|
xml=Android::AXMLParser.new(zip.read('AndroidManifest.xml')).parse
package=xml.get_elements('/manifest')[0].attributes['package']
versionCode=xml.get_elements('/manifest')[0].attributes['versionCode'].to_i
versionName=xml.get_elements('/manifest')[0].attributes['versionName']
label=xml.get_elements('/manifest/application')[0].attributes['label']
arsc=Android::Resource.new(zip.read('resources.arsc'))
begin
label=arsc.find(label,:lang=>LANG) if label[0,1]=='@'
versionName=arsc.find(versionName,:lang=>LANG) if versionName[0,1]=='@'
label=arsc.find(label) if !label
versionName=arsc.find(versionName) if !versionName
rescue
puts package+' failed'
end
apkname="#{package}[#{label}]-#{versionCode}_#{versionName}.apk"
apkname.tr!("/?*:\\\"'",'_')
if versionCode>packages[package][0]
#auto rename
packages[package]=[versionCode,apkname]
p packages[package]
end
}
}
I should have used this code, but this still fails on com.viber.voip
begin
label=arsc.find(label,:lang=>LANG)||arsc.find(label) if label[0,1]=='@'
versionName=arsc.find(versionName,:lang=>LANG)||arsc.find(versionName) if versionName[0,1]=='@'
rescue
puts package+' failed'
end
Sorry for replying too late.
I've tried with com.viber.voip(v.2.2.0.1334 and v2.3.2.61). But I can't reproduce it. Which version did you use? or Can you send reproduced resource file?
Maybe the issue reported by you is a bug. I registered new issue #5, because I want to separate a bug from this item.
hey masatanish, can you guide me in how to run it and test/use it... i am quite new to ruby
Hi gllesian, you can run test with below.
$ bundle exec rake spec
The usage of ruby_apk is in readme.
BTW, if you don't need modify this library, you don't need clone the source. install ruby_apk gem with below, and put 'require "ruby_apk"' in top of your script.
$ gem install ruby_apk
then you can use ruby_apk in your script.
I'd like to query application-label. It isn't yet implemented? (although I can pipe aapt, it is quite heavy).
axml=Android::AXMLParser.new(zip.read('AndroidManifest.xml')) xml=axml.parse label_id=xml.get_elements('/manifest/application')[0].attributes['label'] arsc=Android::Resource.new(zip.read('resources.arsc'))
p arsc.query(label_id,'ja') #not implemented?
There are no ways to know label_id from arsc.strings...