歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android逆向分析源碼中資源代碼還原小工具

一般情況下,我們采用apktool(xml資源)+dex2jar+JDGui(jar to java)反編譯Android apk之後的代碼中,涉及到資源索引的信息全部替換成了十進制的數字。

如何將這些數字還原成為原始的資源索引形式呢?

  1. public g(Context paramContext)  
  2. {  
  3.   super(paramContext);  
  4.   b(2130903088);  
  5.   this.b = ((FirModule)this.k.N().a("fir_module"));  
  6.   int[] arrayOfInt = new int[2];  
  7.   arrayOfInt[0] = 2131427902;  
  8.   arrayOfInt[1] = 2131427901;  
  9.   a(arrayOfInt);  
  10.   f(1);  
  11.   f(2);  
  12. }  

我們希望得到如下形式的代碼:

  1. public g(Context paramContext)  
  2. {  
  3.   super(paramContext);  
  4.   b(R.layout.fir_info_page);  
  5.   this.b = ((FirModule)this.k.N().a("fir_module"));  
  6.   int[] arrayOfInt = new int[2];  
  7.   arrayOfInt[0] = R.string.commended_apps;  
  8.   arrayOfInt[1] = R.string.person_info;  
  9.   a(arrayOfInt);  
  10.   f(1);  
  11.   f(2);  
  12. }  

可讀性就非常高了。

下面講述如何做到這個功能:

 b(2130903088);中的數字轉換為16進制以後,是0x7f030030,通過手工在R.java中搜索我們可以找到:

        public static final int fir_info_page=0x7f030030;

因此在相應的地方替換為對應的資源索引就可以了,處於layout class之下,因此是 R.layout.fir_info_page 。

好了,原理很簡單,接下來我們編寫一個perl腳本來批量做這個事情,具體代碼如下:

  1. #!/usr/bin/perl  
  2. #注意事項:  
  3. #復制一份 R.java在該文件所在目錄  
  4. #第一個參數為:需要處理的源代碼目錄路徑  
  5.   
  6. use strict;  
  7.   
  8. use File::Find;  
  9.   
  10. my $from_str;  
  11. my $to_str;  
  12. my $resource;  
  13. my $init_folder = $ARGV[0];  
  14.   
  15. if (not -d $init_folder)  
  16. {  
  17.   print "目錄:$init_folder不存在.\n";  
  18. print "$0 <source_folder>\n";   
  19.   exit;  
  20. }  
  21.   
  22. #讀取R.java中的所有文本  
  23. my $k_file = "R.java";  
  24. open my $k ,"< $k_file" or die "couldn't open $k_file\n";  
  25. my @keywords = <$k> ;  
  26. close $k;  
  27.   
  28.   
  29. #遍歷每行數據  
  30. for my $line (@keywords)  
  31. {  
  32.   #print "$line";  
  33.   
  34.   #先解析內部class類型:id/style/xml/arrays等  
  35.   #public static final class style {  
  36.   if ($line =~ /public\sstatic\sfinal\sclass\s(\w+)\s\{/)  
  37.   {  
  38.      $resource = $1;  
  39.   }  
  40.   else  
  41.   {  
  42.     #如果格式如下,則解析出來  
  43.     #public static final int MarketPanelTheme=0x7f0c0076;  
  44.     if ($line =~ /public\sstatic\sfinal\sint\s(\w+)=(\w+)\;/)  
  45.     {  
  46.       #print "keywords:$1 <-- $2\n";  
  47.       $from_str = oct $2; #16進制轉化為10進制  
  48.       $to_str = "R\.$resource\.$1";  
  49.       print "$from_str --> $to_str\n\n";  
  50.       find(\&CallBackMe, $init_folder );  
  51.     }  
  52.   }  
  53. }  
  54.   
  55. print "Well Done.\n";  
  56.   
  57. sub CallBackMe  
  58. {  
  59.  my $fullpath = $File::Find::name;  
  60.   
  61.  if(-d $fullpath)  
  62.  {  
  63.       print "[Dir] $fullpath\n";  
  64.  }  
  65.  else  
  66.  {  
  67.    print "[File] $fullpath\n";  
  68.    if($fullpath =~ /\.java$/i)  
  69.    {  
  70.      if($fullpath =~ /$k_file/i)  
  71.      {  
  72.         #ignore it  
  73.         print "Ignored $k_file\n";  
  74.      }  
  75.      else  
  76.      {  
  77.        #replace text  
  78.        print "Replacing $from_str with $to_str in $fullpath\n";  
  79.        ReplaceString($fullpath, $from_str,$to_str);  
  80.      }  
  81.    }  
  82.  }  
  83. }  
  84.   
  85. #Replacing $from with $to in $file  
  86. sub ReplaceString  
  87. {  
  88.   my $file = shift @_;  
  89.   my $from = shift @_;  
  90.   my $to = shift @_;  
  91.   
  92.   open my $fh ,"< $file" or die "couldn't open $file\n";  
  93.   my @lines=<$fh>;  
  94.   close $fh;  
  95.   foreach my $l (@lines)  
  96.   {  
  97.     $l=~s/$from/$to/g;  
  98.   }  
  99.   #print "@lines\n";  
  100.   #write back  
  101.   open my $out , "> $file" or die "couldn't write $file";  
  102.   foreach my $l (@lines)  
  103.   {  
  104.      print $out $l;  
  105.   }  
  106.   close $out;  
  107. }  
Copyright © Linux教程網 All Rights Reserved