Example #1
0
        /// <summary>
        /// 签名
        /// </summary>
        /// <param name="config"></param>
        /// <param name="logView"></param>
        /// <returns></returns>
        public static bool SignApk(KeystoreConfig config, ILog logView)
        {
            string tempApkPath = PathUtils.GetPath(Constants.PATH_TEMPAPK);

            if (!File.Exists(tempApkPath))
            {
                logView.Log(">>>>>>签名失败: " + tempApkPath + "未生成!");
                return(false);
            }

            string jarsignerPath = PathUtils.GetPath(Constants.PATH_JARSIGNER);

            if (!File.Exists(jarsignerPath))
            {
                logView.Log(">>>>>>签名失败: " + jarsignerPath + "不存在!");
                return(false);
            }

            logView.Log("↓↓↓↓↓↓ 签名-开始 ↓↓↓↓↓↓");

            string args = jarsignerPath + " -digestalg SHA1 -sigalg SHA1withRSA -keystore " + config.KeystoreFilePath + " -storepass " + config.Password + " -keypass " + config.Aliaspwd + " " + tempApkPath + " " + config.Aliaskey;

            string[] ret = CmdUtils.ExecCmdAndWaitForExit(args, logView);
            if (ret == null || ret.Length < 2 || !string.IsNullOrEmpty(ret[1]))
            {
                logView.Log(">>>>>>签名失败: 执行CMD失败");
                return(false);
            }

            logView.Log("↑↑↑↑↑↑ 签名-结束 ↑↑↑↑↑↑");
            logView.BlankLine();

            return(true);
        }
Example #2
0
        /// <summary>
        /// 反编译
        /// </summary>
        /// <param name="apkFilePath"></param>
        /// <returns>返回保存反编译信息的目录,为空表示反编译失败</returns>
        public static string DecompileApk(string apkFilePath)
        {
            if (string.IsNullOrEmpty(apkFilePath) ||
                !File.Exists(apkFilePath))
            {
                return(null);
            }

            string apktoolPath = PathUtils.GetPath(Constants.PATH_APKTOOL);

            if (!File.Exists(apktoolPath))
            {
                LogUtils.WriteLine(apktoolPath + "不存在!");
                return(null);
            }

            string decompileDir = PathUtils.GetPath(Constants.DIR_TEMP_DECOMPLIE);

            if (!Directory.Exists(decompileDir))
            {
                Directory.CreateDirectory(decompileDir);
            }
            FileUtils.ClearDir(decompileDir);
            decompileDir = PathUtils.JoinPath(decompileDir, DateTime.Now.ToString("yyyyMMdd_HHmmss"));

            string cmdArgs = apktoolPath + " d " + apkFilePath + " -o " + decompileDir;// -o后面的目录不能已存在

            string[] res = CmdUtils.ExecCmdAndWaitForExit(cmdArgs);
            if (res == null || res.Length < 2 || !string.IsNullOrEmpty(res[1]))
            {
                return(null);
            }

            return(decompileDir);
        }
Example #3
0
        /// <summary>
        /// 将Dex文件转换为Smali文件
        /// </summary>
        /// <param name="decompileDir"></param>
        /// <param name="logView"></param>
        /// <returns></returns>
        public static bool Dex2Smali(string decompileDir, ILog logView)
        {
            if (string.IsNullOrEmpty(decompileDir) || !Directory.Exists(decompileDir))
            {
                logView.Log(">>>>>>将Dex文件转换为Smali文件失败: " + decompileDir + "目录不存在!");
                return(false);
            }

            string dexFilePath = PathUtils.GetPath(Constants.PATH_CLASSDEX);

            if (!File.Exists(dexFilePath))
            {
                logView.Log(">>>>>>将Dex文件转换为Smali文件失败: " + dexFilePath + "文件未生成!");
                return(false);
            }

            string javaPath  = PathUtils.GetPath(Constants.PATH_JAVA);     // java.exe
            string smaliTool = PathUtils.GetPath(Constants.PATH_BAKSMALI); // baksmali.jar

            if (!File.Exists(javaPath))
            {
                logView.Log(">>>>>>将Dex文件转换为Smali文件失败: " + javaPath + "不存在!");
                return(false);
            }
            if (!File.Exists(smaliTool))
            {
                logView.Log(">>>>>>将Dex文件转换为Smali文件失败: " + smaliTool + "不存在!");
                return(false);
            }


            // 生成smali位置,是Apk反编译目录下的smali目录,用于覆盖apk的smali文件
            string targetDir = PathUtils.JoinPath(decompileDir, Constants.DIR_SMALI);

            logView.Log("↓↓↓↓↓↓ 将Dex文件转换为Smali文件-开始 ↓↓↓↓↓↓");

            string args = javaPath + " -jar " + smaliTool + " -o " + targetDir + " " + dexFilePath;

            string[] ret = CmdUtils.ExecCmdAndWaitForExit(args, logView);
            if (ret == null || ret.Length < 2 || !string.IsNullOrEmpty(ret[1]))
            {
                logView.Log(">>>>>>将Dex文件转换为Smali文件失败: 执行CMD失败");
                return(false);
            }

            logView.Log("↑↑↑↑↑↑ 将Dex文件转换为Smali文件-结束 ↑↑↑↑↑↑");
            logView.BlankLine();

            return(true);
        }
