当前位置: 首页 > article >正文

Android 马甲包 google市场混淆技术方案

  1. 指定 混淆字典

在app的gralde里配置混淆字典

-obfuscationdictionary dict.txt#外部字典

-classobfuscationdictionary dict.txt #类字典

-packageobfuscationdictionary dict.txt #包字典

dict.txt 文件内容类似这样的:

zguqnx

mvdmuyh

wmws

jwomtp

nhmhn

zvlogo

pomcwh

bhdnzul

osxbj

gojb

ctvkrg

srmar

sgkarnqi

byghdn

tvebtxw

uxdhno

qmjac

pgxasjnc

ezfb

tuoe

pzdo

写了一个task

/**
 * 生成字典Task
 */
task geneDictTask {
    doFirst{
        def dictPath = rootDir.getAbsolutePath()+'/app/dict.txt'
        def random = new Random()
        def lowercase = "abcdefghijklmnopqrstuvwxyz"
        def wordList = new HashSet()
        for (int i=0;i<10000;i++){
            def word = new StringBuilder()
            def wordLength = random.nextInt(5)+4
            for (int j=0;j<wordLength;j++){
                word.append(lowercase.charAt(random.nextInt(lowercase.length())))
            }
            wordList.add(word.toString())
        }
        def f = new File(dictPath)
        f.getParentFile().mkdirs()
        f.withWriter("UTF-8") {
            it.write(wordList.join(System.lineSeparator()))
        }
    }
}
//

  1. xmlClassGuard

xmlClassGuard {

/*

* 是否查找约束布局的constraint_referenced_ids属性的值,并添加到AabResGuard的白名单中,

* true的话,要求你在XmlClassGuard前依赖AabResGuard插件,默认false

*/

// findConstraintReferencedIds = true

//用于增量混淆的 mapping 文件

mappingFile = file("xml-class-mapping.txt")

//更改manifest文件的package属性,即包名

packageChange = ["com.DOTLESS.gala": "com.DOTLESS.gala"]

//移动目录

moveDir = ["com.DOTLESS.gala": "com.DOTLESS.gala"]

}

  1. 批量修改文件名

ext {
    //需要批量重命名的Been路径
    renameBeenPath = "src/main/java/com/DOTLESS/gala/bean"
    //Been对象名字以什么字符串结尾, 默认Been, 例如设为Beax, 则所有Been都会以Beax结尾, 如GoodsBeax.kt
    beenNameSuffix = "Bear"
    //Been名字的前缀, 例如KoGoodsBeen
    beenPrefix = "Ko"
    //Been对象 Been的前面加的字符串 KoGoodsFishBeen
    beenMidfix = "Fish"
    //特殊的Been比配
//    specialBeensMatcher = ["**/*Been.kt",  "**/*Been.java"]
}

task renameBeenProcesser {
    doLast {
        FileTree beenTree = fileTree(renameBeenPath) {
            include '**/*.java'
            include '**/*.kt'
//            include specialBeensMatcher
        }
        def start = System.currentTimeMillis()
        println(">>>>>> renameBeenProcesser start")
        beenTree.each { File beenFile ->
            //println(beenFile.path + " Processing...")
            def sname = beenFile.name
            def fileEx = sname.substring(sname.lastIndexOf("."))
            sname = sname.replace(fileEx, "")
            def tName = ""
//            if (sname.endsWith("Been")) {
//                tName = beenPrefix + sname.replace("Been", beenMidfix + beenNameSuffix)
//            } else if (sname.endsWith("Bean")) {
//                tName = beenPrefix + sname.replace("Bean", beenMidfix + beenNameSuffix)
//            } else {
                tName = beenPrefix + sname + beenMidfix + beenNameSuffix
//            }
            beenFile.renameTo(beenFile.parentFile.path + File.separator + tName + fileEx)
            //生成一个文件树,替换import后面的路径
            FileTree processTree = fileTree("src") {
                include '**/*.java'
                include '**/*.kt'
                include '**/layout/*.xml'
            }
            processTree.each { File f ->
                ImportBeenReplacer(f.path, sname, tName)
            }
        }
        def cost = (System.currentTimeMillis() - start) / 1000
        println(">>>>>> renameBeenProcesser end(cost:${cost}s)")
    }
}

