【原文地址】http://www.linuxidc.com/Linux/2012-07/66531.htm
一般情况下,我们采用apktool(xml资源)+dex2jar+JDGui(jar to java)反编译Android apk之后的代码中,涉及到资源索引的信息全部替换成了十进制的数字。
如何将这些数字还原成为原始的资源索引形式呢?
- public g(Context paramContext)
- {
- super(paramContext);
- b(2130903088);
- this.b = ((FirModule)this.k.N().a("fir_module"));
- int[] arrayOfInt = new int[2];
- arrayOfInt[0] = 2131427902;
- arrayOfInt[1] = 2131427901;
- a(arrayOfInt);
- f(1);
- f(2);
- }
我们希望得到如下形式的代码:
- public g(Context paramContext)
- {
- super(paramContext);
- b(R.layout.fir_info_page);
- this.b = ((FirModule)this.k.N().a("fir_module"));
- int[] arrayOfInt = new int[2];
- arrayOfInt[0] = R.string.commended_apps;
- arrayOfInt[1] = R.string.person_info;
- a(arrayOfInt);
- f(1);
- f(2);
- }
可读性就非常高了。
下面讲述如何做到这个功能:
b(2130903088);中的数字转换为16进制以后,是0x7f030030,通过手工在R.java中搜索我们可以找到:
public static final int fir_info_page=0x7f030030;
因此在相应的地方替换为对应的资源索引就可以了,处于layout class之下,因此是 R.layout.fir_info_page 。
好了,原理很简单,接下来我们编写一个perl脚本来批量做这个事情,具体代码如下:
- #!/usr/bin/perl
- #注意事项:
- #复制一份 R.java在该文件所在目录
- #第一个参数为:需要处理的源代码目录路径
- use strict;
- use File::Find;
- my $from_str;
- my $to_str;
- my $resource;
- my $init_folder = $ARGV[0];
- if (not -d $init_folder)
- {
- print "目录:$init_folder不存在.\n";
- print "$0 <source_folder>\n";
- exit;
- }
- #读取R.java中的所有文本
- my $k_file = "R.java";
- open my $k ,"< $k_file" or die "couldn't open $k_file\n";
- my @keywords = <$k> ;
- close $k;
- #遍历每行数据
- for my $line (@keywords)
- {
- #print "$line";
- #先解析内部class类型:id/style/xml/arrays等
- #public static final class style {
- if ($line =~ /public\sstatic\sfinal\sclass\s(\w+)\s\{/)
- {
- $resource = $1;
- }
- else
- {
- #如果格式如下,则解析出来
- #public static final int MarketPanelTheme=0x7f0c0076;
- if ($line =~ /public\sstatic\sfinal\sint\s(\w+)=(\w+)\;/)
- {
- #print "keywords:$1 <-- $2\n";
- $from_str = oct $2; #16进制转化为10进制
- $to_str = "R\.$resource\.$1";
- print "$from_str --> $to_str\n\n";
- find(\&CallBackMe, $init_folder );
- }
- }
- }
- print "Well Done.\n";
- sub CallBackMe
- {
- my $fullpath = $File::Find::name;
- if(-d $fullpath)
- {
- print "[Dir] $fullpath\n";
- }
- else
- {
- print "[File] $fullpath\n";
- if($fullpath =~ /\.java$/i)
- {
- if($fullpath =~ /$k_file/i)
- {
- #ignore it
- print "Ignored $k_file\n";
- }
- else
- {
- #replace text
- print "Replacing $from_str with $to_str in $fullpath\n";
- ReplaceString($fullpath, $from_str,$to_str);
- }
- }
- }
- }
- #Replacing $from with $to in $file
- sub ReplaceString
- {
- my $file = shift @_;
- my $from = shift @_;
- my $to = shift @_;
- open my $fh ,"< $file" or die "couldn't open $file\n";
- my @lines=<$fh>;
- close $fh;
- foreach my $l (@lines)
- {
- $l=~s/$from/$to/g;
- }
- #print "@lines\n";
- #write back
- open my $out , "> $file" or die "couldn't write $file";
- foreach my $l (@lines)
- {
- print $out $l;
- }
- close $out;
- }