Example #4
0
        /// <summary>
        /// 回编译
        /// </summary>
        /// <param name="decompileDir"></param>
        /// <param name="logView"></param>
        /// <returns></returns>
        public static bool RecompileApk(string decompileDir, ILog logView)
        {
            if (string.IsNullOrEmpty(decompileDir) || !Directory.Exists(decompileDir))
            {
                logView.Log(">>>>>>回编译失败: " + decompileDir + "目录不存在!");
                return(false);
            }

            string apktoolPath = PathUtils.GetPath(Constants.PATH_APKTOOL);

            if (!File.Exists(apktoolPath))
            {
                LogUtils.WriteLine(">>>>>>回编译失败: " + apktoolPath + "不存在!");
                return(false);
            }

            string tempApkPath = PathUtils.GetPath(Constants.PATH_TEMPAPK);

            if (File.Exists(tempApkPath))
            {
                File.Delete(tempApkPath);
            }

            logView.Log("↓↓↓↓↓↓ 回编译-开始 ↓↓↓↓↓↓");

            string args = apktoolPath + " b " + decompileDir + " -o " + tempApkPath;

            string[] ret = CmdUtils.ExecCmdAndWaitForExit(args, logView);
            if (ret == null || ret.Length < 2 || !string.IsNullOrEmpty(ret[1]))
            {
                logView.Log(">>>>>>回编译失败: 执行CMD失败");
                return(false);
            }

            logView.Log("↑↑↑↑↑↑ 回编译-结束 ↑↑↑↑↑↑");
            logView.BlankLine();

            return(true);
        }
Example #5
0
        /// <summary>
        /// 对齐优化
        /// </summary>
        /// <param name="newApkPath"></param>
        /// <param name="logView"></param>
        /// <returns></returns>
        public static bool AlignApk(string newApkPath, ILog logView)
        {
            string tempApkPath = PathUtils.GetPath(Constants.PATH_TEMPAPK);

            if (!File.Exists(tempApkPath))
            {
                logView.Log(">>>>>>对齐优化失败: " + tempApkPath + "未生成!");
                return(false);
            }

            string zipalignPath = PathUtils.GetPath(Constants.PATH_ZIPALIGN);

            if (!File.Exists(zipalignPath))
            {
                logView.Log(">>>>>>对齐优化失败: " + zipalignPath + "不存在!");
                return(false);
            }

            logView.Log("↓↓↓↓↓↓ 对齐优化-开始 ↓↓↓↓↓↓");

            string args = zipalignPath + " -f 4 " + tempApkPath + " " + newApkPath;

            string[] ret = CmdUtils.ExecCmdAndWaitForExit(args, logView);
            if (ret == null || ret.Length < 2 || !string.IsNullOrEmpty(ret[1]))
            {
                logView.Log(">>>>>>对齐优化失败: 执行CMD失败");
                return(false);
            }

            logView.Log("↑↑↑↑↑↑ 对齐优化-结束 ↑↑↑↑↑↑");
            logView.BlankLine();
            logView.Log("导出apk为: " + newApkPath);
            logView.BlankLine();

            return(true);
        }