//替换有导入目标been的文件内容
def ImportBeenReplacer(String filePath, sourceBeenName, targetBeenName) {
    def readerString = ""
    def hasReplace = false
    def xml = filePath.endsWith(".xml")
    file(filePath).withReader('UTF-8') { reader ->
        reader.eachLine {String it ->
            if (it.find(sourceBeenName)) {
                if (xml) {
                    //println("###$filePath: $sourceBeenName->$targetBeenName")
                    it = it.replaceAll("(?<![a-zA-Z0-9]+)(?<=[\\.]+)$sourceBeenName(?=[ \"\\./>]*)(?![a-zA-Z0-9]+)", targetBeenName)
                } else {
                    it = it.replaceAll("(?<![a-zA-Z0-9]+)(?<=[ \\.<:\\s\\,(]+)$sourceBeenName(?=[ \"\\.>\\?\\:\\(]*)(?![a-zA-Z0-9]+)", targetBeenName)
                }
                hasReplace = true
            }
            readerString <<= it
            readerString << '\n'
        }
    }
    if (hasReplace) {
        if(readerString.toString().endsWith("\n")) readerString = readerString.subSequence(0, readerString.length() - 1)
        //替换文件
        //println(filePath + " has replace been.")
        file(filePath).withWriter('UTF-8') {
            writer ->
                writer.append(readerString)
        }
    }
}


  1. androidJunkCode 添加垃圾代码

androidJunkCode {
    def config = {
        packageBase = "com.dotless.xthv"
        packageCount = 15
        activityCountPerPackage = 3
        excludeActivityJavaFile = false
        otherCountPerPackage = 15
        methodCountPerClass = 10
        resPrefix = "xthv_"
        drawableCount = 10
        stringCount = 10
    }
    variantConfig {
        devDebug config  //和productFlavors里的名字一样,注意不能是大写,不然会报错
        devRelease config
        publishDebug config
        publishRelease config
    }
}

http://www.kler.cn/a/1046.html

相关文章:

  • HQChart使用教程30-K线图如何对接第3方数据44-DRAWPIE数据结构
  • 【cuda学习日记】2.2 使用2维网络(grid)和2维块(block)对矩阵进行求和
  • Python爬虫基础——数据清洗
  • HTML5 网站模板
  • 【优选算法篇】:深入浅出位运算--性能优化的利器
  • 高级java每日一道面试题-2025年01月08日-微服务篇-负载平衡的意义什么 ?
  • 圣帕特里克 VoxEdit 大赛
  • CGAL 点云上采样
  • 关于我拒绝了腾讯测试开发岗offer这件事
  • 【Java】你真的懂封装吗?一文读懂封装-----建议收藏
  • [网络原理] 网络中的基本概念
  • 数据结构与算法——栈和队列<也不过如此>
  • 考虑充电负荷空间可调度特性的分布式电源与电动汽车充电站联合配置方法(Matlab代码实现)
  • 为什么需要在差分或者重要信号换层时在它们旁边加上地孔呢?
  • 什么是计数排序?
  • IP地址的分类
  • ASEMI代理瑞萨TW8825-LA1-CR汽车芯片
  • C++ 98/03 应该学习哪些知识4
  • 2023年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛(同步赛)(H题)(线段树)
  • 国产航顺HK32F030M:定时器计数/PWM输出/输出翻转/输入捕获
  • 【操作系统复习】ch3 内存基础
  • 为什么VMware会给我多创建了两个网络呢?Windows和Linux为什么可以彼此ping的通呢
  • 【文心一言】什么是文心一言,如何获得内测和使用方法。
  • 基于python的奥运会历史数据分析【120年】
  • 「Python 基础」异步 I/O 编程
  • 数据分析之Matplotilb数据可视化