AS--›Gradle乐固加固和下载

Android Studio(AS) 同时被 2 个专栏收录
23 篇文章 0 订阅

推荐阅读, 优先了解Gradle的使用:
AS–›Gradle上传文件至七牛云
AS–›Gradle上传文件至蒲公英

说明

1.只能加固url对应的apk

由于乐固加固只能使用在线APK的url, 所以需要先将本地的APK, 上传至七牛云或者其他文件存储服务器. 拿到url之后, 才能使用乐固加固

2.需要自己手动重新签名

乐固加固后的APK, 并没有签名. 所以, 加固下载后的APK, 需要手动签名. 才能正常安装.

乐固加固

注意: IDE爆红, 不影响代码运行. 请忽视爆红.

import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.MediaType

import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.concurrent.TimeUnit
import com.google.gson.Gson

import com.tencentcloudapi.common.*
import com.tencentcloudapi.common.profile.*
import com.tencentcloudapi.common.exception.*

import com.tencentcloudapi.ms.v20180408.*
import com.tencentcloudapi.ms.v20180408.models.*


buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath "com.squareup.okhttp3:okhttp:3.12.0"
        classpath "com.google.code.gson:gson:2.8.5"
        classpath "com.tencentcloudapi:tencentcloud-sdk-java:3.0.8"
    }
}

ext.leguConfig = [
        "SecretId"       : "",
        "SecretKey"      : "",

        //需要加固的APK url地址
        "apkUrl"         : "",

        //本地APK的路径, 用来计算MD5值
        "apkPath"        : "./ademo.apk",
        //加固后, 下载保存到本地路径
        "downloadApkPath": "./ademo_legu.apk",

        //每隔多少秒, 查询一次加固结果
        "pollTime"       : "10",

        //加固后, 返回的ItemId, 用来轮询结果
        "ItemId"         : "",

        //加固成功的下载地址
        "downloadUrl"    : ""
]

task _leguJiaGu() {
    doFirst {
        Credential cred = new Credential(leguConfig.SecretId, leguConfig.SecretKey)
        HttpProfile httpProfile = new HttpProfile()
        httpProfile.setEndpoint("ms.tencentcloudapi.com")

        ClientProfile clientProfile = new ClientProfile()
        clientProfile.setHttpProfile(httpProfile)

        MsClient client = new MsClient(cred, "", clientProfile)

        def req = new CreateShieldInstanceRequest()
        def appInfo = new com.tencentcloudapi.ms.v20180408.models.AppInfo()
        appInfo.AppUrl = leguConfig.apkUrl
        appInfo.AppMd5 = getFileMd5(leguConfig.apkPath)

        def serviceInfo = new com.tencentcloudapi.ms.v20180408.models.ServiceInfo()
        serviceInfo.ServiceEdition = "basic"
        serviceInfo.SubmitSource = "RDM-rdm"
        serviceInfo.CallbackUrl = ""

        req.AppInfo = appInfo
        req.ServiceInfo = serviceInfo

        CreateShieldInstanceResponse resp = client.CreateShieldInstance(req)

        leguConfig.ItemId = resp.ItemId
        //Progress任务状态: 1-已完成,2-处理中,3-处理出错,4-处理超时
        println "加固处理中:" + DescribeShieldInstancesRequest.toJsonString(resp)

        _legtGetResult.doLast {
            println "加固结束"
        }
        _legtGetResult.execute()
    }
}

/**
 * 用户查询提交过的app列表
 * */
task _leguGetAppList() {
    doFirst {
        Credential cred = new Credential(leguConfig.SecretId, leguConfig.SecretKey)
        HttpProfile httpProfile = new HttpProfile()
        httpProfile.setEndpoint("ms.tencentcloudapi.com")

        ClientProfile clientProfile = new ClientProfile()
        clientProfile.setHttpProfile(httpProfile)

        MsClient client = new MsClient(cred, "", clientProfile)

        String params = "{}"
        DescribeShieldInstancesRequest req = DescribeShieldInstancesRequest.fromJsonString(params, DescribeShieldInstancesRequest.class)

        DescribeShieldInstancesResponse resp = client.DescribeShieldInstances(req)

        System.out.println(DescribeShieldInstancesRequest.toJsonString(resp))
    }
}

/**
 * 查询加固结果
 * */
task _legtGetResult() {
    doFirst {
        def TaskStatus = 2
        while (TaskStatus == 2) {
            println ""

            def cred = new Credential(leguConfig.SecretId, leguConfig.SecretKey)
            def httpProfile = new HttpProfile()
            httpProfile.setEndpoint("ms.tencentcloudapi.com")

            def clientProfile = new ClientProfile()
            clientProfile.setHttpProfile(httpProfile)

            def client = new MsClient(cred, "", clientProfile)

            def params = "{\"ItemId\":\"" + leguConfig.ItemId + "\"}"
            def req = DescribeShieldResultRequest.fromJsonString(params, DescribeShieldResultRequest.class)

            println leguConfig.pollTime + "s后, 查询加固状态:" + params
            Thread.sleep(Integer.parseInt(leguConfig.pollTime) * 1000L)
            def resp = client.DescribeShieldResult(req)

            TaskStatus = resp.TaskStatus

            leguConfig.downloadUrl = resp.ShieldInfo.AppUrl

            //TaskStatus任务状态: 1-已完成,2-处理中,3-处理出错,4-处理超时
            println DescribeShieldResultRequest.toJsonString(resp)
        }

        println ""

        if (TaskStatus == 1) {
            println "加固成功下载地址:" + leguConfig.downloadUrl

            println "开始下载->" + file(leguConfig.downloadApkPath).getAbsolutePath()
            downloadFile(leguConfig.downloadUrl, leguConfig.downloadApkPath)
        } else {
            println "加固失败"
        }
    }
}

