微信5.0.3.1去反编译异常

现在新版本的微信有了一定的防修改机制。不过都是一些比较简单的针对apktool等工具的。制造一些异常,使工具无法正常工作,这样就可以对代码起到保护作用,这里来讲讲它的几种异常的处理。不要用来做坏事哦! 微信5.0.3.1去反编译异常 - 狂热份子 - 狂热份子的博客

解包异常
错误信息如下:
S: Could not decode file, replacing by FALSE value: drawable-hdpi/voip_videobar_bg_pressed.9.png
S: Could not decode file, replacing by FALSE value: drawable-hdpi/voip_receiverwitch_pressed.png
S: Could not decode file, replacing by FALSE value: drawable-hdpi/qqmail_read_attach_list3_pressed.9.png
S: Could not decode file, replacing by FALSE value: drawable-hdpi/talk_room_volume_mask.png
S: Could not decode file, replacing by FALSE value: drawable-hdpi/shakeforsong_btn_on.png
S: Could not decode file, replacing by FALSE value: drawable-hdpi/radar_search_quit_icon.png

提示说各种图片资源无法找到,我们试着查找也无法在res下找到对应的png文件,不要灰心,再仔细找找,看是否藏在了什么地方,直接把.apk改成.zip,然后解压,你会发现在weixin5.0.3.1\assets\preload有一些jar文件,正常的apk文件是没有这样的目录结构的,用java decompiler打开jar或者把jar的扩展名换成zip or rar打开,你就可以以看到每个jar里都有一些png图片,这些图片正是上面异常中无法找到的。

同时你还可以看到有几个奇怪的jar
微信5.0.3.1去反编译异常 - 狂热份子 - 狂热份子的博客
 
开始我以为是一个分割存储的压缩文件,之后我随便找了一个jar进行分割压缩,然后对比十六进制数据,发现不是分割压缩,其实它就是一个数据流切割而已,只要我们写个程序顺序读取三个文件,再写成一个文件就可以了,原来该jar中依然包含着图片,也需要把它们提取出来。

在linux下有相应的工具可以直接做到,不过我们是windows平台,也很简单,自己写一个吧。代码如下
imp ort java.io.BufferedInputStream;
imp ort java.io.BufferedOutputStream;
imp ort java.io.DataInputStream;
imp ort java.io.DataOutputStream;
imp ort java.io.FileInputStream;
imp ort java.io.FileNotFoundException;
imp ort java.io.FileOutputStream;
imp ort java.io.IOException;
public class compound
{
 public static String fileArray[] = {"com.tencent.mm.plugin.voip.jar.0","com.tencent.mm.plugin.voip.jar.1","com.tencent.mm.plugin.voip.jar.2"};
 public static String targetFile = "com.tencent.mm.plugin.voip.jar";
 public static byte[] buff = new byte[1024];
 public static DataOutputStream out = null;
 public static DataInputStream in = null;
 public static String path = null;
 public static void main(String[] args)
 {
  if(args.length <= 0)
  {
   System.out.println("you can not specified the dst path!");
   return;
  }
 
  path= args[0];
 
  try
  {
   System.out.println(path + targetFile);
   out = new DataOutputStream(new FileOutputStream(path + targetFile));
   
  }
  catch(FileNotFoundException e)
  {
   e.printStackTrace();
  }
 
  for(int i = 0; i < fileArray.length; i++)
  {
   try
   {
    in = new DataInputStream(new BufferedInputStream(new FileInputStream(path + fileArray[i])));
    int len = 0;
    try
    {
     while((len = in.read(buff)) != -1)
     {
      System.out.println(len);
      out.write(buff, 0, len);
     }
    }
    catch (IOException e)
    {
     e.printStackTrace();
    }
   }
   catch(FileNotFoundException e)
   {
    e.printStackTrace();
   }
  }
 }
}




1.把\assets\preload下的jar中的图片copy出来
2.用rar直接把weixin5.0.3.1解压
3.把上面copy出来的图片放到weixin5.0.3.1\res\drawable-en-hdpi下面
4.再用rar把weixin5.0.3.1压缩为weixin5.0.3.1.zip,并重命名为weixin5.0.3.1.apk
5.再使用解压命令java -jar apktool_1_4_2.jar d -d weixin5.0.3.1.apk weixin5.0.3.1 这里我们可以看到,以经可以正常解包了

打包时异常解决

libpng error: Not a PNG file
ERROR: Failure processing PNG image D:\reverse\Tools\weixin5.0.3.1_final\res\drawable-hdpi\app_panel_voiceviop_icon.png

提示这个文件不是一个合法的png文件,通过查资料发现它真正的格式是exif文件格式,截图如下
微信5.0.3.1去反编译异常 - 狂热份子 - 狂热份子的博客
 
解决方法
把它的扩展名改为exif,app_panel_voiceviop_icon.exif


打包异常2
D:\reverse\Tools\weixin5.0.3.1_final\res\values\strings.xml:2520: error: Multiple substitutions specified in non-positional format; did you mean to add the form
atted="false" attribute?
D:\reverse\Tools\weixin5.0.3.1_final\res\values\strings.xml:2520: error: Unexpected end tag string

先来看看strings.xml2520处的内容
微信5.0.3.1去反编译异常 - 狂热份子 - 狂热份子的博客

