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

使用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;
    }
}

 

  • 21
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值