歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android逆向分析源碼中資源代碼還原小工具

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

日期:2017/3/1 10:15:07   编辑:Linux編程

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