Meituan Android resource obfuscation protection practices

Source: Internet
Author: User

Meituan Android resource obfuscation protection practices

In the original article, Meituan Android resource obfuscation protection practices, but this article does not provide a specific obfuscation solution, but only adds a function. The function implementation process needs to be implemented by yourself, this article does not implement this function, but has a preliminary preparation for implementing this function.

In the system source code of android 5.0, the code to be modified is located in

/Frameworks/base/tools/aapt/Resource. cpp

Code before modification

& set,                                  const char* resType){    String8 type8(resType);    String16 type16(resType);    bool hasErrors = false;    ResourceDirIterator it(set, String8(resType));    ssize_t res;    while ((res=it.next()) == NO_ERROR) {        if (bundle->getVerbose()) {            printf(    (new resource id %s from %s),                   it.getBaseName().string(), it.getFile()->getPrintableSource().string());        }        String16 baseName(it.getBaseName());        const char16_t* str = baseName.string();        const char16_t* const end = str + baseName.size();        while (str < end) {            if (!((*str >= 'a' && *str <= 'z')                    || (*str >= '0' && *str <= '9')                    || *str == '_' || *str == '.')) {                fprintf(stderr, %s: Invalid file name: must contain only [a-z0-9_.],                        it.getPath().string());                hasErrors = true;            }            str++;        }        String8 resPath = it.getPath();        resPath.convertToResPath();        table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()),                        type16,                        baseName,                        String16(resPath),                        NULL,                        &it.getParams());        assets->addResource(it.getLeafName(), resPath, it.getFile(), type8);    }    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;} data-snippet-id=ext.8cebe8f81e0d5a08794b2195edc114f3 data-snippet-saved=false data-csrftoken=A3eZrNtf-uh85wfj0N23af0vOzZTUPCQG7nA data-codota-status=done>static status_t makeFileResources(Bundle* bundle, const sp& assets,                                  ResourceTable* table,                                  const sp
  
   & set,                                  const char* resType){    String8 type8(resType);    String16 type16(resType);    bool hasErrors = false;    ResourceDirIterator it(set, String8(resType));    ssize_t res;    while ((res=it.next()) == NO_ERROR) {        if (bundle->getVerbose()) {            printf(    (new resource id %s from %s),                   it.getBaseName().string(), it.getFile()->getPrintableSource().string());        }        String16 baseName(it.getBaseName());        const char16_t* str = baseName.string();        const char16_t* const end = str + baseName.size();        while (str < end) {            if (!((*str >= 'a' && *str <= 'z')                    || (*str >= '0' && *str <= '9')                    || *str == '_' || *str == '.')) {                fprintf(stderr, %s: Invalid file name: must contain only [a-z0-9_.],                        it.getPath().string());                hasErrors = true;            }            str++;        }        String8 resPath = it.getPath();        resPath.convertToResPath();        table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()),                        type16,                        baseName,                        String16(resPath),                        NULL,                        &it.getParams());        assets->addResource(it.getLeafName(), resPath, it.getFile(), type8);    }    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;}
  

The Code provided by Meituan is as follows:

String8 obfuscationName;String8 obfuscationPath = getObfuscationName(resPath, obfuscationName);table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()),        type16,        baseName, // String16(obfuscationName),        String16(obfuscationPath), // resPath        NULL,        &it.getParams());assets->addResource(it.getLeafName(), obfuscationPath/*resPath*/, it.getFile(), type8);

Only the getObfuscationName function is called for obfuscation. The returned value is the path after obfuscation. Then, replace resPath with obfuscationPath in addEntry and addResource.

If we want to implement this obfuscation process by ourselves, first we need to familiarize ourselves with the meanings of some attributes, such as getBaseName, getLeafName, getParams, and convertToResPath.

GetBaseName is the name of the resource, does not contain the suffix, such as icon getleafnameis the name of the dynamic resource, with a suffix, such as icon.png getParams is to get the delimiter, such as xxhdpi-v4, get an object, can call it toString () method to convert it to the string form, that is, the previous xxhdpi-v4, note that does not contain the prefix-convertToResPath is to convert \ in the path /, for example, res \ drawable will be converted to res/drawable. This method is located in the resType class of String8. this parameter is input, representing the resource type, string8 type8 (resType) is used internally. To be converted to the String8 type, we can use it directly, but this value does not contain a qualifier, such as drawable.

In the default packaging process, the resource files are all under the res directory. Now we use some logic to transfer the resources to the r directory.

First, get the qualifier

String8 params=it.getParams().toString();

Since the qualifier may be empty, we need to use if for processing.

Define another directory to save the converted directory.

String8 obfuscationPath();

If the resource qualifier is empty, we can directly splice the directory. do not include the qualifier.

If (params. isEmpty () {obfuscationPath. append (r/); // we put it under the r directory, so the first one is r/obfuscationPath. append (type8); // Resource Type obfuscationPath. append (/); // Add/because it is the directory obfuscationPath. append (it. getLeafName (); // follow up with the full list, including the suffix}

If the qualifier is not empty, we need to splice it.

If (params. isEmpty ()){//......} else {obfuscationPath. append (r/); // we put it under the r directory, so the first one is r/obfuscationPath. append (type8); // Resource Type obfuscationPath. append (-); // Add the resource qualifier prefix-obfuscationPath. append (params); // Add the resource qualifier to obfuscationPath. append (/); // Add/because it is the directory obfuscationPath. append (it. getLeafName (); // follow up with the full list, including the suffix}

Then use obfuscationPath instead of resPath when packaging resources.

addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()),                        type16,                        baseName,                        String16(obfuscationPath),                        NULL,                        &it.getParams());        assets->addResource(it.getLeafName(), obfuscationPath, it.getFile(), type8); data-snippet-id=ext.055a61dd5a6e0e06973fbfff8bb91dbc data-snippet-saved=false data-csrftoken=K8bi3Ufd-VTXdHtvTccBK6ypOMRZNIf0iMQw data-codota-status=done>table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()),                        type16,                        baseName,                        String16(obfuscationPath),                        NULL,                        &it.getParams());        assets->addResource(it.getLeafName(), obfuscationPath, it.getFile(), type8);

