How to randomize ProGuard dictionaries on each build?

倾然丶 夕夏残阳落幕 提交于 2021-02-19 02:24:07

问题


I found an article which introduces the concept of randomizing the dictionary entries instead of using the standard "a, b, c, ..." for class names and variables when obfuscating. He explains that tasks can be run in gradle on build to generate a randomized text file which can replace the one provided by default:

tasks.whenTaskAdded { currentTask ->
    //Android Gradle plugin may change this task name in the future
    def prefix = 'transformClassesAndResourcesWithProguardFor'
    if (currentTask.name.startsWith(prefix)) {
        def taskName = currentTask.name.replace(prefix,
                       'createProguardDictionariesFor')
        task "$taskName" {
            doLast {
                createRandomizedDictonaries()
            }
        }

        //append scramble task to proguard task
        currentTask.dependsOn "$taskName"
    }
}

However, I don't know how he runs createRandomizedDictonaries() in gradle and how he creates a text file which contains a random list of letters/integers/symbols. The logic could be something like:

  • Run a function in a class from gradle.
  • Read strings within a master text file (within the app) and adds them one by one into a string Arraylist with a loop? Potentially combine this with some randomization logic to add only X strings from text file?
  • If all the strings were added to an Arraylist, use some randomization logic to add X number of strings into another string Arraylist which is to be used for ProGuard's obfuscation.
  • Create a new text file with the randomized strings from the Arraylist.
  • Direct ProGuard to use newly generated text file for obfuscation.

Solutions for both kotlin and java are welcome.


回答1:


I found a web which is talk about use gradle to build a obfuscationdictionary. https://yrom.net/blog/2019/06/19/simple-codes-to-generate-obfuscation-dictionary/

I run the code in my gradle task, but it needs to modify a little bit. The following is my gradle code:

task genDict{
outputs.file('D:/ProjectName/build/tmp/builddict.txt')
doLast{
    def r =new Random()
    println(r)
    def begin = r.nextInt(1000) + 0x0100
    def end = begin + 0x40000
    println("end: "+end)
    def chars = (begin..end)
            .findAll { Character.isValidCodePoint(it) && Character.isJavaIdentifierPart(it) }
            .collect { String.valueOf(Character.toChars(it)) }
    println("chars: "+chars)
    int max = chars.size()
    println(max)
    def start = []
    def dict = []
    for (int i = 0; i < max; i++) {
        char c = chars.get(i).charAt(0)
        if (Character.isJavaIdentifierStart(c)) {
            start << String.valueOf(c)
        }
    }
    println(start.size())
    def f = outputs.files.getSingleFile()
    f.getParentFile().mkdirs()
    f.withWriter("UTF-8") {
        it.write(start.join(System.lineSeparator()))
        it.write()
    }
}

I think you can set your dictionary rule. This is an example. Don't forget to add the obfuscation rule in your proguard-rules.pro file

-obfuscationdictionary 'D:\ProjectName\build\tmp\builddict.txt'

-classobfuscationdictionary 'D:\ProjectName\build\tmp\builddict.txt'

-packageobfuscationdictionary 'D:\ProjectName\build\tmp\builddict.txt'



来源:https://stackoverflow.com/questions/61015798/how-to-randomize-proguard-dictionaries-on-each-build

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!