使用360加固宝命令行方式加固

    xiaoxiao2022-07-02  151

    使用360加固宝命令行方式加固

    将360加固宝安装程序下载之后,解压,然后通过winodws 的dos命令来调用360加固程序,完成登录,设置,加固应用的操作。

    优点:可以使用程序控制加固工作,将生成的release包在java工程中进行加固,签名,生成多渠道包等工作,不再使用客户端手动加固应用,防止出错,方便快捷。而且可以将我们创建的一个Release包在java工程中完成一系列操作,直致生成多渠道包。可谓是一键完成线上多个渠道包的创建,不再依赖手动选择加固,签名等,大大节约了我们的时间。

     

    360加固宝官网: http://jiagu.360.cn/#/global/index

    步骤一:下载加固宝应用,并解压,如下图。

    解压后是一个360jiagubao_windows_64文件夹,进入jiagu文件夹如下图。请注意下面两个红框的文件。help.txt和jiagu.jar

     

     

    help.txt文件内容如下

        -login <username>             首次使用必须先登录 <360用户名>

            <password>                <登录密码>

        -importsign <keystore_path>         导入签名信息 <密钥路径>

            <keystore_password>             <密钥密码>

            <alias>                 <别名>

            <alias_password>            <别名密码>

        -importmulpkg <mulpkg_filepath>        导入多渠道配置信息,txt格式

        -showsign                查看已配置的签名信息

        -showmulpkg                查看已配置的多渠道信息

        -help                    显示帮助信息

        -config                 配置加固可选项

        ----------------------可选增强服务-------------------------------

            [-crashlog]                【崩溃日志分析】

            [-x86]                    【x86支持】

            [-analyse]                【加固数据分析】

            [-nocert]                【跳过签名校验】

        ----------------------高级加固选项-------------------------------

            [-vmp]                    【全VMP保护】

            [-data]                    【本地数据文件保护】

            [-assets]                【资源文件保护】

            [-filecheck]                【文件完整性校验】

            [-ptrace]                【Ptrace防注入】

            [-so]                    【SO文件保护】

            [-dex2c]                【dex2C保护】

            [-string_obfus]                【字符串加密】

            [-dex_shadow]                【DexShadow】

            [-so_private]                【SO防盗用】

        -----------------------------------------------------------------

        -config_so            配置需要加固的SO文件,以空格分隔

        -config_assets            配置需要忽略的资源文件,以空格分隔

        -config_so_private        配置防盗用的SO文件,以空格分隔

        

        -showconfig                显示已配置加固项

        -version                显示当前版本号

        -update                    升级到最新版本

        -jiagu <inputAPKpath>             加固命令 <APK路径>

            <outputPath>                 <输出路径>

            [-autosign]                 【自动签名】

            [-automulpkg]                 【自动多渠道】

            [-pkgparam mulpkg_filepath]        【自定义文件生成多渠道】

     

     

    步骤二: 在windows环境下执行dos命令

    2.1 :进入该目录下

     

     

     

    2.2 执行登录命令  :  java -jar jiagu.jar -login 用户名 密码 

    登录成功会返回 login success字符串。

     

    2.3 配置

    登录成功后可设置360加固宝。设置一次后,可不再修改,设置保存至本地的。也可以登录客户端手动设置,都是一样的。、

    个人建议不使用它的“启用自动签名”和 使用“跳过签名校验”功能。

     

    2.4 加固apk

    执行加固命令: java -jar jiagu.jar -jiagu input\input.apk output

    java -jar jiagu.jar -jiagu 要加固的apk文件路径 输出apk路径

    注:我使用的是相对路径, 也可以使用绝对路径。

            输出的文件名规则为 源文件名 + “_版本号_” + "jiagu.apk" .如上加固输出文件为 input_6130_jiagu.apk , 其源文件为input.apk

     

     

    使用程序进行加固。

    加固先开始上传(上传至360加固服务器那边,应该是这样的)

     

    上传完成开始加固

     

    加固完成。即加固程序运行结束

     

     

    三、使用脚本工具进行加固

    脚本工具下载地址:https://download.csdn.net/download/liuyu0915/11197032

    实现功能:

    脚本加固apk工具,可以通过该工具批量加固apk,  并支持加固api,加固apk不再需要手动操作加固客户端。内部封装的是360加固宝工具。该工具可以与签名、生成渠道包工具组合起来,达到一键生成线上渠道包的功能(studio生成release包,使用该工具加固,再调用程序进行签名,最后通过创建渠道包工具生成对应的渠道包,整个流程不需要手动操作,使用简单稳定。)。 准备工作:在360加固宝官网上下载360加固宝程序并解压,找到jiagu.jar文件,并记录它的路径。360加固宝下载地址

     

     

    使用方法:

    命令行方式: java -jar 360jiagu.jar kaixin -login 360加固宝用户名 360加固宝登录密码  -input input.apk -output 输出apk路径 -jiaguJar 360加固宝中jiagu.jar的路径

    示例:java -jar 360jiagu.jar kaixin -login 153****8060  mima -input C:\Users\ttkx\Desktop\input.apk -output f:\ouput -jiaguJar D:\github_\AutoCreateApk\jiagu\jiagu.jar

    API调用方式: 直接调用360jiagu.jar中的api .

    调用方法:  JiaGuMain.runJiaGu(JiaGuConfig config).    JiaGuConfig类中设置登录用户名和密码,输入apk和加固完成后输出路径,还需要传360加宝程序解压后jiagu.jar的路径。

    JiaGuConfig config = JiaGuConfig.build() .setJarFile(new File("....\jiagu.jar")) .login("用户名****", "密码****") .addInputApkPath(getInputApkPath("htg_input.apk")) .addInputApkPath(getInputApkPath("app-anzhi_oas-debug.apk")) .outputPath(mOutputPath); JiaGuMain.runJiaGu(config);

    备注:该工具没有设置360加固宝相关设置的功能,如果需要修改加固宝默认设置,可以打开客户端手动设置后关闭再使用该工具进行加固,设置一次之后就不用再设置了。建议大家不使用360加固宝的自动签名和签名校验功能。

     

     

     

    四、脚本工具源码解析

     

    目的: 用程序调用加固apk, 与后续签名和生成多渠道包功能连贯至一起。实现一键生成多渠道线上包的功能。

    创建java工程, 然后使用java api执行windows 的dos命令,调用360加固宝程序 。最终实现加固apk.

    步骤一 : 创建java工程 或是java lib 工程。

    步骤二: 将360加固宝解压文件入至工程中(方便管理)。

    我的目录结构如下:

     

    步骤三: 使用java api 调用dos命令,执行加固程序

    3.1 设置登录用户名和密码 , 输入文件路径 和 输出文件夹路径

    3.4 检查是否登录完成 。 

    检查返回的字符串是否包含login success 字符串即可。

    3.5检查加固是否完成

    检查返回字符串是否包含 “已加固”。

    备注: dos命令在程序中执行是在当前线程,当加固程序完成之后才会走下一行代码。所以当加固程序走完的时候,就能够在输出文件夹内找到对应的已加固apk文件。本人dos命令玩的太差,上面检查360加固登录和加固状态的代码写的稀烂,对返回的字符串处理很low,欢迎大神指点。

    上述三的思想是创建java工程,然后调用360加固宝工具进行加固。我对其进行了二次封装。

    源码

     

    package com.kaixin.jiagu360; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.StringReader; import java.nio.charset.Charset; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; public class JiaGuMain { public static final String JAR_NAME = "jiagu.jar"; public JiaGuMain() { } public static void main(String[] args) { String cmd = args[0]; String[] params = (String[])Arrays.copyOfRange(args, 1, args.length); try { if ("kaixin".equals(cmd)) { disposeArgs(params); } else { System.err.println("请输入kaixin,不要问为什么,因为这是我写的。。。哈哈"); } } catch (Exception var4) { System.err.println("Error: " + var4.getMessage()); } } //处理输入参数 private static void disposeArgs(String[] params) { if (params.length == 0) { error("未发现有效参数"); } else { JiaGuConfig config = JiaGuConfig.build(); Options options = new Options(params); Map<String, List<String>> paramMap = options.builder(); List<String> loginList = (List)paramMap.get("-login"); if (loginList != null && loginList.size() == 2) { String userName = (String)loginList.get(0); String password = (String)loginList.get(1); config.login(userName, password); } else { error("登录参数未发现或不合法"); } List<String> inputApkList = (List)paramMap.get("-input"); String inputApkPath; if (inputApkList != null && inputApkList.size() > 0) { Iterator var11 = inputApkList.iterator(); label55: while(true) { while(true) { if (!var11.hasNext()) { break label55; } inputApkPath = (String)var11.next(); File file = new File(inputApkPath); if (file.exists() && file.isFile() && file.getName().endsWith(".apk")) { config.addInputApkPath(inputApkPath); } else { error("输入待加固apk路径不合法: " + inputApkPath); } } } } else { error("未发现有效的待加固apk"); } List<String> outputDirList = (List)paramMap.get("-output"); if (outputDirList != null && outputDirList.size() > 0) { inputApkPath = (String)outputDirList.get(0); config.outputPath(inputApkPath); } else { error("未发现输出apk路径"); } List<String> jarList = (List)paramMap.get("-jiaguJar"); if (jarList != null && jarList.size() > 0) { String jarPath = (String)jarList.get(0); File file = new File(jarPath); if (file.exists() && file.isFile() && "jiagu.jar".equals(file.getName())) { config.setJarFile(file); } } checkJiaguJar(config); runJiaGu(config); } } private static void checkJiaguJar(JiaGuConfig config) { File jarFile = config.getJarFile(); if (jarFile == null || !jarFile.exists()) { jarFile = FileHelper.searchFile(new File((new File("")).getAbsolutePath()), "jiagu.jar"); config.setJarFile(jarFile); } if (jarFile == null || !jarFile.exists() || !jarFile.isFile() || !"jiagu.jar".equals(jarFile.getName())) { error("未发现加固工具jiagu.jar"); } } private static void error(String content) { if (content != null) { System.err.println(content); } } public static BufferedReader runCmd(String command) { Runtime runtime = Runtime.getRuntime(); try { File jarFile = JiaGuConfig.build().getJarFile(); if (jarFile != null && jarFile.isFile()) { Process process = runtime.exec(command, (String[])null, jarFile.getParentFile()); return new BufferedReader(new InputStreamReader(process.getInputStream(), Charset.forName("GBK"))); } else { error("未发现jiagu.jar文件"); return null; } } catch (IOException var4) { var4.printStackTrace(); return new BufferedReader(new StringReader(var4.getMessage())); } } public static boolean runJiaGu(JiaGuConfig config) { if (config != null && config.getInputApkPath().size() > 0) { checkJiaguJar(config);//检查360加固工具是否存在,如果不存在,在当前项目目录下搜索 boolean login_success = login360JiaGu(config); if (login_success) { System.out.print("加固中。。。。\n"); FileHelper.createNewDir(JiaGuConfig.getConfig().getOutputPath()); List<String> inputApkPathList = config.getInputApkPath(); Iterator var3 = inputApkPathList.iterator(); while(var3.hasNext()) { String inputApkPath = (String)var3.next(); jiaGuOneApk(inputApkPath, config.getOutputPath()); System.out.print("360加固完成输出路径:" + config.getOutputPath()); } return true; } error("360加固宝登录不成功"); } return false; } public static boolean jiaGuOneApk(String inputApkPath, String outputPath) { String jarUtils = "java -jar jiagu.jar"; String command2 = jarUtils + " -jiagu " + inputApkPath + " " + outputPath; BufferedReader bf = runCmd(command2); String bf2Str = getBF2Str(bf); System.out.print(bf2Str); return true; } public static boolean login360JiaGu(JiaGuConfig config) { String jarUtils = "java -jar jiagu.jar"; String command1 = jarUtils + " -login " + config.getUserName() + " " + config.getPassword(); BufferedReader bufferedReader = runCmd(command1); boolean login_success = checkResultInfo(bufferedReader, "login success"); return login_success; } public static String getBF2Str(BufferedReader bf) { if (bf != null) { String line = null; StringBuilder sb = new StringBuilder(); try { while((line = bf.readLine()) != null) { sb.append(line + "\n"); } return sb.toString(); } catch (Exception var4) { var4.getMessage(); } } return ""; } public static boolean checkResultInfo(BufferedReader bufferedReader, String tag) { if (bufferedReader != null) { String line = null; StringBuilder sb = new StringBuilder(); try { while((line = bufferedReader.readLine()) != null) { sb.append(line + "\n"); if (line.contains(tag)) { System.out.println(line + "\n"); return true; } } } catch (Exception var5) { ; } } return false; } } package com.kaixin.jiagu360; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Options { private final String[] mParams; public Options(String[] params) { this.mParams = (String[])params.clone(); } public Map<String, List<String>> builder() { Map<String, List<String>> map = new HashMap(); if (this.mParams != null) { int length = this.mParams.length; List<String> list = null; for(int i = 0; i < length; ++i) { String param = this.mParams[i]; if (param != null && param.length() > 0) { if (param.startsWith("-")) { list = this.getList(map, param); } else if (list != null) { list.add(param); } } } } return map; } private List<String> getList(Map<String, List<String>> map, String key) { if (map.get(key) == null) { map.put(key, new ArrayList()); } return (List)map.get(key); } } // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.kaixin.jiagu360; import java.io.File; import java.util.ArrayList; import java.util.List; public class JiaGuConfig { private static JiaGuConfig mConfig; private List<String> mInputApkPathList = new ArrayList(); private String mOutputPath; private String mUserName; private String mPassword; private File mJarFile; public static synchronized JiaGuConfig build() { if (mConfig == null) { mConfig = new JiaGuConfig(); } return mConfig; } private JiaGuConfig() { } public JiaGuConfig addInputApkPath(String inputApkPath) { this.mInputApkPathList.add(inputApkPath); return this; } public JiaGuConfig outputPath(String outputPath) { this.mOutputPath = outputPath; return this; } public JiaGuConfig login(String userName, String password) { this.mUserName = userName; this.mPassword = password; return this; } public static JiaGuConfig getConfig() { return mConfig; } public List<String> getInputApkPath() { return this.mInputApkPathList; } public String getOutputPath() { return this.mOutputPath; } public String getUserName() { return this.mUserName; } public String getPassword() { return this.mPassword; } public File getJarFile() { return this.mJarFile; } public JiaGuConfig setJarFile(File mJarFile) { this.mJarFile = mJarFile; return this; } public JiaGuConfig setInputApkPathList(List<String> inputApkPathList) { this.mInputApkPathList = inputApkPathList; return this; } }

     

    // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.kaixin.jiagu360; import java.io.File; public class FileHelper { public FileHelper() { } public static void deleteAllFiles(File root) { if (root != null) { File[] files = root.listFiles(); if (files != null) { File[] var2 = files; int var3 = files.length; for(int var4 = 0; var4 < var3; ++var4) { File f = var2[var4]; if (f.isDirectory()) { deleteAllFiles(f); try { f.delete(); } catch (Exception var8) { ; } } else if (f.exists()) { deleteAllFiles(f); try { f.delete(); } catch (Exception var7) { ; } } } } root.delete(); } } public static void deleteAllSonFiles(File root) { if (root != null) { File[] files = root.listFiles(); if (files != null) { File[] var2 = files; int var3 = files.length; for(int var4 = 0; var4 < var3; ++var4) { File f = var2[var4]; if (f.isDirectory()) { deleteAllFiles(f); try { f.delete(); } catch (Exception var8) { ; } } else if (f.exists()) { deleteAllFiles(f); try { f.delete(); } catch (Exception var7) { ; } } } } } } public static boolean createNewDir(String dirPath) { return dirPath != null && dirPath.length() > 0 ? createNewDir(new File(dirPath)) : false; } public static boolean createNewDir(File file) { if (file != null) { if (file.exists()) { deleteAllFiles(file); return file.mkdirs(); } else { return file.mkdirs(); } } else { return false; } } public static File searchFile(File file, String fileName) { if (file != null && file.exists() && fileName != null && fileName.length() > 0) { if (file.isFile() && fileName.equals(file.getName())) { return file; } if (file.isDirectory()) { File[] var2 = file.listFiles(); int var3 = var2.length; for(int var4 = 0; var4 < var3; ++var4) { File sonFile = var2[var4]; String absolutePath1 = sonFile.getAbsolutePath(); if (sonFile.isFile()) { if (fileName.equals(sonFile.getName())) { return sonFile; } } else if (sonFile.isDirectory()) { File resultFile = searchFile(sonFile, fileName); if (resultFile != null && resultFile.isFile() && fileName.equals(resultFile.getName())) { return resultFile; } } } } } return null; } }

     

    最新回复(0)