The complete functions are as follows:

& set,                                  const char* resType){    String8 type8(resType);    String16 type16(resType);    bool hasErrors = false;    ResourceDirIterator it(set, String8(resType));    ssize_t res;    while ((res=it.next()) == NO_ERROR) {        if (bundle->getVerbose()) {            printf(    (new resource id %s from %s),                   it.getBaseName().string(), it.getFile()->getPrintableSource().string());        }        String16 baseName(it.getBaseName());        const char16_t* str = baseName.string();        const char16_t* const end = str + baseName.size();        while (str < end) {            if (!((*str >= 'a' && *str <= 'z')                    || (*str >= '0' && *str <= '9')                    || *str == '_' || *str == '.')) {                fprintf(stderr, %s: Invalid file name: must contain only [a-z0-9_.],                        it.getPath().string());                hasErrors = true;            }            str++;        }        String8 resPath = it.getPath();        resPath.convertToResPath();        //String8 obfuscationPath = getObfuscationName(resPath, obfuscationName);        String8 params=it.getParams().toString();        String8 obfuscationPath();        if(params.isEmpty()){            obfuscationPath.append(r/);            obfuscationPath.append(type8);            obfuscationPath.append(/);            obfuscationPath.append(it.getLeafName());        }else{            obfuscationPath.append(r/);            obfuscationPath.append(type8);            obfuscationPath.append(-);            obfuscationPath.append(params);            obfuscationPath.append(/);            obfuscationPath.append(it.getLeafName());        }        fprintf(stderr, our Path:%s,obfuscationPath.string());        table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()),                        type16,                        baseName,                        String16(obfuscationPath),                        NULL,                        &it.getParams());        assets->addResource(it.getLeafName(), obfuscationPath, it.getFile(), type8);    }    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;} data-snippet-id=ext.e9987aefeb2390d094769ac30ca644cc data-snippet-saved=false data-csrftoken=SdUZWE3g-4Be_rDkyYISJx2RRI82gvorFnv8 data-codota-status=done>static status_t makeFileResources(Bundle* bundle, const sp& assets,                                  ResourceTable* table,                                  const sp
  
   & set,                                  const char* resType){    String8 type8(resType);    String16 type16(resType);    bool hasErrors = false;    ResourceDirIterator it(set, String8(resType));    ssize_t res;    while ((res=it.next()) == NO_ERROR) {        if (bundle->getVerbose()) {            printf(    (new resource id %s from %s),                   it.getBaseName().string(), it.getFile()->getPrintableSource().string());        }        String16 baseName(it.getBaseName());        const char16_t* str = baseName.string();        const char16_t* const end = str + baseName.size();        while (str < end) {            if (!((*str >= 'a' && *str <= 'z')                    || (*str >= '0' && *str <= '9')                    || *str == '_' || *str == '.')) {                fprintf(stderr, %s: Invalid file name: must contain only [a-z0-9_.],                        it.getPath().string());                hasErrors = true;            }            str++;        }        String8 resPath = it.getPath();        resPath.convertToResPath();        //String8 obfuscationPath = getObfuscationName(resPath, obfuscationName);        String8 params=it.getParams().toString();        String8 obfuscationPath();        if(params.isEmpty()){            obfuscationPath.append(r/);            obfuscationPath.append(type8);            obfuscationPath.append(/);            obfuscationPath.append(it.getLeafName());        }else{            obfuscationPath.append(r/);            obfuscationPath.append(type8);            obfuscationPath.append(-);            obfuscationPath.append(params);            obfuscationPath.append(/);            obfuscationPath.append(it.getLeafName());        }        fprintf(stderr, our Path:%s,obfuscationPath.string());        table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()),                        type16,                        baseName,                        String16(obfuscationPath),                        NULL,                        &it.getParams());        assets->addResource(it.getLeafName(), obfuscationPath, it.getFile(), type8);    }    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;}
  

This compilation, the compilation steps refer to the previous written blog http://blog.csdn.net/sbsujjbcy/article/details/47778879.

Replace Our aapt for compilation.

Examples/examples/CvM/Co6y2 + MrHcsS/examples + examples/qOsyKvKx8 + examples/examples + PC9wPg0KPHA + PGltZyBhbHQ9 "here write picture description" src = "http://www.bkjia.com/uploads/allimg/151012/05021U0Y-1.png" title = "/>

Obviously, we have successfully transferred the files in res to the r folder. Resource obfuscation becomes simple. We refer to the obfuscation of classes in java. Our classes are obfuscated into symbols such as a, B, and c. so we only need to define a conversion function to map the original directory to, b, c and other directories, such as anim ing TO a, color ing to B ,.... And so on. Then, rename the files in the corresponding directory. If a-z is not enough, you can use aa-zz or even aaa-zzz. The key is such a conversion function.

The implementation of this function should not be difficult, but I did not write it out of my laziness. Readers are interested in modifying it based on the above Code.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.