static def getFileMd5(filePath) {
    def FILE_READ_BUFFER_SIZE = 16 * 1024
    MessageDigest digester = MessageDigest.getInstance("MD5")
    def stream = new FileInputStream(filePath)
    int bytesRead
    byte[] buf = new byte[FILE_READ_BUFFER_SIZE]
    while ((bytesRead = stream.read(buf)) >= 0) {
        digester.update(buf, 0, bytesRead)
    }
    def md5code = new BigInteger(1, digester.digest()).toString(16)// 16进制数字
    // 如果生成数字未满32位,需要前面补0
    for (int i = 0; i < 32 - md5code.length(); i++) {
        md5code = "0" + md5code
    }
    return md5code

}

//下载加固后的文件
static def downloadFile(url, filePath) {
    def clientBuilder = new OkHttpClient.Builder()
    clientBuilder.connectTimeout(10, TimeUnit.SECONDS)
    clientBuilder.readTimeout(60, TimeUnit.SECONDS)

    OkHttpClient client = clientBuilder.build()

    def request = new Request.Builder()
            .url(url)
            .get()
            .build()

    def response = client.newCall(request).execute()

    def write = new BufferedOutputStream(new FileOutputStream(filePath, false))
    def read = new BufferedInputStream(response.body().byteStream())

    def bytes = new byte[1024]
    def bytesRead = 0
    while ((bytesRead = read.read(bytes)) != -1) {
        write.write(bytes, 0, bytesRead)
    }
    read.close()
    write.flush()
    write.close()
}

执行: gradlew _leguJiaGu

待完善

  • 1:添加自动签名脚本
  • 2:添加Walle分包脚本

如果有小伙伴写好了, 欢迎分享给我.


群内有各(pian)种(ni)各(jin)样(qun)的大佬,等你来撩.

联系作者

点此快速加群

请使用QQ扫码加群, 小伙伴们都在等着你哦!

关注我的公众号, 每天都能一起玩耍哦!

  • 0
    点赞
  • 1
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
<p> <span style="font-size:14px;color:#337FE5;">【为什么学爬虫?】</span> </p> <p> <span style="font-size:14px;">       1、爬虫入手容易,但是深入较难,如何写出高效率的爬虫,如何写出灵活性高可扩展的爬虫都是一项技术活。另外在爬虫过程中,经常容易遇到被反爬虫,比如字体反爬、IP识别、验证码等,如何层层攻克难点拿到想要的数据,这门课程,你都能学到!</span> </p> <p> <span style="font-size:14px;">       2、如果是作为一个其他行业的开发者,比如app开发,web开发,学习爬虫能让你加强对技术的认知,能够开发出更加安全的软件网站</span> </p> <p> <br /> </p> <span style="font-size:14px;color:#337FE5;">【课程设计】</span> <p class="ql-long-10663260"> <span> </span> </p> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 一个完整的爬虫程序,无论大小,总体来说可以分成三个步骤,分别是: </p> <ol> <li class="" style="font-size:11pt;color:#494949;"> 网络请求:模拟浏览器的行为从网上抓取数据。 </li> <li class="" style="font-size:11pt;color:#494949;"> 数据解析:将请求下来的数据进行过滤,提取我们想要的数据。 </li> <li class="" style="font-size:11pt;color:#494949;"> 数据存储:将提取到的数据存储到硬盘或者内存中。比如用mysql数据库或者redis等。 </li> </ol> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 那么本课程也是按照这几个步骤循序渐进的进行讲解,带领学生完整的掌握每个步骤的技术。另外,因为爬虫的多样性,在爬取的过程中可能会发生被反爬、效率低下等。因此我们又增加了两个章节用来提高爬虫程序的灵活性,分别是: </p> <ol> <li class="" style="font-size:11pt;color:#494949;"> 爬虫进阶:包括IP代理,多线程爬虫,图形验证码识别、JS加密解密、动态网页爬虫、字体反爬识别等。 </li> <li class="" style="font-size:11pt;color:#494949;"> Scrapy分布式爬虫:Scrapy框架、Scrapy-redis组件、分布式爬虫等。 </li> </ol> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 通过爬虫进阶的知识点我们能应付大量的反爬网站,而Scrapy框架作为一个专业的爬虫框架,使用他可以快速提高我们编写爬虫程序的效率速度。另外如果一台机器不能满足你的需求,我们可以用分布式爬虫让多台机器帮助你快速爬取数据。 </p> <p style="font-size:11pt;color:#494949;">   </p> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 从基础爬虫到商业化应用爬虫,本套课程满足您的所有需求! </p> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> <br /> </p> <p> <br /> </p> <p> <span style="font-size:14px;background-color:#FFFFFF;color:#337FE5;">【课程服务】</span> </p> <p> <span style="font-size:14px;">专属付费社群+定期答疑</span> </p> <p> <br /> </p> <p class="ql-long-24357476"> <span style="font-size:16px;"><br /> </span> </p> <p> <br /> </p> <p class="ql-long-24357476"> <span style="font-size:16px;"></span> </p>
©️2020 CSDN 皮肤主题: 猿与汪的秘密 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值