示例#1
0
 /// <summary>
 /// 快速排序-比较方法(pxm.id_low比较)
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <returns></returns>
 public static int pxm_compare_id_low(public_xml_model a, public_xml_model b)
 {
     if (a.id_low > b.id_low) return 1;
     else if (a.id_low == b.id_low) return 0;
     else return -1;
 }
示例#2
0
        public virtual void MergeSmali(List<string> copy_folders, List<string> copy_files)
        {
            //合并R.smali(从新合并的public.xml中合并)
            do
            {
                if (!Directory.Exists(m_sdkinfo.in_res))
                    break;
                //寻找R.smali文件和对应的拓展文件
                List<string> sdk_smalis = new List<string>();
                string sdk_R = m_sdkinfo.in_smali + @"\" + m_sdkinfo.PrePackageName.Replace(".",@"\") + @"\R.smali";
                if(!File.Exists(sdk_R))
                    throw new Exception("sdk has muiti R.smali");
                string sdk_R_class = @"L" + Path.GetDirectoryName(sdk_R).Replace(m_sdkinfo.in_smali, "").Replace(@"\", @"/").TrimStart('/');

                List<string> apk_smalis = new List<string>();
                string dex_class_smali_folder = m_apkinfo.in_smali;
                string apk_R = string.Empty;
                utils.get_files_from_folder(m_apkinfo.in_smali, ref apk_smalis, "R.smali");
                if (apk_smalis.Count == 0) {
                    if (Directory.Exists(m_apkinfo.in_smali_classes2)) {
                        utils.get_files_from_folder(m_apkinfo.in_smali_classes2, ref apk_smalis, "R.smali");
                        dex_class_smali_folder = m_apkinfo.in_smali_classes2;
                    }
                }
                foreach (string key in apk_smalis)
                {
                    string tempname = Path.GetDirectoryName(key).Replace(dex_class_smali_folder + @"\", "").Replace(@"\", ".");
                    if (m_apkinfo.settings.MainActivity.IndexOf(tempname) != -1 || m_apkinfo.settings.PackageName == tempname || apk_smalis.Count == 1)
                    {
                        apk_R = key;
                        break;
                    }
                }
                if (apk_R != string.Empty)
                {
                    utils.get_files_from_folder(Path.GetDirectoryName(apk_R), ref apk_smalis, "R$", "*.smali");
                    if (apk_smalis.Count > 0)
                    {
                        do
                        {
                            bool rm_flag = false;
                            for (int m = 0; m < apk_smalis.Count; m++)
                            {
                                if (Path.GetFileName(apk_smalis[m]).Substring(0, 2) != "R$")
                                {
                                    apk_smalis.RemoveAt(m);
                                    rm_flag = true;
                                    break;
                                }
                            }
                            if (rm_flag == false)
                                break;
                        } while (true);
                    }
                }
                else
                {
                    throw new Exception("apk has muiti R.smali");
                }
                string apk_R_class = @"L" + Path.GetDirectoryName(apk_R).Replace(dex_class_smali_folder, "").Replace(@"\", @"/").TrimStart('/');
                //搜集sdk中R.smali和apk中R.smali中的type
                Encoding enc = null;
                enc = TxtFileEncoder.GetEncoding(sdk_R);
                List<string> sdk_R_lines = File.ReadAllText(sdk_R, enc).Replace("\r\n", "*").Split('*').ToList();
                enc = TxtFileEncoder.GetEncoding(apk_R);
                List<string> apk_R_lines = File.ReadAllText(apk_R, enc).Replace("\r\n", "*").Split('*').ToList();
                List<string> sdk_R_class_types = new List<string>();
                List<string> apk_R_class_types = new List<string>();

                string sdk_public = m_sdkinfo.in_res + @"\values\public.xml";
                SortedDictionary<string, List<public_xml_model>> sdk_dict = new SortedDictionary<string, List<public_xml_model>>();
                XmlDocument sdk_public_doc = new XmlDocument();
                sdk_public_doc.Load(sdk_public);
                XmlNodeList sdk_nodes = sdk_public_doc.DocumentElement.ChildNodes;
                if (sdk_nodes.Count > 0)
                {
                    foreach (XmlNode node in sdk_nodes)
                    {
                        public_xml_model pxm = new public_xml_model();
                        pxm.type = node.Attributes["type"].Value;
                        pxm.name = node.Attributes["name"].Value;
                        pxm.id = node.Attributes["id"].Value;
                        pxm.id_high = Convert.ToInt32(pxm.id.Substring(2, 4), 16);
                        pxm.id_low = Convert.ToInt32(pxm.id.Substring(6, 4), 16);
                        if (!sdk_dict.ContainsKey(pxm.type))
                            sdk_dict.Add(pxm.type, new List<public_xml_model>());
                        sdk_dict[pxm.type].Add(pxm);
                    }
                }
                foreach (string sdk_key in sdk_dict.Keys)
                {
                    sdk_R_class_types.Add(sdk_key);
                }
                int insert_pos = -1;
                foreach (string apk_R_line in apk_R_lines)
                {
                    if (apk_R_line.IndexOf(apk_R_class + @"/R$") != -1)
                    {
                        if (insert_pos == -1)
                            insert_pos = apk_R_lines.IndexOf(apk_R_line);
                        apk_R_class_types.Add(apk_R_line.Replace(" ", "").Replace(@";", "").Replace(@",", "").Replace(apk_R_class + @"/R$", ""));
                    }
                }
                //向apk中R.smali添加新的type,并复制新的R$type.smali
                string insert_line = string.Empty;
                string copy_content = string.Empty;
                string copy_from_path = string.Empty;
                string copy_to_path = string.Empty;
                foreach (string sdk_type in sdk_R_class_types)
                {
                    copy_from_path = Path.GetDirectoryName(sdk_R) + @"\R$" + sdk_type + @".smali";
                    copy_to_path = Path.GetDirectoryName(apk_R) + @"\R$" + sdk_type + @".smali";
                    if (!File.Exists(copy_to_path))
                    {
                        File.Copy(copy_from_path, copy_to_path);
                        enc = TxtFileEncoder.GetEncoding(copy_to_path);
                        copy_content = File.ReadAllText(copy_to_path, enc);
                        copy_content = copy_content.Replace(sdk_R_class, apk_R_class);
                        File.WriteAllText(copy_to_path, copy_content, enc);
                    }
                    if (apk_R_class_types.Count == 0 || insert_pos == -1)
                        break;
                    if (apk_R_class_types.IndexOf(sdk_type) == -1)
                    {
                        insert_line = "        " + apk_R_class + @"/R$" + sdk_type + @";,";
                        apk_R_lines.Insert(insert_pos, insert_line);
                    }
                }
                string apk_R_new_content = string.Empty;
                for (int i = 0; i < apk_R_lines.Count; i++)
                {
                    apk_R_new_content += apk_R_lines[i] + "\r\n";
                }
                enc = TxtFileEncoder.GetEncoding(apk_R);
                File.WriteAllText(apk_R, apk_R_new_content, enc);
                //根据public.xml来调整R.smali
                string apk_public = m_apkinfo.in_res + @"\values\public.xml";
                SortedDictionary<string, List<public_xml_model>> apk_dict = new SortedDictionary<string, List<public_xml_model>>();
                XmlDocument apk_public_doc = new XmlDocument();
                apk_public_doc.Load(apk_public);
                XmlNodeList apk_nodes = apk_public_doc.DocumentElement.ChildNodes;
                if (apk_nodes.Count > 0)
                {
                    foreach (XmlNode node in apk_nodes)
                    {
                        public_xml_model pxm = new public_xml_model();
                        pxm.type = node.Attributes["type"].Value;
                        pxm.name = node.Attributes["name"].Value;
                        pxm.id = node.Attributes["id"].Value;
                        pxm.id_high = Convert.ToInt32(pxm.id.Substring(2, 4), 16);
                        pxm.id_low = Convert.ToInt32(pxm.id.Substring(6, 4), 16);
                        if (!apk_dict.ContainsKey(pxm.type))
                            apk_dict.Add(pxm.type, new List<public_xml_model>());
                        apk_dict[pxm.type].Add(pxm);
                    }
                }
                if (apk_dict.Count > 0)
                {
                    string apk_R_type_path = string.Empty;
                    string apk_R_type_content = string.Empty;
                    int apk_R_type_start_pos = -1;
                    int apk_R_type_end_pos = -1;
                    List<string> apk_R_type_lines = new List<string>();
                    string apk_R_type_insert = string.Empty;
                    List<public_xml_model> apk_R_type_pxms = null;
                    foreach (string apk_type in apk_dict.Keys)
                    {
                        apk_R_type_path = Path.GetDirectoryName(apk_R) + @"\R$" + apk_type + @".smali";
                        if (!File.Exists(apk_R_type_path)) continue;
                        enc = TxtFileEncoder.GetEncoding(apk_R_type_path);
                        apk_R_type_content = File.ReadAllText(apk_R_type_path, enc);
                        apk_R_type_lines = apk_R_type_content.Replace("\r\n", "*").Split('*').ToList();
                        apk_R_type_start_pos = apk_R_type_lines.IndexOf(@"# static fields") + 1;
                        apk_R_type_end_pos = apk_R_type_lines.IndexOf(@"# direct methods");
                        apk_R_type_lines.RemoveRange(apk_R_type_start_pos, apk_R_type_end_pos - apk_R_type_start_pos);
                        apk_R_type_pxms = apk_dict[apk_type];
                        apk_R_type_pxms.Reverse();
                        foreach (public_xml_model pxm in apk_R_type_pxms)
                        {
                            apk_R_type_insert = @".field public static final " + pxm.name.Replace(".", "_") + @":I = " + pxm.id;
                            apk_R_type_lines.Insert(apk_R_type_start_pos, apk_R_type_insert);
                            apk_R_type_lines.Insert(apk_R_type_start_pos + 1, "");
                        }
                        apk_R_type_end_pos = apk_R_type_lines.IndexOf(@"# direct methods");
                        apk_R_type_lines.Insert(apk_R_type_end_pos, "");
                        apk_R_type_content = string.Empty;
                        foreach (string apk_R_type_line in apk_R_type_lines)
                        {
                            apk_R_type_content += apk_R_type_line + "\r\n";
                        }
                        File.WriteAllText(apk_R_type_path, apk_R_type_content, enc);
                    }
                }
            } while (false);
            //合并smali文件夹和文件
            if (copy_folders != null)
            {
                string from_folder = string.Empty;
                string to_folder = string.Empty;
                foreach (string folder in copy_folders)
                {
                    from_folder = m_sdkinfo.in_smali + @"\" + folder;
                    to_folder = m_apkinfo.in_smali;
                    if (Directory.Exists(from_folder))
                    {
                        List<string> split_folders = folder.Split('\\').ToList();
                        for (int i = 0; i < split_folders.Count; i++)
                        {
                            if ((i + 1) == split_folders.Count)
                            {
                                utils.copy_folder(from_folder, to_folder);
                            }
                            else
                            {
                                to_folder += @"\" + split_folders[i];
                                if (!Directory.Exists(to_folder))
                                    Directory.CreateDirectory(to_folder);
                            }
                        }
                    }
                }
            }
            if (copy_files != null) {
                try
                {
                    string from_file = string.Empty;
                    string to_file = string.Empty;
                    foreach (string file in copy_files)
                    {
                        from_file = m_sdkinfo.in_smali + @"\" + file;
                        to_file = m_apkinfo.in_smali;
                        if (File.Exists(from_file))
                        {
                            List<string> split_folders = file.Split('\\').ToList();
                            for (int i = 0; i < split_folders.Count; i++)
                            {
                                to_file += @"\" + split_folders[i];
                                if ((i + 1) == split_folders.Count)
                                {
                                    if (File.Exists(to_file))
                                        File.Delete(to_file);
                                    File.Copy(from_file, to_file);
                                }
                                else
                                {
                                    if (!Directory.Exists(to_file))
                                        Directory.CreateDirectory(to_file);
                                }
                            }
                        }
                    }
                }
                catch (Exception e) {
                    e.ToString();
                }
            }
            //植入smali代码
            //需要在每个游戏合并类中自定义合并代码
        }
示例#3
0
 /// <summary>
 /// 快速排序-比较方法(pxm.id_high比较)
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <returns></returns>
 public static int pxm_compare_id_high(public_xml_model a, public_xml_model b)
 {
     if (a.id_high > b.id_high) return 1;
     else if (a.id_high == b.id_high) return 0;
     else return -1;
 }
示例#4
0
        public virtual void MergeRes()
        {
            if (!Directory.Exists(m_sdkinfo.in_res)) return;
            string sdk_public = m_sdkinfo.in_res + @"\values\public.xml";
            string apk_public = m_apkinfo.in_res + @"\values\public.xml";
            SortedDictionary<string, List<public_xml_model>> sdk_dict = new SortedDictionary<string, List<public_xml_model>>();
            SortedDictionary<string, List<public_xml_model>> apk_dict = new SortedDictionary<string, List<public_xml_model>>();
            XmlDocument sdk_public_doc = new XmlDocument();
            sdk_public_doc.Load(sdk_public);
            XmlNodeList sdk_nodes = sdk_public_doc.DocumentElement.ChildNodes;
            if (sdk_nodes.Count > 0)
            {
                foreach (XmlNode node in sdk_nodes)
                {
                    public_xml_model pxm = new public_xml_model();
                    pxm.type = node.Attributes["type"].Value;
                    pxm.name = node.Attributes["name"].Value;
                    pxm.id = node.Attributes["id"].Value;
                    pxm.id_high = Convert.ToInt32(pxm.id.Substring(2, 4), 16);
                    pxm.id_low = Convert.ToInt32(pxm.id.Substring(6, 4), 16);
                    if (!sdk_dict.ContainsKey(pxm.type))
                        sdk_dict.Add(pxm.type, new List<public_xml_model>());
                    sdk_dict[pxm.type].Add(pxm);
                }
            }
            XmlDocument apk_public_doc = new XmlDocument();
            apk_public_doc.Load(apk_public);
            XmlNodeList apk_nodes = apk_public_doc.DocumentElement.ChildNodes;
            if (apk_nodes.Count > 0)
            {
                foreach (XmlNode node in apk_nodes)
                {
                    public_xml_model pxm = new public_xml_model();
                    pxm.type = node.Attributes["type"].Value;
                    pxm.name = node.Attributes["name"].Value;
                    pxm.id = node.Attributes["id"].Value;
                    pxm.id_high = Convert.ToInt32(pxm.id.Substring(2, 4), 16);
                    pxm.id_low = Convert.ToInt32(pxm.id.Substring(6, 4), 16);
                    if (!apk_dict.ContainsKey(pxm.type))
                        apk_dict.Add(pxm.type, new List<public_xml_model>());
                    apk_dict[pxm.type].Add(pxm);
                }
            }

            //调整dict集合内数据
            if (sdk_dict.Count > 0)
            {
                for (int sdk_pos = 0; sdk_pos < sdk_dict.Count; sdk_pos++)
                {
                    KeyValuePair<string, List<public_xml_model>> item = sdk_dict.ElementAt(sdk_pos);
                    List<public_xml_model> pxms = item.Value;
                    utils.quick_sort_fast<public_xml_model>(ref pxms, 0, pxms.Count - 1, shell_utils.pxm_compare_id_low);
                    sdk_dict[item.Key] = pxms;
                }
            }
            if (apk_dict.Count > 0) {
                for (int apk_pos = 0; apk_pos < apk_dict.Count; apk_pos++)
                {
                    KeyValuePair<string, List<public_xml_model>> item = apk_dict.ElementAt(apk_pos);
                    List<public_xml_model> pxms = item.Value;
                    utils.quick_sort_fast<public_xml_model>(ref pxms, 0, pxms.Count - 1, shell_utils.pxm_compare_id_low);
                    apk_dict[item.Key] = pxms;
                }
            }
            //获取ID-HIGH最大值
            int sdk_id_high_max = 0;
            int apk_id_high_max = 0;
            if (sdk_dict.Count > 0)
            {
                List<public_xml_model> pxms = new List<public_xml_model>();
                for (int sort_pos = 0; sort_pos < sdk_dict.Count; sort_pos++)
                {
                    pxms.Add(sdk_dict.ElementAt(sort_pos).Value[0]);
                }
                utils.quick_sort_fast<public_xml_model>(ref pxms, 0, pxms.Count - 1, shell_utils.pxm_compare_id_high);
                pxms.Reverse();
                sdk_id_high_max = pxms[0].id_high;
            }
            if (apk_dict.Count > 0)
            {
                List<public_xml_model> pxms = new List<public_xml_model>();
                for (int m = 0; m < apk_dict.Count; m++)
                {
                    pxms.Add(apk_dict.ElementAt(m).Value[0]);
                }
                utils.quick_sort_fast<public_xml_model>(ref pxms, 0, pxms.Count - 1, shell_utils.pxm_compare_id_high);
                pxms.Reverse();
                apk_id_high_max = pxms[0].id_high;
            }

            //合并public
            if (sdk_dict.Count > 0) {
                int insert_id_high = apk_id_high_max;
                int insert_id_low = 0;
                foreach (string sdk_type in sdk_dict.Keys) {
                    if (apk_dict.ContainsKey(sdk_type))
                    {
                        foreach (public_xml_model pxm in sdk_dict[sdk_type]) {
                            if (!shell_utils.exist_pxm_name(apk_dict[sdk_type], pxm.name)) {
                                public_xml_model insert_pxm = pxm;
                                insert_pxm.id_high = apk_dict[sdk_type].Last().id_high;
                                insert_pxm.id_low = apk_dict[sdk_type].Last().id_low + 1;
                                insert_pxm.id = string.Format("0x{0:X4}", insert_pxm.id_high).ToLower() + string.Format("{0:X4}", insert_pxm.id_low).ToLower();
                                apk_dict[sdk_type].Add(insert_pxm);
                            }
                        }
                    }
                    else {
                        insert_id_high++;
                        insert_id_low = 0;
                        apk_dict[sdk_type] = new List<public_xml_model>();
                        foreach (public_xml_model pxm in sdk_dict[sdk_type])
                        {
                            public_xml_model insert_pxm = pxm;
                            insert_pxm.id_high = insert_id_high;
                            insert_pxm.id_low = insert_id_low++;
                            insert_pxm.id = string.Format("0x{0:X4}", insert_pxm.id_high).ToLower() + string.Format("{0:X4}", insert_pxm.id_low).ToLower();
                            apk_dict[sdk_type].Add(insert_pxm);
                        }
                    }
                }
            }
            //重写public.xml
            if (apk_dict.Count > 0)
            {
                List<public_xml_model> pxms = new List<public_xml_model>();
                for (int m = 0; m < apk_dict.Count; m++)
                {
                    pxms.Add(apk_dict.ElementAt(m).Value[0]);
                }
                utils.quick_sort_fast<public_xml_model>(ref pxms, 0, pxms.Count - 1, shell_utils.pxm_compare_id_high);
                apk_public_doc.DocumentElement.RemoveAll();
                foreach (public_xml_model pxm in pxms) {
                    foreach (public_xml_model insert_pxm in apk_dict[pxm.type]) {
                        XmlElement insert_element = apk_public_doc.CreateElement("public");
                        insert_element.SetAttribute("type", insert_pxm.type);
                        insert_element.SetAttribute("name", insert_pxm.name);
                        insert_element.SetAttribute("id", insert_pxm.id);
                        apk_public_doc.DocumentElement.AppendChild(insert_element);
                    }
                }
                apk_public_doc.Save(apk_public);
            }
            //合并res文件
            List<string> sdk_folders = Directory.GetDirectories(m_sdkinfo.in_res).ToList();
            List<string> apk_folders = Directory.GetDirectories(m_apkinfo.in_res).ToList();
            string sdk_folder_name = string.Empty;
            string apk_file_name = string.Empty;
            foreach (string sdk_folder in sdk_folders) {
                sdk_folder_name = (new DirectoryInfo(sdk_folder)).Name;
                if (sdk_folder_name.IndexOf("values") != -1)
                    continue;
                if (!Directory.Exists(m_apkinfo.in_res + @"\" + sdk_folder_name))
                {
                    utils.copy_folder(sdk_folder, m_apkinfo.in_res);
                }
                else {
                    List<string> sdk_folder_files = Directory.GetFiles(sdk_folder).ToList();
                    foreach (string sdk_folder_file in sdk_folder_files) {
                        apk_file_name = m_apkinfo.in_res + @"\" + sdk_folder_name + @"\" + Path.GetFileName(sdk_folder_file);
                        if (!File.Exists(apk_file_name)) {
                            File.Copy(sdk_folder_file, apk_file_name);
                        }
                    }
                }
            }
            //合并values
            List<string> sdk_value_files = Directory.GetFiles(m_sdkinfo.in_res+@"\values").ToList();
            List<string> apk_value_files = Directory.GetFiles(m_apkinfo.in_res+@"\values").ToList();
            if (sdk_value_files.Count > 0) {
                foreach (string sdk_value_file in sdk_value_files) {
                    apk_file_name = m_apkinfo.in_res + @"\values\" + Path.GetFileName(sdk_value_file);
                    if (Path.GetFileNameWithoutExtension(sdk_value_file) == "public") continue;
                    if (!File.Exists(apk_file_name))
                    {
                        File.Copy(sdk_value_file, apk_file_name);
                    }
                    else {
                        XmlDocument sdk_values_doc = new XmlDocument();
                        sdk_values_doc.Load(sdk_value_file);
                        XmlDocument apk_values_doc = new XmlDocument();
                        apk_values_doc.Load(apk_file_name);
                        if (sdk_values_doc.DocumentElement.ChildNodes.Count > 0) {
                            bool flag = false;
                            foreach (XmlNode sdk_values_node in sdk_values_doc.DocumentElement.ChildNodes)
                            {
                                flag = false;
                                foreach (XmlNode apk_values_node in apk_values_doc.DocumentElement.ChildNodes)
                                {
                                    if (apk_values_node.Attributes["name"].Value == sdk_values_node.Attributes["name"].Value)
                                    {
                                        flag = true;
                                        break;
                                    }
                                }
                                if (!flag)
                                {
                                    apk_values_doc.DocumentElement.AppendChild(apk_values_doc.ImportNode(sdk_values_node, true));
                                }
                            }
                            apk_values_doc.Save(apk_file_name);
                        }

                    }
                }
            }
        }