Example #6
0
        /// <summary>
        /// Jar文件转换成Dex文件
        /// </summary>
        /// <param name="jarPath">Jar文件或目录</param>
        /// <param name="logView"></param>
        /// <returns>返回生成dex文件的路径,为null时表示转换dex文件失败</returns>
        public static string Jar2Dex(string jarPath, ILog logView)
        {
            string javaPath    = PathUtils.GetPath(Constants.PATH_JAVA); // java.exe
            string dexToolPath = PathUtils.GetPath(Constants.PATH_DX);   // dx.jar

            if (!File.Exists(javaPath))
            {
                logView.Log(">>>>>>Jar文件转换成Dex文件失败: " + javaPath + "文件未生成!");
                return(null);
            }
            if (!File.Exists(dexToolPath))
            {
                logView.Log(">>>>>>Jar文件转换成Dex文件失败: " + dexToolPath + "文件未生成!");
                return(null);
            }


            string dexFilePath = PathUtils.GetPath(Constants.DIR_DEX);

            if (!Directory.Exists(dexFilePath))
            {
                Directory.CreateDirectory(dexFilePath);
            }
            FileUtils.ClearDir(dexFilePath);
            // 生成的dex文件路径
            dexFilePath = PathUtils.GetPath(Constants.PATH_CLASSDEX);

            string args = javaPath + " -jar -Xms1024m -Xmx1024m " + dexToolPath + " --dex --output=" + dexFilePath;

            logView.Log("↓↓↓↓↓↓ Jar文件转换成Dex文件-开始 ↓↓↓↓↓↓");
            if (Directory.Exists(jarPath))
            {
                string[] files = Directory.GetFiles(jarPath);
                if (files != null && files.Length > 0)
                {
                    for (int i = 0; i < files.Length; i++)
                    {
                        if (files[i].EndsWith(".jar"))
                        {
                            args += " " + files[i];
                        }
                    }
                }
            }
            else if (File.Exists(jarPath) && jarPath.EndsWith(".jar"))
            {
                args += " " + jarPath;
            }

            string[] ret = CmdUtils.ExecCmdAndWaitForExit(args, logView);
            if (ret == null || ret.Length < 2 || !string.IsNullOrEmpty(ret[1]))
            {
                logView.Log(">>>>>>Jar文件转换成Dex文件失败: 执行CMD失败");
                return(null);
            }

            logView.Log("↑↑↑↑↑↑ Jar文件转换成Dex文件-结束 ↑↑↑↑↑↑");
            logView.BlankLine();

            if (File.Exists(dexFilePath))
            {
                logView.Log("已生成dex文件:" + dexFilePath);
            }
            else
            {
                logView.Log("没生成dex文件:" + dexFilePath);
            }
            logView.BlankLine();

            return(dexFilePath);
        }
Example #7
0
        /// <summary>
        /// 重签名
        /// </summary>
        /// <param name="apkFilePath"></param>
        /// <param name="newApkPath"></param>
        /// <param name="config"></param>
        /// <param name="logView"></param>
        /// <returns></returns>
        public static bool ResignApk(string apkFilePath, string newApkPath, KeystoreConfig config, ILog logView)
        {
            if (string.IsNullOrEmpty(apkFilePath) || !File.Exists(apkFilePath))
            {
                logView.Log(">>>>>>重新签名失败: " + apkFilePath + "不存在!");
                return(false);
            }

            string tempDir = PathUtils.GetPath(Constants.DIR_TEMP_RESIGNAPK);

            if (!Directory.Exists(tempDir))
            {
                Directory.CreateDirectory(tempDir);
            }
            FileUtils.ClearDir(tempDir);
            string tempApkFilePath = PathUtils.JoinPath(tempDir, "temp.apk");

            // 拷贝一份APK作为临时文件,在该临时文件上操作
            FileInfo fi = new FileInfo(apkFilePath);

            if (fi.Exists)
            {
                fi.CopyTo(tempApkFilePath, true);
            }

            logView.BlankLine();
            logView.Log("删除APK文件中META-INF目录下的签名文件");
            ZipUtils.RemoveApkCertFile(tempApkFilePath, logView);

            logView.BlankLine();
            logView.Log("↓↓↓↓↓↓ 重签名-开始 ↓↓↓↓↓↓");

            string jarsignerPath = PathUtils.GetPath(Constants.PATH_JARSIGNER);
            string args          = jarsignerPath + " -digestalg SHA1 -sigalg SHA1withRSA -keystore " + config.KeystoreFilePath + " -storepass " + config.Password + " -keypass " + config.Aliaspwd + " " + tempApkFilePath + " " + config.Aliaskey;

            string[] ret = CmdUtils.ExecCmdAndWaitForExit(args, logView);
            if (ret == null || ret.Length < 2 || !string.IsNullOrEmpty(ret[1]))
            {
                logView.Log(">>>>>>重新签名失败: 执行CMD失败");
                return(false);
            }
            logView.Log("↑↑↑↑↑↑ 重签名-结束 ↑↑↑↑↑↑");


            logView.BlankLine();
            logView.Log("↓↓↓↓↓↓ 对齐优化-开始 ↓↓↓↓↓↓");
            string zipalignPath = PathUtils.GetPath(Constants.PATH_ZIPALIGN);

            args = zipalignPath + " -f 4 " + tempApkFilePath + " " + newApkPath;

            ret = CmdUtils.ExecCmdAndWaitForExit(args, logView);
            if (ret == null || ret.Length < 2 || !string.IsNullOrEmpty(ret[1]))
            {
                logView.Log(">>>>>>对齐优化失败: 执行CMD失败");
                return(false);
            }
            logView.Log("↑↑↑↑↑↑ 对齐优化-结束 ↑↑↑↑↑↑");
            logView.BlankLine();


            if (!File.Exists(newApkPath))
            {
                logView.Log(">>>>>>重新签名失败: " + newApkPath + "导出的新apk文件不存在!");
                return(false);
            }

            logView.Log("导出apk为: " + newApkPath);

            return(true);
        }