解决方法,改成如下
<string name="favorite_second_format">%1$02d:%2$02d</string>
这个与aapt版本有关,新版本的aapt对string.xml中定义的字符串格式要求比之前严格,对%+格式描述符这样的需要添加变量编号,这有些像某些脚本语言在进行格式化输出时,要与之后要输出的变量指定对应关系。


打包异常3
D:\reverse\Tools\weixin5.0.3.1\res\values\public.xml:434: error: Public symbol drawable/account_avatar_bg declared here is not defined.
D:\reverse\Tools\weixin5.0.3.1\res\values\public.xml:435: error: Public symbol drawable/account_icon declared here is not defined.
D:\reverse\Tools\weixin5.0.3.1\res\values\public.xml:436: error: Public symbol drawable/accounts_saftphone_icon declared here is not defined.
D:\reverse\Tools\weixin5.0.3.1\res\values\public.xml:437: error: Public symbol drawable/accounts_warning_icon declared here is not defined.
D:\reverse\Tools\weixin5.0.3.1\res\values\public.xml:61: error: Public symbol drawable/addfriend_whitebtn declared here is not defined.
D:\reverse\Tools\weixin5.0.3.1\res\values\public.xml:439: error: Public symbol drawable/addfriends_bkg declared here is not defined.
D:\reverse\Tools\weixin5.0.3.1\res\values\public.xml:440: error: Public symbol drawable/addfriends_button declared here is not defined.
D:\reverse\Tools\weixin5.0.3.1\res\values\public.xml:441: error: Public symbol drawable/addicon declared here is not defined.
D:\reverse\Tools\weixin5.0.3.1\res\values\public.xml:442: error: Public symbol drawable/albumglow declared here is not defined.
D:\reverse\Tools\weixin5.0.3.1\res\values\public.xml:443: error: Public symbol drawable/albums_bg declared here is not defined.

让我们先来看看434行存的是什么内容
微信5.0.3.1去反编译异常 - 狂热份子 - 狂热份子的博客
 
通过查资料,可以知道错误的原因大概是因为id的顺序有问题,在同一种类型之内,要按id值进行排序。
解决方法---对public.xml中所有原素进行排序处理
所以,写了一个java程序对public.xml中所有原素进行排序
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class resource_sort
{
 public static List<String> all = null;
 public static List<String> typeSequence = null;
 public static Map<String,List<String>> unique = null;
 public static DataOutputStream out = null;
 public static DataInputStream in = null;
 public static String file = null;
 
    public static Pattern pattern = Pattern.compile("<public type=\"(\\w*?)\" name=\"([ \\w\\.]*?)\" id=\"0x([\\dabcdef]*)\" />");
 
 public static void main(String[] args)
 {
  List<String> all = new ArrayList<String>();
  unique = new HashMap<String, List<String>>();
  typeSequence = new ArrayList<String>();
  if(args.length <= 0)
  {
   System.out.println("path error!");
   return;
  }
 
  file = args[0];
 
  try
  {
   in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
   int len = 0;
   try
   {
    String line = null;
    int i = 0;
    String type = null;
    while((line = in.readLine()) != null)
    {
     //System.out.println(line);
     type = getValue(line,1);
     if(type == null)
     {
      System.out.println(line);
      continue;
     }
     //all.add(line);
     if(!unique.containsKey(type))
     {
      List<String> newList = new ArrayList<String>();
      unique.put(type, newList);
      typeSequence.add(type);
     }
     List<String> tempList = unique.get(type);
     tempList.add(line);
    }
   }
   catch (IOException e)
   {
    e.printStackTrace();
   }
  }
  catch(FileNotFoundException e)
  {
   e.printStackTrace();
  }
 
  /*******************sort and write our xml*******************/
  try
  {
   out = new DataOutputStream(new FileOutputStream(file + "_new.xml"));
  }
  catch (FileNotFoundException e)
  {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 
  //write <?xml version=\"1.0\" encoding=\"utf-8\"?>
  //write <resources>
  try
  {
   out.writeBytes("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
   out.writeBytes("<resources>\n");
  }
  catch(IOException e)
  {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 
  //write line
  //Set<String> keys = unique.keySet();
  //for(Iterator it = keys.iterator(); it.hasNext();)
  for(int i = 0; i < typeSequence.size(); i++)
  {
   //String type = (String)it.next();
   //System.out.println("-------------------------------------------------");
   List<String> list = unique.get(typeSequence.get(i));
   
   Collections.sort(list, new MyComparator());
   
   for(int j = 0;j < list.size(); j++)
   {
    String line = list.get(j);
    //System.out.println(line);
    try
    {
     out.writeBytes(line + "\n");
    }
    catch(IOException e)
    {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
  }
 
  //write </resources>
  try
  {
   out.writeBytes("</resources>\n");
  }
  catch(IOException e)
  {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 public static String getValue(String str, int groupIndex/*1 type,2 name,3 id*/)
 {
  Matcher matcher = pattern.matcher(str);
  if(matcher.find())
  {
   return matcher.group(groupIndex);
  }
  return null;
 }
}


import java.util.Comparator;
public class MyComparator implements Comparator<String>
{
 @Override
 public int compare(String arg0, String arg1)
 {
  int id1 = Integer.valueOf(resource_sort.getValue(arg0,3),16);
  int id2 = Integer.valueOf(resource_sort.getValue(arg1,3),16);
  return id1 - id2;
 }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值